D3.js 简介 #
什么是数据可视化? #
数据可视化是将数据转换为图形或图像的过程,使人们能够更直观地理解数据中的模式、趋势和关系。好的数据可视化能够将复杂的数据转化为易于理解的视觉形式。
text
┌─────────────────┐
│ 原始数据 │
│ [1, 2, 3...] │
└────────┬────────┘
│
▼
┌─────────────────┐
│ 数据可视化 │
│ D3.js 处理 │
└────────┬────────┘
│
▼
┌─────────────────┐
│ 视觉呈现 │
│ 图表、图形 │
└─────────────────┘
什么是 D3.js? #
D3.js(Data-Driven Documents,数据驱动文档)是一个用于创建动态、交互式数据可视化的 JavaScript 库。它由 Mike Bostock 于 2011 年创建,是目前最流行、最强大的数据可视化库之一。
核心定位 #
text
┌─────────────────────────────────────────────────────────────┐
│ D3.js │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 数据绑定 │ │ 选择器 │ │ 过渡动画 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 比例尺 │ │ 形状生成 │ │ 布局算法 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
D3.js 的历史 #
发展历程 #
text
2011年 ─── D3.js 诞生
│
│ Mike Bostock 创建
│ Stanford Vis Group
│ 取代 Protovis
│
2012年 ─── D3.js 2.0
│
│ 更多布局算法
│ 地理可视化支持
│
2013年 ─── D3.js 3.0
│
│ 性能优化
│ 更好的动画系统
│
2016年 ─── D3.js 4.0
│
│ 模块化重构
│ ES6 模块支持
│
2018年 ─── D3.js 5.0
│
│ Promise 支持
│ 改进的数据加载
│
2021年 ─── D3.js 7.0
│
│ 现代化重构
│ 更好的 TypeScript 支持
│
至今 ─── 行业标准
│
│ 最流行的可视化库
│ 丰富的生态系统
里程碑版本 #
| 版本 | 时间 | 重要特性 |
|---|---|---|
| 1.0 | 2011 | 初始发布,核心选择器 |
| 2.0 | 2012 | 地理可视化、布局 |
| 3.0 | 2013 | 性能优化、动画改进 |
| 4.0 | 2016 | 模块化架构 |
| 5.0 | 2018 | Promise、fetch 支持 |
| 6.0 | 2020 | 事件系统重构 |
| 7.0 | 2021 | ES 模块、TypeScript |
为什么选择 D3.js? #
传统图表库的局限 #
在使用 D3.js 之前,数据可视化面临以下问题:
javascript
// 传统图表库:预设图表类型,定制困难
const chart = new Chart(ctx, {
type: 'bar',
data: { /* ... */ },
options: { /* 有限的配置选项 */ }
});
D3.js 的解决方案 #
javascript
// D3.js:完全控制,无限可能
d3.select('svg')
.selectAll('rect')
.data(data)
.join('rect')
.attr('x', d => xScale(d.category))
.attr('y', d => yScale(d.value))
.attr('width', xScale.bandwidth())
.attr('height', d => height - yScale(d.value))
.attr('fill', 'steelblue');
D3.js 的核心特点 #
1. 数据驱动 #
D3.js 的核心理念是数据驱动文档:
javascript
const data = [10, 20, 30, 40, 50];
d3.select('body')
.selectAll('div')
.data(data)
.enter()
.append('div')
.style('width', d => d * 5 + 'px')
.text(d => d);
2. 强大的选择器 #
类似 jQuery 的选择器,但更强大:
javascript
d3.select('#chart') // 选择单个元素
.selectAll('.bar') // 选择多个元素
.attr('class', 'active') // 设置属性
.style('color', 'red'); // 设置样式
3. 灵活的过渡动画 #
创建流畅的动画效果:
javascript
d3.selectAll('circle')
.transition()
.duration(1000)
.ease(d3.easeBounce)
.attr('r', 10)
.attr('fill', 'orange');
4. 丰富的比例尺 #
将数据映射到可视空间:
javascript
const xScale = d3.scaleLinear()
.domain([0, 100]) // 数据范围
.range([0, 500]); // 像素范围
xScale(50); // 250
5. 多种布局算法 #
自动计算复杂图形的位置:
javascript
const simulation = d3.forceSimulation(nodes)
.force('link', d3.forceLink(links))
.force('charge', d3.forceManyBody())
.force('center', d3.forceCenter(width/2, height/2));
6. 地理可视化 #
强大的地图可视化能力:
javascript
const projection = d3.geoMercator()
.scale(150)
.translate([width/2, height/2]);
const path = d3.geoPath().projection(projection);
D3.js 与其他可视化库对比 #
D3.js vs Chart.js #
| 特性 | D3.js | Chart.js |
|---|---|---|
| 灵活性 | 极高 | 中等 |
| 学习曲线 | 陡峭 | 平缓 |
| 图表类型 | 无限 | 预设类型 |
| 自定义 | 完全控制 | 配置选项 |
| 动画 | 强大 | 基础 |
| 适用场景 | 专业可视化 | 快速图表 |
D3.js vs ECharts #
| 特性 | D3.js | ECharts |
|---|---|---|
| 设计理念 | 底层构建 | 配置驱动 |
| 灵活性 | 极高 | 高 |
| 中文文档 | 社区翻译 | 官方中文 |
| 图表丰富度 | 自定义 | 预设丰富 |
| 学习成本 | 高 | 中 |
| 适用场景 | 定制可视化 | 企业报表 |
D3.js vs Highcharts #
| 特性 | D3.js | Highcharts |
|---|---|---|
| 开源免费 | ✅ 完全免费 | ⚠️ 商业收费 |
| 灵活性 | 极高 | 中等 |
| 图表类型 | 自定义 | 预设丰富 |
| 技术支持 | 社区 | 商业支持 |
| 学习曲线 | 陡峭 | 平缓 |
| 适用场景 | 专业项目 | 商业项目 |
D3.js 的应用场景 #
1. 数据新闻 #
javascript
// 交互式新闻报道图表
const timeline = d3.select('#timeline')
.selectAll('.event')
.data(events)
.enter()
.append('div')
.classed('event', true)
.on('click', showDetails);
2. 商业仪表板 #
javascript
// 实时数据仪表板
function updateDashboard(data) {
const bars = svg.selectAll('.bar')
.data(data, d => d.id);
bars.enter()
.append('rect')
.merge(bars)
.transition()
.attr('height', d => yScale(d.value));
bars.exit().remove();
}
3. 科学可视化 #
javascript
// 科学数据可视化
const line = d3.line()
.x(d => xScale(d.time))
.y(d => yScale(d.measurement))
.curve(d3.curveMonotoneX);
svg.append('path')
.datum(data)
.attr('d', line);
4. 地理信息可视化 #
javascript
// 地图可视化
svg.selectAll('path')
.data(geojson.features)
.enter()
.append('path')
.attr('d', path)
.attr('fill', d => colorScale(d.properties.value));
5. 网络关系图 #
javascript
// 力导向图
const simulation = d3.forceSimulation()
.force('link', d3.forceLink())
.force('charge', d3.forceManyBody())
.force('center', d3.forceCenter());
simulation.on('tick', () => {
link.attr('x1', d => d.source.x);
node.attr('cx', d => d.x);
});
D3.js 的核心概念 #
选择器(Selection) #
javascript
d3.select('body') // 选择 body 元素
d3.selectAll('p') // 选择所有段落
d3.select('#chart') // 选择 ID
d3.selectAll('.bar') // 选择类名
数据绑定(Data Binding) #
javascript
const update = svg.selectAll('circle')
.data(data);
update.enter() // 新数据
update.exit() // 多余元素
update // 已有元素
比例尺(Scales) #
javascript
d3.scaleLinear() // 线性比例尺
d3.scaleBand() // 序数比例尺
d3.scaleTime() // 时间比例尺
d3.scaleOrdinal() // 离散比例尺
形状(Shapes) #
javascript
d3.line() // 线生成器
d3.area() // 区域生成器
d3.arc() // 弧生成器
d3.pie() // 饼图生成器
D3.js 的设计哲学 #
1. 数据驱动 #
javascript
// 数据决定一切
const circles = svg.selectAll('circle')
.data(data)
.join('circle')
.attr('cx', d => d.x)
.attr('cy', d => d.y
最后更新:2026-03-28