【d3.js入门】使用D3-Path打造精致可视化图表

1,776 阅读7分钟

Kapture 2023-08-28 at 17.46.10.gif

在数据可视化的世界里,图表的美观程度往往直接影响着我们对于数据的理解和解读。今天,我们就来深入探讨一下D3.js中的一个重要部分——Path路径操作,看看如何通过这些操作,打造出更加精致、美观的图表。

首先,我们来看看Path对象。在D3.js中,Path是一个构造函数,用于创建一个SVG路径。这个路径可以包含直线、曲线、圆弧等基本图形元素。例如,我们可以这样创建一个空的路径:

var path = d3.geom.path();

接下来,我们来看看Path对象提供的一些常用方法。

  1. path():这个方法用于返回当前的路径。如果之前没有创建过路径,那么返回的就是一个新的空路径。

  2. moveTo(x, y):这个方法用于将画笔移动到指定的坐标位置。之后的所有绘制操作都会从这个位置开始。

  3. closePath():这个方法用于关闭当前的路径。也就是说,它会将当前路径的起始点和终止点连接起来,形成一个封闭的形状。

  4. lineTo(x, y):这个方法用于添加一条从当前位置到指定位置的直线。直线会穿过所有之前添加的图形元素。

  5. quadraticCurveTo(cpx, cpy, x, y):这个方法用于添加一条二次贝塞尔曲线。二次贝塞尔曲线由三个控制点定义:起始点、控制点和终止点。曲线会穿过所有之前添加的图形元素。

  6. bezierCurveTo(cpx1, cpy1, cpx2, cpy2, x, y):这个方法用于添加一条三次贝塞尔曲线。三次贝塞尔曲线由四个控制点定义:起始点、两个控制点和终止点。曲线会穿过所有之前添加的图形元素。

  7. arcTo(x1, y1, x2, y2, radius):这个方法用于添加一个圆弧。圆弧会穿过所有之前添加的图形元素,但是不会穿过圆心。你可以通过调整控制点的位置和半径,来改变圆弧的形状和位置。

  8. arc(x, y, radius, startAngle, endAngle, anticlockwise):这个方法用于添加一个完整的圆弧,包括起始点、结束点和圆弧上的全部点。你可以通过调整起始角度、结束角度和是否逆时针绘制,来改变圆弧的形状和方向。

首先,创建 SVG 路径的基本语法是:

const path = d3.path();

这里创建了一个空的 SVG 路径,并将其赋值给变量 path。接下来,可以通过调用提供的API向路径中添加命令来绘制形状。

path.moveTo(x, y)

path.moveTo(x, y) 方法用于将路径的起始点移动到指定的坐标 (x, y)。例如,要绘制一个从 (100, 100) 开始的路径,可以使用以下代码:

const path = d3.path();
path.moveTo(100, 100);

path.closePath()

path.closePath() 方法用于将路径的当前点与起始点进行连接,形成一个封闭的路径。例如,要绘制一个由四条线段组成的正方形路径,可以使用以下代码:

const path = d3.path();
path.moveTo(100, 100);
path.lineTo(200, 100);
path.lineTo(200, 200);
path.lineTo(100, 200);
path.closePath();

path.lineTo(x, y)

path.lineTo(x, y) 方法用于从路径的当前点绘制一条直线到指定的坐标 (x, y)。例如,要绘制一个由两条线段组成的路径,可以使用以下代码:

const path = d3.path();
path.moveTo(100, 100);
path.lineTo(200, 100);
path.lineTo(200, 200);

path.quadraticCurveTo(cpx, cpy, x, y)

path.quadraticCurveTo(cpx, cpy, x, y) 方法用于从路径的当前点绘制一条二次贝塞尔曲线,控制点为 (cpx, cpy),终点为 (x, y)。例如,要绘制一个由两条二次贝塞尔曲线组成的路径,可以使用以下代码:

const path = d3.path();
path.moveTo(100, 100);
path.quadraticCurveTo(150, 50, 200, 100);
path.quadraticCurveTo(150, 150, 100, 100);

path.bezierCurveTo(cpx1, cpy1, cpx2, cpy2, x, y)

path.bezierCurveTo(cpx1, cpy1, cpx2, cpy2, x, y) 方法用于从路径的当前点绘制一条三次贝塞尔曲线,控制点1为 (cpx1, cpy1),控制点2为 (cpx2, cpy2),终点为 (x, y)。例如,要绘制一个由两条三次贝塞尔曲线组成的路径,可以使用以下代码:

