Skip to content

Commit e4f288b

Browse files
committed
Merge branch 'dev' into FL/RL-42-43-44/Memory-Leak_Cleanup
2 parents 4625a1e + 189b7ed commit e4f288b

File tree

4 files changed

+76
-224
lines changed

4 files changed

+76
-224
lines changed

package-lock.json

Lines changed: 4 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/webview/Flow.tsx

Lines changed: 15 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,45 @@
1-
import React, { useCallback, useEffect, useRef } from "react";
1+
import React, { useEffect, useRef } from "react";
22
import ReactFlow, {
3-
addEdge,
43
MiniMap,
54
Panel,
65
Controls,
76
Background,
87
useNodesState,
98
useEdgesState,
10-
ReactFlowInstance,
119
Node,
1210
Edge
1311
} from "reactflow";
14-
import "reactflow/dist/style.css";
15-
import { ConnectionLineType } from "../types/connection";
16-
import FlowBuilder from './flowBuilder';
17-
import * as d3 from 'd3';
12+
import FlowBuilder from "./flowBuilder";
1813
import { Tree } from "../types/tree";
19-
import { hierarchyData } from "../types/hierarchyData";
20-
import { getNonce } from "../getNonce";
21-
import { FlowNode } from "typescript";
14+
import "reactflow/dist/style.css";
15+
import "./style.css";
16+
17+
2218

23-
const onInit = (reactFlowInstance: ReactFlowInstance) =>
24-
console.log("flow loaded:", reactFlowInstance);
2519

