3步搞定D3.js饼图与环形图:从基础绘制到高级标签布局
2026/8/23 14:21:38 网站建设 项目流程

3步搞定D3.js饼图与环形图:从基础绘制到高级标签布局

你还在为D3.js饼图标签重叠烦恼?本文将通过3个清晰步骤,带你从基础饼图绘制到环形图变形,再到高级标签布局技巧,全程无需复杂代码,让数据可视化既专业又美观。读完本文你将掌握:基础饼图实现方法、环形图参数配置、智能标签防重叠方案,以及完整的交互式图表案例。

一、基础饼图快速实现

1.1 引入D3.js库

使用国内CDN加速引入D3.js,确保图表在国内网络环境下快速加载:

<script src="https://cdn.bootcdn.net/ajax/libs/d3/7.8.5/d3.min.js"></script>

官方入门文档:docs/getting-started.md

1.2 核心代码实现

通过D3的pie布局和arc生成器,仅需20行代码即可创建基础饼图:

// 准备数据 const data = [12, 31, 22, 17, 25]; const colors = ["#ff6384", "#36a2eb", "#ffce56", "#4bc0c0", "#9966ff"]; // 创建SVG容器 const svg = d3.select("body").append("svg") .attr("width", 400) .attr("height", 400) .append("g") .attr("transform", "translate(200, 200)"); // 生成饼图数据 const pie = d3.pie()(data); // 使用默认配置的pie布局 [docs/d3-shape/pie.md](https://gitcode.com/gh_mirrors/d3/d3/blob/66bfe8c6672873293e1f83253e6fbb1508633826/docs/d3-shape/pie.md?utm_source=gitcode_repo_files) // 创建弧形生成器 const arc = d3.arc() .innerRadius(0) // 内半径为0生成饼图 .outerRadius(150); // 外半径控制饼图大小 [docs/d3-shape/arc.md](https://gitcode.com/gh_mirrors/d3/d3/blob/66bfe8c6672873293e1f83253e6fbb1508633826/docs/d3-shape/arc.md?utm_source=gitcode_repo_files) // 绘制饼图 svg.selectAll("path") .data(pie) .enter() .append("path") .attr("d", arc) .attr("fill", (d, i) => colors[i]) .attr("stroke", "white") .style("stroke-width", "2px");

1.3 关键参数解析

参数作用示例值
innerRadius内半径(0为饼图)0
outerRadius外半径(控制大小)150
startAngle起始角度(弧度)0
endAngle结束角度(弧度)Math.PI * 2

饼图布局默认按数据值降序排列,可通过.sort(null)禁用排序:

const pie = d3.pie().sort(null); // 保持原始数据顺序

二、环形图进阶实现

2.1 从饼图到环形图的转换

只需修改arc生成器的innerRadius参数即可将饼图转换为环形图:

const arc = d3.arc() .innerRadius(70) // 设置内半径创建环形 .outerRadius(150);

2.2 环形图优势与应用场景

环形图相比传统饼图具有以下优势:

  • 中心区域可放置总计数据或标题
  • 视觉上更现代美观
  • 多组数据可嵌套形成多层环形图

基础环形图完整代码示例:test/d3-test.js

2.3 圆角环形图效果

通过cornerRadius参数添加圆角效果,提升视觉体验:

const arc = d3.arc() .innerRadius(70) .outerRadius(150) .cornerRadius(8); // 设置圆角半径

三、高级标签布局技术

3.1 基础文本标签实现

使用arc.centroid()获取弧形中心坐标放置标签:

// 添加基础标签 svg.selectAll("text") .data(pie) .enter() .append("text") .attr("transform", d => `translate(${arc.centroid(d)})`) .attr("text-anchor", "middle") .text(d => d.value);

3.2 解决标签重叠问题

当数据差异较大时,小扇形标签容易重叠,可通过以下方法优化:

// 智能标签定位函数 function labelPosition(d) { const midAngle = d.startAngle + (d.endAngle - d.startAngle) / 2; const outerRadius = 170; // 标签距离中心的距离 const x = Math.sin(midAngle) * outerRadius; const y = -Math.cos(midAngle) * outerRadius; return `translate(${x},${y})`; } // 判断文本方向(左右对齐) function textAnchor(d) { const midAngle = d.startAngle + (d.endAngle - d.startAngle) / 2; return midAngle < Math.PI ? "start" : "end"; } // 添加优化标签 svg.selectAll("text") .data(pie) .enter() .append("text") .attr("transform", labelPosition) .attr("text-anchor", textAnchor) .text(d => d.data.name);

3.3 带连接线的外部标签

为小扇形添加连接线,将标签放置在环形外部:

// 添加连接线 svg.selectAll("polyline") .data(pie) .enter() .append("polyline") .attr("points", d => { const pos = labelPosition(d).replace("translate(", "").replace(")", "").split(","); const mid = arc.centroid(d); return [mid[0], mid[1], mid[0] * 1.2, mid[1] * 1.2, pos[0], pos[1]]; }) .style("fill", "none") .style("stroke", "#666") .style("stroke-width", "1px");

3.4 完整标签布局效果对比

标签类型适用场景优点
中心标签大扇形区域简洁直观
外部标签小扇形区域不遮挡图形
连接线标签复杂数据兼顾可读性和美观

四、实战案例与最佳实践

4.1 交互式环形图实现

结合D3的事件系统添加交互效果:

// 添加鼠标悬停效果 svg.selectAll("path") .on("mouseover", function() { d3.select(this) .transition() .duration(300) .attr("opacity", 0.8) .attr("d", d3.arc().innerRadius(70).outerRadius(160)); }) .on("mouseout", function() { d3.select(this) .transition() .duration(300) .attr("opacity", 1) .attr("d", arc); });

4.2 数据加载与动态更新

从CSV文件加载数据并实现动态更新:

// 加载外部数据 d3.csv("data.csv").then(data => { // 数据预处理 data.forEach(d => { d.value = +d.value; // 转换为数字类型 }); // 更新图表函数 function updateChart(data) { const pie = d3.pie().value(d => d.value); const arcs = pie(data); // 更新路径 svg.selectAll("path") .data(arcs) .transition() .duration(1000) .attr("d", arc); } // 初始渲染 updateChart(data); });

数据文件存放路径:docs/public/data/

4.3 完整案例代码结构

推荐项目文件组织结构:

- index.html # 页面结构 - css/style.css # 样式文件 - js/chart.js # 图表逻辑 - data/ # 数据文件目录

官方示例集合:docs/components/ExampleArcs.vue

五、总结与扩展学习

本文从基础饼图实现讲到高级标签布局,涵盖了D3.js中扇形图的核心技术点。关键知识点包括:

  1. 使用d3.pie()生成饼图数据
  2. 通过d3.arc()控制扇形形状
  3. 调整innerRadius实现环形图
  4. 多种标签布局方案解决重叠问题

进阶学习资源:

  • 多层嵌套环形图:docs/d3-hierarchy/partition.md
  • 动态数据更新:docs/d3-transition/
  • 3D效果扩展:结合CSS 3D变换

通过这些技术,你可以创建出既美观又实用的数据可视化图表,有效传达数据洞察。建议进一步探索D3.js的交互功能和动画效果,打造更具吸引力的数据故事。

提示:实际项目中建议使用模块化导入方式,减小文件体积:

import { pie, arc } from "d3-shape"; // 仅导入所需模块

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询