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

Rechart饼图问题:鼠标移至自定义标签时Tooltip消失

问题:饼图标签悬停时Tooltip消失的解决办法

我用ChakraUI做了带自定义标签和Tooltip的饼图,只有占比≥10%的扇区显示标签。现在的问题是:鼠标移到扇区上时Tooltip正常显示,但移到标签文本上时Tooltip就消失了。相关代码如下:

const CustomChart = ({ data }: ChartProps) => {
  return (
    <PieChart width={400} height={240}>
      <Pie
        data={data}
        dataKey="value"
        innerRadius={50}
        outerRadius={100}
        cx="30%"
        cy="50%"
        labelLine={false}
        label={customLabel}
        style={{ outline: "none" }}
        isAnimationActive={false}
      />
      <Tooltip content={<ChartTooltip />} isAnimationActive={false} />
    </PieChart>
  );
};

const customDonutLabel: PieLabel<CustomDonutLabelRenderProps<ChartDataProps>> = (props) => {
  const slicePercentage = props.payload.value * 100;
  if (slicePercentage < 10) {
    return null;
  }

  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 RADIAN = Math.PI / 180;
  const radius = innerRadius + (outerRadius - innerRadius) * 0.5;

  return (
    <text
      style={{ fontWeight: "semibold", fontSize: "md" }}
      x={cx + radius * Math.cos(-midAngle * RADIAN)}
      y={cy + radius * Math.sin(-midAngle * RADIAN)}
      fill={props.payload.color}
      textAnchor="middle"
      dominantBaseline="middle"
    >
      {Math.round(props.payload.value * 100)}
    </text>
  );
};

const ChartTooltip = (props: ChartTooltipProps) => {
  if (props.active && props.payload && props.payload.length) {
    const { value, name } = props.payload[0];
    const display = `${formatPercentage(value)}% - ${name}`;
    return (
      <ChakraTooltip label={display} openDelay={500}>
        <Text sx={tooltipStyleProps}>{display}</Text>
      </ChakraTooltip>
    );
  }
  return null;
};

解决方法

核心原因

自定义的<text>标签默认会捕获鼠标事件,导致底层的饼图扇区无法接收hover事件,进而触发Tooltip关闭。

修复步骤

给自定义标签的<text>元素添加pointerEvents="none"属性,让文本标签不拦截鼠标事件,确保鼠标悬停在标签上时,事件能穿透到底层的饼图扇区。

修改后的customDonutLabel代码:

const customDonutLabel: PieLabel<CustomDonutLabelRenderProps<ChartDataProps>> = (props) => {
  const slicePercentage = props.payload.value * 100;
  if (slicePercentage < 10) {
    return null;
  }

  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 RADIAN = Math.PI / 180;
  const radius = innerRadius + (outerRadius - innerRadius) * 0.5;

  return (
    <text
      style={{ fontWeight: "semibold", fontSize: "md" }}
      x={cx + radius * Math.cos(-midAngle * RADIAN)}
      y={cy + radius * Math.sin(-midAngle * RADIAN)}
      fill={props.payload.color}
      textAnchor="middle"
      dominantBaseline="middle"
      pointerEvents="none" // 添加这一行
    >
      {Math.round(props.payload.value * 100)}
    </text>
  );
};

效果说明

添加pointerEvents="none"后,鼠标移到标签文本上时,事件会传递给下方的饼图扇区,Tooltip就能保持显示状态,和悬停扇区时的行为完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 09:25:06