跳转至

前置知识 — 必要的 JavaScript 与 SVG

这一章讲什么: 原书第 2 章和第 3 章是「在线章节」——纸质书里只有一份导读和主题清单, 完整教程和代码在 GitHub 仓库里。这两章是可选的:已经会现代 JavaScript 和 SVG 的读者可以跳过。 我们的拆解照原书列的清单逐项讲,每一项只讲到「够跟过后续章节」的程度; 超出原书清单的讲解都标了「补充(不在书里)」。

1. 为什么 D3 需要单独补这两课

D3 建立在两样东西上:JavaScript(它本身是个 JS 库)和 SVG(它画图用的图形格式)。 原书前言写得很直白:你对 JavaScript 懂得越多,从 D3 里得到的就越多1; 而 SVG 是「这本书里几乎每张图背后的格式」——懂 SVG 才能看懂 D3 在底层替你做了什么、才能调试它的输出2。

两章的定位不同:

第 2 章 必要的 JavaScript 第 3 章 必要的 SVG
是什么 一份语言与浏览器 API 的参考 一份动手教程加参考
什么时候必读 没用过 ES2019 特性(箭头函数、解构、展开、Promise、模块) 没画过 SVG 图形
什么时候可跳过 已熟悉现代 JavaScript 已熟悉 SVG 的形状、样式、变换
完整版在哪 仓库 Part1/Chapter02/ 仓库 Part1/Chapter03/

有一个细节值得留意:即使是会 SVG 的老手,原书也建议扫一眼仿射变换(affine transforms)和 SVG DOM 两节——这两块大家普遍不熟,而 D3 项目里天天用到3。

2. 顶层全景:知识清单

  JavaScript 侧(第 2 章清单)                SVG 侧(第 3 章清单)
  ├─ 数据结构:数组方法 / 对象与解构 / Map、Set / 字符串与模板字面量   ├─ 坐标系与视口(viewBox)
  ├─ 函数:普通函数 / 箭头函数 / 生成器                                 ├─ 基本形状:圆、矩形、线、椭圆、多边形
  ├─ 模块:import / export                                              ├─ 填充与描边:fill、stroke、透明度
  ├─ 异步:Promise、Promise.all()、async/await                          ├─ 路径 <path> 与它的微型绘图语言
  ├─ DOM:导航、增删、样式、事件                                        ├─ 文本 <text>、<tspan>、沿路径排字 <textPath>
  ├─ W3C 选择器(CSS 选择器语法,D3 的 select 用它)                     ├─ 图片、链接、foreignObject(内嵌 HTML)
  ├─ Canvas API:画布、2D 上下文、路径绘制、状态保存                      ├─ 仿射变换:translate、scale、rotate、矩阵
  └─ 数据格式:CSV / JSON / XML 的结构与解析                              └─ <g> 组、<defs> 复用、裁剪、蒙版、渐变、SVG DOM API

  图说:左列是「语言与浏览器」,右列是「图形格式」。两列的交集(选择器、DOM)正是 D3 的核心地带。

3. JavaScript 侧:每一项讲到够用

3.1 数组方法与数据变换管道

D3 的程序几乎都在做一件事:把数据数组变成另一批数组或一组图形属性。 原书列的数组方法:map、filter、reduce、flat 等4。 三个最常用的,各给一个具体例子(补充,不在书里,来自通用知识;例子是自编的演示数据):

  const nums = [9, 2, 12, 9, 71];

  nums.filter(n => n > 10)   // [12, 71]        —— 留下满足条件的
  nums.map(n => n * 2)       // [18, 4, 24, 18, 142] —— 逐项变形,长度不变
  nums.reduce((sum, n) => sum + n, 0)  // 103   —— 把全组合并成一个值

  图说:filter 变短、map 等长、reduce 收口。这些方法在 D3 代码里出现频率极高。

3.2 对象解构、展开运算符

