From 345d55deb70e1bec8a2ed7036e9821f7a368fab0 Mon Sep 17 00:00:00 2001 From: valerio bartolini Date: Fri, 14 Apr 2023 18:49:49 +0200 Subject: [PATCH] perf(Topology): :zap: Enable GPU for many nodes --- .../components/Graph/GraphReactAdaptor.tsx | 19 ++++++++++++--- src/core/components/Graph/config.ts | 24 ++++++++++++------- src/pages/Topology/services/index.ts | 6 ++--- 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/core/components/Graph/GraphReactAdaptor.tsx b/src/core/components/Graph/GraphReactAdaptor.tsx index 8e7051d9..9adb022e 100644 --- a/src/core/components/Graph/GraphReactAdaptor.tsx +++ b/src/core/components/Graph/GraphReactAdaptor.tsx @@ -15,6 +15,8 @@ import { DEFAULT_COMBO_CONFIG, DEFAULT_EDGE_CONFIG, DEFAULT_LAYOUT_COMBO_FORCE_CONFIG, + DEFAULT_LAYOUT_FORCE_CONFIG, + DEFAULT_LAYOUT_GFORCE_CONFIG, DEFAULT_MODE, DEFAULT_NODE_CONFIG, DEFAULT_NODE_STATE_CONFIG @@ -81,7 +83,17 @@ const GraphReactAdaptor: FC = memo( ...DEFAULT_LAYOUT_COMBO_FORCE_CONFIG, center: [$node.scrollWidth / 2, $node.scrollHeight / 2], maxIteration: GraphController.calculateMaxIteration(nodes.length), - nodesFilter: ({ x, y }: GraphNode) => !!(!x || !y) + nodesFilter: ({ x, y, comboId }: GraphNode) => !!(!x || !y) && comboId + }, + { + ...DEFAULT_LAYOUT_FORCE_CONFIG, + center: [$node.scrollWidth / 2, $node.scrollHeight / 2], + nodesFilter: ({ x, y, comboId }: GraphNode) => !!(!x || !y) && !comboId && nodes.length < 250 + }, + { + ...DEFAULT_LAYOUT_GFORCE_CONFIG, + center: [$node.scrollWidth / 2, $node.scrollHeight / 2], + nodesFilter: ({ x, y, comboId }: GraphNode) => !!(!x || !y) && !comboId && nodes.length >= 250 } ] }, @@ -233,6 +245,8 @@ const GraphReactAdaptor: FC = memo( topologyGraph.on('afterlayout', () => { topologyGraphRef.current = topologyGraph; + prevNodesRef.current = nodes; + prevEdgesRef.current = edges; setIsGraphLoaded(true); }); @@ -279,8 +293,7 @@ const GraphReactAdaptor: FC = memo( isGraphLoaded && graphInstance && (JSON.stringify(prevNodesRef.current) !== JSON.stringify(nodes) || - JSON.stringify(prevEdgesRef.current) !== JSON.stringify(edges) || - (combos && JSON.stringify(prevCombosRef.current) !== JSON.stringify(combos))) + JSON.stringify(prevEdgesRef.current) !== JSON.stringify(edges)) ) { graphInstance.changeData(GraphController.getG6Model({ edges, nodes, combos })); diff --git a/src/core/components/Graph/config.ts b/src/core/components/Graph/config.ts index 16facea7..e6d71fc1 100644 --- a/src/core/components/Graph/config.ts +++ b/src/core/components/Graph/config.ts @@ -25,13 +25,13 @@ export const DEFAULT_MODE = { ] }; -export const DEFAULT_LAYOUT_COMBO_FORCE_CONFIG = { +export const DEFAULT_LAYOUT_COMBO_FORCE_CONFIG: LayoutConfig = { type: 'comboForce', nodeSize: 30, nodeSpacing: 30, - comboSpacing: 80, + comboSpacing: 50, linkDistance: 150, - nodeStrength: -50, + nodeStrength: -100, edgeStrength: 1, collideStrength: 1, preventOverlap: true, @@ -41,19 +41,27 @@ export const DEFAULT_LAYOUT_COMBO_FORCE_CONFIG = { export const DEFAULT_LAYOUT_FORCE_CONFIG: LayoutConfig = { type: 'force', - clustering: true, - clusterNodeStrength: -1000, - clusterEdgeDistance: 1000, - clusterFociStrength: 1.2, linkDistance: 250, - nodeStrength: -4000, + nodeStrength: -200, edgeStrength: 0.7, collideStrength: 1, nodeSpacing: NODE_SIZE, preventOverlap: true, + alphaMin: 0.08, alpha: 0.1 }; +export const DEFAULT_LAYOUT_GFORCE_CONFIG: LayoutConfig = { + type: 'gForce', + linkDistance: 200, + nodeStrength: 500, + edgeStrength: 200, + collideStrength: 1, + nodeSpacing: NODE_SIZE, + preventOverlap: true, + gpuEnabled: true +}; + export const DEFAULT_NODE_CONFIG = { type: 'circle', size: [NODE_SIZE], diff --git a/src/pages/Topology/services/index.ts b/src/pages/Topology/services/index.ts index 14624f72..f2e777eb 100644 --- a/src/pages/Topology/services/index.ts +++ b/src/pages/Topology/services/index.ts @@ -23,7 +23,7 @@ export const TopologyController = { const color = getColor(index); const img = siteSVG; - return convertEntityToNode({ id: identity, comboId: identity, label, x, y, color, img }); + return convertEntityToNode({ id: identity, label, x, y, color, img }); }), convertProcessGroupsToNodes: (entities: ProcessGroupResponse[]): GraphNode[] => @@ -32,7 +32,7 @@ export const TopologyController = { const color = getColor(role === 'internal' ? 16 : index); const img = role === 'internal' ? skupperProcessSVG : componentSVG; - return convertEntityToNode({ id: identity, comboId: identity, label, x, y, color, img }); + return convertEntityToNode({ id: identity, label, x, y, color, img }); }), convertProcessesToNodes: (processes: ProcessResponse[], groups: GraphNode[]): GraphNode[] => @@ -49,7 +49,7 @@ export const TopologyController = { convertSitesToGroups: (processes: GraphNode[], sites: GraphNode[]): GraphCombo[] => { const groups = processes.map(({ comboId }) => comboId); - return sites.filter((site) => groups.includes(site.comboId)).map(({ id, style, label }) => ({ id, label, style })); + return sites.filter((site) => groups.includes(site.id)).map(({ id, style, label }) => ({ id, label, style })); }, convertFlowPairsToLinks: (flowPairsByAddress: FlowPairsResponse[]): GraphEdge[] =>