@@ -25,44 +25,67 @@ function History(props: Record<string, unknown>) {
25
25
margin = defaultMargin ,
26
26
hierarchy,
27
27
dispatch,
28
- sliderIndex,
29
- viewIndex,
28
+ currLocation,
30
29
} = props ;
31
30
32
31
const svgRef = React . useRef ( null ) ;
33
32
const root = JSON . parse ( JSON . stringify ( hierarchy ) ) ;
34
33
35
- console . log ( " DEBUG >>> hierarchy: " , hierarchy ) ;
34
+ console . log ( ' DEBUG >>> HISTORY currLocation: ' , currLocation ) ;
36
35
37
36
// setting the margins for the Map to render in the tab window.
38
37
const innerWidth = totalWidth - margin . left - margin . right ;
39
38
const innerHeight = totalHeight - margin . top - margin . bottom - 60 ;
40
39
41
40
useEffect ( ( ) => {
42
41
makeD3Tree ( ) ;
43
- } , [ root ] ) ;
42
+ } , [ root , currLocation ] ) ;
43
+
44
+ function labelCurrentNode ( d3root ) {
45
+ if ( d3root . data . index === currLocation . index ) {
46
+ let currNode = d3root ;
47
+ while ( currNode . parent ) {
48
+ currNode . color = '#999' ;
49
+ currNode = currNode . parent ;
50
+ }
51
+ currNode . color = '#999' ;
52
+ return d3root ;
53
+ }
54
+ let found ;
55
+ if ( ! d3root . children ) {
56
+ console . log ( 'DEBUG >>> no child: ' , d3root ) ;
57
+ return found ;
58
+ }
59
+ d3root . children . forEach ( child => {
60
+ if ( ! found ) {
61
+ console . log ( 'DEBUG >>> child: ' , child ) ;
62
+ found = labelCurrentNode ( child ) ;
63
+ }
64
+ } ) ;
65
+ return found ;
66
+ }
44
67
45
68
/**
46
69
* @method makeD3Tree :Creates a new D3 Tree
47
70
*/
48
71
const makeD3Tree = ( ) => {
49
72
const svg = d3 . select ( svgRef . current ) ;
50
- svg . selectAll ( "*" ) . remove ( ) ; // Clear svg content before adding new elements
73
+ svg . selectAll ( '*' ) . remove ( ) ; // Clear svg content before adding new elements
51
74
const tree = data => {
52
- const root = d3 . hierarchy ( data ) ;
53
- // root.dx = 10;
54
- // root.dy = width / (root.height + 1);
55
- // return d3.tree().nodeSize([root.dx, root.dy])(root);
56
- return d3 . tree ( ) . size ( [ innerWidth , innerHeight ] ) ( root ) ;
57
- }
75
+ const treeRoot = d3 . hierarchy ( data ) ;
76
+ return d3 . tree ( ) . size ( [ innerWidth , innerHeight ] ) ( treeRoot ) ;
77
+ } ;
58
78
// const hierarchy = d3.hierarchy(root);
59
79
const d3root = tree ( root ) ;
60
- console . log ( " DEBUG >>> d3root: " , d3root ) ;
80
+ console . log ( ' DEBUG >>> d3root: ' , d3root ) ;
61
81
62
- const g = svg . append ( "g" )
82
+ const currNode = labelCurrentNode ( d3root ) ;
83
+ console . log ( 'DEBUG >>> currNode: ' , currNode ) ;
84
+
85
+ const g = svg . append ( 'g' )
63
86
// .attr("font-family", "sans-serif")
64
87
// .attr("font-size", 10)
65
- . attr ( " transform" , `translate(${ margin . left } ,${ d3root . height === 0 ? ( totalHeight / 2 ) : margin . top } )` ) ;
88
+ . attr ( ' transform' , `translate(${ margin . left } ,${ d3root . height === 0 ? ( totalHeight / 2 ) : margin . top } )` ) ;
66
89
67
90
const link = g . selectAll ( '.link' )
68
91
// root.links() gets an array of all the links,
@@ -72,218 +95,53 @@ function History(props: Record<string, unknown>) {
72
95
. data ( d3root . descendants ( ) . slice ( 1 ) )
73
96
. enter ( )
74
97
. append ( 'path' )
75
- . attr ( "class" , "link" )
76
- . attr ( "d" , d => {
77
- return "M" + d . x + "," + d . y
78
- + "C" + d . x + "," + ( d . y + d . parent . y ) / 2
79
- + " " + d . parent . x + "," + ( d . y + d . parent . y ) / 2
80
- + " " + d . parent . x + "," + d . parent . y ;
81
- } ) ;
98
+ . attr ( 'class' , 'link' )
99
+ . attr ( 'd' , d => `M${ d . x } ,${ d . y
100
+ } C${ d . x } ,${ ( d . y + d . parent . y ) / 2
101
+ } ${ d . parent . x } ,${ ( d . y + d . parent . y ) / 2
102
+ } ${ d . parent . x } ,${ d . parent . y } `) ;
82
103
83
- const node = g . selectAll ( " .node" )
104
+ const node = g . selectAll ( ' .node' )
84
105
. data ( d3root . descendants ( ) )
85
106
. enter ( )
86
- . append ( "g" )
107
+ . append ( 'g' )
87
108
// .selectAll("g")
88
109
// .data(d3root.descendants())
89
110
// .join("g")
90
- . attr ( "transform" , d => `translate(${ d . x } ,${ d . y } )` ) ;
91
-
92
- node . append ( "circle" )
93
- . attr ( "fill" , d => d . children ? "#555" : "#999" )
94
- . attr ( "r" , 14 ) ;
95
-
96
- node . append ( "text" )
97
- . attr ( "dy" , "0.31em" )
98
- . attr ( "text-anchor" , "middle" )
99
- . text ( d => d . data . name )
100
- . clone ( true ) . lower ( )
101
- . attr ( "stroke" , "white" ) ;
111
+ . attr ( 'transform' , d => `translate(${ d . x } ,${ d . y } )` ) ;
112
+
113
+ node . append ( 'circle' )
114
+ . attr ( 'fill' , d => {
115
+ if ( d . data . index === currLocation . index ) {
116
+ return 'red' ;
117
+ }
118
+ return d . color ? d . color : '#555' ;
119
+ } )
120
+ . style ( 'display' , 'block' )
121
+ . style ( 'cursor' , 'pointer' )
122
+ . on ( 'click' , d => {
123
+ console . log ( 'DEBUG >>> onclick d:' , d ) ;
124
+ dispatch ( changeView ( d . data . index ) ) ;
125
+ dispatch ( changeSlider ( d . data . index ) ) ;
126
+ } )
127
+ . attr ( 'r' , 14 ) ;
128
+
129
+ node . append ( 'text' )
130
+ . attr ( 'dy' , '0.31em' )
131
+ . attr ( 'text-anchor' , 'middle' )
132
+ . text ( d => `${ d . data . name } .${ d . data . branch } ` )
133
+ . clone ( true )
134
+ . lower ( )
135
+ . attr ( 'stroke' , 'white' ) ;
102
136
103
137
return svg . node ( ) ;
104
- }
105
-
106
- // /**
107
- // * @method maked3Tree Creates a new Tree History
108
- // * @var
109
- // */
110
- // let maked3Tree = function () {
111
- // removed3Tree();
112
- // // Why the fuck are these values fixed?
113
- // const width = 800;
114
- // const height = 600;
115
- // const svgContainer = d3
116
- // .select(HistoryRef.current)
117
- // .append('svg') // svgContainer is now pointing to svg
118
- // .attr('width', width)
119
- // .attr('height', height);
120
-
121
- // const g = svgContainer
122
- // .append('g');
123
- // // this is changing where the graph is located physically
124
- // // .attr('transform', `translate(${containerWidth}, ${height})`);
125
-
126
- // // d3.hierarchy constructs a root node from the specified hierarchical data
127
- // // (our object titled dataset), which must be an object representing the root node
128
- // const hierarchy = d3.hierarchy(root);
129
- // console.log("DEBUG >>> hierarchy: ", hierarchy);
130
- // const tree = d3
131
- // .tree()
132
- // .nodeSize([width / 10, height / 10]);
133
- // // .separation((a: { parent: object }, b: { parent: object }) => (a.parent == b.parent ? 2 : 2));
134
-
135
- // const d3root = tree(hierarchy);
136
-
137
- // g.selectAll('.link')
138
- // // root.links() gets an array of all the links,
139
- // // where each element is an object containing a
140
- // // source property, which represents the link's source node,
141
- // // and a target property, which represents the link's target node.
142
- // .data(d3root.links())
143
- // .enter()
144
- // .append('path')
145
- // .attr('class', 'link')
146
- // .attr(
147
- // 'd',
148
- // d3
149
- // .linkRadial()
150
- // .angle((d: { x: number }) => d.x)
151
- // .radius((d: { y: number }) => d.y),
152
- // );
153
-
154
- // const node = g
155
- // .selectAll('.node')
156
- // // root.descendants gets an array of of all nodes
157
- // .data(d3root.descendants())
158
- // .enter()
159
- // .append('g')
160
- // .style('fill', d => {
161
- // let loadTime;
162
- // if (d.data.stateSnapshot.children[0].componentData.actualDuration) {
163
- // loadTime = d.data.stateSnapshot.children[0].componentData.actualDuration;
164
- // } else {
165
- // loadTime = 1;
166
- // }
167
-
168
- // if (loadTime !== undefined) {
169
- // if (loadTime > 16) {
170
- // return '#d62b2b';
171
- // }
172
- // }
173
-
174
- // if (d.data.branch < colors.length) {
175
- // return colors[d.data.branch];
176
- // }
177
- // let indexColors = d.data.branch - colors.length;
178
- // while (indexColors > colors.length) {
179
- // indexColors -= colors.length;
180
- // }
181
- // return colors[indexColors];
182
- // })
183
- // .attr('class', 'node--internal')
184
- // .attr('transform', (d: { x: number; y: number }) => `translate(${reinfeldTidierAlgo(d.x, d.y)})`);
185
-
186
- // // here we the node circle is created and given a radius size, we are also giving it a mouseover and onClick functionality
187
- // // mouseover will highlight the node
188
- // // the onCLick of a selected node will dispatch changeSlider and changeView actions. This will act as a timeJump request.
189
- // // further optimization would improve the onclick feature, onclick seems to only register on the lower half of the node
190
- // node
191
- // .append('circle')
192
- // .attr('r', 14)
193
- // .on('mouseover', function (d: 'Record<string, unknown>') {
194
- // d3.select(this).transition(90).duration(18).attr('r', 21);
195
- // })
196
- // .on('click', (d: 'Record<string, unknown>') => {
197
- // // TODO: change
198
- // const index = parseInt(`${d.data.name}.${d.data.branch}`);
199
- // dispatch(changeSlider(index));
200
- // dispatch(changeView(index));
201
- // })
202
- // // think about how I can convert this any to typescript
203
- // .on('mouseout', function () {
204
- // d3.select(this).transition().duration(300).attr('r', 14);
205
- // });
206
-
207
- // node
208
- // .append('text')
209
- // // adjusts the y coordinates for the node text
210
- // .attr('dy', '0.5em')
211
- // .attr('x', (d: { x: number; children?: [] }) =>
212
- // // this positions how far the text is from leaf nodes (ones without children)
213
- // // negative number before the colon moves the text of right side nodes,
214
- // // positive number moves the text for the left side nodes
215
- // (d.x < Math.PI === !d.children ? 0 : 0))
216
- // .attr('text-anchor', 'middle')
217
- // // this arranges the angle of the text
218
- // .attr('transform', (d: { x: number; y: number }) => (
219
- // `rotate(${((d.x < Math.PI ? d.x - Math.PI / 2 : d.x + Math.PI / 2) * 1)
220
- // / Math.PI
221
- // })`
222
- // ))
223
- // .text((d: { data: { name: number; branch: number } }) =>
224
- // // display the name of the specific patch
225
- // `${d.data.name}`);
226
-
227
- // // Zoom Functions
228
- // const zoom = d3.zoom().on('zoom', zoomed);
229
- // svgContainer.call(
230
- // zoom.transform,
231
- // // Changes the initial view, (left, top)
232
- // d3.zoomIdentity.translate(width / 3, height / 4).scale(1),
233
- // );
234
- // // allows the canvas to be zoom-able
235
- // svgContainer.call(
236
- // d3
237
- // .zoom()
238
- // .scaleExtent([0, 0.9]) // [zoomOut, zoomIn]
239
- // .on('zoom', zoomed),
240
- // );
241
- // // helper function that allows for zooming ( think about how I can convert this any to typescript)
242
- // function zoomed(d: any) {
243
- // g.attr('transform', d3.event.transform);
244
- // }
245
-
246
- // // DRAG FUNCTIONS
247
- // node.call(
248
- // d3
249
- // .drag()
250
- // .on('start', dragstarted)
251
- // .on('drag', dragged)
252
- // .on('end', dragended),
253
- // );
254
-
255
- // function dragstarted() {
256
- // d3.select(this).raise();
257
- // g.attr('cursor', 'grabbing');
258
- // }
259
-
260
- // function dragged(d: { x: number; y: number }) {
261
- // d3.select(this)
262
- // .attr('dx', (d.x = d3.event.x))
263
- // .attr('dy', (d.y = d3.event.y));
264
- // }
265
-
266
- // function dragended() {
267
- // g.attr('cursor', 'grab');
268
- // }
269
-
270
- // // define the div for the tooltip
271
- // const tooltipDiv = d3
272
- // .select('body')
273
- // .append('div')
274
- // .attr('class', 'tooltip')
275
- // .style('opacity', 0);
276
-
277
- // function reinfeldTidierAlgo(x: number, y: number) {
278
- // return [(y = +y) * Math.cos((x -= Math.PI / 2)), y * Math.sin(x)];
279
- // }
280
- // };
138
+ } ;
281
139
282
140
// below we are rendering the LegendKey component and passing hierarchy as props
283
141
// then rendering each node in History tab to render using D3, which will share area with LegendKey
284
142
return (
285
143
< >
286
- < LegendKey hierarchy = { hierarchy } />
144
+ { /* <LegendKey hierarchy={hierarchy} /> */ }
287
145
< svg
288
146
ref = { svgRef }
289
147
width = { totalWidth }
0 commit comments