在d3 sankey图中订购节点

seb*_*seb 11 javascript d3.js

我正在尝试在D3 sankey中订购节点.我希望将值较大的节点绘制得更高.

这是相关的代码(基于d3 noob的代码)片段,我试图通过使用D3的内置排序功能来实现我想要的.结果不是我所期望的.

在检查sankey.js时,我并不完全清楚插件是如何命令节点的.任何有关该主题的建议将不胜感激.

//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 };
    });
Run Code Online (Sandbox Code Playgroud)

小智 7

从sankey.js文件中的resolveCollisions()函数中删除以下行将停止更改节点的顺序:

function resolveCollisions() {
    ...
    // nodes.sort(ascendingDepth);  // commented this out to prevent node reordering
    ...
}
Run Code Online (Sandbox Code Playgroud)

然后,节点将被垂直排序,但它们最初是填充的.因此,如果在推送数据之前先对节点进行排序,它们将按排序顺序显示.


End*_*ell 6

如果将布局iterations值设置为零,您将获得按字母顺序(按名称)排列的节点:这对我来说效果很好。

var sankey = d3.sankey()
    .nodeWidth(36)
    .nodePadding(40)
    .size([width, height])
    .layout(0);  /* <<<<<<< setting the iterations to zero */
Run Code Online (Sandbox Code Playgroud)