Skip to content

Commit

Permalink
#1123 Layout styling issues in circuit browser configuration panel.
Browse files Browse the repository at this point in the history
#1120 Implement circuit browser clear button #1121 Adds flip button to
flip 2 neurons.
  • Loading branch information
jrmartin committed May 10, 2021
1 parent a90a8fe commit a0104f4
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 40 deletions.
123 changes: 87 additions & 36 deletions components/interface/VFBCircuitBrowser/Controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import MoreVertIcon from '@material-ui/icons/MoreVert';
import Button from '@material-ui/core/Button';
import IconButton from '@material-ui/core/IconButton';
import DeleteIcon from '@material-ui/icons/Delete';
import SwapVertIcon from '@material-ui/icons/SwapVert';
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
import { createMuiTheme, ThemeProvider } from '@material-ui/core/styles';
import { connect } from "react-redux";
Expand Down Expand Up @@ -70,7 +71,8 @@ const styles = theme => ({
},
expanded: { minHeight : "15px !important", margin : "0px !important" },
// Override default padding in Add Neuron button
addNeuron : { padding : "2vh 2vh 0px 2px" },
addNeuron : { padding : "0px" },
reverseNeurons : { padding : "0 !important" },
// Override default padding in Delete Neuron button
deleteNeuron : { padding : "2vh 0px 0px 4px" },
dottedIcon : { margin : "1rem 0 1rem 0 " },
Expand All @@ -91,7 +93,14 @@ const styles = theme => ({
height : "2vh",
width : "2vh"
},
weightInput : { color : "white !important", height : "20px", border : "none !important", backgroundColor: "#80808040 !important", paddingLeft : "10px !important" }
weightInput : {
color : "white !important",
height : "20px",
border : "none !important",
backgroundColor: "#80808040 !important",
paddingLeft : "10px !important"
},
weightInputDiv : { width : "100% !important" }
});

/**
Expand Down Expand Up @@ -190,11 +199,13 @@ class Controls extends Component {
super(props);
this.state = {
typingTimeout: 0,
expanded : true
expanded : true,
key : 1
};
this.weight = this.props.weight;
this.hops = this.props.hops;
this.addNeuron = this.addNeuron.bind(this);
this.reverseNeurons = this.reverseNeurons.bind(this);
this.neuronTextfieldModified = this.neuronTextfieldModified.bind(this);
this.typingTimeout = this.typingTimeout.bind(this);
this.sliderChange = this.sliderChange.bind(this);
Expand All @@ -203,6 +214,7 @@ class Controls extends Component {
this.deleteNeuronField = this.deleteNeuronField.bind(this);
this.getUpdatedNeuronFields = this.getUpdatedNeuronFields.bind(this);
this.resultSelectedChanged = this.resultSelectedChanged.bind(this);
this.setNeurons = this.setNeurons.bind(this);
this.circuitQuerySelected = this.props.circuitQuerySelected;
this.autoCompleteInput = React.createRef();
this.neuronFields = [{ id : "", label : "" } , { id : "", label : "" }];
Expand Down Expand Up @@ -257,6 +269,18 @@ class Controls extends Component {
this.autocompleteRef[(neuronFields.length - 1).toString()] = React.createRef();
this.forceUpdate();
}

/**
* Reverse neurons textfield
*/
reverseNeurons () {
let neuronFields = this.neuronFields;
[neuronFields[0], neuronFields[neuronFields.length - 1]] = [neuronFields[neuronFields.length - 1], neuronFields[0]]
// User has added the maximum number of neurons allowed in query search
this.neuronFields = neuronFields;
this.autocompleteRef[(neuronFields.length - 1).toString()] = React.createRef();
this.forceUpdate();
}

