利用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 的起点与终点移到这两个点上。