前言
数据可视化是前端开发中的重要技能。面对 D3.js 和 ECharts,很多开发者会陷入选择困难。本文将从底层原理、API 设计、性能、灵活性等维度进行对比,并通过两个实战项目(一个用 D3.js 实现自定义图表,一个用 ECharts 快速搭建仪表盘)让你亲身体验差异。
一、核心差异概览
| 特性 | D3.js | ECharts | |——|——-|———| | 底层 | 基于 SVG/Canvas 的 DOM 操作库 | 基于 Canvas 的图表库 | | 灵活性 | 极高,可定制任何图形 | 中等,提供丰富图表类型但定制复杂 | | 学习曲线 | 陡峭 | 平缓 | | 数据量 | 适合中小规模(<10万点) | 适合大规模(百万级) | | 动画 | 手动实现 | 内置优雅动画 | | 社区 | 资源丰富但分散 | 中文文档友好,社区活跃 |
二、选型原则
- 需要高度定制(如特殊图表、交互)→ D3.js
- 快速开发标准图表(折线图、柱状图、地图等)→ ECharts
- 数据量大(>10万点)→ ECharts(Canvas 渲染)
- 需要 SVG 交互(如缩放、平移)→ D3.js
三、实战对比:相同数据,不同实现
场景:展示某公司近 6 个月销售额趋势
数据:
const data = [
{ month: '2024-01', sales: 1200 },
{ month: '2024-02', sales: 1500 },
{ month: '2024-03', sales: 1100 },
{ month: '2024-04', sales: 1800 },
{ month: '2024-05', sales: 2000 },
{ month: '2024-06', sales: 1700 }
];
3.1 使用 ECharts 实现(5分钟完成)
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
</head>
<body>
<div id="chart" style="width: 600px; height: 400px;"></div>
<script>
const chart = echarts.init(document.getElementById('chart'));
const option = {
xAxis: {
type: 'category',
data: data.map(d => d.month)
},
yAxis: {
type: 'value'
},
series: [{
data: data.map(d => d.sales),
type: 'line',
smooth: true,
areaStyle: {}
}],
tooltip: { trigger: 'axis' }
};
chart.setOption(option);
</script>
</body>
</html>
> 💡 ECharts 的配置项高度结构化,只需提供数据和样式即可。
3.2 使用 D3.js 实现(需更多代码)
<!DOCTYPE html>
<html>
<head>
<script src="https://d3js.org/d3.v7.min.js"></script>
</head>
<body>
<svg id="chart" width="600" height="400"></svg>
<script>
const svg = d3.select('#chart');
const margin = { top: 20, right: 20, bottom: 30, left: 40 };
const width = +svg.attr('width') - margin.left - margin.right;
const height = +svg.attr('height') - margin.top - margin.bottom;
const g = svg.append('g').attr('transform', `translate(${margin.left},${margin.top})`);
// 缩放
const x = d3.scalePoint()
.domain(data.map(d => d.month))
.range([0, width]);
const y = d3.scaleLinear()
.domain([0, d3.max(data, d => d.sales)])
.range([height, 0]);
// 线条生成器
const line = d3.line()
.x(d => x(d.month))
.y(d => y(d.sales))
.curve(d3.curveCatmullRom);
// 绘制折线
g.append('path')
.datum(data)
.attr('fill', 'none')
.attr('stroke', 'steelblue')
.attr('stroke-width', 2)
.attr('d', line);
// 添加坐标轴
g.append('g')
.attr('transform', `translate(0,${height})`)
.call(d3.axisBottom(x));
g.append('g')
.call(d3.axisLeft(y));
</script>
</body>
</html>
> 💡 D3.js 需要手动处理比例尺、坐标轴、路径生成等底层细节。
四、深度对比:性能与定制
4.1 性能测试(10万数据点)
- ECharts:使用 Canvas 渲染,10万点流畅交互(60fps)。
- D3.js:默认 SVG 渲染,10万点 DOM 节点过多,卡顿。可通过 Canvas 适配器优化,但复杂度增加。
4.2 定制能力
- ECharts:通过
graphic元素或自定义系列实现定制,但受限于 API。 - D3.js:完全控制 DOM,可创建任何图形(如自定义 Sankey 图、力导向图)。
五、最佳实践建议
- 混合使用:在 ECharts 中嵌入 D3.js 定制的图形元素(通过
graphic)。 - 数据预处理:无论选哪个库,数据清洗和聚合都应在服务端完成。
- 响应式:D3.js 需手动监听 resize,ECharts 内置
resize方法。
六、总结
- 快速上线标准图表 → ECharts
- 需要独特交互或图形 → D3.js
- 两者不冲突:ECharts 用于 80% 场景,D3.js 用于 20% 定制需求。
下一步可尝试:用 D3.js 实现一个自定义地图可视化,或用 ECharts 集成到 React/Vue 项目中。