Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ordering nodes in d3 sankey diagram

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 };
    });
like image 432
seb Avatar asked Nov 01 '15 11:11

seb


1 Answers

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

like image 188
Aqua 4 Avatar answered Sep 28 '22 18:09

Aqua 4