说的挺好,我咋知道开始三分之一处在哪?
还好这种「复杂」的数学问题,前人已经帮我们探索的差不多了。svg 标准里定义了 SVGGeometryElement.getTotalLength 与 SVGGeometryElement.getPointAtLength 两个方法,通过这两个方法我们可以获得 path 路径的全长,和某一长度时点的位置。不过这两个方法都是附在 DOM 元素上的,直接调用有点麻烦,还好有PureJS 的实现:
import { svgPathProperties } from 'svg-path-properties'; ... render = () => { ... labelElements .attr('style', (link) => { const properties = svgPathProperties(link.arcPath); const totalLength = properties.getTotalLength(); const point = properties.getPointAtLength( link.hasReverseVisualLink ? totalLength / 3 : totalLength / 2, ); return `transform: translate3d(calc(${point.x}px - 50%), calc(${point.y}px - 50%), 0);`; }); ... }
最终效果:
还差一点
效果做到这已经差不多了,不过还有一些不完美的地方
- 各种力的系数,在数据不同时不能通用,还必须根据数据不同试出来一个相对通用的系数函数。
- 不能保证所有的节点都在方框内且不重叠
感觉这两个问题都算是力导布局的固有缺陷,可能那张图的实现根本和力导布局没啥关系呢😂。不过我们使用力导布局也可以实现不错的效果,这种 edge case 可以慢慢来解决了就。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对黑区网络的支持。