You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -47,7 +47,7 @@ export default function ComponentMap({
47
47
consttoolTipTimeoutID=useRef(null);
48
48
49
49
useEffect(()=>{
50
-
dispatch(setCurrentTabInApp('map'));
50
+
dispatch(setCurrentTabInApp('map'));// dispatch sent at initial page load allowing changing "immer's" draft.currentTabInApp to 'map' to facilitate render.
51
51
},[dispatch]);
52
52
53
53
// setting the margins for the Map to render in the tab window.
//The key:value properties of printableObject will be rendered in the JSON Tree
31
-
constprintableObject={}
32
-
//If state is null rather than an object, print "State: null" in tooltip
33
-
if(!dataObj){
29
+
30
+
constprintableObject={}// The key:value properties of printableObject will be rendered in the JSON Tree
31
+
32
+
if(!dataObj){// If state is null rather than an object, print "State: null" in tooltip
34
33
printableObject[containerName]=dataObj;
35
34
}else{
36
-
// Props often contain circular references and messages from the backend must be sent as JSON
37
-
// objects (strings). JSON objects can't contain circular ref's, so the backend filters out problematic
38
-
// values by stringifying the values of object properties and ignoring any values that fail the
39
-
// conversion due to a circular ref.
40
-
// The following logic converts these values back to JS so they display clearly and are collapsible.
35
+
/*
36
+
Props often contain circular references.
37
+
Messages from the backend must be sent as JSON objects (strings).
38
+
JSON objects can't contain circular ref's, so the backend filters out problematic values by stringifying the values of object properties and ignoring any values that fail the conversion due to a circular ref. The following logic converts these values back to JS so they display clearly and are collapsible.
data={printableObject}// data to be rendered, a snapshot object
65
+
theme={{extend: colors,tree: ()=>({className: `tooltipData-JSONTree`})}}// theme set to a base16 theme that has been extended to include "className: 'json-tree'"
66
+
shouldExpandNodeInitially={()=>true}// determines if node should be expanded when it first renders (root is expanded by default)
functionlabelCurrentNode(d3root){// iterates through the parents of a node and applies a color property
45
+
if(d3root.data.index===currLocation.index){// node.data aka d3root.data allows us to access associated node data. So if node.index === currLocation.index...
46
+
47
+
letcurrNode=d3root;// make our input the currNode
48
+
49
+
while(currNode.parent){// while there are parent nodes
50
+
currNode.color='#999';// change or give the node a color property
51
+
currNode=currNode.parent;// change currNode to the parent
50
52
}
51
-
currNode.color='#999';
52
-
returnd3root;
53
+
54
+
currNode.color='#999';// when there are no more parent nodes, change or give the last node a color property
55
+
56
+
returnd3root;// return the modified d3root
53
57
}
58
+
54
59
letfound;
55
-
if(!d3root.children){
56
-
returnfound;
60
+
61
+
if(!d3root.children){// if root has no children array
62
+
returnfound;// return undefined
57
63
}
58
-
d3root.children.forEach((child)=>{
59
-
if(!found){
60
-
found=labelCurrentNode(child);
64
+
65
+
d3root.children.forEach((child)=>{// for each child node within the children array
66
+
if(!found){// if found is undefined
67
+
found=labelCurrentNode(child);//
61
68
}
62
69
});
63
-
returnfound;
70
+
returnfound;// return's the found child node
64
71
}
65
72
66
-
// findDiff function uses same logic as ActionContainer.tsx
67
-
functionfindDiff(index){
68
-
conststatelessCleanning=(obj: {
73
+
functionfindDiff(index){// determines the difference between our current index and the index-1 snapshot and produces an html string
74
+
conststatelessCleaning=(obj: {//'statelessCleaning' functions in the same way as the 'statelessCleaning' function in Diff.tsx
69
75
name?: string;
70
76
componentData?: object;
71
77
state?: string|any;
72
78
stateSnaphot?: object;
73
79
children?: any[];
74
80
})=>{
75
-
constnewObj={ ...obj};
76
-
if(newObj.name==='nameless'){
77
-
deletenewObj.name;
81
+
constnewObj={ ...obj};// duplicate our input object into a new object
82
+
83
+
if(newObj.name==='nameless'){// if our new object's name is nameless
84
+
deletenewObj.name;// delete the name property
78
85
}
79
-
if(newObj.componentData){
80
-
deletenewObj.componentData;
86
+
if(newObj.componentData){// if our new object has a componentData property
87
+
deletenewObj.componentData;// delete the componentData property
81
88
}
82
-
if(newObj.state==='stateless'){
83
-
deletenewObj.state;
89
+
if(newObj.state==='stateless'){// if if our new object's state is stateless
if(newObj.stateSnaphot){// if our new object has a stateSnaphot property
93
+
newObj.stateSnaphot=statelessCleaning(obj.stateSnaphot);// run statelessCleaning on the stateSnapshot
87
94
}
88
-
if(newObj.children){
95
+
96
+
if(newObj.children){// if our new object has a children property
89
97
newObj.children=[];
90
-
if(obj.children.length>0){
98
+
if(obj.children.length>0){// and if our input object's children property is non-empty, go through each children object from our input object and determine, if the object being iterated on either has a stateless state or has a children array with a non-zero amount of objects. Objects that fulfill the above that need to be cleaned through statelessCleaning. Those that are cleaned through this process are then pushed to the new object's children array.
functionfindStateChangeObj(delta,changedState=[]){// function determines whether delta has resulted in a changedState. Function would return an empty array if there were no changes to state and an array of objects that changed state.
111
+
if(!delta.children&&!delta.state){// if delta doesn't have a children property or a state property
changedState.push(...findStateChangeObj(delta.children[child]));// recursively call this function on each child object. Push every 'stateful' child into the changedState array.
115
126
// }
116
127
});
117
-
returnchangedState;
128
+
129
+
returnchangedState;// return the changedState array with any and all stateful delta objects.
118
130
}
119
131
120
-
constdelta=diff(
121
-
statelessCleanning(snapshots[index-1]),
122
-
statelessCleanning(snapshots[index]),
132
+
constdelta=diff(// 'diff' function from 'jsondiffpatch' returns the difference in state between the (snapshot that occurred before the indexed snapshot) and the (indexed snapshot).
133
+
statelessCleaning(snapshots[index-1]),
134
+
statelessCleaning(snapshots[index]),
123
135
);
124
-
constchangedState=findStateChangeObj(delta);
125
-
// figured out the formatting for hover, applying diff.csss
constsvg=d3.select(svgRef.current);// d3.select Selects the first element/node that matches svgRef.current. If no element/node match returns an empty selection. If multiple elements/nodes match the selector, only the first matching element/node (in document order) will be selected.
148
+
svg.selectAll('*').remove();// Selects all elements. The elements will be selected in document order (top-to-bottom). We then remove the selected elements/nodes from the DOM
149
+
150
+
consttree=(data)=>{// function that takes in data and turns it into a d3 tree.
151
+
consttreeRoot=d3.hierarchy(data);// 'd3.hierarchy' constructs a root node from the specified hierarchical data.
152
+
returnd3.tree().size([innerWidth,innerHeight])(treeRoot);// d3.tree creates a new tree layout with a size option of innerWidth (~line 41) and innerHeight (~line 42). We specify our new tree layout's root as 'treeRoot' which assigns an x and y property to each node to represent an [x, y] coordinate system.
142
153
};
143
-
constd3root=tree(root);
144
154
145
-
constcurrNode=labelCurrentNode(d3root);
155
+
constd3root=tree(root);// create a d3. tree from our root
156
+
constcurrNode=labelCurrentNode(d3root);// iterate through our nodes and apply a color property
// source property, which represents the link's source node,
159
-
// and a target property, which represents the link's target node.
166
+
.selectAll('.link')// select all elements that contain the string '.link' and return a selection
160
167
.data(d3root.descendants().slice(1))
161
168
.enter()
162
169
.append('path')
@@ -179,12 +186,11 @@ function History(props: Record<string, unknown>): JSX.Element {
179
186
.on('click',(event,d)=>{
180
187
dispatch(changeView(d.data.index));
181
188
dispatch(changeSlider(d.data.index));
189
+
/*
190
+
created popup div and appended it to display div(returned in this function)
182
191
183
-
// created popup div and appended it to display div(returned in this function)
184
-
// D3 doesn't utilize z-index for priority,
185
-
// rather decides on placement by order of rendering
186
-
// needed to define the return div with a className to have a target to append to
187
-
// with the correct level of priority
192
+
D3 doesn't utilize z-index for priority, rather decides on placement by order of rendering needed to define the return div with a className to have a target to append to with the correct level of priority
193
+
*/
188
194
functionrenderToolTip(){
189
195
const[x,y]=d3.pointer(event);
190
196
constdiv=d3
@@ -271,11 +277,12 @@ function History(props: Record<string, unknown>): JSX.Element {
271
277
272
278
useEffect(()=>{
273
279
makeD3Tree();
274
-
},[root,currLocation]);
280
+
},[root,currLocation]);// if the 'root' or 'currLocation' changes, re-build the D3 Tree
275
281
276
282
useEffect(()=>{
277
-
dispatch(setCurrentTabInApp('history'));
283
+
dispatch(setCurrentTabInApp('history'));// dispatch sent at initial page load allowing changing "immer's" draft.currentTabInApp to 'webmetrics' to facilitate render.
278
284
},[]);
285
+
279
286
// then rendering each node in History tab to render using D3, which will share area with LegendKey
dispatch(setCurrentTabInApp('performance-comparison'));// dispatch sent at initial page load allowing changing "immer's" draft.currentTabInApp to 'performance-comparison' to facilitate render.
dispatch(setCurrentTabInApp('performance-comparison'));// dispatch sent at initial page load allowing changing "immer's" draft.currentTabInApp to 'performance-comparison' to facilitate render.
dispatch(setCurrentTabInApp('performance'));// dispatch sent at initial page load allowing changing "immer's" draft.currentTabInApp to 'performance' to facilitate render.
168
168
},[dispatch]);
169
169
170
170
// Creates the actions array used to populate the compare actions dropdown
dispatch(setCurrentTabInApp('performance-comparison'));// dispatch sent at initial page load allowing changing "immer's" draft.currentTabInApp to 'performance-comparison' to facilitate render.
0 commit comments