原书点名的 ES2019 特性:箭头函数、解构、展开运算符(spread)、Promise、模块5。 解构和展开是「把对象和数组拆开再组装」的语法糖,D3 例子里到处都是:

  const point = {x: 100, y: 200};
  const {x, y} = point;        // x=100, y=200 —— 从对象里按名字取出字段

  const a = [1, 2], b = [3, 4];
  [...a, ...b]                 // [1, 2, 3, 4] —— 展开:把数组解开再拼成新数组

3.3 Promise 与 async/await:异步是 D3 的常态

加载外部数据文件是异步的:浏览器发请求、等服务器回数据,这段时间不能干等, 所以加载函数不直接返回数据,而是返回一个 Promise——一个「数据将来会到」的凭证, 你对着它 .then() 注册「到了之后怎么办」6。

  fetch(dataFile)                          // 发出请求,马上返回 Promise
    .then(response => response.text())    // 响应到了,取出文本(又是一个 Promise)
    .then(text => console.log(text))      // 文本到了,打印

  // 等价写法:async/await,读起来像同步代码
  const response = await fetch(dataFile);
  console.log(await response.text());

Promise.all() 把多个 Promise 合成一个:全部到齐才继续,适合一次加载好几个数据文件7。 D3 的加载函数(第 04 章)全部返回 Promise,这两段写法在后面的章节会反复出现。

3.4 ES 模块:import 与 export

D3 v7 以 ECMAScript 模块(简称 ES 模块)的形式发布。模块就是一个文件, 用 export 把功能递出去,用 import 把别的文件的功能拿进来。第 01 章里那行 import * as d3 from "https://cdn.skypack.dev/d3@7" 就是把整个 d3 包作为一个模块引进来, * as d3 的意思是「它 export 的所有名字,都挂在 d3 这个对象下面」8。

3.5 DOM、CSS 选择器与 Canvas

DOM(文档对象模型)是浏览器把网页表示成的一棵元素树;JavaScript 可以顺着这棵树找到任意元素、 改它的内容、样式和属性、给它挂事件9。D3 的 d3.select() 用的选择器语法和 CSS 完全一致: #id 选 id,.class 选类,tag 选标签名10。

Canvas 是另一种画图方式:一块位图画布,JavaScript 拿到一个「绘图上下文」对象后, 用命令式的一行行调用画像素。SVG 是「一个元素一个对象」、可以用 CSS 和事件精细操控; Canvas 是「画完就忘」,快,但单个图形无法再选中。D3 两种都支持,大部分章节用 SVG, 第 12、18、19 章会专门演示 Canvas 渲染11。

3.6 数据格式:CSV、JSON、XML

原书清单的最后一项是三种标准数据格式12:

格式 长相 D3 里怎么用
CSV 每行一条记录、逗号分列,第一行是表头 第 04 章的 d3.csv() 加载并解析成对象数组
JSON JavaScript 对象的文本形式,花括号嵌套 d3.json() 一步解析成 JS 对象;地图章(第 20、21 章)的 GeoJSON 就是它
XML 尖括号标签树 现代可视化用得少,了解即可

4. SVG 侧:图形的字母表

4.1 坐标系与视口

SVG 画布有自己的坐标系:原点在左上角,x 向右、y 向下,单位是像素(第 01 章画圆点时已经用过)。 viewBox 是 SVG 的「取景框」属性:它声明画面的逻辑坐标范围,浏览器负责把逻辑坐标缩放到元素的实际尺寸—— 这是 SVG 图形能任意缩放不失真的根基,也是第 15 章地图缩放、交互平移的底层机制13。

4.2 基本形状

SVG 预定义了一组形状标签,原书清单点了名:圆 <circle>、矩形 <rect>、线 <line>、椭圆 <ellipse>、 多边形 <polygon> 和折线 <polyline>14。第 01 章用过 <circle> 的三个属性; 柱状图就是一排 <rect>——第 03 章(Quick Start)会用它从零画一张图。每种形状的属性都直接、好记: 矩形要 x、y、width、height,线要 x1、y1、x2、y2。

4.3 填充、描边与透明度

