复用网页生态
生成结果仍是 HTML、SVG 与 CSS。元素层级、继承样式和事件监听器可以直接通过浏览器开发工具检查。
把浏览器原生 DOM 当作可视化场景图,以 selection、data join 和显式变换连接数据与文档。论文的核心价值来自表示透明性,以及这种设计对调试、动态更新和性能的影响。
2011 年的网页可视化需要同时使用 HTML、CSS、JavaScript 与 SVG。许多工具用自有 scenegraph 封装浏览器 DOM,带来更简洁的图形词汇,也切断了浏览器开发工具、CSS、标准文档与新平台能力。D3 选择提供一个小型 visualization kernel:数据直接绑定到原生元素,开发者明确指定应当改变哪些节点和属性。
生成结果仍是 HTML、SVG 与 CSS。元素层级、继承样式和事件监听器可以直接通过浏览器开发工具检查。
操作符调用时立即产生效果,错误更接近发生位置;控制流程留在用户 JavaScript 中,减少延迟求值带来的隐藏状态。
开发者选择需要修改的元素和属性,避免重新计算完整 scenegraph,并直接修改 DOM,省去中间表示传播。

D3 采用 W3C Selectors API。顶层 select 返回首个匹配元素,selectAll 按文档遍历顺序返回全部匹配元素。选择器支持标签、class、唯一标识、属性、包含关系和相邻关系,也可组合交集与并集。
操作符覆盖 attr、style、property、html 与 text。值可以是常量,也可以是逐元素执行的函数;函数接收已绑定数据 d 与组内索引 i。each 提供任意 JavaScript 回调。操作符返回原 selection,因此支持 method chaining。
d3.selectAll("p")
.style("color", "white")
.attr("data-state", function(d, i) { return i; });
对子 selection 使用 selectAll 时,元素按祖先分组。d3.selectAll("p").selectAll("b") 会按段落保存多个组;直接查询 d3.selectAll("p b") 得到扁平选择。data join 在每个组内计算,函数索引也以组为边界。

data 接收任意值数组并绑定到选中节点。默认按索引配对;可提供 key function,让新旧数据按稳定键对应,从而在动画中保持 object constancy。绑定结果保存在节点上,重新选择后仍能访问,论文称为 sticky data。
存在数据、缺少节点。selection 中保存占位对象,随后通过 append 或 insert 实例化元素。
数据与节点成功匹配。data 直接返回这一子选择,适合更新位置、颜色和文字等动态属性。
存在节点、缺少新数据。可执行离场动画,结束后调用 remove 清理元素。

三个按钮展示同一组旧节点面对不同新数据时的 enter、update 与 exit 集合。
on 暴露 DOM 原生事件。回调接收 (d, i),目标节点由 this 访问,当前事件保存在 d3.event。带命名空间的事件名称允许多个监听器共存。
transition 从 selection 派生。它沿用 attr 与 style 的调用形式,在当前值与目标值之间插值。delay 和 duration 可按元素计算,从而实现错峰动画;缓动函数可按名称选择。内置 interpolator 覆盖数值、含数值的字符串、RGB/HSL 颜色、数组和嵌套对象,也允许自定义。
每个元素的 transition 保持互斥,由统一 timer queue 提供一致时间。动画完成事件可串联后续 transition 或删除 exit 元素。论文报告这种设计可以管理数千个并发 timer,未提供单独的 timer 数量曲线或资源占用表。
修改数据或属性定义后调用 render。系统缺少依赖信息时需要重算属性并把中间 scenegraph 传播到 SVG。
程序明确选择元素、属性及生命周期阶段。控制粒度提高,也要求开发者自行判断哪些部分应当更新。
属性函数到渲染阶段才运行。闭包捕获的变量可能已改变,隐藏控制流程会延迟错误暴露。
操作符调用时立即修改节点并返回。布局变成生成或修改普通数据结构的 helper,随后由 selection 映射到元素。
核心 selection kernel 之上提供 shapes、scales、layouts、behaviors、geo 与 geometry 等模块。它们输出普通数据或原生 path,沿用数据驱动函数语义。论文列举 pie/arc、line、area、linear/log/quantile scale、partition、chord、force、stack、treemap、zoom、GeoJSON path、Voronoi、convex hull 与 quadtree。
| 实例 | 输入与表示 | D3 机制 | 公开规模 | 证据边界 |
|---|---|---|---|---|
| Animated HTML Treemap | Flare package hierarchy;叶节点映射为 HTML div | sticky treemap、ordinal color scale、click handler、transition | 静态版本 21 行 JavaScript;Protovis 17 行;加入交互与动画后 54 行 | 说明原生 HTML 的兼容性与近似记法效率;未做任务时间实验 |
| Noncontiguous Cartogram | U.S. Census 边界,经 MapShaper 简化、GDAL 转为 GeoJSON;CDC 2008 肥胖率 | Albers equal-area projection、geo.path、centroid、SVG transform | 34 行 JavaScript;值域 10.0% Colorado 至 20.1% Indiana | 展示 geo module 与 CSS/SVG 组合;未测地图理解 |
| Bézier Curves Explained | 五个二维控制点;数组切片产生低阶曲线 | SVG path/line/circle、drag 事件、逐步缓存路径 | 139 行 JavaScript,不含注释 | 展示任意 data-driven graphics;缓存策略属于实例实现 |
论文比较 D3、Protovis 与 Flash/Flare。指标覆盖从页面加载到首次显示的 initialization time,以及连续交互或动画时的平均 frame rate。Figure 10 只绘制曲线,没有发布逐点表格;下表收录正文和坐标轴明确公开的全部数字。
| 协议项 | 论文设置 |
|---|---|
| 工作负载 1 | 四维 scatterplot matrix,支持 brushing & linking;每帧随机选择一个子图和两个坐标,形成矩形 brush,所有散点图同步高亮。 |
| 工作负载 2 | animated stacked graph,在两组固定数据值之间连续动画;D3/Protovis 使用各自 stack layout,Protovis 使用 3.3 transition,Flash 使用 Flare。 |
| 规模 | 数据点从 500 增加到 20,000;Figure 10 标注 500、5,000、10,000、20,000。 |
| 初始化 | 每个版本重复 10 次,报告平均值;页面 refresh 计时,因此包含缓存过的 Flash library 带来的节省。 |
| 帧率 | 每个 10 秒区间记录平均帧率,持续 5 分钟;随后计算样本均值与方差。 |
| 方差 | 标准差比均值小 1–2 个数量级,论文没有在图中展示误差条或逐点方差。 |
| 硬件 | MacBook Pro,双核 2.66 GHz 处理器,8 GB RAM,Mac OS X 10.6.7。 |
| 软件 | Google Chrome 11.0 beta;Adobe Flash Player 10.2 plug-in。 |

