This repository has been archived by the owner on Oct 10, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGraphWorkspace.jsx
99 lines (87 loc) · 3.4 KB
/
GraphWorkspace.jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import React from 'react'
import GraphViz from './GraphViz'
import NodesTable from './NodesTable'
import Filter from './Filter'
export default class GraphWorkspace extends React.PureComponent {
propTypes: {
graph: React.PropTypes.any.isRequired
};
state = {
selectedNodes: [],
filter: {
value: '',
frequency: 0,
spread: 0,
score: 0,
},
};
componentWillReceiveProps(nextProps) {
if (nextProps.graph !== this.props.graph) {
this.setState({selectedNodes:[]});
}
}
render() {
return (
(this.props.graph && this.props.graph.nodes.length) > 0 ?
<div className="row main-container">
{this.filterBlock()}
<div className="graph-workspace">
{this.nodesBlock()}
{this.graphBlock()}
</div>
</div>
:
<div className="row graph-workspace" >
<div className="col-md-12">No data to visualize</div>
</div>
);
}
filterBlock = () => {
return <div className="filter-container">
<Filter graph={this.props.graph} onChange={this.onFilterChange}/>
</div>
};
nodesBlock = () => {
return <div className="card nodes-table-container">
<NodesTable graph={this.props.graph}
filter={this.state.filter}
selectedNodes={this.state.selectedNodes}
onSelectionAdd={this.onSelectionAdd}
onSelectionRemove={this.onSelectionRemove}/>
</div>;
};
graphBlock = () => {
return <div className="card graph-panel">
<GraphViz graph={this.props.graph}
filter={this.state.filter}
selectedNodes={this.state.selectedNodes}
onSelectionAdd={this.onSelectionAdd}
onSelectionRemove={this.onSelectionRemove}/>
</div>
};
computeDescendants(graph, currentDescendants, allDescendants = []) {
if (allDescendants.length == 0) allDescendants = currentDescendants;
let nextDescendants = _.chain(graph.edges)
.filter(edge => currentDescendants.includes(edge.origin))
.map(edge=> edge.destination).value();
allDescendants = _.concat(allDescendants, nextDescendants);
if (nextDescendants.length == 0) return allDescendants;
return this.computeDescendants(graph, nextDescendants, allDescendants);
}
onTableRemoved = (node, recursive) => {
const affectedNodes = (recursive) ? this.computeDescendants(this.props.graph, [node.nodeId]) : [node.nodeId];
let newSelected = _.filter(this.state.selectedNodes, node => !affectedNodes.includes(node.nodeId));
this.setState({selectedNodes: newSelected});
};
onSelectionAdd = (nodes) => {
const newSelected = _.unionBy(this.state.selectedNodes, nodes);
this.setState({selectedNodes: newSelected});
};
onSelectionRemove = (nodes) => {
const newSelected = _.differenceBy(this.state.selectedNodes, nodes);
this.setState({selectedNodes: newSelected});
};
onFilterChange = filter => {
this.setState({filter});
};
}