D3 入门笔记

2026-07-25 23:59:34

npm、yarnan安装依赖包

npm i d3 / yarn add d3

import * as d3 from "d3";

3.D3对象、选择集(d3-selection)、操作

引入d3.js后,就可以获得要使用的d3对象了。每次打点调用 d3 提供的函数方法,都会返回一个 d3 对象,这样可以继续调用 d3 的其他函数方法。

创建画布,绘制图形(Draw canvas)

1 // Create chart dimensions

2 // 定义svg图形宽高,以及柱状图间距

3 const svgWidth = 500, svgHeight = 300, barPadding = 14;

4 const margin = {

5 top: 20,

6 right: 40,

7 bottom: 20,

8 left: 40

9 }

10

11 // Draw canvas

12 // 绘制图形

13 const svg = d3.select('.d3-demo')

14 .attr('width', svgWidth)

15 .attr('height', svgHeight);

D3 选择元素提供了两个函数:select 和 selectAll。

select 选中符合条件的第一个元素。

selectAll 选择所有与指定的 selector 匹配的元素。

详情:https://www.d3js.org.cn/document/d3-selection/#installing

选择元素后可以操作元素,操作元素主要分为增加 ( append )、插入 ( insert )、删除元素 ( remove ) 和设置获取元素属性 ( attr, style )。

1 console.log(d3.select('.d3-demo3'));

2 d3.select('.d3-demo3')

3 .style('background-color', '#c3272b')

4 .append('text')

5 .text('D3-demo-1')

6 .style('color', 'red')

7 .attr('x', 20)

8 .attr('y', 20)

9

运行结果:

4. 数据绑定

数据绑定是将数据绑定到 DOM 元素上,D3 中数据绑定提供了 datum() 和data()两个函数,一般都使用data()函数。

1 d3.select("body")

2 .selectAll("p")

3 .data([4, 8, 15, 16, 23, 42])

4 .enter()

5 .append("p")

6 .text(function(d) { return "I’m number " + d + "!"; });

运行结果:

enter和exit操作

数据绑定的时候可能出现 DOM 元素与数据元素个数不匹配的问题,那么 enter 和 exit 就是用来处理这个问题的。enter 操作用来添加新的 DOM 元素,exit 操作用来移除多余的 DOM 元素。

如果数据元素多于 DOM 个数时用 enter,如果数据元素少于 DOM元素,则用 exit。

在数据绑定时候存在三种情形:

数据元素个数多于 DOM 元素个数

数据元素与 DOM 元素个数一样

数据元素个数少于 DOM 元素个数

情形 1:数据元素个数多于 DOM 元素个数

如以下例子,如果文档中p标签的个数少于数组个数(6个),则使用 enter 和 append 操作来补齐 DOM 元素:

d3.select("body")

.selectAll("p")

.data([4, 8, 15, 16, 23, 42])

.enter().append("p")

.text(function(d) { return "I’m number " + d + "!"; });

情形 2:数据元素与 DOM 元素个数一样

如果这种情况再使用 data 来绑定数据,相当于是更新了每个 DOM 元素所对应的数据,此时不需要加入新节点也不需要删除多余的节点:

//update

let p = d3.select("body")

.selectAll("p")

.data([4, 8, 15, 16, 23, 42])

.text(function(d) { return d; });

情形 3:数据元素个数少于 DOM 元素个数

假设p元素的个数多于 6 个,数据元素个数为 6,则:

let p = d3.select("body")

.selectAll("p")

.data([4, 8, 15, 16, 23, 42])

.text(function(d) { return d; });

p.exit().remove() //移除多余的元素

但是在实际应用中,不可能先去统计一下元素个数,因此这三种情形可以一起使用:(在画图表时一般都是直接使用append添加元素,因为画布是从空白开始添加元素的)

// Update 情形2

let p = d3.select("body")

.selectAll("p")

.data([4, 8, 15, 16, 23, 42])

.text(function(d) { return d; });

// Enter 情形1

p.enter().append("p")

.text(function(d) { return d; });

// Exit 情形3

p.exit().remove();

