Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#1123 , #1120 and #1121 #1131

Merged
merged 2 commits into from
May 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 : 2}
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