I'm trying to create a hierarchical graph using vis.js. I can create the hierarchical graph, but the layout is not what I'm looking for: the nodes are on seemingly arbitrary levels. I want the nodes to be on different levels based on how many edges between them and the root.
The data originally comes from SQL. Currently, I have a Python script that processes the data into DOT language (and I can display the graph with the layout that I want using Graphviz), so that's why I'm using the .convertDot method. I could re-process the network after being imported into vis.js and add the correct "level" attribute to each node individually, but there must be a better way.
Here's the full HTML/JS document that I have so far:
<!DOCTYPE HTML>
<html>
<head>
<script src="./vis/dist/vis.js"></script>
<link href="./vis/dist/vis.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="graph", style="height: 1000px"></div>
<script>
// provide data in the DOT language
var DOTstring = 'digraph {"13332500" -> "13483400" "13567500" -> "13483400" "10037901" -> "10037902" "10037902" -> "13483400" "15038400" -> "13455700" "13455700" -> "13455702" "13455702" -> "13483400" "13567300" -> "13483400" "11890500" -> "13483400" "13483400" -> "13554900"}';
var parsedData = vis.network.convertDot(DOTstring);
var data = {
nodes: parsedData.nodes,
edges: parsedData.edges
}
var container = document.getElementById('graph');
var options = parsedData.options;
// you can extend the options like a normal JSON variable:
options.layout = {
"hierarchical": true
}
// create a network
var network = new vis.Network(container, data, options);
</script>
</body>
</html>
Here's what the code will produce:
And here's the layout that I'm looking for, as produced by graphviz:
In case you're wondering why I'm trying to do this in vis.js when I already have it working in graphviz: the reason is I want to make it interactive.
As of vis.js version 6.2, there is a new option that allows the graph to be displayed as desired. Use sortMethod: 'directed'
and shakeTowards: 'roots'
.
Modifying options.layout
in my original script gives the desired result:
<!DOCTYPE HTML>
<html>
<head>
<script src="./vis/dist/vis.js"></script>
<link href="./vis/dist/vis.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="graph", style="height: 1000px"></div>
<script>
// provide data in the DOT language
var DOTstring = 'digraph {"13332500" -> "13483400" "13567500" -> "13483400" "10037901" -> "10037902" "10037902" -> "13483400" "15038400" -> "13455700" "13455700" -> "13455702" "13455702" -> "13483400" "13567300" -> "13483400" "11890500" -> "13483400" "13483400" -> "13554900"}';
var parsedData = vis.network.convertDot(DOTstring);
var data = {
nodes: parsedData.nodes,
edges: parsedData.edges
}
var container = document.getElementById('graph');
var options = parsedData.options;
// you can extend the options like a normal JSON variable:
options.layout = {
hierarchical: {
sortMethod: 'directed', // hubsize, directed
shakeTowards: 'roots', // roots, leaves
direction: 'DU' // UD, DU, LR, RL
}
}
// create a network
var network = new vis.Network(container, data, options);
</script>
</body>
</html>