Learn D3.js — 全书拆解
Learn D3.js — 全书拆解
30 秒导读: 这是一本 2026 年的 D3.js v7 实战教材,回答一个问题: 怎样用网页标准(HTML/CSS/SVG/Canvas)把数据变成可交互的图。 它的答案不是「图表模板」,而是一台翻译流水线:数据进、函数加工、图形出。 全书 19 章的正文,就是把这台流水线的每个工种各讲一遍。 本组文档是我们重写的完整拆解,二十二篇。读完不必看原书。
1. 先交代清楚:这是谁在什么时候写的
| 作者 | Helder da Rocha——巴西开发者、教师,自 D3 v3 时代起使用和教授 D3;前言自述「多年探索、使用和教学 D3」的经验是本书的主要原料 |
| 成书 | Packt《Learn D3.js》第二版,2026 年 6 月(第一版 2019 年 3 月);基于 D3 v7.9.0 与 ES2019 |
| 配套 | 全书代码在 GitHub(PacktPublishing/Learn-D3.js-Second-Edition),按章分目录,书中印出的片段常是节选 |
| 利益相关 | 无。D3 本身开源免费;作者与 D3 核心团队无雇佣关系 |
时代坐标: 写于 D3 v7 已是成熟版本的年代。Observable 平台被当作 D3 的主社区, Canvas 渲染、大数据交互成为常规话题;TypeScript、框架集成(npm/React)被刻意排除在正文外, 只在附录各给一篇指引。
2. 全书一条主线(读完这一节,你就懂了这本书)
这本书从头贯到尾只有一条推理链:图表是「数据 → 函数 → 图形」的翻译, 而翻译的每一环,都可以也应该由数据驱动。 下面把这条链走一遍—— 只讲「发生了什么、为什么只能这样」,机制细节全在对应篇章里。
① 一切从「绑数据」开始
不用 D3 也能画图(手写 SVG 标签就行)。D3 真正的发明是: 把一批网页元素和一批数据绑在一起,让数据说了算——数组多一项就多一个元素, 少一项就删一个。这一个动作(data + join)是后面十八章全部内容的根。 (第 01 篇)
② 绑好之后,数据要先进得来、洗得动
真实数据在外部文件里:CSV(逗号分隔的表格文本)/JSON(网页数据交换的通用文本格式)经 d3-fetch 一步加载, 表格字符串经 d3-dsv 解析(值全是以文本形式存着的数!行函数边解析边加工); 进来之后还要找最大最小、排序、分组、分箱——d3-array 是这套「数据车间」。 (第 04、06、07 篇)
③ 数据是数,图形是像素,中间隔着比例尺
数据的量级(0.387 到 67.67)和画布的像素(0 到 500)之间, 需要一个翻译函数:比例尺。它把「数据域」映射到「像素域」, 线性(等比例)/对数(按数量级压缩)/序数/时间各管一类输入。坐标轴只是比例尺的可视化—— 没有比例尺就没有轴。(第 08、09 篇)
④ 点线面饼树,全是「生成器函数」
从数据到 path 字符串的距离,由生成器抹平:d3.line() 吃坐标吐折线、
d3.area() 加基线(面的下边界)成面、d3.arc() 出扇形、d3.pie()/d3.stack() 先重排数据再喂给前者。
记住生成器的两分类:形状生成器产字符串,布局生成器产数据——这是全书中段的主结构。
(第 11、12 篇)
⑤ 图会动了,而且会回应用户
给属性修改加一行 transition,数值就平滑过渡(背后是插值器逐帧算中间值); 给元素挂上行为对象,拖拽、框选、缩放就有了语义事件。 缩放的真功夫在「语义缩放」:轴要重算、线宽要除以缩放系数、细节要分级出现。 (第 13、14、15 篇)
⑥ 层级数据与网络数据,换两种「中间表示」
树、矩形树图、圈包共享同一个 hierarchy 对象(数据 → hierarchy → 布局 → 图); 网络数据分两种形态(矩阵(二维数表)/ node-link),各配一类图(弦图 / 桑基图 / 力导向)。 力导向是全书唯一的「模拟式布局」:位置不是算出来的,是冷却出来的。 (第 16–19 篇)
⑦ 地图:把「投影」也变成一个函数
经纬度到像素的翻译器叫投影,一百多个,分三大类;geoPath 把 GeoJSON (开放标准)+ 投影缝成 path。专题地图(choropleth、点密度)就是把第 ③④ 步的 比例尺与生成器,搬到地理数据上——全书在这里合龙。(第 20、21 篇)
⑧ 一句话压缩
D3 教你的是「数据驱动」的思维方式:先问数据长什么样,再问哪条流水线能把它变成图; 图不对时,回去改数据或改翻译函数,而不是改图形。 这与给模板的图表库是两条相反的路——前期多写代码,换来任意图形的自由。
3. 章节地图
这张表不用记任何术语——每一篇的名字后面,写的是「读完你能回答什么问题」。
| 篇 | 读完你就能回答 |
|---|---|
| 01 数据驱动文档 | D3 到底是什么?「数据说了算」第一次出现长什么样? |
| 02 前置知识 | 我缺的 JavaScript/SVG 知识有哪些、各自要补到什么程度? |
| 03 快速上手 | 一张能加载数据、点按钮切换、带动画的柱状图怎么从零搭出来? |
| 04 加载与解析 | CSV/JSON 怎么进门?「值全是字符串」的坑在哪? |
| 05 选择器与 join | join 内部怎么对账?为什么顺序变了必须重绑、key 函数是干嘛的? |
| 06 数据处理 | 找最值、排序、统计、集合运算——d3-array 和原生差在哪三点? |
| 07 生成与分箱分组 | 直方图怎么画?tidy/宽表之争在分组工具上怎么兑现? |
| 08 坐标轴 | 轴的 SVG 结构是什么?网格线怎么「拉长刻度线」? |
| 09 比例尺 | 连续/插值/离散三族怎么选?log 为什么不能含 0? |
| 10 颜色 | 类别/顺序/发散三类数据各配什么方案?颜色插值在哪个空间发生? |
| 11 线与面 | 一条 path 字符串怎么从数据算出来?样条曲线的代价是什么? |
| 12 饼与堆叠 | 饼图和堆叠图各多了哪一步数据加工?Canvas 怎么接同一套代码? |
| 13 过渡与动画 | 多个过渡并行为什么不打架?动画结束怎么接到下一件事? |
| 14 事件/拖拽/刷选 | 屏幕坐标怎么翻译成图的坐标?框选缩放的五步是什么? |
| 15 缩放 | 语义缩放的三件套(÷k、rescaleX、分级取舍)怎么落地? |
| 16 树 | hierarchy 对象是什么?换根、展开折叠靠什么方法? |
| 17 分区与包含 | 冰柱/旭日/treemap/圈包各自牺牲什么换什么? |
| 18 流与网络 | 弦图和桑基图的分界线在哪?数据形态怎么互换? |
| 19 力导向 | alpha 冷却曲线怎么控制?拖拽节点为什么要把模拟「再加热」? |
| 20 地图(上) | GeoJSON 怎么画成图?比大小为什么必须等积投影? |
| 21 地图(下) | 地图缩放为什么要改投影而不是套 transform?旋转地球为什么要四元数? |
| 22 资源 | 出问题了去查什么?地图渲染不对是不是缠绕顺序病? |
推荐顺序: 01 → 03 → 05 → 09 是地基,之后按图索骥; 只想了解「D3 的思想骨架」,读第 2 节(本页)+ 01、05、16 三篇就够。
4. 这本书覆盖什么、不覆盖什么
覆盖(而且讲得比多数材料扎实)—— 读完你能回答:
- 数据绑定的内部机制(enter/update/exit 对账、key 函数),不是只会调 join;
- 比例尺/坐标轴/颜色三件套怎么按数据类型选型;
- 形状生成器与布局生成器的两分法,以及各自怎么配访问器;
- 过渡动画的生命周期与多过渡编排(命名、链式、打断规则);
- 拖拽/刷选/缩放三个行为的完整配置,以及组合时的冲突处理;
- 层级(hierarchy)、网络、地理三条高级数据线的完整流水线;
- 大量「为什么会这样」的坑:字符串数值、CSS 优先级、SVG 命名空间(浏览器靠它认出 SVG 标签)、缠绕顺序……
不覆盖(别指望在这本里找):
| 缺什么 | 说明 |
|---|---|
| 该不该画 | 饼图的知觉缺陷、配色的心理学、叙事设计——书教怎么画,不教何时别画 |
| 工程化 | 无测试、无构建、无 CI;TypeScript 与框架集成被明确排除(各只有附录一篇) |
| D3 内部实现 | 布局算法(树/treemap/力模拟)当黑箱教,公式与推导不展开 |
| 数据准备的 GIS 功夫 | 坐标系转换、拓扑修复推给 mapshaper/QGIS 等离线工具 |
| WebGL 与大渲染管线 | 图形一律 SVG/Canvas;百万级要素的出路没有系统讲 |
| 书之后的事 | 写于 2026 年,版本口径是 D3 v7.9.0——API(库对外暴露的函数与用法约定)稳定,但 CDN 链接与 IDE 推荐会过时 |
5. 我们的判断
判断(我们的,不是书里的): 这本书在今天的价值排序是—— ①「数据驱动」心智模型的完整教材(不过时)> ②各工具的选型地图(轻微过时)> ③环境配置的实操细节(已半过时)。 它最适合当「D3 唯一一本系统教材」来读;遇到具体 API 查 d3js.org,遇到具体图型查 Observable。 如果错,会错在: 如果数据可视化的主流范式从「命令式 DOM 操作」迁走 (比如全面转向 WebGL 声明式框架),D3 这套以 join 为中心的教学骨架会失去中心—— 但以 2026 年的生态看,这个迁移还远未发生。
判断(我们的,不是书里的): 全书最值得带走的可迁移技能不是任何 API, 而是三个反复出现的设计模式:「配置与执行分离」的生成器函数、 「数据重排 → 图形渲染」的两阶段布局、以及「中间表示」(hierarchy 对象、 邻接矩阵、GeoJSON)作为数据与图之间的稳定接口(两边都认的中间格式)。 这三个模式在 D3 之外(自己写任何 DSL、任何图表库)都直接复用。 如果错,会错在: 把模式当银弹——每个模式都有代价(学习曲线、间接层、双重内存), 小项目里直接字符串拼 DOM 可能更快;模式的价值随项目复杂度上升。
判断(我们的,不是书里的): 对「编程语言与系统研究」的读者,这本书有额外的读法: D3 是领域特定语言(DSL)设计的活标本——链式 API、函数生成器、访问器约定、 流式管道(投影五段),每一个都是语言设计的决策案例,而且每一个都有 15 年的社区检验。 读的时候多问一句「这个 API 形状为什么是这样」,收益会翻倍。 如果错,会错在: DSL 视角会放大「API 美学」的权重,而工程视角里更要紧的是 生态(插件、示例、招人)——两者不矛盾,但别用前者替代后者的评估。
6. 许诺兑现表
| 许诺在哪 | 应兑现在哪 | 核过了吗 |
|---|---|---|
| 本页 §2 ③ 比例尺 | 09 全篇 | ✓ |
| 本页 §2 ④ 生成器两分法 | 11(形状)、12(布局) | ✓ |
| 本页 §2 ⑥ hierarchy 中间表示 | 16 §2 | ✓ |
| 本页 §2 ⑦ 投影也是函数 | 20 §3 | ✓ |
01 对 join 的预告 | 05 全篇 | ✓ |
03 各工具「后面拆开讲」 | 08–15 各篇 | ✓ |
12 Canvas 承诺(18/19 章再现) | 19 §3.5、20 §3 | ✓ |
15 语义缩放预告(树/地图用) | 19 §5.2、21 §3.2 | ✓ |
16 布局生成器五个兄弟的其余三个 | 17 全篇 | ✓ |
拆解写于 2026-10-19,依据 Packt 第二版(2026-06)。原始书籍文件不入库,
本组文档是我们自己的重写;每条引用都可用 node scripts/book-verify.mjs learn-d3js 回核。