You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何计算D3绘制的饼图中每个饼片的中心?

实现D3饼图的外部文本标注(内部线条隐藏)

核心思路

要达成目标,关键在于计算每个饼片的中心角度,以此为基础推导标注线的起点(饼片边缘)和终点(文本位置),同时将饼图内部的线段设为透明。

具体实现步骤

1. 计算饼片的中心角度

D3饼布局生成的每个数据对象包含startAngle(起始角度)和endAngle(结束角度),中心角度为两者的平均值:

const getMidAngle = d => d.startAngle + (d.endAngle - d.startAngle) / 2;

2. 计算标注线的坐标

借助三角函数,结合饼图半径、中心角度,计算出标注线的关键坐标:

  • 起点:饼片边缘的位置(从圆心出发,半径长度的坐标)
  • 终点:向外延伸一段距离后的位置(用于放置文本)

假设饼图圆心坐标为[cx, cy],半径为radius,文本偏移量为labelOffset:

const getLabelPoints = (d, cx, cy, radius, labelOffset) => {
  const midAngle = getMidAngle(d);
  // 饼片边缘的起点坐标
  const startX = cx + radius * Math.cos(midAngle);
  const startY = cy + radius * Math.sin(midAngle);
  // 文本所在的终点坐标
  const endX = cx + (radius + labelOffset) * Math.cos(midAngle);
  const endY = cy + (radius + labelOffset) * Math.sin(midAngle);
  return { startX, startY, endX, endY };
};

3. 绘制隐藏内部线段的标注线

用D3绘制路径时,仅保留饼片边缘到文本的可见线段,将圆心到饼片边缘的线段设为透明:

svg.selectAll('.label-line')
  .data(pieData)
  .enter()
  .append('path')
  .attr('class', 'label-line')
  .attr('d', d => {
    const { startX, startY, endX, endY } = getLabelPoints(d, cx, cy, radius, 50);
    // 路径:圆心→饼片边缘(透明),饼片边缘→文本位置(可见)
    return `M ${cx},${cy} L ${startX},${startY} L ${endX},${endY}`;
  })
  .attr('stroke', 'transparent') // 隐藏圆心到饼边的线段
  .attr('stroke', '#000') // 显示饼边到文本的线段
  .attr('stroke-width', 1);

4. 添加文本标注

将文本放置在标注线终点,根据中心角度调整文本对齐方式,避免遮挡或溢出:

svg.selectAll('.label-text')
  .data(pieData)
  .enter()
  .append('text')
  .attr('class', 'label-text')
  .attr('x', d => getLabelPoints(d, cx, cy, radius, 50).endX)
  .attr('y', d => getLabelPoints(d, cx, cy, radius, 50).endY)
  .attr('text-anchor', d => {
    const midAngle = getMidAngle(d);
    // 右侧饼片文本左对齐,左侧饼片文本右对齐
    return midAngle < Math.PI ? 'start' : 'end';
  })
  .attr('dominant-baseline', 'middle')
  .text(d => d.data.label);

调整技巧

  • 修改labelOffset的值可以控制文本与饼图的距离
  • 若需要更美观的标注线,可将直线替换为贝塞尔曲线
  • 可根据中心角度调整文本旋转角度,提升可读性

内容的提问来源于stack exchange,提问作者Jojo Ceasar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 16:03:17