diff options
author | Kristóf Marussy <kristof@marussy.com> | 2023-09-04 16:28:20 +0200 |
---|---|---|
committer | Kristóf Marussy <kristof@marussy.com> | 2023-09-04 16:28:20 +0200 |
commit | 20cd0081fbb1fd569a4679ccbd8bda959f022fa3 (patch) | |
tree | 259e8c40cc2976579c178e56ce6636a9036b802d /subprojects/frontend/src/graph | |
parent | build: add Dockerfile (diff) | |
download | refinery-20cd0081fbb1fd569a4679ccbd8bda959f022fa3.tar.gz refinery-20cd0081fbb1fd569a4679ccbd8bda959f022fa3.tar.zst refinery-20cd0081fbb1fd569a4679ccbd8bda959f022fa3.zip |
refactor(frontend): graph visualizer performance
Also show scopes unconditionally if enabled.
Diffstat (limited to 'subprojects/frontend/src/graph')
-rw-r--r-- | subprojects/frontend/src/graph/DotGraphVisualizer.tsx | 25 | ||||
-rw-r--r-- | subprojects/frontend/src/graph/dotSource.ts | 6 |
2 files changed, 24 insertions, 7 deletions
diff --git a/subprojects/frontend/src/graph/DotGraphVisualizer.tsx b/subprojects/frontend/src/graph/DotGraphVisualizer.tsx index 41fd7225..02f31085 100644 --- a/subprojects/frontend/src/graph/DotGraphVisualizer.tsx +++ b/subprojects/frontend/src/graph/DotGraphVisualizer.tsx | |||
@@ -29,13 +29,17 @@ function DotGraphVisualizer({ | |||
29 | graph, | 29 | graph, |
30 | fitZoom, | 30 | fitZoom, |
31 | transitionTime, | 31 | transitionTime, |
32 | animateThreshold, | ||
32 | }: { | 33 | }: { |
33 | graph: GraphStore; | 34 | graph: GraphStore; |
34 | fitZoom?: FitZoomCallback; | 35 | fitZoom?: FitZoomCallback; |
35 | transitionTime?: number; | 36 | transitionTime?: number; |
37 | animateThreshold?: number; | ||
36 | }): JSX.Element { | 38 | }): JSX.Element { |
37 | const transitionTimeOrDefault = | 39 | const transitionTimeOrDefault = |
38 | transitionTime ?? DotGraphVisualizer.defaultProps.transitionTime; | 40 | transitionTime ?? DotGraphVisualizer.defaultProps.transitionTime; |
41 | const animateThresholdOrDefault = | ||
42 | animateThreshold ?? DotGraphVisualizer.defaultProps.animateThreshold; | ||
39 | const disposerRef = useRef<IReactionDisposer | undefined>(); | 43 | const disposerRef = useRef<IReactionDisposer | undefined>(); |
40 | const graphvizRef = useRef< | 44 | const graphvizRef = useRef< |
41 | Graphviz<BaseType, unknown, null, undefined> | undefined | 45 | Graphviz<BaseType, unknown, null, undefined> | undefined |
@@ -75,6 +79,8 @@ function DotGraphVisualizer({ | |||
75 | Workaround for error in `@types/d3-graphviz`. | 79 | Workaround for error in `@types/d3-graphviz`. |
76 | */ | 80 | */ |
77 | renderer.transition(transition as any); | 81 | renderer.transition(transition as any); |
82 | let animate = true; | ||
83 | let previousSize = 0; | ||
78 | let newViewBox = { width: 0, height: 0 }; | 84 | let newViewBox = { width: 0, height: 0 }; |
79 | renderer.onerror(LOG.error.bind(LOG)); | 85 | renderer.onerror(LOG.error.bind(LOG)); |
80 | renderer.on( | 86 | renderer.on( |
@@ -106,17 +112,27 @@ function DotGraphVisualizer({ | |||
106 | } | 112 | } |
107 | disposerRef.current = reaction( | 113 | disposerRef.current = reaction( |
108 | () => dotSource(graph), | 114 | () => dotSource(graph), |
109 | (source) => { | 115 | (result) => { |
110 | if (source !== undefined) { | 116 | if (result === undefined) { |
111 | renderer.renderDot(source); | 117 | return; |
112 | } | 118 | } |
119 | const [source, size] = result; | ||
120 | // Disable tweening for large graphs to improve performance. | ||
121 | // See https://github.com/magjac/d3-graphviz/issues/232#issuecomment-1157555213 | ||
122 | const newAnimate = size + previousSize < animateThresholdOrDefault; | ||
123 | if (animate !== newAnimate) { | ||
124 | renderer.tweenPaths(newAnimate); | ||
125 | animate = newAnimate; | ||
126 | } | ||
127 | previousSize = size; | ||
128 | renderer.renderDot(source); | ||
113 | }, | 129 | }, |
114 | { fireImmediately: true }, | 130 | { fireImmediately: true }, |
115 | ); | 131 | ); |
116 | graphvizRef.current = renderer; | 132 | graphvizRef.current = renderer; |
117 | } | 133 | } |
118 | }, | 134 | }, |
119 | [graph, fitZoom, transitionTimeOrDefault], | 135 | [graph, fitZoom, transitionTimeOrDefault, animateThresholdOrDefault], |
120 | ); | 136 | ); |
121 | 137 | ||
122 | return <GraphTheme ref={setElement} />; | 138 | return <GraphTheme ref={setElement} />; |
@@ -125,6 +141,7 @@ function DotGraphVisualizer({ | |||
125 | DotGraphVisualizer.defaultProps = { | 141 | DotGraphVisualizer.defaultProps = { |
126 | fitZoom: undefined, | 142 | fitZoom: undefined, |
127 | transitionTime: 250, | 143 | transitionTime: 250, |
144 | animateThreshold: 50, | ||
128 | }; | 145 | }; |
129 | 146 | ||
130 | export default observer(DotGraphVisualizer); | 147 | export default observer(DotGraphVisualizer); |
diff --git a/subprojects/frontend/src/graph/dotSource.ts b/subprojects/frontend/src/graph/dotSource.ts index 5f7707aa..5e0b44c8 100644 --- a/subprojects/frontend/src/graph/dotSource.ts +++ b/subprojects/frontend/src/graph/dotSource.ts | |||
@@ -142,7 +142,7 @@ function createNodes(graph: GraphStore, lines: string[]): void { | |||
142 | const classes = classList.join(' '); | 142 | const classes = classList.join(' '); |
143 | const name = nodeName(graph, node); | 143 | const name = nodeName(graph, node); |
144 | const border = node.kind === 'INDIVIDUAL' ? 2 : 1; | 144 | const border = node.kind === 'INDIVIDUAL' ? 2 : 1; |
145 | const count = scopes && data.equalsSelf !== 'TRUE' ? ` ${data.count}` : ''; | 145 | const count = scopes ? ` ${data.count}` : ''; |
146 | lines.push(`n${i} [id="${node.name}", class="${classes}", label=< | 146 | lines.push(`n${i} [id="${node.name}", class="${classes}", label=< |
147 | <table border="${border}" cellborder="0" cellspacing="0" style="rounded" bgcolor="white"> | 147 | <table border="${border}" cellborder="0" cellspacing="0" style="rounded" bgcolor="white"> |
148 | <tr><td cellpadding="4.5" width="32" bgcolor="green">${name}${count}</td></tr>`); | 148 | <tr><td cellpadding="4.5" width="32" bgcolor="green">${name}${count}</td></tr>`); |
@@ -323,7 +323,7 @@ function createEdges(graph: GraphStore, lines: string[]): void { | |||
323 | 323 | ||
324 | export default function dotSource( | 324 | export default function dotSource( |
325 | graph: GraphStore | undefined, | 325 | graph: GraphStore | undefined, |
326 | ): string | undefined { | 326 | ): [string, number] | undefined { |
327 | if (graph === undefined) { | 327 | if (graph === undefined) { |
328 | return undefined; | 328 | return undefined; |
329 | } | 329 | } |
@@ -336,5 +336,5 @@ export default function dotSource( | |||
336 | createNodes(graph, lines); | 336 | createNodes(graph, lines); |
337 | createEdges(graph, lines); | 337 | createEdges(graph, lines); |
338 | lines.push('}'); | 338 | lines.push('}'); |
339 | return lines.join('\n'); | 339 | return [lines.join('\n'), lines.length]; |
340 | } | 340 | } |