利用d3.js力导布局绘制资源拓扑图实例教程(6)

import intersect from 'path-intersection';

const render = () => { 
 ...

 nodes
 // 过滤出所有的信息节点
 .filter(node => !node.isAppNode)
 .forEach((node) => {
 ...
 // 根据信息节点的信息得到对应的 visualLink 对象 index
 const idx = findVisualLinkIndex(node)
 visualLinks[idx].start = [source.x!, source.y!];
 visualLinks[idx].middle = [node.x!, node.y!];
 visualLinks[idx].end = [target.x!, target.y!];

 const A = visualLinks[idx].start;
 const B = visualLinks[idx].end;
 const C = visualLinks[idx].middle;

 const a = dist(B, C);
 const b = dist(C, A);
 const c = dist(A, B);

 // 余弦定理求得∠C
 const angle = Math.acos((a * a + b * b - c * c) / (2 * a * b));
 // 正弦定理求得外接圆半径
 const r = _.round(c / Math.sin(angle) / 2, 4);

 // 角度大小flag,因为我们要的是条弧线而不是一个残缺的圆,所以恒为0
 const laf = 0;

 // 弧线方向flag,根据AB的斜率判断C在AB线的那一边,再确定弧线方向
 const saf = +((B[0] - A[0]) * (C[1] - A[1]) - (B[1] - A[1]) * (C[0] - A[0]) < 0);

 const origArcPath = ['M', A, 'A', r, r, 0, laf, saf, B].join(' ');

 const raidus = NODE_RADIUS;
 const startCirclePath = [
 'M', A,
 'm', [-raidus, 0],
 'a', raidus, raidus, 0, 1, 0, [raidus * 2, 0],
 'a', raidus, raidus, 0, 1, 0, [-raidus * 2, 0],
 ].join(' ');
 const endCirclePath = [
 'M', B,
 'm', [-raidus, 0],
 'a', raidus, raidus, 0, 1, 0, [raidus * 2, 0],
 'a', raidus, raidus, 0, 1, 0, [-raidus * 2, 0],
 ].join(' ');

 const startIntersection = intersect(origArcPath, startCirclePath)[0];
 const endIntersection = intersect(origArcPath, endCirclePath)[0];

 const arcPath = [
 'M', [startIntersection.x, startIntersection.y],
 'A', r, r, 0, laf, saf, [endIntersection.x, endIntersection.y],
 ].join(' ');

 visualLinks[idx].arcPath = arcPath;
 });

 pathElements
 .attr('d', (link) => {
 return link.arcPath;
 });

 ...
}

效果已经很接近了!

字叠到一起啦,臣妾看不清啊

到这一步整体效果其实已经差不多了,但追求完美的我们怎么可能到此为止呢?仔细看看这个图,因为调用信息是一个方盒而不是原型的节点,如果应用和资源间有来有往,那这个字很容易叠到一起。可以尝试调整碰撞力(Collision)和弹簧力(Links)来让他们别叠到一起,不过试下来发现调整这两个系数很容易把整个图弄得乱七八糟的。那咋办呢?我们就要到此为止了吗?不妨换个思路,如果应用与资源间有来有往,则这个连接信息就不放到中间点,而是放到开始三分之一处。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/381.html