D3.js Sankey Diagrams中的链接可以是除了立方贝塞尔曲线之外的任何东西吗?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了D3.js Sankey Diagrams中的链接可以是除了立方贝塞尔曲线之外的任何东西吗?相关的知识,希望对你有一定的参考价值。

我正在尝试使用Sankey library制作D3.js的能量流图。在我看到的每个example中,节点之间的链接看起来相似并且连续不断。我的理解是Sankey库代码使用D3 Shape库绘制立方贝塞尔曲线。

我想知道是否有任何标准方法来绘制更复杂的连接链接?

具体来说,我希望这些连接看起来像these flow charts创建的Lawrence Livermore National Lab或来自this diagraman academic article。这两者在曲线之前都具有某种“缓冲”,并且对角线部分看起来彼此平行(或稍微平行)。对于我的情况,如果所有对角线部分都以45度角平行,并且具有可变大小的缓冲区,我更愿意。

有没有人对如何做到这一点有任何想法?我是D3.js的新手,非常感谢你有任何帮助或指导!

答案

好吧,“标准”方式是D3中预定义的link functions ...但我们可以用任何返回新path定义字符串的函数替换那些。函数的输入是链接对象,它具有源和目标x / y坐标。因此,两者之间的简单直线“路径”可以像这样实现:

function straightLine(d, i) {
    return "M" + d.source.x + "," + d.source.y +
          " L" + d.target.y + "," + d.target.y;
}

您将用于在svg <path>元素上设置“d”属性,如下所示:

svg.selectAll("path.link")
    .data(mydata)
    .attr("d", straightLine);

对于您的特定情况,构建具有水平开始/结束部分和45°角中间部分的路径,我们使用起点/终点来计算中间交汇点 - 例如:

function angledLine(d, i) {
    var dh = d.target.x - d.source.x; // horizontal distance
    var dv = d.target.y - d.source.y; // vertical distance
    var a1 = d.source.x + (dy - dx)/2; // 1st angle point x
    var a2 = d.target.x - (dy - dx)/2; // 2nd angle point x

    return "M" + d.source.x + "," + d.source.y +
          " L" + a1 + "," + d.source.y + 
          " L" + a2 + "," + d.target.y + 
          " L" + d.target.y + "," + d.target.y;
}

第一个arg d是链接对象。为清楚起见,我正在生成一个相当冗长的路径字符串(具有绝对坐标的连接线)。这样可以正常工作,但可以通过使用“H”和“V”命令水平/垂直移动(或小写版本移动相对距离)来简化。如果要缩短路径字符串(数据较少,但可读性较差),也可以在没有“L”命令的情况下将x,y对串在一起。

注意:此实现假定水平距离>垂直距离。我将把它留给OP确定如何修改另一种情况的路径(改变角度?在角度中间添加一条垂直线?在每一端添加垂直部分?)精心设计的链接生成器将必须考虑上下左右布局,以及源另一侧的目标(负距离)。但这应该有助于你开始......

第二个arg i是数据数组中链接的索引。尽管在此示例中未使用它,但它可用于向左或向右推动倾斜部分,以帮助避免平行路径中的某些重叠。因人而异

以上是关于D3.js Sankey Diagrams中的链接可以是除了立方贝塞尔曲线之外的任何东西吗?的主要内容,如果未能解决你的问题,请参考以下文章

d3.js v4 sankey图 - 粒子和拖动不起作用

当链接太多时,d3 sankey插件没有绘制?

D3 sankey图 - 强制节点位置

是否可以将 Shiny 应用程序中的工具提示添加到使用 ggalluvial 创建的 Sankey 图中?

使用 d3.js 在 svg 上创建关闭按钮

D3.js 中的array_replace?