Skip to content

Commit d241056

Browse files
committed
fixup! Add pagination to split large graph visualizations
1 parent 54ea80d commit d241056

File tree

3 files changed

+34
-28
lines changed

3 files changed

+34
-28
lines changed

graph-visualization/artifactDependenciesGraph/artifactDependenciesGraph.js

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,30 @@ function getHierarchicalVisConfiguration() {
44
shape: "hexagon",
55
shadow: false,
66
font: {
7-
strokeWidth: 13,
7+
strokeWidth: 4,
88
strokeColor: "#F2F2FF",
9-
size: 11,
9+
size: 9,
1010
},
1111
size: 22,
12+
widthConstraint: {
13+
maximum: 50
14+
}
1215
},
1316
edges: {
1417
arrows: {
1518
to: {
1619
enabled: true,
17-
scaleFactor: 0.6,
20+
scaleFactor: 0.5,
1821
},
1922
},
2023
scaling: {
21-
max: 10,
24+
max: 8,
2225
},
2326
},
2427
physics: {
2528
hierarchicalRepulsion: {
2629
nodeDistance: 200, // 100
27-
centralGravity: 0.6, // 0.2
30+
centralGravity: 0.5, // 0.2
2831
springLength: 200, // 200
2932
springConstant: 0.06, // 0.05
3033
damping: 0.09, // 0.09
@@ -82,50 +85,45 @@ function getConfiguration(containerId, credentials, visConfiguration) {
8285
initialCypher:
8386
//"MATCH (a1:Artifact)-[r1:DEPENDS_ON*0..1]->(a2:Artifact) WHERE a2.topologicalSortIndex >= $startIndex AND a2.topologicalSortIndex < $endIndex RETURN a1,r1,a2 ORDER BY a2.topologicalSortIndex",
8487
//"MATCH (a1:Artifact)-[r1:DEPENDS_ON*0..1]->(a2:Artifact) WHERE a2.topologicalSortIndex >= 0 RETURN a1,r1,a2 ORDER BY a2.topologicalSortIndex SKIP toInteger($startIndex) LIMIT toInteger($blockSize)",
85-
"MATCH (a1:Artifact)-[r1:DEPENDS_ON*0..2]->(a2:Artifact) WHERE a2.topologicalSortIndex >= 0 RETURN a1,r1,a2 ORDER BY a2.topologicalSortIndex SKIP toInteger($startIndex) LIMIT toInteger($blockSize)",
88+
"MATCH (a1:Artifact)-[r1:DEPENDS_ON*0..1]->(a2:Artifact) WHERE a1.topologicalSortIndex >= 0 AND a2.topologicalSortIndex >= 0 AND a1 <> a2 RETURN a1,r1,a2 ORDER BY a2.topologicalSortIndex, a1.topologicalSortIndex SKIP toInteger($startIndex) LIMIT toInteger($blockSize)",
8689
};
8790
}
8891

8992
function draw() {
9093
const containerElement = document.getElementById("visualizations");
9194

9295
// Render at most 50 (maxIndex) visualizations. Rendering ends when no query records are left.
93-
const maxVisualizations = 110; //FIXME larger values lead to a bug where "visualization-finished" isn't written
94-
const recordsPerVisualization = 60;
95-
let finishedVisualizations = 0;
96+
const maxVisualizations = 100; //FIXME larger values lead to a bug where "visualization-finished" isn't written
97+
const recordsPerVisualization = 160;
9698

97-
for (let index = 0; index < maxVisualizations; index++) {
99+
for (let index = 0; (index < maxVisualizations); index++) {
98100
const indexedVisualizationContainer = document.createElement("div");
99101
indexedVisualizationContainer.id = `viz-${index}`;
100102
indexedVisualizationContainer.classList.add("indexedVisualization");
101103
containerElement.appendChild(indexedVisualizationContainer);
102104

103105
const config = getConfiguration(indexedVisualizationContainer.id, getNeo4jCredentials(), getHierarchicalVisConfiguration());
104106
const neoViz = new NeoVis.default(config);
107+
105108
neoViz.registerOnEvent(NeoVis.NeoVisEvents.CompletionEvent, (event) => {
106-
finishedVisualizations++;
107-
//console.log(`Finished ${finishedVisualizations} visualizations`)
108-
if (finishedVisualizations >= maxVisualizations) {
109-
// All visualizations were completed.
110-
// Wait for 5 seconds until the physics stabilized
111-
const containerElementClassList = indexedVisualizationContainer.parentElement.classList;
112-
setTimeout(() => {
113-
containerElementClassList.add("visualization-finished");
114-
}, 5000);
115-
}
116109
if (event.recordCount == 0) {
117110
indexedVisualizationContainer.remove(); // remove an empty canvas
118111
} else {
119112
setTimeout(() => {
120113
neoViz.stabilize();
121114
indexedVisualizationContainer.classList.add("visualization-finished");
122-
// const unfinishedVisualizations = document.querySelectorAll(".indexedVisualization:not(.visualization-finished)");
123-
// if (unfinishedVisualizations === 0) {
124-
// indexedVisualizationContainer.parentElement.add("visualization-finished");
125-
// }
115+
116+
const unfinishedVisualizations = document.querySelectorAll(".indexedVisualization:not(.visualization-finished)");
117+
if (unfinishedVisualizations.length === 0) {
118+
indexedVisualizationContainer.parentElement.classList.add("visualization-finished");
119+
}
126120
}, 5000);
127121
}
128122
});
123+
neoViz.registerOnEvent(NeoVis.NeoVisEvents.ErrorEvent, (event) => {
124+
indexedVisualizationContainer.classList.add("visualization-failed");
125+
indexedVisualizationContainer.textContent = event.error.message;
126+
});
129127
const parameters = {blockSize: recordsPerVisualization, startIndex: index * recordsPerVisualization, endIndex: (index + 1) * recordsPerVisualization };
130128
neoViz.render(undefined, parameters);
131129
}

graph-visualization/index.css

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ div {
44
}
55

66
.indexedVisualization {
7-
max-width: 98vw;
7+
width: 98vw;
88
height: 100vh;
99
display:inline-block;
1010
/* border-width: 2px;
@@ -13,12 +13,20 @@ div {
1313
}
1414

1515
.indexedVisualization.visualization-finished {
16+
border-width: 1px;
1617
border-style: solid;
1718
border-color: lightgreen;
1819
}
1920

20-
.indexedVisualization:not(.visualization-finished) {
21+
.indexedVisualization:not(.visualization-finished):not(.visualization-failed) {
2122
border-width: 2px;
2223
border-style: dotted;
2324
border-color: orange;
24-
}
25+
}
26+
27+
.indexedVisualization.visualization-failed {
28+
height: 4em;
29+
border-width: 2px;
30+
border-style: solid;
31+
border-color: red;
32+
}

graph-visualization/renderVisualizations.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const camelToKebabCase = (str) => str.replace(/[A-Z]/g, (letter) => `-${letter.t
2525
*/
2626
const takeCanvasScreenshots = async (browser, htmlFilename) => {
2727
const page = await browser.newPage();
28-
await page.setViewport({ width: 4000, height: 2400, isMobile: false, isLandscape: true, hasTouch: false, deviceScaleFactor: 1 });
28+
await page.setViewport({ width: 12000, height: 6000, isMobile: false, isLandscape: true, hasTouch: false, deviceScaleFactor: 1 });
2929

3030
console.log(`Loading ${htmlFilename}`);
3131
await page.goto(`file://${htmlFilename}`);

0 commit comments

Comments
 (0)