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