/**
* Validates neurons ID's are valid, checks there's at least 8 numbers in it
Expand Down Expand Up @@ -341,6 +365,13 @@ class Controls extends Component {
this.weight = event.target.value;
}

setNeurons () {
this.neuronFields = [{ id : "", label : "" } , { id : "", label : "" }];
while (this?.props?.circuitQuerySelected.length > 0) {
this?.props?.circuitQuerySelected.pop();
}
this.setState({ key: Math.random() });
}
/**
* Update neuron fields if there's a query preselected.
*/
Expand Down Expand Up @@ -394,10 +425,10 @@ class Controls extends Component {
return (
<ThemeProvider theme={theme}>
<div>
<div style={ { position: "absolute", width: "2vh", height: "100px",zIndex: "100" } }>
<div style={ { position: "absolute", width: ".75vh", height: "10vh",zIndex: "100" } }>
<i style={ { zIndex : "1000" , cursor : "pointer", top : "10px", left : "10px" } } className={stylingConfiguration.controlIcons.home} onClick={self.props.resetCamera }></i>
<i style={ { zIndex : "1000" , cursor : "pointer", marginTop : "20px", left : "10px" } } className={stylingConfiguration.controlIcons.zoomIn} onClick={self.props.zoomIn }></i>
<i style={ { zIndex : "1000" , cursor : "pointer", marginTop : "5px", left : "10px" } } className={stylingConfiguration.controlIcons.zoomOut} onClick={self.props.zoomOut }></i>
<i style={ { zIndex : "1000" , cursor : "pointer", marginTop : "5px", left : "10px" } } className={stylingConfiguration.controlIcons.zoomOut} onClick={self.props.clear }></i>
</div>
{ this.props.resultsAvailable()
? <ul className={classes.legend} id="circuitBrowserLegend">
Expand All @@ -408,7 +439,7 @@ class Controls extends Component {
</ul>
: null
}
<Accordion className={classes.root} defaultExpanded={expanded} >
<Accordion key={this.state.key} className={classes.root} defaultExpanded={expanded} >
<AccordionSummary
expandIcon={<ExpandMoreIcon fontSize="large" />}
onClick={() => self.setState({ expanded : !expanded })}
Expand All @@ -420,15 +451,15 @@ class Controls extends Component {
</div>
</AccordionSummary>
<AccordionDetails classes={{ root : classes.details }}>
<Grid container justify="center" alignItems="center">
<Grid container style={ { margin : "2vh 2vh 0 0" } } item sm={1} justify="center" alignItems="center">
<Grid container justify="space-between" alignItems="center">
<Grid item sm={1} justify="center" alignItems="center">
<div>
<AdjustIcon />
<MoreVertIcon classes={{ root : classes.dottedIcon }}/>
<RoomIcon />
</div>
</Grid>
<Grid id="neuronFieldsGrid" item sm={10}>
<Grid style={ { marginRight : "1vh !important" } } id="neuronFieldsGrid" item sm={9}>
{ neuronFields.map((field, index) => (
<Grid container alignItems="center" justify="center" key={"TextFieldContainer" + index}>
<Grid item sm={neuronColumnSize} key={"TextFieldItem" + index}>
Expand All @@ -455,35 +486,46 @@ class Controls extends Component {
</Grid>
))}
</Grid>
<Grid item sm={2} classes={{ root : classes.addNeuron }}>
{ addNeuronDisabled
? null
: <IconButton
id="addNeuron"
color="inherit"
size="small"
onClick={this.addNeuron}
>
<AddCircleOutlineIcon />
</IconButton>
}
</Grid>
<Grid item sm={10} classes={{ root : classes.addNeuron }}>
{ addNeuronDisabled
? null
: <Typography>Add Neuron</Typography>
}
<Grid item justify="space-between" alignItems="center" sm={1}>
<IconButton
id="reverseNeurons"
color="inherit"
size="medium"
className={classes.reverseNeurons}
onClick={this.reverseNeurons}
style={ { paddingLeft : "1vh" } }
>
<SwapVertIcon fontSize="large" />
</IconButton>
</Grid>
{ addNeuronDisabled
? null
: <Grid container style={ { marginTop : "1vh" } } justify="space-between" alignItems="center">
<Grid item sm={2} classes={{ root : classes.addNeuron }}>
<IconButton
id="addNeuron"
color="inherit"
size="small"
onClick={this.addNeuron}
>
<AddCircleOutlineIcon />
</IconButton>
</Grid>
<Grid item sm={10} classes={{ root : classes.addNeuron }}>
<Typography>Add Neuron</Typography>
</Grid>
</Grid>
}
</Grid>
</AccordionDetails>
<Divider />
<AccordionActions>
<Grid container justify="center" alignItems="center" >
<Grid container justify="space-between" alignItems="center" >
<Grid container spacing={1}>
<Grid item sm={2}>
<Grid item sm={3}>
<Typography># Paths</Typography>
</Grid>
<Grid item sm={10}>
<Grid item sm={9}>
<Slider
aria-labelledby="discrete-slider-always"
defaultValue={this.hops}
Expand All @@ -496,21 +538,30 @@ class Controls extends Component {
/>
</Grid>
</Grid>
<Grid container alignItems="flex-end">
<Grid item sm={2}>
<Grid container spacing={1} alignItems="flex-end">
<Grid item sm={3}>
<Typography>Min Weight</Typography>
</Grid>
<Grid item sm={4}>
<Input label="Graph weight" defaultValue={this.weight} onChange={this.weightChange} inputProps={{ 'aria-label': 'description', id : "weightField", className : classes.weightInput }} />
<Grid item sm={9}>
<Input className={classes.weightInputDiv} label="Graph weight" defaultValue={this.weight} onChange={this.weightChange} inputProps={{ 'aria-label': 'description', id : "weightField", className : classes.weightInput }} />
</Grid>
<Grid item container justify="flex-end" sm={6}>
<Button
color="primary"
variant="contained"
size="small"
className="MuiGrid-grid-sm-12"
id="refreshCircuitBrowser"
onClick={() => this.props.updateGraph(this.neuronFields, this.hops, this.weight)}
>Refresh Graph</Button>
>Refresh</Button>
</Grid>
<Grid item container justify="flex-end" sm={6}>
<Button
color="secondary"
variant="contained"
className="MuiGrid-grid-sm-12"
id="clearCircuitBrowser"
onClick={() => this.props.clearGraph()}
>Clear</Button>
</Grid>
</Grid>
</Grid>
Expand Down
30 changes: 26 additions & 4 deletions components/interface/VFBCircuitBrowser/VFBCircuitBrowser.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class VFBCircuitBrowser extends Component {
this.resetCamera = this.resetCamera.bind(this);
this.zoomIn = this.zoomIn.bind(this);
this.zoomOut = this.zoomOut.bind(this);
this.clearGraph = this.clearGraph.bind(this);
this.queriesUpdated = this.queriesUpdated.bind(this);
this.updateHops = this.updateHops.bind(this);
this.updateWeight = this.updateWeight.bind(this);
Expand All @@ -77,6 +78,7 @@ class VFBCircuitBrowser extends Component {
this.hoverNode = null;

this.graphRef = React.createRef();
this.controlsRef = React.createRef();
this.__isMounted = false;
this.objectsLoaded = 0;
this.focused = false;
Expand Down Expand Up @@ -170,6 +172,11 @@ class VFBCircuitBrowser extends Component {
}
this.graphRef.current.ggv.current.zoom(zoom - out , 100);
}

clearGraph () {
this.setState({ neurons : [{ id : "", label : "" } , { id : "", label : "" }], graph : { nodes : [], links : [] } });
this.controlsRef.current.setNeurons()
}

/**
* Handle Left click on Nodes
Expand Down Expand Up @@ -238,8 +245,15 @@ class VFBCircuitBrowser extends Component {
}
};

let params = {
results: response.data,
configuration : configuration,
styling : stylingConfiguration,
NODE_WIDTH : NODE_WIDTH, NODE_HEIGHT : NODE_HEIGHT
}

// Invoke web worker to perform conversion of graph data into format
worker.postMessage({ message: "refine", params: { results: response.data, configuration : configuration, styling : stylingConfiguration, NODE_WIDTH : NODE_WIDTH, NODE_HEIGHT : NODE_HEIGHT } });
worker.postMessage({ message: "refine", params: params });
})
.catch( function (error) {
self.setState( { loading : false } );
Expand Down Expand Up @@ -309,6 +323,8 @@ class VFBCircuitBrowser extends Component {
circuitQuerySelected={this.circuitQuerySelected}
datasource="SOLR"
legend = {self.state.legend}
ref={self.controlsRef}
clearGraph={self.clearGraph}
/>
</div>
: <GeppettoGraphVisualization
Expand All @@ -322,8 +338,8 @@ class VFBCircuitBrowser extends Component {
linkLabel={link => link.label}
// Width of links, log(weight)
linkWidth={link => link.weight ? Math.log(link.weight) : 1 }
linkCurvature='curvature'
linkDirectionalArrowLength={link => link.weight ? Math.log(link.weight) * 3 : .5}
linkCurvature={.075}
linkDirectionalArrowLength={link => link.weight ? Math.log(link.weight) * 5 : 4}
linkDirectionalArrowRelPos={.75}
linkCanvasObject={(link, ctx) => {
const MAX_FONT_SIZE = 5;
Expand Down Expand Up @@ -501,7 +517,11 @@ class VFBCircuitBrowser extends Component {
nodeCanvasObjectMode={node => 'replace'}
// bu = Bottom Up, creates Graph with root at bottom
dagMode="lr"
dagLevelDistance = {100}
nodeVal = { node => {
node.fx = node.level == 0 ? node.positionX : node.fx ? node.fx : 0 ;
node.fy = node.level > 0 ? -100 * node.level : node.fy ? node.fy : 0 ;
}}
dagLevelDistance = {25}
onDagError={loopNodeIds => {}}
// Handles clicking event on an individual node
onNodeClick = { (node,event) => this.handleNodeLeftClick(node,event) }
Expand All @@ -525,8 +545,10 @@ class VFBCircuitBrowser extends Component {
resetCamera={self.resetCamera}
zoomIn={self.zoomIn}
zoomOut={self.zoomOut}
clearGraph={self.clearGraph}
circuitQuerySelected={this.circuitQuerySelected}
legend = {self.state.legend}
ref={self.controlsRef}
/>
}
// Function triggered when hovering over a nodeoptions
Expand Down

0 comments on commit a0104f4

Please sign in to comment.