d3.js 重力节点布局_节点间多关系显示处理

本文介绍了如何在d3.js的重力布局中处理节点间多关系,确保多条线不叠加并保持美观。通过统计两点间的线条数并分配到map中,根据节点名设置方向和编号,利用tick方法配置线条样式,实现曲线连接。同时讨论了linePadding参数对箭头布局的影响,提供了解决箭头拥挤的方法。
摘要由CSDN通过智能技术生成

d3重力布局——节点间多关系处理

相关的知识:

path相关的知识

<path>标签是d3里面功能最为丰富的标签,很多图形用该标签可以制作出来。它通过一系列的坐标点来绘制。在d3的图形绘制中。经常会用到。

用法:给出一个坐标点,在坐标点前面添加一个英文字母,表示如何运动到此坐标点。

英文字母的按照功能可分为5类:

  • 移动类
    • M = moveto:将画笔移动到指定坐标
  • 直线类
    • L = lineto:画直线到指定坐标。
    • H = horizontal lineto:画水平线到指定坐标。
    • V = vertical lineto:画垂直线到指定坐标。
  • 曲线类
    • C = curveto:画三次贝塞尔曲线经两个指定控制点到达最终坐标。
    • S = shorthand/smooth curveto:与前一条三次贝塞尔曲线,第一个控制点为前一条曲线第二个控制点的对称点,只需要输入第二个控制点和终点,即可绘制一个三次贝塞尔曲线
    • Q = quadratic Bezier curveto:画一个二次贝塞尔曲线经过一个指定控制点到达终点坐标
    • T = Shorthand/smooth quadratic Bezier curveto:与前一条贝塞尔曲线相连,控制点为前一条二次贝塞尔曲线控制点的对称点。只需输入终点,即可绘制一个二次贝塞尔曲线。
  • 弧线类
    • A = elliptical arc:画椭圆曲线到指定坐标
  • 闭合类
    • Z = closepath:绘制一条直线,连接终点和起点,用来封闭图形。

到这里,我们知道了绘制一个<path>所要知道的基本的英文字母的基本意思

问题解析

然后就开始处理我们的核心问题:节点间的多关系

在实际应用场景中,人与人之间的关系不仅仅是单向,更多的是多项的,例如:小明 — 朋友 — 小红 ,小明 — 同学 — 小红 ;或者 小红— 朋友 — 小明 ,小红 — 同学 — 小明。

如果在d3的重力导向布局中如果不对这种节点间的关系做处理,很多关系会叠加载一块,影响美观与观感。
在这里插入图片描述
在现有的数据可视化框架中也有相关案例,例如echarts。你只需要设置lineStyle的属性curveness的值就可以使得线条呈现一个弧度。但是由于项目的特殊性,很多情况下需要我们用d3来完成自由度更高,并且一些个定制化的服务。
在这里插入图片描述
因此,在d3关于节点间的多关系处理中,曲线连接是一种比较好的方案。因此解决问题的核心在于如何绘制曲线,并且保证两点之间的多条线不会覆盖?在多条线弯曲下,如何平均半圆弧弯曲避免全跑到某半圆弧上?定义曲线弧方向?

首先统计下两点之间的线条数,再将这些连接线分配到一个 map 里,两个节点的 name 字段进行拼接做成 key,这样计算得到两点之间的连接线总数。

然后在遍历时同 map 的线根据方向分成正向、反向两组,正向组遍历给每条线追加设置一个 linknum 编号,同理,反向组遍历追加一个 -linknum 编号值。这个正向、反向判断方法很多,根据节点 source.name、target.name 进行比较,这里其实是比较 ASCII 码。而我们设定的 linknum 值就是来确定该条弧线的弯曲度和弯曲方向的,这里搭配下面代码讲解比较好理解:

关系处理

//在vue的methods的方法中
dealRealtions(links) {
       
      var linkGroup = {
   };  //用来分组,将两点之间的连线进行归类
      var linkMap = {
   };  //对连接线的计数
      for (var i = 0; i < links.length; i++) {
   
        var key = links[i].source.name < links[i].target.name ? links[i].source.name + ':' + links[i].target.name : links[i].target.name + ':' + links[i].source.name;
        if (!linkMap.hasOwnProperty(key)) {
   
          linkMap[key] = 0 ;
        }
        linkMap[key] += 1;
        if (!linkGroup.hasOwnProperty(key)) {
   
          linkGroup[key] = [];
        }
        linkGroup[key].push(links[i]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值