2620
const OverviewFlow = () => {
27-
const reactFlowWrapper = useRef<HTMLDivElement>(null);
21+
2822
const initialNodes : Node[] = [];
2923
const initialEdges : Edge[] = [];
3024

3125
const [nodes, setNodes, onNodesChange] = useNodesState([]);
3226
const [edges, setEdges, onEdgesChange] = useEdgesState([]);
3327

34-
const onConnect = useCallback(
35-
(params) => setEdges((eds) => addEdge({ ...params, type: ConnectionLineType.Bezier, animated: true }, eds)),
36-
[]
37-
);
38-
3928

4029
useEffect(() => {
4130
window.addEventListener('message', (e: MessageEvent) => {
42-
// object containing type prop and value prop
43-
const msg : MessageEvent = e;
44-
console.log(e)
31+
32+
// Object containing type prop and value prop
33+
const msg : MessageEvent = e;
34+
const flowBuilder = new FlowBuilder
4535

4636
switch (msg.data.type) {
4737
case 'parsed-data': {
4838
let data : Tree | undefined = msg.data.value;
49-
mappedData(data)
39+
40+
// Creates our Tree structure
41+
flowBuilder.mappedData(data, initialNodes, initialEdges)
42+
5043
setEdges(initialEdges);
5144
setNodes(initialNodes)
5245
break;
@@ -56,70 +49,6 @@ const OverviewFlow = () => {
5649
}, []);
5750

5851

59-
// Function that creates Tree Structure
60-
function mappedData (data: Tree) : void {
61-
62-
// Create a holder for the heirarchical data (msg.value), data comes in an object of all the Trees
63-
const root : d3.HierarchyNode<Tree> = d3.hierarchy(data)
64-
65-
// Dynamically adjust height and width of display depending on the amount of nodes
66-
const totalNodes : number = root.descendants().length;
67-
const width : number = Math.max(totalNodes * 100, 800);
68-
const height = Math.max(totalNodes * 20, 500)
69-
70-
71-
//create tree layout and give nodes their positions and
72-
const treeLayout : d3.TreeLayout<unknown> = d3.tree()
73-
.size([ width, height ])
74-
.separation((a: d3.HierarchyPointNode<Node>, b: d3.HierarchyPointNode<Node>) => (a.parent == b.parent ? 2 : 2.5))
75-
76-
77-
treeLayout(root);
78-
// Iterate through each Tree and create a node
79-
root.each((node: any) : void => {
80-
console.log('Node', node)
81-
// Create a Node from the current Root and add it to our nodes array
82-
initialNodes.push({
83-
id: node.data.id,
84-
position: { x: node.x ? node.x : 0, y: node.y ? node.y : 0 },
85-
type: 'default',
86-
data: { label: node.data.name },
87-
style: {
88-
borderRadius: '6px',
89-
borderWidth: '2px',
90-
borderColor: '#6b7280',
91-
display: 'flex',
92-
justifyContent: 'center',
93-
placeItems: 'center',
94-
backgroundColor: `${(node.data.isClientComponent) ? '#fdba74' : '#93C5FD'}`,
95-
}
96-
});
97-
98-
// If the current node has a parent, create an edge to show relationship
99-
if (node.data.parent) {
100-
const newEdge : Edge = {
101-
id: `${getNonce()}`,
102-
source: node.data.parent,
103-
target: node.data.id,
104-
type: ConnectionLineType.Bezier,
105-
animated: true,
106-
};
107-
108-
109-
// Check if the edge already exists before adding
110-
const edgeExists : boolean = initialEdges.some(
111-
edge => edge.source === newEdge.source && edge.target === newEdge.target
112-
);
113-
114-
// If edge does not exist, add to our edges array
115-
if (!edgeExists) {
116-
initialEdges.push(newEdge)
117-
}
118-
}
119-
}
120-
)
121-
122-
}
12352

12453
return (
12554
<div style={{ height: '600px', width: '100%' }}>
@@ -128,8 +57,6 @@ const OverviewFlow = () => {
12857
edges={edges}
12958
onNodesChange={onNodesChange}
13059
onEdgesChange={onEdgesChange}
131-
onConnect={onConnect}
132-
onInit={onInit}
13360
fitView
13461
attributionPosition="top-right"
13562
style={{ width: '100%', height: '100%' }}

src/webview/flowBuilder.tsx

Lines changed: 51 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -1,154 +1,74 @@
1-
import React from 'react';
2-
// will create a build func and then call the helper funcs to return an object
3-
// make a new instance of this class in flow, call the build method, and pass this as state
1+
import { ConnectionLineType, Edge, Node } from 'reactflow';
2+
import { Tree } from '../types/tree';
3+
import { getNonce } from '../getNonce';
4+
import * as d3 from 'd3'
45

5-
interface Node {
6-
id: string;
7-
data: {
8-
label: React.ReactNode;
9-
};
10-
type: string;
11-
position: { x: number, y: number };
12-
style: {
13-
borderRadius: string;
14-
borderWidth: string;
15-
borderColor: string;
16-
display: string;
17-
justifyContent: string;
18-
placeItems: string;
19-
backgroundColor: string;
20-
};
21-
}
6+
// Contructs our family tree for React application root file that was selected
227

23-
interface Edge {
24-
id: string;
25-
source: string;
26-
target: string;
27-
type: string;
28-
animated: boolean;
29-
}
8+
class FlowBuilder {
309

31-
interface ParsedDataItem {
32-
fileName: string;
33-
isClientComponent: boolean;
34-
children?: ParsedDataItem[];
35-
thirdParty?: boolean;
36-
reactRouter?: boolean;
37-
}
10+
public mappedData (data: Tree, nodes: Node[], edges: Edge[]) : void {
3811

39-
interface Settings {
40-
thirdParty: boolean;
41-
reactRouter: boolean;
42-
}
12+
// Create a holder for the heirarchical data (msg.value), data comes in an object of all the Trees
13+
const root : d3.HierarchyNode<Tree> = d3.hierarchy(data)
4314

44-
class FlowBuilder {
45-
private parsedData: ParsedDataItem[];
46-
private viewData: ParsedDataItem[];
47-
private id: number;
48-
private x: number;
49-
private y: number;
50-
private edgeId: number;
51-
public initialEdges: Edge[];
52-
public initialNodes: Node[];
15+
// Dynamically adjust height and width of display depending on the amount of nodes
16+
const totalNodes : number = root.descendants().length;
17+
const width : number = Math.max(totalNodes * 100, 800);
18+
const height = Math.max(totalNodes * 20, 500)
19+
5320

54-
constructor(data: ParsedDataItem) {
55-
this.parsedData = [data];
56-
this.id = 0;
57-
this.x = 0;
58-
this.y = 0;
59-
this.initialNodes = [];
60-
this.initialEdges = [];
61-
this.viewData = [];
62-
this.edgeId = 0;
63-
}
21+
//create tree layout and give nodes their positions and
22+
const treeLayout : d3.TreeLayout<unknown> = d3.tree()
23+
.size([ width, height ])
24+
.separation((a: d3.HierarchyPointNode<Node>, b: d3.HierarchyPointNode<Node>) => (a.parent == b.parent ? 2 : 2.5))
6425

65-
private buildNodesArray(parsedData: ParsedDataItem[] | undefined, x: number = this.x, y: number = this.y): void {
66-
if (!parsedData) return;
6726

68-
parsedData.forEach((item) => {
69-
const node: Node = {
70-
id: (++this.id).toString(),
71-
data: {
72-
label: (
73-
<div className="text-sm font-medium text-ellipsis overflow-hidden ..." key={this.id}>{item.fileName}</div>
74-
)
75-
},
76-
// type: item.depth === 0 ? 'input' : '',
77-
type: 'default',
78-
position: { x: (x += 40), y: (y += 30) },
27+
treeLayout(root);
28+
// Iterate through each Tree and create a node
29+
root.each((node: any) : void => {
30+
31+
// Create a Node from the current Root and add it to our nodes array
32+
nodes.push({
33+
id: node.data.id,
34+
position: { x: node.x ? node.x : 0, y: node.y ? node.y : 0 },
35+
type: node.depth === 0 ? 'input' : !node.children ? 'output' : 'default',
36+
data: { label: node.data.name },
7937
style: {
8038
borderRadius: '6px',
8139
borderWidth: '2px',
8240
borderColor: '#6b7280',
8341
display: 'flex',
8442
justifyContent: 'center',
8543
placeItems: 'center',
86-
backgroundColor: `${(item.isClientComponent) ? '#fdba74' : '#93C5FD'}`,
87-
},
88-
};
89-
this.initialNodes.push(node);
90-
if (item.children) {
91-
this.buildNodesArray(item.children, (this.x += 40), (this.y += 30));
92-
}
93-
});
94-
};
95-
96-
private buildEdgesArray(parsedData: ParsedDataItem[] | undefined, parentID?: number): void {
97-
if (!parsedData) return;
98-
99-
parsedData.forEach((item) => {
100-
const nodeID = ++this.edgeId;
101-
if (parentID) {
102-
const edge: Edge = {
103-
id: `e${parentID}-${nodeID}`,
104-
source: parentID.toString(),
105-
target: nodeID.toString(),
106-
type: 'bezier',
107-
animated: false,
44+
backgroundColor: `${(node.data.isClientComponent) ? '#fdba74' : '#93C5FD'}`,
45+
}
46+
});
47+
48+
// If the current node has a parent, create an edge to show relationship
49+
if (node.data.parent) {
50+
const newEdge : Edge = {
51+
id: `${getNonce()}`,
52+
source: node.data.parent,
53+
target: node.data.id,
54+
type: ConnectionLineType.Bezier,
55+
animated: true,
10856
};
109-
this.initialEdges.push(edge);
110-
}
111-
if (item.children) {
112-
this.buildEdgesArray(item.children, nodeID);
113-
}
114-
});
115-
}
116-
117-
public build(settings: Settings): void {
118-
const treeParsed = JSON.parse(JSON.stringify(this.parsedData[0]));
119-
// console.log('settings: ', settings);
120-
const traverse = (node: ParsedDataItem): void => {
121-
let validChildren: ParsedDataItem[] = [];
12257

123-
for (let i = 0; i < node.children?.length; i++) {
124-
if (
125-
node.children[i].thirdParty &&
126-
settings.thirdParty &&
127-
!node.children[i].reactRouter
128-
) {
129-
validChildren.push(node.children[i]);
130-
} else if (node.children[i].reactRouter && settings.reactRouter) {
131-
validChildren.push(node.children[i]);
132-
} else if (
133-
!node.children[i].thirdParty &&
134-
!node.children[i].reactRouter
135-
) {
136-
validChildren.push(node.children[i]);
58+
59+
// Check if the edge already exists before adding
60+
const edgeExists : boolean = edges.some(
61+
edge => edge.source === newEdge.source && edge.target === newEdge.target
62+
);
63+
64+
// If edge does not exist, add to our edges array
65+
if (!edgeExists) {
66+
edges.push(newEdge)
13767
}
13868
}
139-
140-
// Update children with only valid nodes, and recurse through each node
141-
node.children = validChildren;
142-
node.children.forEach((child) => {
143-
traverse(child);
144-
});
14569
}
146-
traverse(treeParsed);
147-
// Update the viewData state
148-
this.viewData = ([treeParsed]);
149-
console.log('viewData:', this.viewData);
150-
this.buildNodesArray(this.viewData);
151-
this.buildEdgesArray(this.viewData);
70+
)
71+
15272
}
15373
}
15474

0 commit comments

Comments
 (0)