Skip to content

Commit 164d30c

Browse files
authored
Merge pull request #22 from oslabs-beta/FL-JA/D3-visualization
Fl ja/d3 visualization
2 parents e45e116 + 0963ed2 commit 164d30c

File tree

9 files changed

+482
-13
lines changed

9 files changed

+482
-13
lines changed

package-lock.json

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

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@
101101
"babel": "^6.23.0",
102102
"babel-loader": "^9.1.3",
103103
"css-loader": "^6.8.1",
104+
"d3": "^7.8.5",
104105
"react": "^18.2.0",
105106
"react-dom": "^18.2.0",
106107
"reactflow": "^11.10.1",

src/getNonce 2.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
function getNonce() {
2+
let text = "";
3+
const possible =
4+
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
5+
for (let i = 0; i < 32; i++) {
6+
text += possible.charAt(Math.floor(Math.random() * possible.length));
7+
}
8+
return text;
9+
}
10+
11+
module.exports = { getNonce }

src/parser.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ export class Parser {
7171
reactRouter: false,
7272
reduxConnect: false,
7373
children: [],
74+
parent: null,
7475
parentList: [],
7576
props: {},
7677
error: '',
@@ -180,6 +181,9 @@ export class Parser {
180181
if (componentTree.parentList.includes(componentTree.filePath)) {
181182
return;
182183
}
184+
// if (typeof componentTree.parentList === 'string' && componentTree.parentList.includes(componentTree.filePath)) {
185+
// return;
186+
// }
183187

184188
// Create abstract syntax tree of current component tree file
185189
let ast: babel.ParseResult<File>;
@@ -468,6 +472,7 @@ export class Parser {
468472
count: 1,
469473
props: props,
470474
children: [],
475+
parent: parent.id,
471476
// consider adding the id to the parentList array somehow for D3 integration...
472477
parentList: [parent.filePath].concat(parent.parentList),
473478
error: '',

src/treeTemplates/tree 2.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
const Tree = {
2+
id: undefined,
3+
fileName: undefined,
4+
filePath: undefined,
5+
// children & parentList should be populated with other Tree objects
6+
children: [],
7+
parentList: [],
8+
isClientComponent: false
9+
}
10+
11+
module.exports = { Tree };

src/types/hierarchyData.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { Tree } from "./tree"
2+
3+
4+
export interface hierarchyData {
5+
children?: hierarchyData[],
6+
data: Tree,
7+
depth: number,
8+
height: number,
9+
parent: hierarchyData | null
10+
}

src/types/tree.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export type Tree = {
1111
reactRouter: boolean;
1212
reduxConnect: boolean;
1313
children: Tree[];
14+
parent: string;
1415
parentList: string[];
1516
props: { [key: string]: boolean; };
1617
error: string;

src/webview/Flow.tsx

Lines changed: 81 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useCallback, useEffect } from "react";
1+
import React, { useCallback, useEffect, useRef } from "react";
22
import ReactFlow, {
33
addEdge,
44
MiniMap,
@@ -12,38 +12,108 @@ import ReactFlow, {
1212
import "reactflow/dist/style.css";
1313
import { ConnectionLineType } from "../types/connection";
1414
import FlowBuilder from './flowBuilder';
15+
import * as d3 from 'd3';
16+
import { Tree } from "../types/tree";
17+
import { hierarchyData } from "../types/hierarchyData";
18+
import { getNonce } from "../getNonce";
1519

1620
const onInit = (reactFlowInstance: ReactFlowInstance) =>
1721
console.log("flow loaded:", reactFlowInstance);
1822

1923
const OverviewFlow = () => {
24+
const reactFlowWrapper = useRef<HTMLDivElement>(null);
2025
const initialNodes = [];
2126
const initialEdges = [];
22-
23-
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
24-
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
27+
28+
const [nodes, setNodes, onNodesChange] = useNodesState([]);
29+
const [edges, setEdges, onEdgesChange] = useEdgesState([]);
2530

2631
const onConnect = useCallback(
2732
(params) => setEdges((eds) => addEdge({ ...params, type: ConnectionLineType.Bezier, animated: true }, eds)),
2833
[]
2934
);
3035

36+
3137
useEffect(() => {
3238
window.addEventListener('message', (e) => {
33-
const msg = e.data; // object containing type prop and value prop
39+
// object containing type prop and value prop
40+
const msg = e.data;
41+
3442
switch (msg.type) {
3543
case 'parsed-data': {
36-
const results = new FlowBuilder(msg.value);
37-
results.build(msg.settings)
38-
setNodes(results.initialNodes);
39-
setEdges(results.initialEdges);
44+
let data : object | undefined = msg.value;
45+
console.log('data', data)
46+
mappedData(data)
47+
console.log('nodes', initialNodes)
48+
setEdges(initialEdges);
49+
setNodes(initialNodes)
50+
console.log('edges: ', edges);
4051
break;
4152
}
4253
}
4354
});
4455
}, []);
4556

57+
58+
// Function that creates Tree Structure
59+
function mappedData (data) {
60+
61+
// Create a holder for the heirarchical data (msg.value), data comes in an object of all the Trees
62+
const root : any = d3.hierarchy(data)
63+
console.log('root', root)
64+
65+
//create tree layout and give nodes their positions
66+
const treeLayout = d3.tree().size([800, 500])
67+
treeLayout(root);
68+
69+
// Iterate through each Tree and create a node
70+
root.each((node: any) : void => {
71+
72+
// Create a Node from the current Root and add it to our nodes array
73+
initialNodes.push({
74+
id: node.data.id,
75+
type: 'default',
76+
data: { label: node.data.name },
77+
position: { x: node.x ? node.x : 0, y: node.y ? node.y : 0 },
78+
style: {
79+
borderRadius: '6px',
80+
borderWidth: '2px',
81+
borderColor: '#6b7280',
82+
display: 'flex',
83+
justifyContent: 'center',
84+
placeItems: 'center',
85+
backgroundColor: `${(node.data.isClientComponent) ? '#fdba74' : '#93C5FD'}`,
86+
}
87+
});
88+
89+
// If the current node has a parent, create an edge to show relationship
90+
if (node.data.parent) {
91+
const newEdge = {
92+
id: `${getNonce()}`,
93+
source: node.data.parent,
94+
target: node.data.id,
95+
type: ConnectionLineType.Bezier,
96+
animated: true,
97+
};
98+
99+
100+
// Check if the edge already exists before adding
101+
const edgeExists = initialEdges.some(
102+
edge => edge.source === newEdge.source && edge.target === newEdge.target
103+
);
104+
105+
// If edge does not exist, add to our edges array
106+
if (!edgeExists) {
107+
initialEdges.push(newEdge)
108+
}
109+
}
110+
}
111+
)
112+
113+
}
114+
46115
return (
116+
<div style={{ height: '600px', width: '100%' }}>
47117
<ReactFlow
48118
nodes={nodes}
49119
edges={edges}
@@ -53,6 +123,7 @@ const OverviewFlow = () => {
53123
onInit={onInit}
54124
fitView
55125
attributionPosition="top-right"
126+
style={{ width: '100%', height: '100%' }}
56127
>
57128
<MiniMap
58129
nodeStrokeColor={(n): string => {
@@ -80,6 +151,7 @@ const OverviewFlow = () => {
80151
<Controls />
81152
<Background color="#aaa" gap={16} />
82153
</ReactFlow >
154+
</div>
83155
);
84156
};
85157

webpack.config 2.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
const path = require('path')
2+
3+
4+
module.exports = {
5+
entry: './src/webview/index.jsx',
6+
output: {
7+
filename: 'bundle.js',
8+
path: path.resolve(__dirname, './build'),
9+
},
10+
resolve: {
11+
extensions: ['.js', '.jsx', '.css'],
12+
},
13+
module: {
14+
rules: [
15+
{
16+
test: /\.jsx?/,
17+
exclude: /node_modules/,
18+
use: {
19+
loader: "babel-loader",
20+
options: {
21+
presets: ['@babel/preset-env', '@babel/preset-react']
22+
}
23+
}
24+
},
25+
{
26+
test: /\.(scss|css)$/,
27+
use: ["style-loader", "css-loader"],
28+
},
29+
]
30+
},
31+
mode: "development"
32+
}

0 commit comments

Comments
 (0)