-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathChart.js
99 lines (91 loc) · 3.56 KB
/
Chart.js
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 Nodes from './Bubbles';
import Papers from './Papers';
import SubTitle from './SubTitle';
import {observer} from 'mobx-react';
import {onSVGClick, onSVGMouseOver} from '../eventhandlers/SVGEvents';
import {hasSubstring} from './Helpers';
import addWindowResizer from '../eventhandlers/WindowEvents';
import {startForceSim} from "../helpers/forceSimulation";
/**
* The Chart component.
* Renders the subtitle of the chart and the chart svg element itself.
* Connected to MobX through the observer() wrapper;
* @type {<T extends IReactComponent>(clazz: T) => void | IReactComponent | Chart}
*/
const Chart = observer(
class Chart extends React.Component {
/**
* React lifecycle hook called after the initial rendering of
* the Chart component.
* Uses d3 force methods to calculate the bubbe and paper layout.
* When done updates the current size of the svg according
* to the vis-col div's width;
*/
componentDidMount() {
// TODO show indicator/spinner while layout is calculating ?
startForceSim(this.props.store, (store) => {
this.props.store.bubblesStore.saveAllCoordsToOriginalCoords();
this.props.store.papersStore.saveAllCoordsToOriginalCoords();
this.props.store.forceSimIsDone = true;
});
this.props.store.updateDimensions();
addWindowResizer(this.props.store);
}
/**
* Renders the left column of the visualization
* containing the svg and the subtitle.
* Papers are split into 4 categories so they can be rendered
* to the svg in the correct order (last rendered element in an svg is 'topmost' element).
* @returns {*}
*/
render() {
let {
flaglessPapers,
activeEntities,
selectedEntities,
hoveredEntity,
} = this.props.store.papersStore;
const { searchString, svgWidth, svgHeight, bubblesStore } = this.props.store;
const store = this.props.store;
const { hasSelectedEntities, hasHoverEntities} = this.props.store.papersStore;
// Filter papers according to the flags they have (hover/selected/active)
// and the searchString;
// Convert them to Papers components
// searchString is the input of the list search
flaglessPapers = hasSelectedEntities ? '' :
<Papers store={store} papers={flaglessPapers.filter((paper) => hasSubstring(paper, searchString))}/>;
const activePapers = hasSelectedEntities ? '' :
<Papers store={store} papers={activeEntities.filter((paper) => hasSubstring(paper, searchString))}/>;
const selectedPapers = !hasSelectedEntities ? '' :
<Papers store={store} papers={selectedEntities.filter((paper) => hasSubstring(paper, searchString))}/>;
const hoverPapers = !hasHoverEntities ? '' :
<Papers store={store} papers={hoveredEntity.filter((paper) => hasSubstring(paper, searchString))}/>;
return (
/* HTML starts here */
<div className="vis-col">
<SubTitle store={store}/>
<div id="headstart-chart">
<svg
width={svgWidth}
height={svgHeight}
id="chart-svg"
onClick={onSVGClick.bind(this, store)}
onMouseOver={onSVGMouseOver.bind(this, store)}
>
<g id="chart_canvas">
<rect width={svgWidth} height={svgHeight}/>
{flaglessPapers}
<Nodes store={store} nodes={bubblesStore}/>
{activePapers}
{selectedPapers}
{hoverPapers}
</g>
</svg>
</div>
</div>
/* HTML ends here */
)
}
});
export default Chart;