图形的颜色由两组属性管:fill(内部填充)和 stroke(轮廓描边),各自的颜色、宽度、虚线样式都可控; 透明度有专门的 opacity 属性。SVG 里既可以用标签属性写(fill="gold"), 也可以用 CSS 写(fill: gold),两者都在用15。第 10 章(颜色)会把这套体系接到 D3 的颜色工具上。

4.4 <path>:一个标签画万物

直线、曲线、圆弧、任意复杂轮廓,最后都落到 <path> 一个标签上。 它的 d 属性装一串微型绘图语言的指令:字母是命令,数字是坐标。第 11 章开头原书给了两个真实例子16:

  M280,160 L170,130 L280,0 L40,160 L150,190 L40,320 z     ← 折线五角星
  M261,141 A100,100,0,1,1,100,141 L180,20 L180,20 z       ← 带圆弧的图形

  图说:M = 移动到起点,L = 画直线到,A = 画圆弧到,z = 闭合。
  D3 的形状生成器(第 11、12 章)干的就是「替你算这串字符」。

记住四个字母就够读后面章节:M 提笔移动到、L 直线画到、A 圆弧画到、z 闭合路径。 D3 的形状生成器(shape generators)本质就是这串字符的计算器:你喂数据,它吐 d 字符串。

4.5 文本与组

<text> 是 SVG 的文字标签,对齐由 text-anchor 和基线属性控制; 多行文字用 <tspan> 分段;<textPath> 能让文字沿着一条路径排开17。 <g> 是组容器:把多个形状包成一个整体,对组做变换、设样式,组内全体生效—— 第 03 章重构柱状图时会用它管理成批的柱子。

4.6 仿射变换:translate、scale、rotate

变换(transform)是 SVG 里最容易被低估的机制:它给元素(或组)挂一个几何变换, 写法是属性里一串命令18:

  <g transform="translate(50, 20) scale(2)">
    <!-- 这个组里的所有图形:先挪到 (50,20),再放大 2 倍 -->
  </g>

  图说:translate 平移、scale 缩放、rotate 旋转。命令从右往左作用于局部坐标系,
  所以「先平移后缩放」和「先缩放后平移」结果不同。

D3 的缩放交互(d3-zoom,第 15 章)、地图投影(d3-geo,第 20、21 章)底层全是这套变换, 原书才建议老手也别跳过这一节3。

4.7 SVG DOM API

SVG 元素在 DOM 里就是普通节点,JavaScript 可以读写它们;此外还有一批图形专用的 API: 取某点的当前变换矩阵、量路径长度、算包围盒、判断一个点在不在形状内19。 D3 把这些底层调用也包进了自己的方法里,但调试时(第 05 章末尾的调试一节)你会直接和它们打交道。

5. 边界与局限

  • 这两章在原书里不完整:纸质版只有导读,完整教程在线。我们的讲解补到了「够跟后续章节」, 但系统性不如原书在线版——要深入,去仓库 Part1/Chapter02/、Part1/Chapter03/20。
  • 原书明确说「不需要在继续之前掌握每一个主题,遇到陌生的再回来查」21——这一份同样当查得到的手册用。
  • 补充内容(3.1–3.3 的例子、4.4 的读法)是通用知识,不是原书文字;凡属补充均已当场标注。

6. 可带走的

  1. D3 的地基是 JavaScript + SVG,原书第 2、3 章是两张「缺什么补什么」的清单,不是必读课;
  2. filter 变短、map 等长、reduce 收口——数组三件套贯穿全书;
  3. 加载数据是异步的:Promise + async/await 两种写法都要认得;
  4. import * as d3 from "..." 把 D3 作为 ES 模块整体引进来;
  5. SVG 坐标原点在左上角、y 向下;viewBox 是逻辑取景框,缩放不失真;
  6. <path> 的 d 属性是一串命令字符,M 移动、L 直线、A 圆弧、z 闭合;D3 形状生成器就是这台计算器;
  7. fill 管填充、stroke 管描边;<g> 组让批量操作有落点;
  8. transform 三命令 translate/scale/rotate,顺序有讲究——缩放和平移的先后顺序不同,结果就不同;
  9. 每章原书都在 GitHub 仓库放了可运行完整代码,书里印的片段常是节选22。

