1
+ import * as d3 from 'd3' ;
2
+ import StudentData from "../Data1.json" ;
3
+ import React , { useLayoutEffect } from "react" ;
4
+
5
+ function D3Tree ( props ) {
6
+ useLayoutEffect ( ( ) => {
7
+ var width = window . innerWidth ;
8
+ var height = window . innerHeight ;
9
+
10
+ var svg = d3 . select ( "#tree" )
11
+ . append ( "svg" ) . attr ( "width" , width ) . attr ( "height" , height )
12
+ . call ( d3 . zoom ( ) . on ( "zoom" , function ( event ) {
13
+ svg . attr ( "transform" , event . transform )
14
+ } ) )
15
+ . append ( "g" )
16
+ . attr ( "transform" , "translate(" + width / 2 + "," + height / 3 + ")" ) ;
17
+ var data = props . TreeData ;
18
+
19
+ var treemap = d3 . tree ( ) . size ( [ height , width ] ) . nodeSize ( [ 120 , 40 ] ) ;
20
+
21
+ var stratify = d3 . stratify ( ) . id ( d => d . rollNo ) . parentId ( d => d . parentId ) ;
22
+ var root = stratify ( data ) ;
23
+
24
+ var i = 0 ;
25
+ var duration = 750 ;
26
+
27
+ root . x0 = height / 2 ;
28
+ root . y0 = 0 ;
29
+
30
+ if ( root . children ) {
31
+ root . children . forEach ( collapse ) ; }
32
+ function collapse ( d ) {
33
+ if ( d . children ) {
34
+ d . _children = d . children
35
+ d . _children . forEach ( collapse )
36
+ d . children = null
37
+ }
38
+ }
39
+ update ( root ) ;
40
+
41
+ function update ( source ) {
42
+ var treeData = treemap ( root ) ;
43
+
44
+ var nodes = treeData . descendants ( ) ,
45
+ links = treeData . descendants ( ) . slice ( 1 ) ;
46
+
47
+ nodes . forEach ( function ( d ) {
48
+ d . y = d . depth * 180 ;
49
+ } ) ;
50
+
51
+
52
+ var node = svg . selectAll ( 'g.node' )
53
+ . data ( nodes , function ( d ) { return d . id || ( d . id = ++ i ) ; } ) ;
54
+
55
+ var nodeEnter = node . enter ( ) . append ( 'g' )
56
+ . attr ( 'class' , 'node' )
57
+ . attr ( "transform" , function ( d ) {
58
+ return "translate(" + source . x0 + "," + source . y0 + ")" ;
59
+ } )
60
+ . on ( 'click' , click )
61
+ . on ( "mouseover" , function ( d , node ) {
62
+ updateChildren ( d , node )
63
+ var g = d3 . select ( this ) ;
64
+ if ( g . property ( "childNodes" ) . length < 3 ) {
65
+ g . append ( 'circle' )
66
+ . attr ( 'class' , 'button' )
67
+ . attr ( 'fill' , 'gray' )
68
+ . attr ( 'r' , 10 )
69
+ . attr ( "cx" , - 10 )
70
+ . attr ( "cy" , - 14 ) ;
71
+ g . select ( '.button' )
72
+ . append ( 'animate' )
73
+ . classed ( 'animate' , true )
74
+ . attr ( 'attributeName' , 'r' )
75
+ . attr ( 'values' , '0;10' )
76
+ . attr ( 'begin' , 'indefinite' )
77
+ . attr ( 'dur' , '0.2s' )
78
+ . attr ( 'repeatCount' , 1 ) ;
79
+ g . append ( 'text' )
80
+ . classed ( 'button' , true )
81
+ . attr ( 'x' , - 16 )
82
+ . attr ( 'y' , - 10 )
83
+ . text ( "FB" )
84
+ . style ( "border" , "solid" )
85
+ . style ( "stroke" , "white" )
86
+ . style ( "cursor" , "pointer" )
87
+ . on ( 'click' , test ) ;
88
+ g . _groups [ 0 ] [ 0 ] . getElementsByTagName ( "animate" ) [ 0 ] . beginElement ( ) ;
89
+ } else {
90
+ g . selectAll ( '.button' ) . style ( "visibility" , "visible" ) ;
91
+ }
92
+ } )
93
+ . on ( "mouseout" , function ( ) {
94
+ d3 . select ( this ) . selectAll ( '.button' ) . style ( "visibility" , "hidden" ) ;
95
+ } )
96
+ . on ( 'contextmenu' , function ( node , d ) {
97
+ props . setDetails ( { name : d . id ,
98
+ branch : d . data . branch ,
99
+ year : d . data . year ,
100
+ email : d . data . email ,
101
+ picture : d . data . picture ,
102
+ linkedIn : d . data . linkedIn ,
103
+ hometown : d . data . hometown ,
104
+ coCurriculars : d . data . coCurriculars ,
105
+ socialMedia : d . data . socialMedia ,
106
+ display : true
107
+ } ) ;
108
+ } ) ;
109
+
110
+ nodeEnter . append ( 'circle' )
111
+ . attr ( 'class' , 'node' )
112
+ . attr ( 'r' , 1e-6 )
113
+ . style ( "fill" , function ( d ) {
114
+ return d . _children ? "lightsteelblue" : "#fff" ;
115
+ } )
116
+ . on ( 'mouseover' , ( d ) => {
117
+ var g = d . target . parentNode
118
+ if ( g . childNodes . length > 3 ) {
119
+ g . getElementsByTagName ( "animate" ) [ 0 ] . beginElement ( ) ;
120
+ }
121
+ } ) ;
122
+
123
+ nodeEnter . append ( 'text' )
124
+ . attr ( "dy" , ".35em" )
125
+ . attr ( "x" , 13 )
126
+ . text ( function ( d ) {
127
+ return d . id ;
128
+ } ) ;
129
+
130
+ var nodeUpdate = nodeEnter . merge ( node )
131
+ . attr ( "fill" , "#fff" )
132
+ . attr ( "stroke" , "steelblue" )
133
+ . attr ( "stroke-width" , "3px;" )
134
+ . style ( 'font' , '12px sans-serif' )
135
+
136
+ nodeUpdate . transition ( )
137
+ . duration ( duration )
138
+ . attr ( "transform" , function ( d ) {
139
+ return "translate(" + d . x + "," + d . y + ")" ;
140
+ } ) ;
141
+
142
+ nodeUpdate . select ( 'circle.node' )
143
+ . attr ( 'r' , 10 )
144
+ . style ( "fill" , function ( d ) {
145
+ return d . _children ? "lightsteelblue" : "#fff" ;
146
+ } )
147
+ . attr ( 'cursor' , 'pointer' ) ;
148
+
149
+ var nodeExit = node . exit ( ) . transition ( )
150
+ . duration ( duration )
151
+ . attr ( "transform" , function ( d ) {
152
+ return "translate(" + source . x + "," + source . y + ")" ;
153
+ } )
154
+ . remove ( ) ;
155
+
156
+ nodeExit . select ( 'circle' )
157
+ . attr ( 'r' , 1e-6 ) ;
158
+
159
+ nodeExit . select ( 'text' )
160
+ . style ( 'fill-opacity' , 1e-6 ) ;
161
+
162
+ var link = svg . selectAll ( 'path.link' )
163
+ . data ( links , function ( d ) { return d . id ; } ) ;
164
+
165
+ var linkEnter = link . enter ( ) . insert ( 'path' , "g" )
166
+ . attr ( "class" , "link" )
167
+ . attr ( 'd' , function ( d ) {
168
+ var o = { x : source . x0 , y : source . y0 }
169
+ return diagonal ( o , o )
170
+ } ) ;
171
+
172
+ var linkUpdate = linkEnter . merge ( link )
173
+ . attr ( "fill" , "none" )
174
+ . attr ( "stroke" , "#ccc" )
175
+ . attr ( "stroke-width" , "2px" )
176
+
177
+ linkUpdate . transition ( )
178
+ . duration ( duration )
179
+ . attr ( 'd' , function ( d ) { return diagonal ( d , d . parent ) } ) ;
180
+
181
+ var linkExit = link . exit ( ) . transition ( )
182
+ . duration ( duration )
183
+ . attr ( 'd' , function ( d ) {
184
+ var o = { x : source . x , y : source . y }
185
+ return diagonal ( o , o )
186
+ } )
187
+ . remove ( ) ;
188
+
189
+ nodes . forEach ( function ( d ) {
190
+ d . x0 = d . x ;
191
+ d . y0 = d . y ;
192
+ } ) ;
193
+
194
+ function diagonal ( s , d ) {
195
+ const path = `M ${ s . x } ${ s . y }
196
+ C ${ ( s . x + d . x ) / 2 } ${ s . y } ,
197
+ ${ ( s . x + d . x ) / 2 } ${ d . y } ,
198
+ ${ d . x } ${ d . y } `
199
+ return path ;
200
+ }
201
+
202
+ function test ( ) {
203
+ console . log ( "clicked" ) ;
204
+ }
205
+
206
+ function click ( d , node ) {
207
+ if ( node . children ) {
208
+ node . _children = node . children ;
209
+ node . children = null ;
210
+ } else {
211
+ node . children = node . _children ;
212
+ node . _children = null ;
213
+ }
214
+ update ( node ) ;
215
+ }
216
+ }
217
+ } , [ ] )
218
+
219
+ return (
220
+ < div id = "tree" > </ div >
221
+ )
222
+ }
223
+ export default D3Tree ;
0 commit comments