Skip to content

Commit df90450

Browse files
committed
Add Typescript modules dependency visualization
1 parent 0fe1b02 commit df90450

File tree

4 files changed

+263
-61
lines changed

4 files changed

+263
-61
lines changed

graph-visualization/README.md

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,37 @@
11
# Render Graph Visualizations
22

3-
This [node.js](https://nodejs.org/de) project provides the script [renderVisualizations.js](./renderVisualizations.js) to save all graph visualizations as image files.
3+
This [node.js](https://nodejs.org/de) project provides the script [renderVisualizations.js](./renderVisualizations.js) to render all graph visualizations as image files.
4+
5+
## Prerequisites
6+
7+
- Run `npm ci` in this directory to download all necessary dependencies.
8+
9+
## How it works
10+
411
[renderVisualizations.js](./renderVisualizations.js) uses these three steps:
512

6-
- opens every HTML file with [Puppeteer](https://pptr.dev) in a headless browser
7-
- takes screenshots of all contained [HTML5 Canvas elements](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas?retiredLocale=de)
8-
- saves them as [PNG](https://en.wikipedia.org/wiki/PNG) files in the current directory
13+
- Opens every HTML file in this directory and its subdirectories with [Puppeteer](https://pptr.dev) in a headless browser
14+
- Takes screenshots of all contained [HTML5 Canvas elements](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas?retiredLocale=de)
15+
- Creates a directory with the name of the HTML converted to snake case in the current directory
16+
- Saves all screenshots as [PNG](https://en.wikipedia.org/wiki/PNG) files into that newly created directory
917

10-
## Example
18+
## How to run it in the CLI
1119

12-
If the current working directory is e.g. `temp/projectname/reports/graph-visualizations` within this repository,
13-
then the command would look like this:
20+
Under the assumption that your current working directory is `temp/projectname/reports/graph-visualizations` in the root directory of this repository, then the command would look like this:
1421

1522
```shell
1623
node ./../../../../graph-visualization/renderVisualizations
1724
```
25+
26+
## How to open it in the browser
27+
28+
- Open one of the HTML files in the Browser using `file://` prefix followed by the full path or using a Live Server.
29+
- Enter the password for the local Neo4j database `neo4j` that you have chosen as initial password.
30+
- Wait until the orange frames turn green and use drag'n'drop or scrolling to see the part of the Graph you're interested in.
31+
- Currently, the frames are intentionally very large to get a practicable resolution for saving the images. This might get refined in future.
32+
33+
## Scripts
34+
35+
- [renderVisualizations.js](./renderVisualizations.js) is the main Node.js script that renders the Graph Visualizations using a Command Line Interface (CLI)
36+
- [vis-configuration-presets.js](./vis-configuration-presets.js) contains functions that return predefined visualization configurations. Currently (May 2024), there is only one configuration for visualizing hierarchical, topology sorted Graphs.
37+
- [visualization-pagination.js](./visualization-pagination.js) provides pagination for visualizing large Graphs by splitting them up into smaller Subgraphs all in separate images.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="UTF-8">
6+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
7+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
8+
9+
<title>Typescript Module Dependencies Graph Visualization with neovis.js</title>
10+
11+
<link rel="stylesheet" href="./../index.css">
12+
<script src="./../node_modules/neovis.js/dist/neovis.js"></script>
13+
<script type="text/javascript" src="./../vis-configuration-presets.js"></script>
14+
<script type="text/javascript" src="./../visualization-pagination.js"></script>
15+
<script type="text/javascript" src="graphVisualizationTypescriptModuleDependencies.js"></script>
16+
</head>
17+
18+
<body">
19+
<span>
20+
<label for="neo4j-server-password">Neo4j Server Password:</label>
21+
<input type="password" id="neo4j-server-password" name="neo4j-server-password" />
22+
<input type="submit" id="neo4j-server-login" value="Login" onClick="draw()" />
23+
</span>
24+
<div id="visualizations"></div>
25+
</body>
26+
27+
</html>
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
function getNeo4jCredentials() {
2+
return {
3+
serverUrl: "bolt://localhost:7687",
4+
serverUser: "neo4j",
5+
serverPassword: document.getElementById("neo4j-server-password").value,
6+
};
7+
}
8+
9+
function getConfiguration(credentials, visConfiguration, containerId = "visualizations") {
10+
return {
11+
containerId: containerId,
12+
neo4j: credentials,
13+
visConfig: visConfiguration,
14+
// Note: "defaultLabelConfig" is used instead of named label configs: { NameOfTheLabel: {...}, ...}
15+
// The reason for that is that neovis.js takes the first label that is returned by Neo4j.
16+
// If there are multiple Labels this is not stable to use.
17+
// Since we only expect one type of labels here (homogenous graph) we can simply use the default label config.
18+
// Reference: https://github.com/neo4j-contrib/neovis.js/blob/cef0aa16d647ffe0fd9ca457bcffa6e0cb7c55c8/src/neovis.ts#L524
19+
defaultLabelConfig: {
20+
[NeoVis.NEOVIS_ADVANCED_CONFIG]: {
21+
function: {
22+
// Print all properties for the title (when nodes are clicked)
23+
title: NeoVis.objectToTitleHtml,
24+
// Use "name" as label. Remove file extension. Add dependency level (maxDistanceFromSource) in parentheses.
25+
label: (node) => {
26+
return node.properties.name.replace(/\.\w+$/gm, "") + "(" + node.properties.maxDistanceFromSource + ")";
27+
},
28+
},
29+
},
30+
},
31+
relationships: {
32+
DEPENDS_ON: {
33+
label: false,
34+
value: "cardinality",
35+
[NeoVis.NEOVIS_ADVANCED_CONFIG]: {
36+
function: {
37+
title: NeoVis.objectToTitleHtml
38+
},
39+
}
40+
},
41+
},
42+
initialCypher:
43+
"MATCH (module:TS:Module)-[dependency:DEPENDS_ON*0..1]->(dependent:TS:Module) WHERE module.topologicalSortIndex >= 0 AND dependent.topologicalSortIndex >= 0 AND module <> dependent RETURN module,dependency,dependent ORDER BY dependent.topologicalSortIndex, module.topologicalSortIndex SKIP toInteger($startIndex) LIMIT toInteger($blockSize)",
44+
};
45+
}
46+
47+
function draw() {
48+
const config = getConfiguration(getNeo4jCredentials(), hierarchicalHexagons());
49+
paginatedGraphVisualization({ containerElementId: "visualizations", neoVizConfiguration: config });
50+
}

0 commit comments

Comments
 (0)