7. 原文地图

主题 原书章 原文位置
第 2 章定位与主题清单 Essential JavaScript for D3 (Online) text/08-ch02-chapter-2-essential-javascript-for-d3-online.txt:4(搜「reference guide」) · text/08-ch02-chapter-2-essential-javascript-for-d3-online.txt:17(搜「Topics covered」)
面向读者的要求 Essential JavaScript for D3 (Online) text/08-ch02-chapter-2-essential-javascript-for-d3-online.txt:11(搜「ES2019」)
地图综合示例 Essential JavaScript for D3 (Online) text/08-ch02-chapter-2-essential-javascript-for-d3-online.txt:35(搜「world map」)
第 3 章定位与主题清单 Essential SVG for D3 (Online) text/09-ch03-chapter-3-essential-svg-for-d3-online.txt:2(搜「main graphics format」) · text/09-ch03-chapter-3-essential-svg-for-d3-online.txt:17(搜「Topics covered」)
仿射变换与 SVG DOM 建议 Essential SVG for D3 (Online) text/09-ch03-chapter-3-essential-svg-for-d3-online.txt:12(搜「affine transforms」)
新手该掌握的 SVG 基本功 Essential SVG for D3 (Online) text/09-ch03-chapter-3-essential-svg-for-d3-online.txt:14(搜「circles, rectangles, and lines」)
代码所在目录 两章共用 text/08-ch02-chapter-2-essential-javascript-for-d3-online.txt:37(搜「Part1/Chapter02」) · text/09-ch03-chapter-3-essential-svg-for-d3-online.txt:42(搜「Part1/Chapter03」)

  1. 出处:「Essential JavaScript for D3 (Online)」第 3 段(text/08-ch02-chapter-2-essential-javascript-for-d3-online.txt:3,搜「the more JavaScript you know」)。原文:「D3 is a JavaScript library, and the more JavaScript you know, the more you will benefit from it.」 ↩

  2. 出处:「Essential SVG for D3 (Online)」第 2 段(text/09-ch03-chapter-3-essential-svg-for-d3-online.txt:2,搜「main graphics format」)。原文:「SVG … is the main graphics format used by D3. Almost every chart, diagram, and interactive visualization in this book is drawn with SVG elements.」 ↩

  3. 出处:「Essential SVG for D3 (Online)」第 12 段(text/09-ch03-chapter-3-essential-svg-for-d3-online.txt:12,搜「affine transforms」)。原文:「even readers with SVG experience may want to skim the sections on affine transforms and the SVG DOM, which are often less familiar and come up frequently in D3 projects.」 ↩↩

  4. 出处:「Essential JavaScript for D3 (Online)」第 19 段(text/08-ch02-chapter-2-essential-javascript-for-d3-online.txt:19,搜「map, filter, reduce」)。完整清单还包括对象与解构、Map 和 Set、字符串与模板字面量、方法链。 ↩

  5. 出处:「Essential JavaScript for D3 (Online)」第 12 段(text/08-ch02-chapter-2-essential-javascript-for-d3-online.txt:12,搜「arrow functions」)。原文:「If you know basic JavaScript … but haven't worked with ES2019 features like arrow functions, destructuring, spread operators, promises, or modules, this chapter will fill those gaps.」 ↩

  6. 出处:「Loading and Parsing Data」第 41–47 段(text/12-ch05-chapter-5-loading-and-parsing-data.txt:41,搜「GET request」;:44,搜「blocks execution」)。第 5 章对 fetch 与 await 的讲解是原书正文里最完整的一段,此处引用的是第 2 章清单的对应条目(text/08-ch02-chapter-2-essential-javascript-for-d3-online.txt:23,搜「async/await」)。 ↩

  7. 出处:「Essential JavaScript for D3 (Online)」第 23 段(text/08-ch02-chapter-2-essential-javascript-for-d3-online.txt:23,搜「Promise.all」)。 ↩

  8. 出处:「Data-driven documents」第 265 段(text/07-ch01-chapter-1-data-driven-documents.txt:265,搜「skypack」)。导入语句原文:import * as d3 from "https://cdn.skypack.dev/d3@7";(链接查阅于 2026-10-19)。 ↩

  9. 出处:「Essential JavaScript for D3 (Online)」第 25 段(text/08-ch02-chapter-2-essential-javascript-for-d3-online.txt:25,搜「Navigating and modifying」)。 ↩

  10. 出处:「Essential JavaScript for D3 (Online)」第 27 段(text/08-ch02-chapter-2-essential-javascript-for-d3-online.txt:27,搜「W3C selectors」);选择器语法与 querySelector() 的对应关系见「Selections and Data Binding」第 36 段(text/13-ch06-chapter-6-selections-and-data-binding.txt:36,搜「querySelectorAll」)。 ↩

  11. 出处:「Essential JavaScript for D3 (Online)」第 30 段(text/08-ch02-chapter-2-essential-javascript-for-d3-online.txt:30,搜「Canvas API」);Canvas 渲染在书中的位置见「Creating Pies and Stacks」第 14 段(text/19-ch12-chapter-12-creating-pies-and-stacks.txt:14,搜「HTML Canvas」)与「Force-Directed Networks」目录(text/26-ch18-chapter-18-force-directed-networks.txt:1 前后)。 ↩

  12. 出处:「Essential JavaScript for D3 (Online)」第 32 段(text/08-ch02-chapter-2-essential-javascript-for-d3-online.txt:32,搜「CSV, JSON, and XML」)。 ↩

  13. 出处:「Essential SVG for D3 (Online)」第 32 段(text/09-ch03-chapter-3-essential-svg-for-d3-online.txt:32,搜「Affine transforms and viewBox」)。viewBox 的语义讲解是补充(不在书里,来自通用知识);原书在线版该节标题为「Affine transforms and viewBox」。 ↩

  14. 出处:「Essential SVG for D3 (Online)」第 21 段(text/09-ch03-chapter-3-essential-svg-for-d3-online.txt:21,搜「Circles, rectangles, lines」)。 ↩

  15. 出处:「Essential SVG for D3 (Online)」第 23 段(text/09-ch03-chapter-3-essential-svg-for-d3-online.txt:23,搜「fills, strokes, and opacity」)。 ↩

  16. 出处:「Creating Line and Area Charts」第 39–40 段(text/18-ch11-chapter-11-creating-line-and-area-charts.txt:39,搜「M280,160」)。两条 path 字符串照抄原书;字母含义的逐项讲解是补充(不在书里,来自通用知识)。 ↩

  17. 出处:「Essential SVG for D3 (Online)」第 26 段(text/09-ch03-chapter-3-essential-svg-for-d3-online.txt:26,搜「<tspan> elements」)。 ↩

  18. 出处:「Essential SVG for D3 (Online)」第 33 段(text/09-ch03-chapter-3-essential-svg-for-d3-online.txt:33,搜「the transformation matrix」)。「命令从右往左作用」一句是补充(不在书里,来自通用知识)。 ↩

  19. 出处:「Essential SVG for D3 (Online)」第 38 段(text/09-ch03-chapter-3-essential-svg-for-d3-online.txt:38,搜「current transformation matrix」)。 ↩

  20. 出处:「Essential JavaScript for D3 (Online)」第 37 段(text/08-ch02-chapter-2-essential-javascript-for-d3-online.txt:37,搜「Part1/Chapter02」)与「Essential SVG for D3 (Online)」第 42 段(text/09-ch03-chapter-3-essential-svg-for-d3-online.txt:42,搜「Part1/Chapter03」)。 ↩

  21. 出处:「Essential JavaScript for D3 (Online)」第 15 段(text/08-ch02-chapter-2-essential-javascript-for-d3-online.txt:15,搜「return to a specific section」)。 ↩

  22. 出处:「Preface」第 17–20 段(text/05-fm-preface.txt:18,搜「often show only part」)。原文:「many of the printed code listings focus on specific concepts, they often show only part of the full source.」 ↩