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

Recharts饼图标签居中问题:如何将标签置于扇区中心?

Recharts饼图自定义标签居中修复方案

你刚接触React,用Recharts实现了带自定义标签的环形饼图,但遇到标签(如图中的20、11)无法精准定位到对应扇区中心的问题。以下是针对你代码的修复方案:

原始代码

<PieChart width={400} height={240} style={{ outline: "none" }}>
      <Pie
        data={data}
        dataKey="value"
        innerRadius={50}
        outerRadius={100}
        labelLine={false}
        label={customDonutLabel}
        style={{ outline: "none" }}
      />
      <Tooltip content={<ChartTooltip />} />
    </PieChart>


const customDonutLabel: PieLabel<CustomDonutLabelRenderProps<ChartDataProps>> = (props) => {
  const slicePercentage = props.payload.value * 100;
  if (slicePercentage < 10) {
    return null;
  }
  const RADIAN = Math.PI / 180;
  const innerRadius = convertToNumber(props.innerRadius);
  const outerRadius = convertToNumber(props.outerRadius);
  const cx = convertToNumber(props.cx);
  const cy = convertToNumber(props.cy);
  const midAngle = convertToNumber(props.midAngle);

  const radius = innerRadius + (outerRadius - innerRadius) * 0.35;
  const x = cx + radius * Math.cos(-midAngle * RADIAN);
  const y = cy + radius * Math.sin(-midAngle * RADIAN);

  return (
    <text
      style={{ fontWeight: "semibold", fontSize: "md" }}
      x={x}
      y={y}
      fill={props.payload.color}
      textAnchor={x > cx ? "start" : "end"}
      dominantBaseline="central"
    >
      {Math.round(props.payload.value * 100)}
    </text>
  );
};

问题分析与修复

当前代码的核心问题在于标签位置计算的半径比例不对,以及文本对齐方式设置错误:

  • 用0.35的比例计算环形内的半径,会让标签偏向环形内侧,而非正中心;
  • textAnchor根据x坐标设置start/end,会导致文本偏移,而非在坐标点居中。

修改后的customDonutLabel函数:

const customDonutLabel: PieLabel<CustomDonutLabelRenderProps<ChartDataProps>> = (props) => {
  const slicePercentage = props.payload.value * 100;
  if (slicePercentage < 10) {
    return null;
  }
  const RADIAN = Math.PI / 180;
  const innerRadius = convertToNumber(props.innerRadius);
  const outerRadius = convertToNumber(props.outerRadius);
  const cx = convertToNumber(props.cx);
  const cy = convertToNumber(props.cy);
  const midAngle = convertToNumber(props.midAngle);

  // 计算环形的中间半径,确保标签在扇区正中心
  const radius = innerRadius + (outerRadius - innerRadius) / 2;
  const x = cx + radius * Math.cos(-midAngle * RADIAN);
  const y = cy + radius * Math.sin(-midAngle * RADIAN);

  return (
    <text
      style={{ fontWeight: "semibold", fontSize: "md" }}
      x={x}
      y={y}
      fill={props.payload.color}
      textAnchor="middle" // 设置文本在x坐标点居中
      dominantBaseline="central" // 保持垂直居中
    >
      {Math.round(props.payload.value * 100)}
    </text>
  );
};

关键修改点

  1. 半径计算:将0.35改为/2,直接取环形内外半径的中间值,确保标签落在扇区的径向中心;
  2. 文本对齐:把textAnchor固定为middle,让文本以计算出的(x,y)坐标为中心对齐,避免左右偏移。

这样修改后,标签就能精准定位到对应扇区的中心位置了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 19:38:34