d3 force graph version

This commit is contained in:
Michael Quigley 2022-08-04 13:48:38 -04:00
parent 9002513774
commit 36c050380a
No known key found for this signature in database
GPG Key ID: 9B60314A9DD20A62
4 changed files with 17888 additions and 221 deletions

18003
ui/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,7 @@
"react": "^18.2.0",
"react-data-table-component": "^7.5.2",
"react-dom": "^18.2.0",
"react-flow-renderer": "^10.3.12",
"react-force-graph-2d": "^1.23.10",
"react-scripts": "5.0.1",
"styled-components": "^5.3.5",
"web-vitals": "^2.1.4"

View File

@ -1,31 +1,62 @@
import ReactFlow, {useNodesState} from "react-flow-renderer";
import * as metadata from './api/metadata';
import {useEffect, useState} from "react";
import {useEffect, useLayoutEffect, useRef, useState} from "react";
import ForceGraph2D from 'react-force-graph-2d';
let g1 = {}
const Network = (props) => {
const [nodes, setNodes, onNodesChange] = useNodesState([])
const [edges, setEdges] = useState([]);
const ref = useRef();
const [graph, setGraph] = useState({nodes: [], links: []})
useEffect(() => {
let mounted = true
metadata.overview().then(resp => {
let ovr = buildGraph(resp.data)
setNodes(ovr.nodes)
setEdges(ovr.edges)
console.log('nodes', ovr.nodes);
})
let g1 = graph
let interval = setInterval(() => {
metadata.overview().then(resp => {
let g = buildGraph(resp.data)
if(!compareGraphs(g, g1)) {
setGraph(g)
g1 = g
}
})
}, 1000)
return () => {
mounted = false
clearInterval(interval)
}
}, [])
return (
<div className={"network"}>
<h1>Network</h1>
<ReactFlow
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
<ForceGraph2D
ref={ref}
width={1024}
height={300}
graphData={graph}
nodeDefaultSize={[100, 50]}
nodeCanvasObject={(node, ctx, globalScale) => {
const label = node.name;
const fontSize = 12/globalScale;
ctx.font = `${fontSize}px JetBrains Mono`;
const textWidth = ctx.measureText(label).width;
const bckgDimensions = [textWidth, fontSize].map(n => n + fontSize * 2.2); // some padding
ctx.fillStyle = '#3b2693';
ctx.strokeStyle = '#3b2693'
ctx.lineWidth = 0.5
ctx.fillRect(node.x - bckgDimensions[0] / 2, node.y - bckgDimensions[1] / 2, ...bckgDimensions);
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillStyle = 'white';
ctx.fillText(label, node.x, node.y);
node.__bckgDimensions = bckgDimensions; // to re-use in nodePointerAreaPaint
}}
onEngineStop={() => {
ref.current.zoomToFit(200);
}}
/>
</div>
)
@ -34,34 +65,24 @@ const Network = (props) => {
function buildGraph(overview) {
let out = {
nodes: [],
edges: []
links: []
}
let id = 1
overview.forEach((item) => {
let envId = id
out.nodes.push({
id: '' + envId,
data: {label: 'Environment: ' + item.environment.zitiIdentityId},
position: {x: (id * 25), y: 0},
draggable: true
id: item.environment.zitiIdentityId,
name: 'Environment: ' + item.environment.zitiIdentityId
});
id++
if(item.services != null) {
item.services.forEach((item) => {
if(item.active) {
item.services.forEach((svc) => {
if(svc.active) {
out.nodes.push({
id: '' + id,
data: {label: 'Service: ' + item.zitiServiceId},
position: {x: (id * 25), y: 0},
draggable: true
id: svc.zitiServiceId,
name: 'Service: ' + svc.zitiServiceId
})
out.edges.push({
id: 'e' + envId + '-' + id,
source: '' + envId,
target: '' + id,
animated: true
out.links.push({
source: item.environment.zitiIdentityId,
target: svc.zitiServiceId
})
id++
}
});
}
@ -69,4 +90,18 @@ function buildGraph(overview) {
return out
}
function compareGraphs(g, g1) {
if(g.nodes.length !== g1.nodes.length) return false;
for(let i = 0; i < g.nodes.length; i++) {
if(!compareNodes(g.nodes[i], g1.nodes[i])) return false;
}
return true
}
function compareNodes(n, n1) {
if(n.id !== n1.id) return false;
if(n.name !== n1.name) return false;
return true;
}
export default Network;

View File

@ -26,7 +26,6 @@ function getAuthorization(security) {
function getApiKey() {
const localUser = JSON.parse(localStorage.getItem("user"))
if(localUser) {
console.log('getApiKey', localUser.token)
return Promise.resolve({ apiKey: localUser.token });
} else {
throw new Error("token not available");