Given a directed graph, where a value is associated with each node, how can we use vis.js to display the nodes ordered according to this value? E.g., all nodes at same depth are displayed left to right from "most valuable" to "least valuable"
In the example below, nodes 5 through 8 are children of node 4 and are added to left to right, in that order due to the index of edges
and not with respect to the value
of each node.
So we can rearrange edges
to sort descending over the from
node's value
in nodes
:
function rank(edges) {
// get a copy of edges
let edges2 = edges.map(function(edge) {return Object.assign({}, edge);});
// sort edges by node value
edges2.sort(function(a, b) {
let nodeA = nodes.find(function(n) {return n.id == a.from});
let nodeB = nodes.find(function(n) {return n.id == b.from});
return nodeB.value - nodeA.value;
});
return edges2;
}
Working example with both unranked, and the ranking per this function:
const nodes = [
{id: 1, level: 0, value: 1, label: "1"},
{id: 2, level: 1, value: 1, label: "2"},
{id: 3, level: 1, value: 2, label: "3"},
{id: 4, level: 2, value: 1, label: "4"},
{id: 5, level: 3, value: 1, label: "5"},
{id: 6, level: 3, value: 2, label: "6"},
{id: 7, level: 3, value: 3, label: "7"},
{id: 8, level: 3, value: 4, label: "8"}
];
const edges = [
{from: 2, to: 1},
{from: 3, to: 1},
{from: 4, to: 3},
{from: 5, to: 4},
{from: 6, to: 4},
{from: 7, to: 4},
{from: 8, to: 4}
];
const options = {
nodes: {
shape: "dot"
},
edges: {
smooth: {
type: "cubicBezier",
forceDirection: "vertical",
roundness: 0.4
}
},
layout: {
hierarchical: {
direction: "UD",
},
},
physics: false
}
// unranked
const data1 = {
nodes: nodes,
edges: edges
}
const container1 = document.getElementById("network1");
const network1 = new vis.Network(container1, data1, options);
// ranked
const data2 = {
nodes: nodes,
edges: rank(edges)
}
function rank(edges) {
// get a copy of edges
let edges2 = edges.map(function(edge) {return Object.assign({}, edge);});
// sort edges by node value
edges2.sort(function(a, b) {
let nodeA = nodes.find(function(n) {return n.id == a.from});
let nodeB = nodes.find(function(n) {return n.id == b.from});
return nodeB.value - nodeA.value;
});
return edges2;
}
const container2 = document.getElementById("network2");
const network2 = new vis.Network(container2, data2, options);
#wrapper {
display: flex;
}
#network1 {
flex: 0 0 50%;
height: 180px;
border: 1px solid #000;
}
#network2 {
flex: 1;
height: 180px;
border: 1px solid #000;
}
<script type="text/javascript" src="https://unpkg.com/vis-network@9.0.4/dist/vis-network.min.js"></script>
<div id="wrapper">
<div id="network1"></div>
<div id="network2"></div>
</div>