| 正文明确结果 | 结论 | 适用范围 |
|---|---|---|
| D3 与 Protovis | D3 页面加载至少快 2 倍;数据规模增加时 D3 帧率至少为 Protovis 的 2 倍。 | 两项给定可视化、上述硬件与 2011 年软件版本。 |
| D3 与 Flash | D3 页面加载至少快 3 倍;Flash 在规模增加时帧率为 D3 的 2–2.5 倍。 | Flash 版本没有使用 Adobe Flex;论文称加入 Flex 会额外增加超过 1 秒加载时间。 |
| 外部使用者观察 | Jason Davies 报告 Bézier 教程从 Protovis 的 30 fps 提升到约 90 fps。 | 用户报告,独立于论文的两项正式 benchmark。 |
| 系统 | 核心表示 | 优势 | 论文指出的限制 | 在本文中的角色 |
|---|---|---|---|---|
| CSS | DOM selector + declarative style | 标准化、简洁、继承 | 无法按数据创建和删除元素 | selection 概念来源与配套技术 |
| jQuery | DOM selection 与 mutation | 通用文档操作便利 | 缺少高层 data join,复杂动态可视化需手工管理节点 | 最接近的文档变换参照 |
| XSLT | XML template rule | 简单结构变换优雅 | 缺少可视化高层抽象,数学与交互任务笨重 | 声明式文档变换参照 |
| Processing / Raphaël | 低层绘图 API | 图形 primitive 与结果关系直接 | 复杂可视化缺少 scale、layout 等便利抽象;部分表示难以检查或被封装 | 图形库设计空间 |
| InfoVis frameworks | 组件层级或 operator pipeline | 组合已有组件 | 新颖视图经常需要软件工程能力与新 operator | 高层框架参照 |
| Protovis 3.3 | 专用 mark 与中间 scenegraph | 静态场景简洁、mark 继承、anchor | 隐式全局重绘、延迟求值、原生表示映射成本 | 直接设计与性能基线 |
| Flash + Flare | Flash display object / Sprite | 实验中动态帧率最高 | 插件初始化与专有平台;页面加载较慢 | 直接性能基线 |
selection/data join/enter-update-exit/transition 的 API 设计;三项应用的实现规模;两项 benchmark 的硬件、软件、重复次数、数据规模和相对性能;Figure 1–11 的实例。
表示透明性改善 accessibility、expressiveness 与协作潜力。论文提供设计论证、案例和用户轶事,缺少系统用户研究来分离学习成本、调试速度与标准知识迁移。
D3 把“可视化语言”的中心从图形语法转向增量数据同步协议。data join 是核心抽象,layout 与 shape 可以作为普通函数模块叠加,因此 kernel 保持小而开放。
可把 data join 的生命周期思想用于 renderer-in-the-loop 的程序图编辑:通过稳定 key 保存节点身份,对新增、保留和删除的 graph node 分别安排初始化、参数更新与清理,并记录执行反馈。
问题边界准确;直接利用 DOM、CSS、browser tools 与标准资料;enter/update/exit 形成可组合的动态生命周期;性能实验同时报告加载和帧率,保留了 Flash 帧率领先这一结果。
可访问性与调试优势主要依据论证和少量引语;没有任务完成时间、错误率或学习曲线对照;Figure 10 缺少原始数据与置信区间;实验只覆盖一台机器、一个 beta 浏览器和两种可视化。
论文公开工作负载、规模、重复协议与环境,足以重建实验结构;未给出逐次样本、实现 commit、自动化脚本和精确计时 API,难以复算曲线。现代 D3 API 已发生变化,复现历史结果需要锁定旧版本。
发布原始测量表和代码快照;跨浏览器与硬件报告 bootstrap confidence interval;把局部更新比例设为独立变量;增加开发者实验,测量实现时间、定位错误时间与 DOM/SVG 先验知识。
原笔记依据 Wobbrock 与 Kientz 的框架把 D3 归为 artifact contribution,并把性能比较视为 empirical contribution;依据 Oulasvirta 与 Hornbæk 的问题类型框架,把它视为对既有低效解法的 constructive solution。网页保留这组评论的核心观点。关于“持续流行证明 confidence”的表述更适合作为后见影响力证据,无法代替 2011 年论文内部的受控验证。
d3.svg.area、d3.layout.pie 与 d3.event。当前 D3 已拆分模块并更改大量名称。本文讲解依据 2011 年论文语义,现代官方仓库只用于确认 D3 仍是基于网页标准的开源可视化库。domain/hcimethod/software-framework-designmethod/declarative-data-bindingtask/data-visualization