D3.js 核心概念——形状(四)连线生成器 Links

语言: CN / TW / HK

这是我参与11月更文挑战的第12天,活动详情查看:2021最后一次更文挑战


系列文章可以查看《数据可视化》专栏


参考:


连线生成器 Links 基于两个坐标点,绘制出平滑的三次贝塞尔曲线作为两点之间(从起源点 source point 到目标点 target point)的连线,一般用于树形图 tree diagram 中。

所绘制的连线在起点和终点的处的切线可以有三种形式,分别通过三种不同的方法创建三种不同的连线生成器(以下称为 link),适用于不同方向的树形图中

  • 使用方法 d3.linkVertical() 创建(生成垂直切线的)连线生成器(以下称为 linkVertical,一般用于父节点和子节点是上下相对位置的树形图中
  • 使用方法 d3.linkHorizontal() 创建(生成水平切线的)连线生成器(以下称为 linkHorizontal,一般用于父节点和子节点是水平左右相对位置的树形图中
  • 使用方法 d3.linkRadial() 创建(生成径向切线的)连线生成器(以下称为 linkRadial,一般用于根节点在内部,后代节点在外部的环形树形图中

它既是一个方法,可以直接调用,传递需要可视化的数据,连线生成器会根据数据构建出连线。一般是以一个对象作为入参,它最基本的形式是包含 sourcetarget 这两个属性,分别表示连线的起点和终点,这两个属性的属性值最基本的形式就是一个数组,分别表示起点或终点的 xy

js // D3 默认支持的连线生成器入参数据形式 link({  source: [100, 100],  target: [300, 300] });

💡 调用连线生成器时返回的结果,也会基于生成器是否设置了父容器 context 而不同。如果设置了父容器,则生成 <path> 元素,并添加到父容器中;如果没有设置父容器,则生成字符串。

它也是一个对象,具有多种方法设置不同的参数,一般通过链式调用的方式来使用:

对于 linkVerticallinkHorizontal 连线生成器有以下方法

  • link.source(sourceFunc) 设置起始点读取函数。该函数的入参是调用连线生成器时传递的数据 d,D3 默认该数据是一个对象,且具有 source 属性表示起始点,因此默认读取函数如下

    js function source(d) {  return d.source; }

    💡 如果入参的数据形式和 D3 的默认形式不同,需要手动设置起始点读取函数,返回起始点

  • link.target(targetFunc) 设置起始点读取函数。默认读取函数如下

    js function target(d) {  return d.target; }

  • link.x(xFunc) 设置横坐标读取函数。D3 默认起点和终点都是一个含有两个元素的数组,第一个元素表示这些点的横坐标,第二个元素表示这些点的纵坐标,因此默认读取函数如下

    js function x(d) {  return d[0]; }

    💡 如果入参的数据形式和 D3 的默认形式不同,需要手动设置点读取函数,返回横坐标

  • link.y(yFunc) 设置纵坐标读取函数。默认读取函数如下

    js function y(d) {  return d[1]; }

  • link.context(parentDOM) 用于设置父容器

对于 linkRadial 连线生成器有类似的方法,不过它的横坐标变成角度(单位是弧度),纵坐标变成了径向距离

  • linkRadial.angle(angleFunc) 类似于 link.x(xFunc),设置角度读取函数,返回的角度单位是弧度

  • linkRadial.radius(radiusFunc) 类似于 link.y(yFunc),设置径向距离读取函数

    💡 调用径向连线生成器时,它生成的连线的中心坐标默认是 (0, 0),可以为其父容器(一般是元素 <g>)设置 transform 属性,移动到目标位置

💡 如果希望从抽象的数据开始以构建树形图,可以使用 d3-hierarchy 模块。该模块基于抽象的数据和页面大小自动计算布局,即将抽象的数据映射到页面的可视化图形元素,生成各连线的起点 source 和终点 target 坐标数据。再将这些数据分别传递给相应的连线生成器即可分别生成连线。