
D3.js 调研:113K stars 的可视化鼻祖怎么被 Observable Plot 接班了,Mike Bostock 的 15 年传奇
D3.js 是 Mike Bostock 2011 年在斯坦福读博时写的 ” 用数据操纵 DOM” 的库 —— 15 年过去它依然是现代 web 可视化的底层事实标准,但 Mike Bostock 的精力已经转向 Observable Plot 和 Observable Framework,D3 本体进入维护期。
写在前面:2026 年可视化生态的 5 大阵营
打开任何一个前端项目想加图表,选项多到眼花。Data Visualization Libraries 2026 这类综述文章会把工具分成 5 大类:
| 阵营 | 代表工具 | 主要用户 | 渲染目标 |
|---|---|---|---|
| JS viz libraries | D3.js、ECharts、Plotly、Chart.js、Highcharts | 前端工程师 | SVG / Canvas |
| React-friendly | Recharts、Visx、Nivo、Tremor | React 开发者 | SVG |
| Declarative grammars | Vega-Lite、Vega、Observable Plot | 分析师、notebook 用户 | SVG |
| Network and graph | Sigma.js、Cytoscape.js、G6、X6 | 图数据团队 | Canvas |
| BI and newsroom | Superset、Metabase、Tableau、Looker、Power BI | 分析师、PM、记者 | 多 |
D3 在 JS viz libraries 类里是 ” 底层基础设施 ” —— ECharts / Plotly / Chart.js 都是 chart 库,D3 是 DOM 操纵原语。所有现代可视化库的底层几乎都在用 D3:Recharts / Visx / Nivo / AntV G2 / Vega-Lite / Observable Plot / Superset / Metabase ……。
一、它解决什么问题
D3(Data-Driven Documents)把自己定位为 DOM manipulation library,核心三件事:
- 数据 → DOM 绑定(selectAll().data().join() 三段式)
- 数据 → 视觉映射(scales:linear / log / ordinal / time)
- 数据驱动的转换(transitions、enter / update / exit)
基本信息
| 项 | 数据 |
|---|---|
| 仓库 | d3/d3 |
| Stars | 113,574 ⭐(GitHub API 实时,11 万级) |
| Forks | 22,673(极高) |
| License | ISC ✅(v6 是 BSD-3-Clause,v7+ 改为 ISC) |
| 创建 | 2010-09-27(15 年老项目) |
| 最新 release | v7.9.0(2024-03-12,距离 2026-08 已 2 年半 没正式 release) |
| 最后 push | 2026-05-28(docs / links fix,不是 feature commit) |
| 体积 | 59 KB(meta-package,因为 d3/d3 只是入口) |
| 主语言 | Shell(meta-package 统计口径) |
| Open issues | 20(极低) |
| OpenSSF Scorecard | 4.5/10(Maintained 0/10 失分) |
| 作者 | Mike Bostock(Stanford PhD → NYT Graphics → Observable CEO) |
| 官网 | d3js.org |
| 配套 | observablehq/plot 5.4K ⭐ + observablehq/framework |
核心架构 :d3/d3 不是单一库, 是 umbrella package —— 它依赖 32 个独立 sub-modules(d3-selection / d3-scale / d3-shape 等),每个都可单独用 npm install。
二、D3 不是什么:D3 是底层原语,不是 chart 库
D3 的哲学(README 原话):
“D3 is not a monolithic framework that seeks to provide every conceivable feature. Instead, D3 solves the crux of the problem: efficient manipulation of documents based on data.”
翻译:
- ❌ D3 不是 chart library(没有
d3.barChart()这种函数) - ❌ D3 不是 visualization framework(不会给你 ” 开箱即用 ” 的图表)
- ✅ D3 是 DOM manipulation library + data binding primitive
一个简单的 bar chart,D3 要写 ~30 行:
import * as d3 from 'd3';
const data = [30, 50, 80, 40, 60];
const svg = d3.select('#chart').append('svg').attr('width', 400).attr('height', 200);
const x = d3.scaleBand().domain(d3.range(data.length)).range([0, 400]).padding(0.1);
const y = d3.scaleLinear().domain([0, d3.max(data)]).range([200, 0]);
svg.selectAll('rect')
.data(data)
.join('rect')
.attr('x', (_, i) => x(i))
.attr('y', d => y(d))
.attr('width', x.bandwidth())
.attr('height', d => 200 - y(d))
.attr('fill', 'steelblue');
对比 ECharts 一个 bar chart ~5 行:
const chart = echarts.init(document.getElementById('chart'));
chart.setOption({xAxis: { type: 'category', data: ['A','B','C','D','E'] },
yAxis: {type: 'value'},
series: [{data: [30, 50, 80, 40, 60], type: 'bar' }]
});
D3 vs Observable Plot vs Chart.js:抽象层对比
| 维度 | D3 | Observable Plot | Chart.js / ECharts |
|---|---|---|---|
| 抽象层 | low(底层原语) | mid(grammar of graphics) | high(chart presets) |
| Bar chart 行数 | ~30 行 | ~5 行 | ~10 行 |
| 学习曲线 | 陡 | 中 | 缓 |
| Customization ceiling | unlimited | high | bounded by config |
| 适合 | 创新 viz / 数据新闻 | 探索性分析 + 标准 | 仪表盘 / 快速图表 |
核心差异:
- D3 给你最大自由度(你能做出 NYT Graphics 那种级别的 viz)
- ECharts 给你最大效率(chart preset 写起来快)
- Observable Plot 是中间路线:“D3 with less code”,同团队(Mike Bostock)出品
三、6 大核心模块 + 32 个 sub-modules 生态
D3 的设计哲学:modular by design。主仓 d3/d3 只是 meta-package,依赖 32 个独立 sub-modules,每个都可单独 npm install。
6 大核心模块(按重要度)
| 模块 | GitHub Stars | 最后更新 | 状态 | 用途 |
|---|---|---|---|---|
| d3-selection | 572 | 2025-01-03 | ✅ 活跃 | DOM 选择 + 数据绑定 |
| d3-scale | 1,617 | 2026-02-23 | ✅ 活跃 | 比例尺(linear / log / ordinal / time / band) |
| d3-shape | 2,527 | 2023-10-06 | ⚠️ 2 年没更新 | SVG 路径生成(line / area / arc / pie) |
| d3-force | 2,000 | 2023-12-30 | ⚠️ 2.5 年没更新 | 力导向图布局 |
| d3-geo | 1,097 | 2024-06-28 | ⚠️ NOASSERTION ⚠️ | 地理投影(Mapbox 风格地图) |
| d3-time | 238 | 2024-06-03 | ⚠️ | 时间格式 + interval |
完整 32 个模块(d3/d3 v7.9.0 package.json 列举)
d3-array 数据结构(max/extent/group/rollup)d3-axis 坐标轴生成器
d3-brush 区域选择(拖拽刷选)d3-chord 弦图
d3-color 颜色空间转换
d3-contour 等高线 + density estimation
d3-delaunay Delaunay triangulation(Voronoi)d3-dispatch 事件分发
d3-drag 拖拽行为
d3-dsv CSV / TSV 解析
d3-ease 缓动函数
d3-fetch fetch 封装
d3-format 数字格式化(千分位 / 精度 / SI prefix)d3-hierarchy 层次结构(tree / treemap / pack)d3-interpolate 数值插值
d3-path Canvas 路径(d3-shape 依赖)d3-polygon 多边形操作
d3-quadtree 四叉树(碰撞检测)d3-random 随机数生成
d3-scale-chromatic 色板(viridis / cividis / inferno)d3-timer requestAnimationFrame 封装
d3-transition 过渡动画
d3-zoom 缩放 + 平移
6 大子生态
| 子生态 | 代表项目 | 简介 |
|---|---|---|
| Plot 类 | Observable Plot | 同团队的高层 grammar of graphics |
| 框架绑定 | Recharts / Visx / Nivo | React 生态用 D3 的 scale / shape |
| Chart 库 | Chart.js / ECharts / Plotly | 高层封装,跟 D3 是平级 |
| 国内生态 | AntV G2 / G6 | G2 API 设计受 D3 启发 |
| 声明式 grammar | Vega-Lite / Vega | JSON 描述 viz,底层编译到 SVG |
| 图表协作平台 | Observable / Datawrapper / Flourish | 基于 D3 的 SaaS 产品 |
四、D3 vs Observable Plot vs ECharts vs AntV vs Plotly 五大对比
10 维对比表
| 维度 | D3.js | Observable Plot | Apache ECharts | AntV G2/G6 | Plotly |
|---|---|---|---|---|---|
| License | ISC ✅ | ISC ✅ | Apache-2.0 ✅ | MIT ✅ | MIT ✅ |
| Stars | 113K ⭐ | 5.4K ⭐ | 67K ⭐ | 12K ⭐ | 17K ⭐ |
| 抽象层 | low(底层原语) | mid(grammar) | high(chart preset) | mid-high | mid-high |
| 渲染目标 | SVG / Canvas / HTML | SVG | Canvas + SVG | SVG / Canvas | SVG |
| 学习曲线 | 陡 | 中 | 中 | 中 | 中 |
| Bar chart 行数 | ~30 | ~5 | ~10 | ~10 | ~15 |
| 维护状态 | ⚠️ 维护期 | ✅ 活跃(2026-05 commit) | ✅ 活跃 | ✅ 活跃 | ✅ 活跃 |
| 业务场景 | 创新 viz | 探索性分析 | 仪表盘 | 国内 BI | 科学计算 |
| 作者 | Mike Bostock | 同团队 | 百度 | 蚂蚁 | Plotly 商业 |
| 适合人群 | viz 极客 | 探索性分析师 | dashboard 开发者 | 国内生态 | Python 数据科学 |
核心差异
1️⃣ D3 是底层原语,其他都是 chart 库
- D3 给底层原语(scale + shape + selection),你自己组装
- ECharts / Plotly 给 chart preset(写 setOption 即可)
- Observable Plot 是中间路线 :grammar of graphics 风格(声明式 marks + scales), 底层用 D3 实现
2️⃣ D3 影响所有现代可视化库
不是吹 —— 这是事实:
- Recharts = React + d3-scale + d3-shape
- Visx = Airbnb 出品 + d3-scale + d3-shape + React
- Nivo = React + d3 高层封装
- AntV G2 = 国内 D3-style API
- Vega-Lite 编译产物底层用 D3
- Observable Plot = D3 同团队
- Superset / Metabase 内部图表组件用 D3
学 D3 = 学 viz 领域的 ” 汇编语言 ”。其他高层库都是 ” 高级语言 ”。
3️⃣ D3 vs Observable Plot:Mike Bostock 的 ” 两步走 ”
- D3 (2011-):底层原语,给前端工程师
- Observable Plot (2020-):高层声明式 grammar of graphics,给分析师
Observable Plot 是 D3 之上的 ” 小兄弟 ”,由同一个团队维护 。如果你的痛点是 ”D3 写起来太啰嗦,但 ECharts / Plotly 太死板 ” → 用 Observable Plot。
4️⃣ D3 vs ECharts 业务决策
- D3 适合:创新 viz / 数据新闻 / 学术 / viz 库开发
- ECharts 适合:dashboard / 国内中后台 / 快速交付
- Plotly 适合:Python 数据科学 / Jupyter / 学术论文
五、35 分钟实战:D3 写第一个交互式 bar chart
Step 1:HTML 容器(3 分钟)
<!DOCTYPE html>
<html>
<head><title>D3 bar chart</title></head>
<body>
<div id="chart"></div>
<script type="module" src="./main.js"></script>
</body>
</html>
Step 2:引入 D3(3 分钟)
npm install d3
# 或者直接 CDN
# import * as d3 from 'https://cdn.jsdelivr.net/npm/d3@7/+esm';
Step 3:D3 三段式写 bar chart(15 分钟)
// main.js
import * as d3 from 'd3';
const data = [{ name: 'A', value: 30},
{name: 'B', value: 50},
{name: 'C', value: 80},
{name: 'D', value: 40},
{name: 'E', value: 60}
];
const margin = {top: 20, right: 30, bottom: 40, left: 50};
const width = 600 - margin.left - margin.right;
const height = 400 - margin.top - margin.bottom;
const svg = d3.select('#chart')
.append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);
// X 轴 scale
const x = d3.scaleBand()
.domain(data.map(d => d.name))
.range([0, width])
.padding(0.1);
// Y 轴 scale
const y = d3.scaleLinear()
.domain([0, d3.max(data, d => d.value)])
.nice()
.range([height, 0]);
// X 轴
svg.append('g')
.attr('transform', `translate(0,${height})`)
.call(d3.axisBottom(x));
// Y 轴
svg.append('g')
.call(d3.axisLeft(y));
// Bars(数据 join 的三段式:enter / update / exit)svg.selectAll('.bar')
.data(data)
.join('rect')
.attr('class', 'bar')
.attr('x', d => x(d.name))
.attr('y', d => y(d.value))
.attr('width', x.bandwidth())
.attr('height', d => height - y(d.value))
.attr('fill', 'steelblue')
.attr('rx', 4)
.on('mouseover', function() {d3.select(this).attr('fill', 'orange'); })
.on('mouseout', function() {d3.select(this).attr('fill', 'steelblue'); });
Step 4:加 transition(7 分钟)
// 加 enter transition
svg.selectAll('.bar')
.data(data)
.join(enter => enter.append('rect')
.attr('class', 'bar')
.attr('x', d => x(d.name))
.attr('y', height) // 从底部进入
.attr('width', x.bandwidth())
.attr('height', 0)
.attr('fill', 'steelblue')
.attr('rx', 4)
.call(enter => enter.transition().duration(750)
.attr('y', d => y(d.value))
.attr('height', d => height - y(d.value))),
update => update.transition().duration(750)
.attr('y', d => y(d.value))
.attr('height', d => height - y(d.value))
);
Step 5:在 React 项目里用 D3(7 分钟)
D3 操作 DOM,React 也操作 DOM,两者会 ” 打架 ”。关键原则:D3 管计算,React 管渲染。
import {useEffect, useRef} from 'react';
import * as d3 from 'd3';
function D3BarChart({data}) {const ref = useRef();
useEffect(() => {const svg = d3.select(ref.current);
const x = d3.scaleBand().domain(data.map(d => d.name)).range([0, 400]).padding(0.1);
const y = d3.scaleLinear().domain([0, d3.max(data, d => d.value)]).range([200, 0]);
svg.selectAll('rect')
.data(data)
.join('rect')
.attr('x', (_, i) => x(data[i].name))
.attr('y', d => y(d.value))
.attr('width', x.bandwidth())
.attr('height', d => 200 - y(d.value))
.attr('fill', 'steelblue');
}, [data]);
return <svg ref={ref} width={400} height={200} />;
}
六、4 大风险(critical 视角)
D3 是个 11 万 stars 的超级明星项目,但数据告诉我们它正在 进入维护期。
⚠️ 风险 1:v7.9.0 之后 2 年半没正式 release
GitHub tags 显示 最新 tag 还是 v7.9.0 (2024-03-12)。距离 2026-08 已经 2 年 5 个月。
Web 上有一些 ”D3 v8 已经发布 ” 的说法,但 GitHub 上根本找不到 v8 tag。可能 Mike Bostock 跳过了 v8 直接做 Observable Plot。
⚠️ 风险 2:OpenSSF Maintained 0/10
OpenSSF Scorecard 4.5/10 评分里,“Maintained 0/10” 是最大失分项:
“0 commit(s) and 1 issue activity found in the last 90 days”(2026-03-09 数据)
实际 commits 还有(最近 2026-05-28),但都是 docs / links fix:
ca958d45 2026-05-28 docs: Incorrect alt text copied from the Observable Framewor
42ccb63d 2025-12-02 fix broken link (#4084)
66bfe8c6 2025-07-27 Fix external edge bundling references (#4039)
没有任何 feature commit。
⚠️ 风险 3:sub-modules 失活严重
| 模块 | 最后更新 | 距今 |
|---|---|---|
| d3-shape | 2023-10-06 | 2 年 |
| d3-force | 2023-12-30 | 2.5 年 |
| d3-geo | 2024-06-28 | 1.2 年 + NOASSERTION ⚠️ |
d3-shape 是 SVG 路径生成的核心(line / area / arc / pie 都靠它),2 年没更新是个信号。
⚠️ 风险 4:Mike Bostock 精力转向 Observable Plot / Observable Framework
- Observable Plot (2020-): 5,361 ⭐ / 2026-05-16 commit 还在活跃
- Observable Framework: 静态站点生成器 / Mike Bostock 新作
D3 本体不再是作者精力中心。
✅ 但是:D3 护城河极深
- 113K stars / 22K forks = 生态护城河
- ISC 许可 = 完全商业可用
- Superset / Metabase / Plotly / Observable Plot 都用 D3 = 持续维护
- 15 年生产验证 = 不会 ” 突然消失 ”
结论 :D3 不会死, 但增长曲线已经平,未来创新点在 Observable Plot 和其他高层库。
七、总结
3 个最值得学 D3 的理由
1️⃣ D3 是可视化领域的 ” 汇编语言 ”
学了 D3 理解底层原理(selection + scale + shape + data join),其他高层库(ECharts / Plotly / Observable Plot / Recharts / Visx / Nivo / AntV)都是 ” 高级语言 ”。
2️⃣ D3 是 viz 创新的天花板
- NYT Graphics(数据新闻)几乎都是 D3 做的
- Observable 平台(Mike Bostock 现在的工作)的复杂 viz 几乎都是 D3
- 数据新闻 / 可视化艺术作品 / 学术 viz → 终极方案都是 D3
3️⃣ D3 生态护城河深
- 113K stars / 22K forks
- 32 个 sub-modules / ISC 许可
- Superset / Metabase / Plotly 等都在底层用 D3
- 就算作者停更,社区也能维护
适合用 D3 的场景
- ✅ 自定义 / 创新可视化(bespoke viz)
- ✅ 数据新闻(NYT / The Pudding 风格)
- ✅ 可视化库开发(Recharts / Visx 作者都精通 D3)
- ✅ 科研 / 学术创新 viz
- ✅ 想 ” 看穿 ” 可视化底层原理
不适合用 D3 的场景
- ❌ 快速 dashboard(用 ECharts / Chart.js / Recharts)
- ❌ 探索性数据分析(用 Observable Plot / Vega-Lite)
- ❌ React 业务页面图表(用 Recharts / Visx / Nivo)
- ❌ 国内中后台(用 ECharts / AntV)
先试一周
| Day | 任务 |
|---|---|
| 1 | 跑通 d3-scale + d3-selection 基础示例(官方 first-steps) |
| 2-3 | 写一个 interactive bar chart with transitions |
| 4-5 | 加 d3-axis + d3-shape 做组合图(line + bar) |
| 6-7 | 把 D3 嵌入 React 组件(用 useRef + useEffect) |
如果一周后你能手写 selectAll().data().join() 三段式 + 解释 enter / update / exit,D3 就入门了。
参考
- d3/d3 GitHub —— 主仓 113K ⭐
- observablehq/plot GitHub —— 同团队新作 5.4K ⭐
- D3 官网 —— 官方文档 + examples
- D3 v7.9.0 README —— 最新 release
- Observable Plot 官网 —— 高级 grammar of graphics
- Mike Bostock 个人网站 —— 作者主页
- D3 package.json 32 个 sub-modules —— 完整依赖列表
- Hivebook Wiki · D3.js 词条 —— 2026 综述
- Visx 文档(”Visx = d3 + React”) —— D3 在 React 生态的应用
- AntV G2 文档 —— 国内 D3-style API
- OpenSSF Scorecard d3/d3 —— 4.5/10 数据来源
- Apache ECharts 调研 —— 上一篇文章,67K ⭐ 高层 chart 库
- AntV 调研 —— 上一篇文章,12K ⭐ 国内生态
- Plotly 调研 —— Python 数据科学可视化
📎 WordPress 链接
- 官方链接:《D3.js 调研:113K stars 的可视化鼻祖怎么被 Observable Plot 接班了,Mike Bostock 的 15 年传奇》
- 短链:
https://east196.cn/?p=426 - WordPress API ID:426
- 状态:published · 2026-08-29