跳转至

数据驱动文档 — D3 是什么、怎么转起来

这一章讲三件事: D3 到底是什么、不是什么;它那条「数据驱动文档」的核心机制怎么转; 以及怎么在本地把开发环境搭起来、跑通第一个程序。 读完你会拿到全书的地基:选择元素 → 绑数据 → 元素跟着数据变——后面十八章全部建立在这条链上。

1. 先看现象:一个点、一排点、一排会动的点

D3 做出的网页图表有个共同点:图不是一张画死的图片,而是和数据连在一起的一堆网页元素。 数据一变,图的形状、颜色、位置就跟着变,还能平滑地动画过去。

这一章的主线例子极简:在网页上画圆点。我们就拿它从头走到尾, 每一步旁边都有具体的数字——这一章的每个核心机制,都会在这排圆点上占一步1。

  ① 一个点      ② 一排点                ③ 换数据               ④ 动画过渡
  ⚫            ⚫ ⚫ ⚫ ⚫ ⚫ ⚫ ⚫        🔴 🔴 🔴 🔴 🔴 🔴 🔴      ⚫→🔴 位置滑动过去
  r=10         7 个点,r=10             7 个点,r=5,红色        1 秒内渐变
  (100,100)    x 坐标 = 数组里的值      x 坐标 = 新数组的值

  图说:同一张 600×200 像素的 SVG 画布,四步是同一个程序的进化。

这四步对应的四段代码,下面就一段段讲。

2. 顶层全景:D3 把什么接到了什么上

原书给的架构一句话:是数据在驱动文档——文档指网页,数据变了,文档的呈现直接跟着变2。

  数据数组 [100, 200, 300, …]
      │  bind(绑定)
      ▼
  选择器选中的网页元素(<circle>、<rect>、<text>…)
      │  每个元素 ↔ 数组里的一项,一一对应
      ▼
  浏览器渲染出的画面

  图说:D3 站在数据和网页元素中间,职责是让两边保持同步。

拆开看,链条上有三个角色,各自有名字:

角色 是什么 在圆点例子里
数据 一个普通的 JavaScript 数组或对象 [100, 200, 300, 350, 375, 400, 500]
元素 网页里的图形标签,大多是 SVG <circle> 圆点
选择器(selection) D3 对「一批元素 + 一批数据」的封装,所有操作都挂在它上面 d3.select("#chart").selectAll("circle").data(values)

