I'm trying to order the nodes in D3 sankey. I want nodes that have larger values to be drawn higher up.
This is the relevant code (based on d3 noob's code) snippet, where I try to achieve what I want by using D3's inbuilt sort function. The outcome is not what I would expect.
Upon inspecting sankey.js, it's not entirely clear to me how the plug-in orders the nodes. Any advise on the topic would be appreciated.
//set up graph in same style as original example but empty
graph = {"nodes" : [], "links" : []};
data.forEach(function (d) {
graph.nodes.push({ "name": d.source });
graph.nodes.push({ "name": d.target });
graph.links.push({ "source": d.source,
"target": d.target,
"value": +d.value });
});
//try to sort the nodes and links before indexing them (not working)
graph.nodes.sort(function (a,b) {return d3.descending(a.value, b.value); });
graph.links.sort(function (a,b) {return d3.descending(a.value, b.value); });
// return only the distinct / unique nodes
graph.nodes = d3.keys(d3.nest()
.key(function (d) { return d.name; })
.map(graph.nodes));
// loop through each link replacing the text with its index from node
graph.links.forEach(function (d, i) {
graph.links[i].source = graph.nodes.indexOf(graph.links[i].source);
graph.links[i].target = graph.nodes.indexOf(graph.links[i].target);
});
//now loop through each nodes to make nodes an array of objects
// rather than an array of strings
graph.nodes.forEach(function (d, i) {
graph.nodes[i] = { "name": d };
});
Below steps can be used to create sankey with custom node order.
let data = {nodes:[],links:[]}
function to order/sort All nodes
const sankey = d3.sankey()
.size(graphSize)
.nodeId(d => d.id)
.nodeWidth(nodeWidth)
.nodePadding(0.5)
.nodeAlign(nodeAlignment)
.nodeSort(null) //creates sankey nodes as ordered in the data
let graph = sankey(data)
Sankey documentation
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With