D3.js logo

D3.js

数据驱动文档(Data-Driven Documents)的底层可视化库,用于将数据与 DOM 绑定,基于 SVG、Canvas 和 HTML 创造强大的交互式数据可视化。

精选工具可视化图表数据驱动SVG

D3.js 是 GitHub 星标最高(113k+)的数据可视化库,通过将数据与 DOM 绑定,基于 SVG、Canvas 和 HTML 创造强大的交互式可视化,提供比例尺、布局、形状生成器等完整工具集,灵活性无与伦比。

D3.js

数据驱动文档(Data-Driven Documents)的底层可视化库,用于将数据与 DOM 绑定,基于 SVG、Canvas 和 HTML 创造强大的交互式数据可视化。

技术简介说明

D3.js 全称为 Data-Driven Documents,由 Mike Bostock 于 2011 年在斯坦福大学可视化设计期间创造,是目前 GitHub 上星标最多(113,000+)的数据可视化库。它的核心理念是将数据与 DOM 元素通过声明式绑定(data binding)直接关联,让开发者能够以数据驱动的方式操作文档结构,生成高度定制化的可视化效果。

与大多数开箱即用的高层图表库不同,D3 是一个"元库"(meta-library)——它不提供预设的图表类型,而是提供一套完整的工具集:选择集(selection)、比例尺(scale)、形状生成器(shape generator)、力导向布局(force layout)、地理投影(geo projection)等。开发者通过这些基础模块自由组合,构建任何可以想象的可视化形式。这种底层设计赋予了 D3 无与伦比的灵活性,同时也带来了较高的学习曲线。

自 v6 起,D3 全面转向 ES Modules(ESM),v7 更是要求 Node.js 12+ 并以纯 ESM 形式发布。D3 由 Observable 团队维护,官网品牌为"D3 by Observable",与 Observable Plot(高层快速绘图 API)形成互补:Plot 处理常见图表的快速生成,D3 负责定制化和复杂可视化场景。

基本信息

  • 官网:https://d3js.org/
  • GitHub:https://github.com/d3/d3
  • License:ISC(与 MIT 等效的宽松许可)
  • 最新版本:v7.9.0(2024 年 3 月发布)
  • 主要维护者/公司:Mike Bostock / Observable, Inc.
  • GitHub Stars:~113,000+(2026 年 6 月数据,数据可视化库中最高)
  • npm 周下载量:~1,470 万(主包 d3)+ 各子模块单独下载量极高(d3-array 日均约 1,150 万次)

快速上手

安装

# 使用 npm 安装完整 D3 包
npm install d3
 
# 或使用 yarn
yarn add d3
 
# 或使用 pnpm
pnpm add d3
 
# 按需安装单个子模块(推荐用于 tree-shaking)
npm install d3-selection d3-scale d3-shape
 
# CDN 方式引入(UMD 全局变量)
<script src="https://cdn.jsdelivr.net/npm/d3@7"></script>
 
# ES Module 方式(推荐)
<script type="module">
  import * as d3 from "https://cdn.jsdelivr.net/npm/d3@7/+esm";
</script>

基础配置

D3 v7 是纯 ES Module 库,在构建工具中无需额外配置。对于 Vite / Rollup / webpack 5+ 等现代构建工具,直接 import 即可:

// 完整导入
import * as d3 from 'd3'
 
// 按需导入(减小 bundle 体积)
import { select, selectAll } from 'd3-selection'
import { scaleLinear } from 'd3-scale'
import { line, arc } from 'd3-shape'

TypeScript 类型支持:D3 自带 .d.ts 类型声明,无需额外安装 @types/d3

最小示例

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>D3 最小示例</title>
  <style>
    bar { background: steelblue; }
  </style>
