d3 sankey图表 - 沿x轴手动定位节点

时间:2014-02-03 22:35:08

标签: javascript d3.js sankey-diagram

我使用d3 sankey实现遇到的一个问题是,无法指定节点在x轴上的位置。我一直在寻找源代码,并没有真正的“干净”方式来以合理的比例指定x值(即,图表为5个节点宽度的1-5)。我正在创建一些可以像课程计划器一样用于教育的东西,因此x值将与学期相对应。假设我有一门课程,直到大二二年级才能参加,这将是x的3(1/2是新生,3/4大二等)。问题是,如果事先没有任何东西链接到这个课程,它总是在x为1,所以我想将它推到正确的两个空格。

我注意到实际sankey图表中的x值并不反映它上面有多少个节点,所以这有点难以做到。

我也遇到this question,我意识到默认情况下图表不会让我定位节点。我没有问题调整sankey.js实现这一点的例子,但我现在仍然坚持如何这样做。

4 个答案:

答案 0 :(得分:16)

这是可能的。请参阅此JSFiddle

enter image description here

可以修改sankey.js中的computeNodeBreadths函数,以查找已分配给节点的显式x位置(node.xPos):

  function computeNodeBreadths() {
    var remainingNodes = nodes,
        nextNodes,
        x = 0;

    while (remainingNodes.length) {
      nextNodes = [];
      remainingNodes.forEach(function(node) {

        if (node.xPos)
            node.x = node.xPos;
        else
            node.x = x;

        node.dx = nodeWidth;
        node.sourceLinks.forEach(function(link) {
          nextNodes.push(link.target);
        });
      });
      remainingNodes = nextNodes;
      ++x;
    }

    //
    moveSinksRight(x);
    scaleNodeBreadths((width - nodeWidth) / (x - 1));
  }

然后,您需要做的就是在所需节点上指定xPos。在上面的例子中,我在node2上设置了xPos = 1。请参阅JSFiddle示例中的getData():

... }, {
        "node": 2,
        "name": "node2",
        "xPos": 1
    }, { ...

答案 1 :(得分:3)

如果有人想要如何修复已部署节点(rects)的初始位置,您可以这样做:

sankey.layout = function(iterations) {
    computeNodeLinks();
    computeNodeValues();
    computeNodeBreadths();
    computeNodeDepths(iterations);
    computeAbsolutePositions(); // add this in sankey.js file
    computeLinkDepths();
    return sankey;
};

自己添加职位:

function computeAbsolutePositions() {
    nodes[0].x = 0;
    nodes[0].y = 0;
    nodes[1].x = 260;
    nodes[1].y = 0;
};

请注意,当你对它们进行硬编码时,你必须要记住rects的位置,因为在这个例子中没有使用sankey.js最初使用的碰撞检查函数。

希望可以帮助别人!

答案 2 :(得分:1)

让我们调用x坐标layerlayer=0将保留边缘,layer=n将成为右边缘。在JSON文件的nodes字段中,添加键值对layer: your_desired_x_as_integer

然后转到sankey.js文件并找到函数componentsByBreadth.forEach。 将行node.x = component.x + node.x;替换为:

if (node.layer) node.x=node.layer;
else node.x = component.x + node.x;

您也可以像这样定义图层密度,例如:放置在层0,1,2或0,4,8上的节点将具有一个中心节点,并且两个位于sankey宽度的边缘,但0,1,5将不具有。

如果您需要更多帮助,我的D3 Sankey应用程序中包含此功能以及其他功能:http://sankey.csaladen.es

答案 3 :(得分:0)

可能不是您之后的干净答案,但您可以明确更改源和目​​标x属性,然后更新链接

http://bl.ocks.org/danharr/af796d91926d254dfe99