选择器是全书的枢纽词,现在只给最小口径:D3 用 CSS 选择器语法(比如 #chart、 circle)抓到网页元素后,不直接返回元素本身,而是包成一个「选择器对象」; 后续的绑定数据、改属性、加动画,全是这个对象上的方法3。 为什么值得包一层,第 2 节讲完圆点例子你就明白了。

3. 核心原理

3.1 D3 是什么:一个 JavaScript 库,但不是图表库

原书第一章开宗明义:D3 是 JavaScript 库,但不是图表库4。 图表库(比如 Chart.js)给你现成的「柱状图」「饼图」模板,填数据就出图; D3 不给模板,它给的是造图的工具——准备数据的、把数据绑到图形上的、算角度算路径的、加动画的。

代价和收益都写在设计里:

图表库 D3
画一张标准柱状图 几行代码 代码更多,要自己拼装
画一个图表库里没有的东西 做不到 任意图形都能绑任意数据,不受限5
控制力 模板定死了 每个像素都由数据和代码决定

原书的态度很明确:前期多写的代码,换来的是「能做出任何图」的自由。 无数获奖的交互式新闻图表是用 D3 做的;它完全开源,商业项目也能免费用6。

D3 的名字是 Data-driven documents(数据驱动文档)的缩写。 它由 Mike Bostock、Jeff Heer 和 Vadim Ogievetsky 创造, 被几十万个网站使用,是世界上最流行的 JavaScript 数据可视化库之一7。

3.2 工具箱里有什么:四类工具

原书把 D3 的工具分了四层,这张图记一下,全书章节就是按这四层展开的8:

  ① 核心机制:流畅接口(fluent API)操作 DOM + 数据绑定 + 事件 + 过渡动画
  ② 可视化工具:布局生成器、比例尺、坐标轴、投影、形状生成器、配色方案
  ③ 数据工具:异步加载解析 JSON/CSV、数组操作、生成序列和随机数、插值、本地化格式化
  ④ 上面全部按模块组织,默认打包 29 个,全书按需展开

  图说:①是发动机,②是图纸库,③是原料车间。第 6 章拆①,第 7-12 章拆②③。

fluent API(流畅接口)指方法连写:a.b().c().d() 一路点下去,每一步返回的还是同一个对象,所以能接着点。下面圆点例子里的 d3.select(...).append(...).attr(...) 就是这种写法。 D3 用它替代了浏览器自带的 DOM 操作接口(那套接口啰嗦得多),并且把数据绑定、事件、动画都缝进了这条链里9。

3.3 主线例子第一步:先不用 D3,用 SVG 画一个点

要理解 D3 在替你做什么,先看不用它时长什么样。

SVG 是网页画矢量图的标准:用 XML 标签描述图形,浏览器负责渲染。 在一个空 HTML 文件的 <body> 里放一块 600×200 像素的 SVG 画布, 里面写一个 <circle>(圆)标签,就给三个属性:

  <svg id="chart" width="600" height="200">
    <circle r="10" cy="100" cx="100" />
  </svg>

  图说:cx=100 圆心横坐标,cy=100 圆心纵坐标,r=10 半径,单位都是像素,
  原点在 SVG 画布的左上角。刷新页面,看到一个半径 10 的黑点。

这三个属性的含义原书交代得很清楚:cx、cy 是圆心的 x、y 坐标(从左上角起算,单位像素), r 是半径10。浏览器打开,一个黑点就显示出来了。

注意此时的坐标系:y 轴向下为正。圆心在 (100,100) 就是「从左边数 100 像素、从上边数 100 像素」。 这和数学课上的坐标系不一样,后面每一章画图都要用到这个口径。

3.4 主线例子第二步:用 D3 画同一个点

把 <circle> 从 HTML 里删掉,改用代码来生成它。先在页面里引入 D3 库本身:

  <script type="module">
    import * as d3 from "https://cdn.skypack.dev/d3@7";  // CDN 链接(查阅于 2026-10-19)
    // 后续的 D3 代码都写在这里
  </script>

  图说:从 CDN(内容分发网络,替你托管公开库文件的静态服务器)下载整个 D3 v7 库,
  作为一个 JavaScript 模块导入,"d3" 这个名字后面的所有功能就都能用了。

然后把画点写成一条方法链:

  d3.select("#chart")
    .append("circle")
      .attr("r", 10)
      .attr("cy", 100)
      .attr("cx", 100);

  图说:这是「一条命令」——选中 id 为 chart 的 SVG,给它追加一个圆,再设三个属性。
  缩进只是便于阅读,每一段缩进代表一层新的上下文。

原书强调这是一条命令,折行只为易读:每一行是一个方法(method),逐个执行11。 四个方法各司其职:

方法 干了什么 对应的「手写 SVG」
d3.select("#chart") 用 CSS 选择器语法选中那个 <svg>,包成选择器对象 —
.append("circle") 在它里面造一个 <circle> 子元素,并把选择器指向新元素 <circle> 标签
.attr("r", 10) 等三行 给元素设属性 r="10" 等三个属性

结果和手写 SVG 一模一样。所以你看出选择器对象的价值了吗:它不是多此一举的包一层, 而是把「选中、创建、设置」统一成了一条可以无限接下去的链。

3.5 主线例子第三步:一排点——数据绑定的第一次出现

一个点用不着 D3。真正的主角登场:一个数据数组,七个值。

  const values = [100, 200, 300, 350, 375, 400, 500];

改写成下面这段代码(对比上一步,append() 换成了三个新方法, attr() 的第二个参数从固定的 10 变成了一个箭头函数):

  d3.select("#chart")
    .selectAll("circle")
    .data(values)
    .join("circle")
      .attr("r", 10)
      .attr("cy", 100)
      .attr("cx", d => d)

  图说:d => d 是 JavaScript 箭头函数,等价于 function(d) { return d; }:
  把绑到当前元素上的那项数据原样返回。

四个新方法,逐一看做了什么12:

  1. selectAll("circle") —— 选出页面上所有 <circle>(此时还没有,是个空选择)。
  2. data(values) —— 把数组 values 绑到这个选择上。从这一刻起,每个元素(包括还不存在的)都对应数组里的一项。
  3. join("circle") —— 这一步是 D3 的招牌:检查数据和元素的数量,数组有 7 项、圆有 0 个, 于是自动创建 7 个 <circle> 补上。数组比元素多就创建,比元素少就删除,一样多就复用——数据永远是老大。
  4. 三个 attr() —— 对 7 个圆逐个设置。关键在 cx:它收到的是绑到这个圆上的那项数据。 第一个圆拿到 100,第二个拿到 200……七个圆的横坐标正好排成数组的样子。

跑出来的效果:7 个黑圆点横排在 y=100 的线上,横向位置由数组里的数决定13。 数组有 7 项,页面就有 7 个点,一个不多一个不少——这就是「数据驱动」四个字的第一次现身。 改数组(书里建议试试 0–600 之间的任意值、或增删项),刷新页面,点的个数和位置跟着变。

join() 的三分逻辑(enter/update/exit:数据多出来的创建、对得上的更新、数据没了的删除) 是全书最重要的机制,后面第 05 章整章拆它。这里先记住一句话:数组和元素谁听谁的?听数组的。

3.6 主线例子第四步:换数据——元素的复用

数据会变。书里接着演示:两秒后把七个点换成一批新数据。先写一个和 update 绑在一起的函数:

  function update(dataset) {
    d3.select("#chart").selectAll("circle")
      .data(dataset)
        .attr("r", 5)
        .attr("cx", d => d)
        .style("fill", "red")
  }
  const newArray = [225, 425, 125, 50, 450, 75, 325];  // 新数据
  setTimeout(update, 2000, newArray);                  // 2 秒后执行

  图说:setTimeout 是 JavaScript 自带的定时器:2 秒(2000 毫秒)后调用 update,参数是 newArray。

2 秒后发生的事:页面上那 7 个圆没有删掉重建,而是被复用了——半径从 10 缩到 5, 横坐标换成新数组的值,颜色由黑变红14。

注意这段代码里 没有 join()。为什么不用?因为新数组还是 7 项,圆还是 7 个, 没有元素需要增删,data() 直接把新数据绑回原有元素,后面跟着的属性修改就生效了15。

这里藏着 D3 省心的地方:增删改三种情况,一种写法全兜住。 数组变长了 join() 会补元素,变短了会删元素,等长就纯更新。 你只管用 .data() 喂新数据,元素层面的事它自动同步——这正是原书说的 「增、改、删数据时,图形的显示直接跟着变」16。

3.7 主线例子第五步:动画——一行代码的过渡

最后一步,让变化「滑」过去而不是瞬间跳变。只需在 data() 之后插一句:

  .transition().duration(1000)

transition() 把后面跟着的属性修改变成动画;duration(1000) 把时长设为 1 秒 (不写这句,默认时长是 ¼ 秒)17。于是 2 秒后,7 个圆花 1 秒的时间: 一边缩小、一边变红、一边滑到新位置18。

到这里,主线例子走完了完整一圈:

  手写 SVG 一个点 → D3 生成一个点 → 数组驱动七个点 → 换数据原地更新 → 加 transition 平滑动画
      每一步只加了几个单词,但第 ③ 步开始,图和数据就连在一起了

  图说:这五步就是 D3 应用的完整生命周期:绑数据、同步元素、改属性、过渡。

3.8 开发环境:书里的推荐与提醒

工欲善其事。原书对环境设置给了明确建议,核心三点:

第一,用什么编辑器。 需要一个支持 HTML/JavaScript 语法高亮、自带(或插件提供)本地 Web 服务器的编辑器——为什么必须有服务器,下一章讲数据加载时会看到(浏览器禁止网页直接读本地文件)。 书里推荐两个都免费的:WebStorm(非商业用途免费,服务器内置)和 Visual Studio Code(要装 Live Server 插件)19。

第二,代码例子从哪来。 全书代码在 GitHub 仓库 PacktPublishing/Learn-D3.js-Second-Edition, 按 Part1/–Part3/ 分目录,每章一个文件夹,书里每个片段都能在仓库里找到完整可运行的版本20。

第三,在线替代品及其坑。 不想配本地环境,可以用 CodePen、JSFiddle 这类在线编辑器, 或者 D3 圈最流行的 Observable 笔记本平台21。但原书对 Observable 有一个诚实的警告: 它用的是响应式编程模型,变量赋值、异步加载、事件处理的写法都和普通网页 JavaScript 不一样, 也享受不到浏览器的调试工具;新手最好先按「网页里的普通 JavaScript」学好 D3,再去碰它22。

3.9 D3 的模块架构:40+ 个模块,默认打包 29 个

D3 不是一个整块,而是 40 多个模块的集合;import * as d3 载入的默认打包里含 29 个, 其余(比如画桑基图、力导向图的扩展模块)要单独引入23。

最小化的例子:连整个 D3 都不用,只引 d3-selection 一个模块就能画图:

  import * as d3 from "https://cdn.skypack.dev/d3-selection@3";  // CDN 链接(查阅于 2026-10-19)
  d3.select("body").append("svg").append("circle")
    .attr("r", 20).attr("x", 50).attr("y", 50);

但原书马上补了警告:单独引模块并不省事——漏引依赖、引入顺序错、版本不兼容, 都会产生很难排查的错误。所以全书例子一律引整个 d3 包,只有用到默认包之外的模块时才单独演示正确引法24。

4. 作者的判断与证据

这一章是入门引导,判断不多,但有两条值得单独标出来:

判断 性质 证据
「图表库做不了原创的图,D3 能」 作者主张,行业共识 无数获奖交互图表用 D3 制作、几十万个网站在用6
「Observable 对新手不合适」 作者个人经验之谈 给出具体理由:响应式模型不同、无浏览器调试工具22
「初学者别拆包引模块」 作者教学取向 理由:配置错误会干扰学习目标24

原书没有利益相关声明;D3 本身开源免费,作者自 v3 时代起使用和教授 D3, 前言称这本书是「多年探索、使用和教学 D3」的经验总结25。

5. 边界与局限

  • 本章的圆点例子不讲「为什么」。join() 内部怎么决定增删、data() 怎么对应元素与数据项, 本章只给用法。机制层面在第 05 章(选择器与数据绑定)拆。
  • 环境配置写得很快。npm/Node 工程化设置在书里被明确排除(「advanced setup is not covered」), 只在附录有一篇简短指引26。
  • 版本口径:全书基于 D3 v7.9.0 与 ES2019,引库地址是 CDN 链接; 这些 URL 和版本号会随时间过时,机制不会。
  • 「2001 年创建」疑为笔误:原书正文写 D3「Created by Mike Bostock, Jeff Heer, and Vadim Ogievetsky in 2001」7, 而 D3 的前身 Protovis 约 2009 年出现、D3 首个版本发布于 2011 年——我们按原文照引,但此处的年份与公认的 D3 历史对不上,读者引用时请留意。

判断(我们的,不是书里的): D3 真正的设计巧思在本章只露出了冰山一角—— join() 把「数据库事务式的同步协议」搬到了 DOM 上(声明目标状态,框架算 diff), 这个思想后来被 React 等界面库独立地重新发明了一遍。学 D3 的价值不只在画图, 也在亲眼看到一个「声明式同步」协议在 2011 年就已经完整存在。 如果错,会错在: 把 D3 的 join 与 React 的 diffing 类比得过满——两者目标相似 (让元素状态跟上数据),但实现层级、粒度与更新策略都不同,类比只到「思想同源」为止。

6. 可带走的

本章主线例子,一行走完: SVG 画布上,[100, 200, 300, 350, 375, 400, 500] 经 selectAll("circle").data(values).join("circle") 变成 7 个圆;2 秒后换绑 [225, 425, 125, 50, 450, 75, 325] 并加 .transition().duration(1000),圆缩小、变红、滑到新位置。 数组里的数全是原书给的,不是编的。

  1. D3 = Data-driven documents,一个把数据绑到网页元素上的 JavaScript 工具箱,不是图表库;
  2. 它的核心链条是 选择器 → 绑数据 → 元素随数据增删改;join() 让数组永远说了算;
  3. d3.select(...).append(...).attr(...) 一条链写完,fluent API 替代了啰嗦的浏览器原生 DOM 接口;
  4. SVG 坐标原点在左上角,y 轴向下为正;
  5. 数据绑定后,attr("cx", d => d) 里的 d 就是绑到当前元素的那项数据(箭头函数 d => d 等价于 function(d){return d;});
  6. 元素数量没变时可以不用 join() 直接 .data() 重绑更新;
  7. .transition().duration(1000) 一行把属性修改变成 1 秒动画(默认 ¼ 秒);
  8. 开发需要一个本地 Web 服务器(后面章节会讲为什么),VS Code + Live Server 或 WebStorm 都可以;
  9. D3 有 40+ 模块、默认打包 29 个;初学别拆包引,全书统一 import * as d3;
  10. Observable 笔记本是 D3 的流行平台,但响应式模型和网页 JS 不同,新手先学普通环境。

7. 原文地图

主题 原书章 原文位置
D3 的定义、创造者、普及度 Data-driven documents text/07-ch01-chapter-1-data-driven-documents.txt:25(搜「stands for Data-driven」) · text/07-ch01-chapter-1-data-driven-documents.txt:29(搜「hundreds of thousands」)
不是图表库、四类工具 Data-driven documents text/07-ch01-chapter-1-data-driven-documents.txt:37(搜「not a charting library」) · text/07-ch01-chapter-1-data-driven-documents.txt:49(搜「fluent API」)
数据驱动文档架构 Data-driven documents text/07-ch01-chapter-1-data-driven-documents.txt:63(搜「drives the documents」)
选择器对象 Data-driven documents text/07-ch01-chapter-1-data-driven-documents.txt:72(搜「selection object」)
IDE 推荐与服务器 Data-driven documents text/07-ch01-chapter-1-data-driven-documents.txt:108(搜「Choosing an IDE」) · text/07-ch01-chapter-1-data-driven-documents.txt:120(搜「web server」)
在线环境 / Observable 警告 Data-driven documents text/07-ch01-chapter-1-data-driven-documents.txt:168(搜「CodePen」) · text/07-ch01-chapter-1-data-driven-documents.txt:184(搜「reactive programming model」)
SVG 画点三属性 Data-driven documents text/07-ch01-chapter-1-data-driven-documents.txt:237(搜「r="10" cy="100" cx="100"」) · text/07-ch01-chapter-1-data-driven-documents.txt:240(搜「cx and cy」)
引入 D3(CDN) Data-driven documents text/07-ch01-chapter-1-data-driven-documents.txt:265(搜「skypack」)
append 画点 Data-driven documents text/07-ch01-chapter-1-data-driven-documents.txt:285(搜「append("circle")」) · text/07-ch01-chapter-1-data-driven-documents.txt:290(搜「single command」)
values 数组与 join 七圆点 Data-driven documents text/07-ch01-chapter-1-data-driven-documents.txt:311(搜「100, 200, 300, 350」) · text/07-ch01-chapter-1-data-driven-documents.txt:330(搜「empty selection」) · text/07-ch01-chapter-1-data-driven-documents.txt:335(搜「d => d」)
update 换数据 Data-driven documents text/07-ch01-chapter-1-data-driven-documents.txt:353(搜「function update」) · text/07-ch01-chapter-1-data-driven-documents.txt:372(搜「newArray」) · text/07-ch01-chapter-1-data-driven-documents.txt:378(搜「setTimeout」)
transition 动画 Data-driven documents text/07-ch01-chapter-1-data-driven-documents.txt:393(搜「¼ of a second」) · text/07-ch01-chapter-1-data-driven-documents.txt:398(搜「duration(1000)」)
模块架构 40+/29 Data-driven documents text/07-ch01-chapter-1-data-driven-documents.txt:417(搜「over 40 modules」) · text/07-ch01-chapter-1-data-driven-documents.txt:418(搜「29 modules」)
只引 d3-selection Data-driven documents text/07-ch01-chapter-1-data-driven-documents.txt:423(搜「importing just the d3-selection」)
章小结 Data-driven documents text/07-ch01-chapter-1-data-driven-documents.txt:447(搜「paradigms in D3」)

  1. 出处:「Data-driven documents」第 2 段(text/07-ch01-chapter-1-data-driven-documents.txt:2,搜「goal of this chapter」)。本章目标:介绍 D3、讲它怎么工作、搭好练习环境,并「create a simple D3 application」验证安装。 ↩

  2. 出处:「Data-driven documents」第 63 段(text/07-ch01-chapter-1-data-driven-documents.txt:63,搜「drives the documents」)。原文:「it's the data that drives the documents that display visualizations. By adding, changing, and removing data, you directly affect the way your chart is displayed.」 ↩

  3. 出处:「Data-driven documents」第 72 段(text/07-ch01-chapter-1-data-driven-documents.txt:72,搜「selection object」)。原文:「Selectors are used to select one or more elements and create what D3 calls a selection object, which can then be used to apply styles and change the attributes of the selected elements.」 ↩

  4. 出处:「Data-driven documents」第 37 段(text/07-ch01-chapter-1-data-driven-documents.txt:37,搜「not a charting library」)。原文:「D3 is a JavaScript library, but not a charting library.」 ↩

  5. 出处:「Data-driven documents」第 43 段(text/07-ch01-chapter-1-data-driven-documents.txt:43,搜「find in any charting」)。原文:「You can use it to design original visualizations that you won't find in any charting library or service.」 ↩

  6. 出处:「Data-driven documents」第 32 段(text/07-ch01-chapter-1-data-driven-documents.txt:32,搜「award-winning」)。原文:「Many award-winning interactive visualizations were created with D3. It is also free and open source. You can use it in any project, commercial or not.」 ↩↩

  7. 出处:「Data-driven documents」第 25 段(text/07-ch01-chapter-1-data-driven-documents.txt:25,搜「stands for Data-driven」)与第 29 段(text/07-ch01-chapter-1-data-driven-documents.txt:29,搜「Ogievetsky」)。原文:「D3, which stands for Data-driven documents… Created by Mike Bostock, Jeff Heer, and Vadim Ogievetsky in 2001, it's currently used in hundreds of thousands of websites」。年份 2001 照原文照引,与公认 D3 历史(2011 年发布)不符,疑为笔误——见正文 §5。 ↩↩

  8. 出处:「Data-driven documents」第 48 至 59 段(text/07-ch01-chapter-1-data-driven-documents.txt:47,搜「toolkit for interactive」;:53,搜「layout generators」;:56,搜「asynchronously load and parse」)。 ↩

  9. 出处:「Data-driven documents」第 49 段(text/07-ch01-chapter-1-data-driven-documents.txt:49,搜「fluent API」)。原文:「The library's core is a fluent API for selecting nodes and controlling the document object model (DOM), replacing the DOM API entirely.」DOM 即文档对象模型,浏览器把网页表示成的一棵元素树。 ↩

  10. 出处:「Data-driven documents」第 240 段(text/07-ch01-chapter-1-data-driven-documents.txt:240,搜「cx and cy」)。原文:「The <circle> element requires three attributes: cx and cy for the x,y position of its center (100,100), in pixels, starting at the top left, and r for the circle's radius (10 pixels).」 ↩

  11. 出处:「Data-driven documents」第 290 段(text/07-ch01-chapter-1-data-driven-documents.txt:290,搜「single command」)与第 296 段(text/07-ch01-chapter-1-data-driven-documents.txt:296,搜「single line of code」)。原文:「This is a single command that runs a sequence of operations (methods).」 ↩

  12. 出处:「Data-driven documents」第 330–336 段(text/07-ch01-chapter-1-data-driven-documents.txt:330,搜「empty selection」;:336,搜「arrow functions」)。原文逐条列出四个方法的含义;「this is the same as function(d) { return d; }」见第 336 段。 ↩

  13. 出处:「Data-driven documents」第 338–344 段(text/07-ch01-chapter-1-data-driven-documents.txt:338,搜「seven dots」;:344,搜「data values from the array」)。原文:「We used the data array to drive the position of each circle.」 ↩

  14. 出处:「Data-driven documents」第 380–381 段(text/07-ch01-chapter-1-data-driven-documents.txt:380,搜「shrink」)。原文:「the dots will be displayed as before, but two seconds later, the circles will shrink, become red, and move to different positions」。 ↩

  15. 出处:「Data-driven documents」第 385–387 段(text/07-ch01-chapter-1-data-driven-documents.txt:365,搜「rebind」)。原文:「A join() command is not necessary here because there aren't elements to be added or removed: all existing circles are reused.」 ↩

  16. 出处:「Data-driven documents」第 78 段(text/07-ch01-chapter-1-data-driven-documents.txt:78,搜「synchronizes the data」)。原文:「D3 synchronizes the data with elements, removing extra elements when the dataset shrinks and adding new ones when it grows.」 ↩

  17. 出处:「Data-driven documents」第 392–398 段(text/07-ch01-chapter-1-data-driven-documents.txt:393,搜「¼ of a second」;:398,搜「duration(1000)」)。原文:「A default transition takes ¼ of a second, but you can make it a little longer by setting its duration.」 ↩

  18. 出处:「Data-driven documents」第 411–413 段(text/07-ch01-chapter-1-data-driven-documents.txt:412,搜「Congratulations」)。原文:「the dots will spend one more second changing color, shrinking, and moving to their new positions.」 ↩

  19. 出处:「Data-driven documents」第 110–122 段(text/07-ch01-chapter-1-data-driven-documents.txt:110,搜「at the time of writing」;:122,搜「Live Server」)。两个 IDE 的名称与免费口径见第 112–113 段。 ↩

  20. 出处:「Data-driven documents」第 153–159 段(text/07-ch01-chapter-1-data-driven-documents.txt:158,搜「github.com/PacktPublishing」)。仓库 URL 与按章分目录的组织方式见第 156–163 段;前言「Preface」第 17–20 段(text/05-fm-preface.txt:17,搜「GitHub repository」)亦有说明。 ↩

  21. 出处:「Data-driven documents」第 167–180 段(text/07-ch01-chapter-1-data-driven-documents.txt:168,搜「CodePen」;:177,搜「Observable platform」)。 ↩

  22. 出处:「Data-driven documents」第 183–189 段(text/07-ch01-chapter-1-data-driven-documents.txt:184,搜「reactive programming model」)。原文:「It uses a reactive programming model, which differs from the way JavaScript runs in a web page, and you won't be able to use browser debugging tools.」响应式编程:变量的值会自动跟着依赖它的计算更新,而不是你手动一步步执行——Observable 单元格之间就是这种关系。 ↩↩

  23. 出处:「Data-driven documents」第 417–419 段(text/07-ch01-chapter-1-data-driven-documents.txt:417,搜「over 40 modules」)。原文:「There are over 40 modules… you automatically load the 29 modules that make up the default bundle.」 ↩

  24. 出处:「Data-driven documents」第 423–437 段(text/07-ch01-chapter-1-data-driven-documents.txt:434,搜「hard-to-find errors」;:436,搜「avoids configuration errors」)。 ↩↩

  25. 出处:「Preface」第 26–28 段(text/05-fm-preface.txt:26,搜「since version 3」)。原文:「I have been using and teaching D3 since version 3, and much of this book is shaped by that experience.」 ↩

  26. 出处:「Data-driven documents」第 103–104 段(text/07-ch01-chapter-1-data-driven-documents.txt:104,搜「npm」)。原文:「Experienced frontend developers who already use an IDE and a local Node.js environment can add D3 to their project with the npm (see Chapter 20). This advanced setup is not covered in this book.」 ↩