</head>
<body>
  <div id="chart"></div>
  <script type="module">
    import * as d3 from 'https://cdn.jsdelivr.net/npm/d3@7/+esm'
 
    const data = [30, 86, 168, 281, 303, 365]
 
    const x = d3.scaleLinear()
      .domain([0, d3.max(data)])
      .range([0, 420])
 
    d3.select('#chart')
      .selectAll('div')
      .data(data)
      .join('div')
        .style('width', d => `${x(d)}px`)
        .text((d, i) => i)
  </script>
</body>
</html>

核心概念与架构

模块化架构

D3 采用高度模块化的架构,由 30+ 个独立的 ES 子模块组成,每个模块职责单一、可独立使用:

d3(完整包)
├── d3-selection      — DOM 选择集与数据绑定(核心)
├── d3-transition     — 基于选择集的动画过渡
├── d3-scale          — 比例尺:线性、序数、时间、对数等
├── d3-scale-chromatic — 颜色方案与插值器
├── d3-shape          — 形状生成器:线、弧、面积等
├── d3-array          — 数组统计与操作工具
├── d3-axis           — 坐标轴组件
├── d3-color          — 颜色空间(RGB、HSL、Lab 等)
├── d3-interpolate    — 值插值(数字、颜色、对象)
├── d3-time           — 时间计算工具
├── d3-time-format    — 时间格式化与解析
├── d3-format         — 数字格式化
├── d3-quadtree       — 四叉树空间索引
├── d3-geo            — 地理投影与球面几何
├── d3-path           — SVG Path 序列化
├── d3-polygon        — 多边形几何工具
├── d3-random         — 随机数生成器
├── d3-force          — 力导向模拟布局
├── d3-hierarchy      — 层次数据结构(树、集群、打包等)
├── d3-contour        — 等值线/密度等高线
├── d3-delaunay       — Delaunay 三角剖分 / Voronoi 图
├── d3-chord          — 弦图布局
├── d3-sankey         — 桑基图布局(第三方扩展)
├── d3-zoom           — 缩放与平移交互
├── d3-drag           — 拖拽交互
├── d3-brush          — 框选交互
├── d3-fetch          — 数据加载(CSV、JSON、XML 等)
├── d3-timer          — 高效定时器(requestAnimationFrame 封装)
└── d3-dispatch       — 事件分发系统

核心工作原理

1. 选择集(Selection) D3 的核心是选择集机制,通过 CSS 选择器选中 DOM 元素并赋予数据绑定能力:

const circles = svg.selectAll('circle')
  .data(dataset)        // 数据绑定
  .join('circle')       // enter + update + exit 一体化
    .attr('r', d => d.value)
    .attr('fill', 'steelblue')

2. Enter-Update-Exit 模式 这是 D3 最核心的数据驱动范式。当数据与 DOM 绑定时:

  • Enter:数据多于 DOM 元素 → 创建新元素
  • Update:数据与已有元素对应 → 更新属性
  • Exit:DOM 元素多于数据 → 移除多余元素

selection.join() 是 v5+ 推荐的简化写法,内部自动处理 enter/update/exit。

3. 比例尺(Scale) 比例尺是数据域(domain)到视觉范围(range)的映射函数,是连接数据与视觉的桥梁:

// 线性比例尺
const x = d3.scaleLinear()
  .domain([0, 100])    // 数据域
  .range([0, 500])     // 像素范围
 
x(50)  // → 250

4. 渲染无关性 D3 的形状生成器、比例尺、统计函数等都是纯计算函数,不直接操作 DOM。这意味着它们可以与 SVG、Canvas、WebGL 甚至服务器端渲染配合使用。