const path = d3.path();
path.moveTo(100, 100);
path.bezierCurveTo(150, 50, 150, 150, 200, 100);
path.bezierCurveTo(150, 150, 150, 50, 100, 100);

path.arcTo(x1, y1, x2, y2, radius)

path.arcTo(x1, y1, x2, y2, radius) 方法用于从路径的当前点绘制一条圆弧,起点为当前点,终点为 (x2, y2),半径为 radius,并且圆弧与切线的夹角为 90 度。例如,要绘制一个由两条弧线组成的路径,可以使用以下代码:

const path = d3.path();
path.moveTo(100, 100);
path.arcTo(200, 100, 200, 200, 50);
path.arcTo(200, 200, 100, 200, 50);

path.arc(x, y, radius, startAngle, endAngle, anticlockwise)

path.arc(x, y, radius, startAngle, endAngle, anticlockwise) 方法用于从路径的当前点绘制一条圆弧,起点为当前点,终点为圆弧上的某个点,圆心为 (x, y),半径为 radius,起始角度为 startAngle,结束角度为 endAngle,并且可以选择绘制方向为顺时针或逆时针。例如,要绘制一个由两条弧线组成的路径,可以使用以下代码:

const path = d3.path();
path.moveTo(100, 100);
path.arc(150, 100, 50, 0, Math.PI, false);
path.arc(150, 150, 50, Math.PI, 0, false);

path.rect(x, y, w, h)

path.rect(x, y, w, h) 方法用于从路径的当前点绘制一个矩形,左上角的坐标为 (x, y),宽度为 w,高度为 h。例如,要绘制一个矩形路径,可以使用以下代码:

const path = d3.path();
path.rect(100, 100, 100, 100);

path.toString()

path.toString() 方法用于将路径对象转换为字符串表示形式。例如,要将路径对象转换为字符串并在控制台输出,可以使用以下代码:

const path = d3.path();
path.rect(100, 100, 100, 100);
console.log(path.toString());

实战

看过了API,我们就开始动手写个demo吧。 利用moveTo和lineTo命令我们可以轻松绘制直线,折线。我们就绘制一个简单的由直线构成的64卦吧!

image.png

长实线表示阳,短虚线表示阴,阴阳,阴阳就绘制好了。

paths.forEach((element, _i) => {
//红色和蓝色:红色代表阳,蓝色代表阴。
const path = d3.path();
path.moveTo(element[0].x1, element[0].y1);
path.lineTo(element[0].x2, element[0].y2);

if (element.length > 1) {
    path.moveTo(element[1].x1, element[1].y1);
    path.lineTo(element[1].x2, element[1].y2);
}

g.append('path')
    .attr('d', path)
    .attr('stroke-width', 0)
    .attr('opacity', 0)
    .transition()
    .delay(1000 * n + 100 * _i)
    .duration(500)
    .attr('opacity', 1)
    .attr('stroke-width', 10)
    .attr('stroke', element.length > 1 ? '#87CEEB' : '#FF7F50');

});

demo中阴阳我们采取了不同的颜色表示,所有每一爻都是一个path路径。

我们再使用arc命令绘制一个八卦。用棕色填充一下,看起来他是一个完整的path路径。

image.png

let path2 = d3.path();
path2.arc(0, 0 - r / 2, r / 2, -Math.PI / 2, Math.PI * 0.5);
path2.arc(0, 0 + r / 2, r / 2, Math.PI / 2, Math.PI * 1.5);
path2.arc(0, 0, r, Math.PI / 2, Math.PI * 1.5,true);
gb.append('path')
    .attr('d', path2)
    .attr('fill', '#000')

image.png

很快啊! 我们的一个小小demo就开好了,我是一个算卦的网站,卦象和解释当然得点击解锁(充会员解锁),是吧。

以上就是 D3.js 中 d3.path() 方法及其常用的绘制路径的方法的使用说明。通过这些方法的组合,可以绘制出各种形状的路径,并实现复杂的图形绘制效果。D3.js中的Path路径操作提供了丰富的功能,可以帮助我们轻松地创建出各种复杂的图形元素。通过熟练掌握这些操作,我们就可以在数据可视化的世界里游刃有余,打造出更加精致、美观的图表。


源码和演示地址:https://scqilin.github.io/d3js/path/path.html