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": "^18.2.0",
"react-data-table-component": "^7.5.2", "react-data-table-component": "^7.5.2",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-flow-renderer": "^10.3.12", "react-force-graph-2d": "^1.23.10",
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
"styled-components": "^5.3.5", "styled-components": "^5.3.5",
"web-vitals": "^2.1.4" "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 * 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 Network = (props) => {
const [nodes, setNodes, onNodesChange] = useNodesState([]) const ref = useRef();
const [edges, setEdges] = useState([]); const [graph, setGraph] = useState({nodes: [], links: []})
useEffect(() => { useEffect(() => {
let mounted = true let mounted = true
metadata.overview().then(resp => { let g1 = graph
let ovr = buildGraph(resp.data) let interval = setInterval(() => {
setNodes(ovr.nodes) metadata.overview().then(resp => {
setEdges(ovr.edges) let g = buildGraph(resp.data)
console.log('nodes', ovr.nodes); if(!compareGraphs(g, g1)) {
}) setGraph(g)
g1 = g
}
})
}, 1000)
return () => { return () => {
mounted = false mounted = false
clearInterval(interval)
} }
}, []) }, [])
return ( return (
<div className={"network"}> <div className={"network"}>
<h1>Network</h1> <h1>Network</h1>
<ReactFlow <ForceGraph2D
nodes={nodes} ref={ref}
edges={edges} width={1024}
onNodesChange={onNodesChange} 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> </div>
) )
@ -34,34 +65,24 @@ const Network = (props) => {
function buildGraph(overview) { function buildGraph(overview) {
let out = { let out = {
nodes: [], nodes: [],
edges: [] links: []
} }
let id = 1
overview.forEach((item) => { overview.forEach((item) => {
let envId = id
out.nodes.push({ out.nodes.push({
id: '' + envId, id: item.environment.zitiIdentityId,
data: {label: 'Environment: ' + item.environment.zitiIdentityId}, name: 'Environment: ' + item.environment.zitiIdentityId
position: {x: (id * 25), y: 0},
draggable: true
}); });
id++
if(item.services != null) { if(item.services != null) {
item.services.forEach((item) => { item.services.forEach((svc) => {
if(item.active) { if(svc.active) {
out.nodes.push({ out.nodes.push({
id: '' + id, id: svc.zitiServiceId,
data: {label: 'Service: ' + item.zitiServiceId}, name: 'Service: ' + svc.zitiServiceId
position: {x: (id * 25), y: 0},
draggable: true
}) })
out.edges.push({ out.links.push({
id: 'e' + envId + '-' + id, source: item.environment.zitiIdentityId,
source: '' + envId, target: svc.zitiServiceId
target: '' + id,
animated: true
}) })
id++
} }
}); });
} }
@ -69,4 +90,18 @@ function buildGraph(overview) {
return out 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; export default Network;

View File

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