利用d3.js力导布局绘制资源拓扑图实例教程(5)
效果如下:

这些线一对A都没有,分不清正反啊
应用与资源间的关系,是有方向的,大部分情况下是应用调用资源,也有情况会有双向的调用,除了文字意外,我们还需要加上箭头来表明是谁在调用谁。怎么加这个箭头呢?svg 的 path 元素有一个 marker-end 属性,通过设置这个属性可以可以将一个 svg 元素绘制到 path 元素最后的向量上。
// 在 svg 元素中添加一个 marker 元素
<svg>
<marker
id="arrow"
viewBox="-10 -10 20 20"
markerWidth="20"
markerHeight="20"
orient="auto"
>
<path
d="M-6.75,-6.75 L 0,0 L -6.75,6.75"
fill="none"
stroke="#E5E5E5"
/>
</marker>
</svg>
...
const pathElements = svg.append('g')
.selectAll('path')
.data(visualLinks)
.enter().append('path')
.attr('fill', 'none')
// 设置 marker-end 属性
.attr('marker-end', 'url(#arrow)')
.attr('id', link => link.id)
.attr('stroke-width', 1)
.attr('stroke', '#E5E5E5');
...
但直接这样写的话,效果会很差,为啥呢?因为我们 path 元素的起点与终点是节点的中心点,直接这样的话箭头都在节点上面,如图:

看到中间那朵菊花没
所以我们没法直接通过加这个属性来加上箭头,我们需要对 path 做一些处理,对 path 线段去头去尾。那怎么做呢?还好有巨佬已经实现了一种算法,算出两个 path 元素之间的交点,因此我们可以在算出原 arcPath 后,再算出这条弧线与节点外一个大一点的圆的交点,再把原 arcPath 的起点与终点移到这两个点上。
