@@ -2,225 +2,217 @@ import React, { Component } from 'react';
2
2
import '../styles/components/_d3Tree.scss' ;
3
3
import * as d3 from 'd3' ;
4
4
5
- var root = { } ;
5
+ let root = { } ;
6
6
let duration = 750 ;
7
7
8
8
9
9
class Chart extends Component {
10
- constructor ( props ) {
11
- super ( props ) ;
12
- }
13
-
14
10
componentDidMount ( ) {
15
11
root = JSON . parse ( JSON . stringify ( this . props . snapshot ) ) ;
16
12
this . maked3Tree ( ) ;
17
13
}
18
14
19
- componentWillUpdate ( newProps ) {
20
- if ( this . props . snapshot !== newProps . snapshot ) {
21
- root = JSON . parse ( JSON . stringify ( newProps . snapshot ) ) ;
22
- this . maked3Tree ( ) ;
23
- }
15
+ componentDidUpdate ( ) {
16
+ root = JSON . parse ( JSON . stringify ( this . props . snapshot ) ) ;
17
+ this . maked3Tree ( ) ;
24
18
}
25
-
19
+
26
20
removed3Tree ( ) {
27
21
const { anchor } = this . refs ;
28
22
while ( anchor . hasChildNodes ( ) ) {
29
23
anchor . removeChild ( anchor . lastChild ) ;
30
24
}
31
25
}
32
-
33
- maked3Tree ( ) {
26
+
27
+ maked3Tree ( ) {
34
28
this . removed3Tree ( ) ;
35
- duration = 0 ;
36
-
37
- var margin = { top : 20 , right : 120 , bottom : 20 , left : 120 } ,
38
- width = 600 - margin . right - margin . left ,
39
- height = 600 - margin . top - margin . bottom ;
40
-
41
- var i = 0 ;
42
-
43
- var tree = d3 . layout . tree ( )
44
- . nodeSize ( [ 20 , ] )
45
- . separation ( function separation ( a , b ) {
46
- return a . parent == b . parent ? 3 : 1 ;
47
- } ) ;
48
-
49
- var diagonal = d3 . svg . diagonal ( )
50
- . projection ( function ( d ) { return [ d . y , d . x ] ; } ) ;
51
-
52
- var svg = d3 . select ( this . refs . anchor ) . append ( "svg" )
53
- . attr ( "width" , "100%" )
54
- . attr ( "height" , "100%" )
55
- . attr ( "cursor" , "-webkit-grab" )
56
- . attr ( "preserveAspectRatio" , "xMinYMin slice" )
57
- . call ( d3 . behavior . zoom ( ) . on ( "zoom" , function ( ) {
58
- svg . attr ( "transform" , "translate(" + d3 . event . translate + ")" + " scale(" + d3 . event . scale + ")" )
59
- } ) )
60
- . append ( "g" )
61
- . attr ( "transform" , "translate(" + 60 + "," + height / 2 + ")" )
29
+ duration = 0 ;
30
+
31
+ const margin = { top : 20 , right : 120 , bottom : 20 , left : 120 } ;
32
+ const width = 600 - margin . right - margin . left ;
33
+ const height = 600 - margin . top - margin . bottom ;
34
+
35
+ let i = 0 ;
36
+
37
+ const tree = d3 . layout . tree ( )
38
+ . nodeSize ( [ 20 ] )
39
+ . separation ( ( a , b ) => ( a . parent === b . parent ? 3 : 1 ) ) ;
40
+
41
+ const diagonal = d3 . svg . diagonal ( )
42
+ . projection ( d => [ d . y , d . x ] ) ;
43
+
44
+ const svg = d3 . select ( this . refs . anchor ) . append ( 'svg' )
45
+ . attr ( 'width' , '100%' )
46
+ . attr ( 'height' , '100%' )
47
+ . attr ( 'cursor' , '-webkit-grab' )
48
+ . attr ( 'preserveAspectRatio' , 'xMinYMin slice' )
49
+ . call ( d3 . behavior . zoom ( ) . on ( 'zoom' , ( ) => svg . attr ( 'transform' , `translate(${ d3 . event . translate } ) scale(${ d3 . event . scale } )` ) ) )
50
+ . append ( 'g' )
51
+ . attr ( 'transform' , `translate(60,${ height / 2 } )` ) ;
62
52
63
53
// Add tooltip div
64
- var div = d3 . select ( " body" ) . append ( " div" )
65
- . attr ( " class" , " tooltip" )
66
- . style ( " opacity" , 1e-6 )
67
- . on ( " mouseover" , tipMouseover )
68
- . on ( " mouseout" , tipMouseout )
54
+ const div = d3 . select ( ' body' ) . append ( ' div' )
55
+ . attr ( ' class' , ' tooltip' )
56
+ . style ( ' opacity' , 1e-6 )
57
+ . on ( ' mouseover' , tipMouseover )
58
+ . on ( ' mouseout' , tipMouseout )
69
59
70
60
root . x0 = height / 2 ;
71
61
root . y0 = 0 ;
72
-
62
+
73
63
function update ( source ) {
74
- // Compute the new tree layout.
75
- var nodes = tree . nodes ( root ) . reverse ( ) ,
76
- links = tree . links ( nodes ) ;
77
-
78
- // Normalize for fixed-depth.
79
- nodes . forEach ( function ( d ) { d . y = d . depth * 180 ; } ) ;
80
-
81
- // Update the nodes…
82
- var node = svg . selectAll ( "g.node" )
83
- . data ( nodes , function ( d ) { return d . id || ( d . id = ++ i ) ; } ) ;
84
-
85
- // Enter any new nodes at the parent's previous position.
86
- var nodeEnter = node . enter ( ) . append ( "g" )
87
- . attr ( "class" , "node" )
88
- . attr ( "transform" , function ( d ) { return "translate(" + source . y0 + "," + source . x0 + ")" ; } )
89
- . on ( "click" , click )
90
- . on ( "mouseover" , mouseover )
91
- . on ( "mouseout" , mouseout )
92
- . on ( "mousemove" , function ( d ) { mousemove ( d ) ; } ) ;
93
-
94
-
95
- nodeEnter . append ( "circle" )
96
- . attr ( "r" , 1e-6 )
97
- . style ( "fill" , function ( d ) { return d . _children ? "lightsteelblue" : "#fff" ; } ) ;
98
-
99
- nodeEnter . append ( "text" )
100
- . attr ( "x" , function ( d ) { return d . children || d . _children ? - 10 : 10 ; } )
101
- . attr ( "dy" , ".35em" )
102
- . attr ( "text-anchor" , function ( d ) { return d . children || d . _children ? "end" : "start" ; } )
103
- . text ( function ( d ) { return d . name ; } )
104
- . style ( 'fill' , '#6FB3D2' )
105
- . style ( "fill-opacity" , 1e-6 ) ;
106
-
107
- // Transition nodes to their new position.
108
- var nodeUpdate = node . transition ( )
109
- . duration ( duration )
110
- . attr ( "transform" , function ( d ) { return "translate(" + d . y + "," + d . x + ")" ; } ) ;
111
-
112
- nodeUpdate . select ( "circle" )
113
- . attr ( "r" , 7 )
114
- . style ( "fill" , function ( d ) { return d . _children ? "#A1C658" : "#D381C3" ; } ) ;
115
-
116
- nodeUpdate . select ( "text" )
117
- . style ( "fill-opacity" , 1 ) ;
118
-
119
- // Transition exiting nodes to the parent's new position.
120
- var nodeExit = node . exit ( ) . transition ( )
121
- . duration ( duration )
122
- . attr ( "transform" , function ( d ) { return "translate(" + source . y + "," + source . x + ")" ; } )
123
- . remove ( ) ;
124
-
125
- nodeExit . select ( "circle" )
126
- . attr ( "r" , 1e-6 ) ;
127
-
128
- nodeExit . select ( "text" )
129
- . style ( "fill-opacity" , 1e-6 ) ;
130
-
131
- // Update the links…
132
- var link = svg . selectAll ( "path.link" )
133
- . data ( links , function ( d ) { return d . target . id ; } ) ;
134
-
135
- // Enter any new links at the parent's previous position.
136
- link . enter ( ) . insert ( "path" , "g" )
137
- . attr ( "class" , "link" )
138
- . attr ( "d" , function ( d ) {
139
- var o = { x : source . x0 , y : source . y0 } ;
140
- return diagonal ( { source : o , target : o } ) ;
141
- } ) ;
142
-
143
- // Transition links to their new position.
144
- link . transition ( )
145
- . duration ( duration )
146
- . attr ( "d" , diagonal ) ;
147
-
148
- // Transition exiting nodes to the parent's new position.
149
- link . exit ( ) . transition ( )
150
- . duration ( duration )
151
- . attr ( "d" , function ( d ) {
152
- var o = { x : source . x , y : source . y } ;
153
- return diagonal ( { source : o , target : o } ) ;
154
- } )
155
- . remove ( ) ;
156
-
157
- // Stash the old positions for transition.
158
- nodes . forEach ( function ( d ) {
64
+ // Compute the new tree layout.
65
+ const nodes = tree . nodes ( root ) . reverse ( ) ;
66
+ const links = tree . links ( nodes ) ;
67
+
68
+ // Normalize for fixed-depth.
69
+ nodes . forEach ( ( d ) => { d . y = d . depth * 180 ; } ) ;
70
+
71
+ // Update the nodes…
72
+ const node = svg . selectAll ( 'g.node' )
73
+ . data ( nodes , ( d ) => {
74
+ if ( ! d . id ) d . id = ++ i ;
75
+ return d . id ;
76
+ } ) ;
77
+
78
+ // Enter any new nodes at the parent's previous position.
79
+ const nodeEnter = node . enter ( ) . append ( 'g' )
80
+ . attr ( 'class' , 'node' )
81
+ . attr ( 'transform' , ( ) => `translate(${ source . y0 } ,${ source . x0 } )` )
82
+ . on ( 'click' , click )
83
+ . on ( 'mouseover' , mouseover )
84
+ . on ( 'mouseout' , mouseout )
85
+ . on ( 'mousemove' , d => mousemove ( d ) ) ;
86
+
87
+ nodeEnter . append ( 'circle' )
88
+ . attr ( 'r' , 1e-6 )
89
+ . style ( 'fill' , d => ( d . _children ? 'lightsteelblue' : '#fff' ) ) ;
90
+
91
+ nodeEnter . append ( 'text' )
92
+ . attr ( 'x' , d => ( d . children || d . _children ? - 10 : 10 ) )
93
+ . attr ( 'dy' , '.35em' )
94
+ . attr ( 'text-anchor' , d => ( d . children || d . _children ? 'end' : 'start' ) )
95
+ . text ( d => d . name )
96
+ . style ( 'fill' , '#6FB3D2' )
97
+ . style ( 'fill-opacity' , 1e-6 ) ;
98
+
99
+ // Transition nodes to their new position.
100
+ const nodeUpdate = node . transition ( )
101
+ . duration ( duration )
102
+ . attr ( 'transform' , d => `translate(${ d . y } ,${ d . x } )` ) ;
103
+
104
+ nodeUpdate . select ( 'circle' )
105
+ . attr ( 'r' , 7 )
106
+ . style ( 'fill' , d => ( d . _children ? '#A1C658' : '#D381C3' ) ) ;
107
+
108
+ nodeUpdate . select ( 'text' )
109
+ . style ( 'fill-opacity' , 1 ) ;
110
+
111
+ // Transition exiting nodes to the parent's new position.
112
+ const nodeExit = node . exit ( ) . transition ( )
113
+ . duration ( duration )
114
+ . attr ( 'transform' , ( ) => `translate(${ source . y } ,${ source . x } )` )
115
+ . remove ( ) ;
116
+
117
+ nodeExit . select ( 'circle' )
118
+ . attr ( 'r' , 1e-6 ) ;
119
+
120
+ nodeExit . select ( 'text' )
121
+ . style ( 'fill-opacity' , 1e-6 ) ;
122
+
123
+ // Update the links…
124
+ const link = svg . selectAll ( 'path.link' )
125
+ . data ( links , d => d . target . id ) ;
126
+
127
+ // Enter any new links at the parent's previous position.
128
+ link . enter ( ) . insert ( 'path' , 'g' )
129
+ . attr ( 'class' , 'link' )
130
+ . attr ( 'd' , ( ) => {
131
+ const o = { x : source . x0 , y : source . y0 } ;
132
+ return diagonal ( { source : o , target : o } ) ;
133
+ } ) ;
134
+
135
+ // Transition links to their new position.
136
+ link . transition ( )
137
+ . duration ( duration )
138
+ . attr ( 'd' , diagonal ) ;
139
+
140
+ // Transition exiting nodes to the parent's new position.
141
+ link . exit ( ) . transition ( )
142
+ . duration ( duration )
143
+ . attr ( 'd' , ( ) => {
144
+ const o = { x : source . x , y : source . y } ;
145
+ return diagonal ( { source : o , target : o } ) ;
146
+ } )
147
+ . remove ( ) ;
148
+
149
+ // Stash the old positions for transition.
150
+ nodes . forEach ( ( d ) => {
159
151
d . x0 = d . x ;
160
152
d . y0 = d . y ;
161
- } ) ;
153
+ } ) ;
162
154
}
163
-
155
+
164
156
// Toggle children on click.
165
157
function click ( d ) {
166
- if ( d . children ) {
158
+ if ( d . children ) {
167
159
d . _children = d . children ;
168
160
d . children = null ;
169
- } else {
161
+ } else {
170
162
d . children = d . _children ;
171
163
d . _children = null ;
172
- }
173
- update ( d ) ;
164
+ }
165
+ update ( d ) ;
174
166
}
175
167
176
168
// Show state on mouse over
177
169
function mouseover ( ) {
178
- div . transition ( )
179
- . duration ( 300 )
180
- . style ( " display" , " block" )
181
- . style ( " opacity" , 1 )
170
+ div . transition ( )
171
+ . duration ( 300 )
172
+ . style ( ' display' , ' block' )
173
+ . style ( ' opacity' , 1 )
182
174
}
183
-
175
+
184
176
function mouseout ( ) {
185
- div . transition ( )
186
- . duration ( 3000 )
187
- . style ( " opacity" , 1e-6 )
188
- . style ( " display" , " none" ) ;
177
+ div . transition ( )
178
+ . duration ( 3000 )
179
+ . style ( ' opacity' , 1e-6 )
180
+ . style ( ' display' , ' none' ) ;
189
181
}
190
182
191
- function tipMouseover ( ) {
192
- div . transition ( )
193
- . duration ( 300 )
194
- . style ( " opacity" , 1 ) ;
183
+ function tipMouseover ( ) {
184
+ div . transition ( )
185
+ . duration ( 300 )
186
+ . style ( ' opacity' , 1 ) ;
195
187
}
196
188
197
189
function tipMouseout ( ) {
198
- div . transition ( )
199
- . duration ( 3000 )
200
- . style ( " opacity" , 1e-6 )
201
- . style ( " display" , " none" ) ;
190
+ div . transition ( )
191
+ . duration ( 3000 )
192
+ . style ( ' opacity' , 1e-6 )
193
+ . style ( ' display' , ' none' ) ;
202
194
}
203
195
204
- function mousemove ( d ) {
205
- div
206
- . text ( d . state == undefined ? 'No state found' : JSON . stringify ( d . state , null , 4 ) )
207
- . style ( " left" , ( d3 . event . pageX ) + "px" )
208
- . style ( " top" , ( d3 . event . pageY ) + "px" ) ;
196
+ function mousemove ( d ) {
197
+ div
198
+ . text ( ! d . state ? 'No state found' : JSON . stringify ( d . state , null , 4 ) )
199
+ . style ( ' left' , ` ${ d3 . event . pageX } px` )
200
+ . style ( ' top' , ` ${ d3 . event . pageY } px` ) ;
209
201
}
210
-
202
+
211
203
function collapse ( d ) {
212
- if ( d . children ) {
204
+ if ( d . children ) {
213
205
d . _children = d . children ;
214
206
d . _children . forEach ( collapse ) ;
215
207
d . children = null ;
216
- }
208
+ }
217
209
}
218
-
210
+
219
211
update ( root ) ;
220
212
duration = 750 ;
221
-
222
- // root.children.forEach(collapse);
223
- }
213
+
214
+ // root.children.forEach(collapse);
215
+ }
224
216
225
217
render ( ) {
226
218
return < div ref = "anchor" className = "d3Container" /> ;
0 commit comments