核心特性

  • 无与伦比的灵活性:D3 不提供预设图表,而是提供构建任何可视化所需的基础工具,适合完全定制化的视觉设计
  • 数据驱动 DOM 操作:通过选择集和数据绑定,以声明式方式将数据映射到 DOM 属性,天然适合响应式数据变化
  • 模块化与 Tree-shaking:30+ 独立子模块可按需导入,现代构建工具可自动剔除未使用代码
  • 丰富的数学与统计工具:内置数组统计、随机数生成、几何计算、力导向模拟等,是数据处理和可视化的瑞士军刀
  • 完整的交互系统:内置 zoom(缩放)、drag(拖拽)、brush(框选)等交互行为,可组合出复杂的交互可视化
  • SVG + Canvas + HTML 多渲染目标:同一套数据逻辑可输出到 SVG(DOM 可访问)、Canvas(高性能)或 HTML 元素
  • 地理可视化支持:d3-geo 提供完整的地图投影系统,支持 TopoJSON/GeoJSON,可绘制复杂的世界地图和地理热力图
  • 力导向布局:d3-force 提供物理模拟引擎,适合节点-链接图、网络图、气泡图等
  • 层次数据布局:d3-hierarchy 支持树图、treemap、sunburst、circle-packing 等多种层次数据可视化
  • 活跃且庞大的社区:113K+ GitHub Stars,Observable 平台上有大量公开的 D3 可视化作品可供学习

生态图

关键依赖

D3 本身是零依赖的纯 JavaScript 库,仅依赖原生 Web API(DOM、Canvas、SVG)。各子模块之间的依赖关系是明确的,例如:

  • d3-axis 依赖 d3-selectiond3-scaled3-format
  • d3-shape 依赖 d3-path
  • d3-transition 依赖 d3-selectiond3-interpolated3-timer

上层封装库

由于 D3 学习曲线陡峭,社区衍生出大量基于 D3 的高层封装库:

库名定位说明
Observable Plot高层快速绘图D3 官方团队开发,声明式 API,快速生成分布图、折线图、热力图等
Vega / Vega-Lite声明式可视化语法用 JSON 语法描述可视化,底层可用 D3 渲染
NivoReact 图表库基于 D3 的 React 图表组件集,提供丰富的预设图表类型
VictoryReact/Victory 图表Formidable 开发,D3 驱动,支持 React 和 React Native
RechartsReact 图表库基于 D3 的声明式 React 图表,API 简洁
C3.jsD3 预设图表可复用的 D3 图表组件,API 类似 Highcharts
** Billboard.js**C3.js 继任者C3.js 的社区分支,更活跃的维护和更新
d3-tip工具提示D3 专用的 tooltip 扩展库
d3-scale-chromatic颜色方案包含所有 ColorBrewer 和 viridis 颜色方案

社区生态

  • ObservableHQ:D3 作者 Mike Bostock 创建的交互式数据科学平台,是学习和分享 D3 可视化的首选平台
  • Block Builder:社区用户构建的 D3 可视化画廊(bl.ocks.org 遗产)
  • D3 Graph Gallery:法国统计师 Yan Holtz 维护的 D3 图表示例库
  • d3-gallery(GitHub):社区收集的 D3 可视化案例
  • R/Python 集成:通过 htmlwidgets 或 IPython 嵌入,D3 可在 R Markdown 和 Jupyter 中使用

适用场景

  • 高度定制化数据可视化:当标准图表库无法满足独特的视觉设计需求时,D3 是唯一能提供完全控制力的选择。适合品牌定制可视化、艺术化数据展示。
  • 交互式探索仪表板:结合 zoom、brush、drag 等交互原语,D3 可以构建支持缩放、框选、联动的高交互数据探索界面,适合数据分析师和科研人员。
  • 复杂网络图与关系图:利用 d3-force 力导向布局,适合构建社交网络图、知识图谱、组织架构、依赖关系图等节点-链接型可视化。
  • 地理信息系统(GIS)可视化:d3-geo 模块提供完整的地图投影系统,支持 TopoJSON/GeoJSON 数据格式,适合构建自定义地图、热力地图、航线图等。
  • 层次数据可视化:d3-hierarchy 支持 treemap、sunburst、circle-packing 等,适合展示文件目录、组织结构、分类体系等层次数据。
  • 数据新闻与信息图:纽约时报、The Pudding 等数据新闻机构的标志性可视化作品大多基于 D3,适合讲述数据故事的复杂信息图。
  • 科学研究与数据探索:在 Observable 笔记本中,D3 是科学计算和数据探索的标准工具,适合快速实验性可视化。

