我正在尝试使用Sankey library制作D3.js的能量流图。在我看到的每个example中,节点之间的链接看起来相似并且连续不断。我的理解是Sankey库代码使用D3 Shape库绘制立方贝塞尔曲线。
我想知道是否有任何标准方法来绘制更复杂的连接链接?
具体来说,我希望这些连接看起来像these flow charts创建的Lawrence Livermore National Lab或来自this diagram的an 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
是数据数组中链接的索引。尽管在此示例中未使用它,但它可用于向左或向右推动倾斜部分,以帮助避免平行路径中的某些重叠。因人而异