一、官网
二、理解
D3.js 是一个基于 JavaScript 的开源数据可视化库,由数据可视化专家 Mike Bostock 创建,旨在通过数据驱动的方式动态生成和操作文档。它利用 Web 标准(HTML、SVG 和 CSS)将数据转化为直观的图形,帮助开发者构建高度定制化、交互性强的可视化应用。
三、D3.js 适用场景表格
| 场景分类 | 具体场景 | 适用性 | 示例 |
|---|---|---|---|
| 基础图表 | 条形图、折线图、饼图 | ✅ 适合,但需手动编写代码;若追求快速开发,可考虑封装库(如 C3.js) | 销售数据对比、时间序列趋势分析 |
| 复杂交互 | 力导向图、桑基图、树状图 | ✅ 高度适合,D3.js 提供布局算法和动态交互支持 | 社交网络关系分析、能源流动可视化、组织架构图 |
| 地理可视化 | 动态地图、区域热力图 | ✅ 适合,结合 GeoJSON/TopoJSON 实现高精度地理数据渲染 | 疫情传播地图、人口迁移分析 |
| 实时数据监控 | 仪表盘、动态数据流 | ✅ 适合,通过 transition() 和动态数据绑定实现流畅更新 | 股票行情监控、服务器性能指标仪表盘 |
| 高度定制化需求 | 非标准图表、艺术化数据表达 | ✅ 最佳选择,完全控制 DOM 和视觉样式 | 音乐频谱动画、文学文本关系网络 |
| 动画与过渡效果 | 元素渐变、路径动画、交互反馈 | ✅ 适合,内置 transition() 和 ease() 函数 | 数据加载动画、图表元素高亮效果 |
| 大数据量渲染 | 十万级以上数据点(需优化) | ⚠️ 需结合 WebGL 或 Canvas 优化(如使用 d3-canvas 插件) | 科学计算数据、大规模网络图 |
| 移动端适配 | 响应式图表、触摸交互 | ✅ 适合,但需手动处理触摸事件(或结合 Hammer.js) | 移动端数据看板、触控式图表操作 |
四、对比其他库的场景适配
| 需求场景 | D3.js | ECharts/Highcharts | Plotly |
|---|---|---|---|
| 标准折线图/柱状图 | 🟠 可实现(代码多) | 🟢 最佳选择 | 🟢 推荐 |
| 力导向图/桑基图 | 🟢 最佳选择 | ❌ 不支持 | 🟠 部分支持 |
| 地理地图(动态投影) | 🟢 最佳选择 | 🟠 基础支持 | 🟠 基础支持 |
| 3D 数据可视化 | ❌ 需扩展 | ❌ 不支持 | 🟢 推荐 |
| 移动端触控交互 | 🟠 需手动适配 | 🟢 优化良好 | 🟠 部分支持 |
五、简单的demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>D3.js 简单柱状图</title>
<script src="https://d3js.org/d3.v7.min.js"></script>
<style>
.bar { fill: steelblue; }
.bar:hover { fill: orange; }
.axis-label { font-size: 12px; text-anchor: middle; }
</style>
</head>
<body>
<!-- 图表容器 -->
<svg width="500" height="300"></svg>
<script>
// 1. 准备数据
const data = [12, 35, 8, 28, 19];
// 2. 设置图表尺寸和边距
const margin = { top: 20, right: 20, bottom: 50, left: 50 };
const width = 500 - margin.left - margin.right;
const height = 300 - margin.top - margin.bottom;
// 3. 创建SVG画布并平移(留出边距)
const svg = d3.select("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", `translate(${margin.left}, ${margin.top})`);
// 4. 定义比例尺
const xScale = d3.scaleBand()
.domain(d3.range(data.length)) // 输入范围:数据索引 [0, 1, 2...]
.range([0, width]) // 输出范围:画布宽度
.padding(0.2); // 柱子间距
const yScale = d3.scaleLinear()
.domain([0, d3.max(data)]) // 输入范围:数据最大值
.range([height, 0]); // 输出范围:画布高度(Y轴反转)
// 5. 绘制坐标轴
const xAxis = d3.axisBottom(xScale).tickFormat(i => `数据${i}`);
const yAxis = d3.axisLeft(yScale);
svg.append("g")
.attr("transform", `translate(0, ${height})`)
.call(xAxis);
svg.append("g")
.call(yAxis);
// 6. 添加坐标轴标签
svg.append("text")
.attr("class", "axislabel")
.attr("x", width / 2)
.attr("y", height + 30)
.text("数据索引");
svg.append("text")
.attr("class", "axis-label")
.attr("transform", "rotate(-90)")
.attr("x", -height / 2)
.attr("y", -30)
.text("数值");
// 7. 绑定数据并绘制柱子
svg.selectAll(".bar")
.data(data)
.enter()
.append("rect")
.attr("class", "bar")
.attr("x", (d, i) => xScale(i)) // X位置:索引映射
.attr("y", d => yScale(d)) // Y位置:数值映射
.attr("width", xScale.bandwidth()) // 宽度:自动计算
.attr("height", d => height - yScale(d)); // 高度:画布高度 - Y位置
// 8. 添加交互:鼠标悬停高亮
svg.selectAll(".bar")
.on("mouseover", function() {
d3.select(this).style("fill", "red");
})
.on("mouseout", function() {
d3.select(this).style("fill", "steelblue");
});
</script>
</body>
</html>

19

被折叠的 条评论
为什么被折叠?