开发与工程化

开发流程

# 克隆 D3 源码(用于开发或贡献)
git clone https://github.com/d3/d3.git
cd d3
 
# 安装依赖
pnpm install
 
# 运行测试
pnpm test
 
# 构建
pnpm rollup -c

在 React / Vue / Svelte 中使用

D3 操作 DOM 的方式与 React/Vue 的虚拟 DOM 冲突,需要小心集成:

React 集成策略

// 方式一:仅使用 D3 的计算模块,React 负责渲染
import { scaleLinear } from 'd3-scale'
import { line } from 'd3-shape'
 
function LineChart({ data, width, height }) {
  const x = scaleLinear().domain([0, 100]).range([0, width])
  const y = scaleLinear().domain([0, 100]).range([height, 0])
  const path = line().x(d => x(d.x)).y(d => y(d.y))(data)
  return <svg><path d={path} /></svg>
}
 
// 方式二:使用 ref 让 D3 直接操作特定 DOM 子树
function ForceGraph({ nodes }) {
  const svgRef = useRef()
  useEffect(() => {
    const svg = d3.select(svgRef.current)
    // ... D3 操作
  }, [nodes])
  return <svg ref={svgRef} />
}

Vue 集成策略:类似 React,优先使用 D3 的纯计算模块(scale、shape、array),在 onMounted 中用 useRefref 获取 DOM 节点供 D3 操作。

Svelte 集成:Svelte 与 D3 的兼容性最好——Svelte 直接操作 DOM,与 D3 的选择集理念一致。

构建与部署

  • D3 子模块均发布在 npm,构建工具(Vite / webpack / Rollup)原生支持
  • 纯 ESM 发布,不支持 CommonJS require(v7+),需要 async import 或构建工具转换
  • CDN 部署:https://cdn.jsdelivr.net/npm/d3@7https://unpkg.com/d3@7
  • 推荐按需导入子模块,避免全量打包

CI/CD 集成

D3 本身是纯客户端库,CI/CD 只需确保:

  • Node.js ≥ 12(v7 要求)
  • 单元测试使用 jsdom 或 happy-dom 提供 DOM 环境
  • 视觉回归测试使用 Playwright / Puppeteer 截图对比

性能与安全

性能特点

  • SVG 渲染:适合中小规模数据(< 1000 个元素),每个元素是独立 DOM 节点,可通过 CSS 样式控制,但大量元素时 DOM 操作开销大
  • Canvas 渲染:D3 支持 Canvas 渲染(通过 d3-path + Canvas API),适合大规模数据(10,000+ 点),性能远优于 SVG
  • d3-force 布局计算:力导向模拟的计算复杂度为 O(n²),节点数超过 1,000 时需使用四叉树近似(forceManyBody().theta())或 Web Worker
  • d3-delaunay:Delaunay 三角剖分性能极高,适合最近点查询和 Voronoi 交互区域划分
  • 内存使用:D3 本身内存占用低,但大量 SVG 元素会导致浏览器内存压力

优化建议

  • 数据量大时(> 1000 点),优先使用 Canvas 而非 SVG
  • 使用 d3-quadtree 进行空间索引,避免 O(n²) 的碰撞检测
  • 使用 Web Worker 进行 d3-force 布局的后台计算
  • 使用 requestAnimationFrame(d3-timer)控制渲染频率
  • 对静态元素使用 will-change: transform CSS 提示浏览器合成层优化
  • 使用 d3.zoomextentscaleExtent 限制缩放范围,避免极端缩放导致的渲染问题

