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

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

【免费下载链接】d3 Bring data to life with SVG, Canvas and HTML. :bar_chart::chart_with_upwards_trend::tada: 【免费下载链接】d3 项目地址: https://gitcode.com/gh_mirrors/d3/d3

你还在为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://link.gitcode.com/i/578164c5de08dbab81ec027cf480c00b)

// 创建弧形生成器
const arc = d3.arc()
  .innerRadius(0)          // 内半径为0生成饼图
  .outerRadius(150);       // 外半径控制饼图大小 [docs/d3-shape/arc.md](https://link.gitcode.com/i/d5068523eb2a9f0811cf82a776330020)

// 绘制饼图
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. 多种标签布局方案解决重叠问题

进阶学习资源:

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

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

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

【免费下载链接】d3 Bring data to life with SVG, Canvas and HTML. :bar_chart::chart_with_upwards_trend::tada: 【免费下载链接】d3 项目地址: https://gitcode.com/gh_mirrors/d3/d3

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

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值