5. 过渡(d3-transition)

D3 支持动画效果,这种动画效果可以通过对样式属性的过渡实现。

比如对元素的背景颜色进行过渡:

d3.select("body").transition()

.style("background-color", "black");

详情:https://www.d3js.org.cn/document/d3-transition/#installing

https://observablehq.com/@d3/learn-d3-animation?collection=@d3/learn-d3

6. 比例尺(d3-scale)

比例尺是 D3 重要概念。

对于可视化来说,比例尺是一个很方便的工具:将抽象的维度数据映射为可视化表示。比例尺这个概念跟地图比例尺的概念是一样的,要一个画布上绘制一幅世界地图,需要按一定的比例将整个世界投射到画布上。

虽然经常使用位置编码定量数据,比如将测量单位米使用像素映射。但是比例尺可以对任何视觉编码进行映射,比如颜色,描边的宽度或者符号的大小。比例尺也可以用来对任意类型的数据进行映射,比如分类数据或离散的数据。

三个要素:定义域、值域、对应法则。

其中 scaleLinear() 对应法则,domain() 是定义域,range() 是值域。

以线性比例尺为例:

let x = d3.scaleLinear()

.domain([10, 130])

.range([0, 960]);

x(20); // 80

x(50); // 320

以线性比例尺为例(数值映射为颜色):

let color = d3.scaleLinear()

.domain([10, 100])

.range(["brown", "steelblue"]);

color(20); // "#9a3439"

color(50); // "#7b5167"

详情:https://www.d3js.org.cn/document/d3-scale/#installing

7. 坐标轴(d3-axis)

坐标轴组件可以将 scales (opens new window)显示为人类友好的刻度标尺参考,减轻了在可视化中的视觉任务。

例:

// Create chart dimensions

// 定义svg图形宽高,以及柱状图间距

const svgWidth = 500, svgHeight = 300, barPadding = 14;

const margin = {

top: 20,

right: 40,

bottom: 20,

left: 40

}

// Draw canvas

// 绘制图形

const svg = d3.select('.d3-demo')

.attr('width', svgWidth)

.attr('height', svgHeight);

// Create scales

// 首先是拿到最大值构建x轴坐标

let xScale = d3.scaleLinear()

.domain([0, d3.max(dataX)])

.range([margin.left, svgWidth - margin.right]);

// 接下来是反转值,用作y轴坐标

let yScale = d3.scaleLinear()

.domain([0, d3.max(dataY) + 20])

.range([svgHeight - margin.bottom, margin.top])

// 横轴的API使用

let x_axis = d3.axisBottom()

.scale(xScale)

// 纵轴的API使用

let y_axis = d3.axisLeft()

.scale(yScale);

svg.append("g")

.attr("transform", `translate(${0}, ${svgHeight - margin.bottom})`)

.call(x_axis);

svg.append("g")

.attr("transform", `translate(${margin.left}, 0)`)

.call(y_axis);

View Code

运行结果:

8. 基本图表

数据来源:使d3-fetch模块中的d3.json()读取json文件的数据

{

"code": 200,

"message": "操作成功",

"data": [

{

"name": 0,

"value": 20

},

{

"name": 1,

"value": 40

},

{

"name": 2,

"value": 100

},

{

"name": 3,

"value": 56

},

{

"name": 4,

"value": 120

},

{

"name": 5,

"value": 180

},

{

"name": 6,

"value": 30

},

{

"name": 7,

"value": 40

},

{

"name": 8,

"value": 40

}

]

}

View Code

折线图

View Code

运行结果:

柱状图

View Code

运行结果:

9. 小结

这篇文章只是介绍了d3的基本操作,官网有很多的知识点需要自行查看。当你看完这篇入门笔记后,能对d3有一个简单的认识,加上对SVG基本图形的了解可以创造出一些基础的图表,加油,加油!!!

最后给一个d3画图表的基本步骤,按这个步骤可以指导你画图思路。上面的实例就是按这个步骤实现的,可以作为参考。

Demo项目开源地址:https://gitee.com/userzp/vue3-d3.git