安全注意事项

  • XSS 风险:使用 selection.html() 而非 selection.text() 时,若数据包含用户输入,可能导致 XSS 攻击。务必对用户输入进行转义
  • CDN 完整性:使用 CDN 引入 D3 时,应添加 SRI(Subresource Integrity)hash 防止供应链攻击
  • eval 风险:避免在 D3 代码中使用动态生成的函数体(如 new Function()

技术对比

D3.js vs Chart.js vs ECharts

对比维度D3.jsChart.jsApache ECharts
定位底层数据操作与可视化引擎简单易用的图表库功能丰富的商业级图表库
学习曲线陡峭(需理解选择集、比例尺、布局)平缓(配置式 API)中等(配置项多但有文档)
渲染方式SVG / Canvas / HTML 可选CanvasCanvas(大数据集)/ SVG
Bundle 大小全量 ~90KB gzipped,按需可至 ~10KB~65KB gzipped~400KB gzipped
灵活性极高(可创造任何可视化)低(仅限预设图表类型)中(丰富预设但难完全定制)
内置图表类型无(需手工构建)8 种(bar、line、pie 等)20+ 种
交互能力可完全自定义内置 tooltip、legend、zoom内置丰富交互
适用数据规模小到大(Canvas 模式)小到中中到大(百万级数据点)
React/Vue 集成需小心处理 DOM 冲突有官方 react-chartjs-2 等封装有 vue-echarts 等封装
GitHub Stars~113,000~67,000~62,000
npm 周下载量~1,470 万~240-1000 万~800 万

D3.js vs Observable Plot

对比维度D3.jsObservable Plot
定位底层工具集高层声明式图表 API
API 风格命令式、链式声明式、标记(mark)驱动
学习曲线陡峭平缓
适用场景完全定制化可视化快速 EDA 和标准图表
底层关系基于 D3 构建

最佳实践

生产环境最佳实践

1. 按需导入,控制 bundle 体积

// ❌ 避免全量导入
import * as d3 from 'd3'
 
// ✅ 按需导入子模块
import { scaleLinear, extent } from 'd3'
// 或更细粒度
import { scaleLinear } from 'd3-scale'
import { extent } from 'd3-array'

2. 使用 join() 替代手动 enter/update/exit

// ❌ 旧式写法
const circles = svg.selectAll('circle').data(data)
circles.enter().append('circle')
circles.exit().remove()
 
// ✅ 推荐写法
svg.selectAll('circle')
  .data(data)
  .join('circle')
    .attr('r', d => d.value)

3. 将比例尺和布局逻辑与渲染分离

// 纯计算逻辑可测试、可复用
const computeLayout = (data, width, height) => {
  const x = d3.scaleLinear().domain(d3.extent(data, d => d.x)).range([0, width])
  const y = d3.scaleLinear().domain(d3.extent(data, d => d.y)).range([height, 0])
  return { x, y }
}
 
// 渲染逻辑单独处理
const render = (svg, data, scales) => { ... }

4. 过渡动画使用 .transition() 但注意性能

// 少量元素可自由使用过渡
circles.transition().duration(750)
  .attr('r', d => d.value)
 
// 大量元素避免过渡,直接设置属性

5. 为 Canvas 渲染使用 d3-path

const path = d3.path()
d3.line().context(path)(data)
canvasContext.beginPath()
canvasContext.fillStyle = 'steelblue'
new Function(path)()  // 或直接使用 Path2D
canvasContext.fill()

常见陷阱

  • DOM 冲突:在 React/Vue 中使用 D3 时,避免让 D3 操作虚拟 DOM 管理的节点。使用 useRef / ref 隔离 D3 操作范围
  • 全量导入import * as d3 from 'd3' 会打包全部模块(~90KB gzipped),按需导入可减至 10-20KB
  • 内存泄漏:在 React useEffect 中创建的 D3 定时器、事件监听器需在清理函数中销毁
  • 比例尺域错误d3.scaleLinear() 的 domain 和 range 长度必须一致,否则行为未定义
  • force simulation 未停止d3.forceSimulation() 会持续运行,需在组件卸载时调用 simulation.stop()

技术局限与边界

已知限制

  • 学习曲线极陡峭:D3 的选择集、数据绑定、Enter-Update-Exit 模式需要时间掌握。新手通常需要数周才能产出复杂可视化
  • 不提供预设图表:D3 不会帮你画一个"柱状图"——你需要自己创建 SVG 元素、计算位置、绘制坐标轴。这意味着开发一个简单柱状图的代码量远大于 Chart.js
  • 纯 ESM 限制:v7 起不再支持 CommonJS require(),需要旧版 Node.js 或构建工具支持
  • SVG 性能天花板:大量 SVG 元素(> 1000)会导致浏览器重排/重绘缓慢,必须切换到 Canvas 渲染或使用 WebGL
  • 服务端渲染复杂:D3 深度依赖 DOM API,服务端渲染需要 jsdom 模拟完整 DOM 环境,性能和完整性受限
  • 移动端手势支持弱:D3 的 zoom/drag 基于 Pointer Events,移动端体验不如专门的触摸手势库
  • 无内置响应式:D3 不提供容器尺寸监听,需要手动使用 ResizeObserver 实现响应式图表
  • 调试困难:链式调用和函数式风格使错误栈难以追踪,初学者调试成本高

不适用场景

  • 简单的业务后台图表 → 使用 Chart.js 或 ECharts 更高效
  • 需要快速原型验证 → Observable Plot 或 ECharts 更合适
  • 团队可视化经验不足 → D3 学习投入产出比不划算
  • 需要实时流数据图表 → 考虑 uPlot、LightningChart 等专注实时场景的库
  • 大规模数据(> 100 万点)→ 考虑 WebGL 方案(deck.gl、regl)或专业库(LightningChart)

迁移注意事项

  • D3 v7 到未来 v8 可能的变化:ESM-only 已确立,关注 Node.js 最低版本要求
  • 从 D3 v6 迁移到 v7 的主要变化:d3.selection 的 iterables 支持改进,d3.force 的随机种子变化
  • 从 D3 v5 迁移到 v6+:Promise-based API(移除 d3-request),事件参数变化

学习资源

2026 年现状

版本与活跃度

  • 最新稳定版:v7.9.0(2024 年 3 月发布),v7 系列最后一次更新
  • GitHub Stars:~113,000+(2026 年 6 月),持续增长,是 GitHub 上星标最多的数据可视化库
  • 最后代码提交:2025 年 12 月(仓库活跃度正常,以依赖更新和小修复为主)
  • npm 周下载量:主包约 1,470 万次,各子模块合计更高

发展趋势

  • 维护状态:D3 进入稳定维护期,无重大功能版本计划。v8 尚无公开路线图
  • Observable Plot 互补:Observable 团队将更多新特性投入到 Observable Plot(高层 API),D3 核心库趋于稳定
  • 社区热度:D3 在 2025 JavaScript Rising Stars 中仍名列前茅,作为底层库的地位稳固
  • 生态扩展:d3-sankey、d3-hexbin 等社区扩展保持活跃;Observable 平台持续产出 D3 教程和示例
  • AI 集成:社区出现 AI 辅助生成 D3 代码的工具(如 Observable 的 AI 功能),降低学习门槛

未来展望

D3 作为数据可视化领域的基础设施,其地位在可预见的未来不会被动摇。虽然高层库(ECharts、Chart.js、Observable Plot)持续分流简单场景的用户,但在定制化、复杂可视化、数据新闻、科研探索等领域,D3 仍然是不可替代的首选工具。2026 年的 D3 生态以稳定为主,核心库保持低频更新,社区和上层库(Observable Plot)是主要创新阵地。