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