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

如何在React+D3.js饼图中实现标签Tooltip效果

解决方案:给React-D3饼图添加悬停Tooltip显示情感标签

我来帮你修改现有的Pie组件,实现鼠标悬停切片时显示包含情感标签和数值的Tooltip功能。下面是完整的修改代码和关键说明:

修改后的Pie组件代码

import React, { useEffect, useRef } from "react";
import * as d3 from "d3";

const Pie = props => {
  const ref = useRef(null);
  const tooltipRef = useRef(null); // 新增Tooltip的DOM引用

  const createPie = d3
    .pie()
    .value(d => d.value)
    .sort(null);

  const createArc = d3
    .arc()
    .innerRadius(props.innerRadius)
    .outerRadius(props.outerRadius);

  const colors = d3.scaleOrdinal(d3.schemeCategory10);
  const format = d3.format(".2f");

  useEffect(
    () => {
      const data = createPie(props.data);
      const group = d3.select(ref.current);
      const tooltip = d3.select(tooltipRef.current);

      // 处理饼图切片的数据绑定与更新
      const groupWithData = group.selectAll("g.arc").data(data);
      groupWithData.exit().remove();

      const groupWithUpdate = groupWithData
        .enter()
        .append("g")
        .attr("class", "arc");

      // 切片路径处理,添加交互事件
      const path = groupWithUpdate
        .append("path")
        .merge(groupWithData.select("path.arc"));

      path
        .attr("class", "arc")
        .attr("d", createArc)
        .attr("fill", (d, i) => colors(i))
        .style("cursor", "pointer") // 提示用户可交互
        // 鼠标悬停时显示Tooltip
        .on("mouseover", (event, d) => {
          tooltip
            .style("display", "block")
            .html(`<strong>${d.data.emotion}</strong><br/>数值: ${format(d.value)}`);
        })
        // 鼠标移动时更新Tooltip位置
        .on("mousemove", (event) => {
          tooltip
            .style("left", `${event.pageX + 10}px`)
            .style("top", `${event.pageY - 10}px`);
        })
        // 鼠标离开时隐藏Tooltip
        .on("mouseout", () => {
          tooltip.style("display", "none");
        });

      // 保留原有切片内的数值文本
      const text = groupWithUpdate
        .append("text")
        .merge(groupWithData.select("text"));

      text
        .attr("text-anchor", "middle")
        .attr("alignment-baseline", "middle")
        .attr("transform", d => `translate(${createArc.centroid(d)})`)
        .style("fill", "white")
        .style("font-size", 10)
        .text(d => format(d.value));
    },
    [props.data]
  );

  return (
    <div style={{ position: "relative" }}> {/* 相对定位容器,让Tooltip绝对定位生效 */}
      <svg width={props.width} height={props.height}>
        <g ref={ref} transform={`translate(${props.outerRadius} ${props.outerRadius})`} />
      </svg>
      {/* 自定义Tooltip元素,初始隐藏 */}
      <div
        ref={tooltipRef}
        style={{
          position: "absolute",
          display: "none",
          backgroundColor: "rgba(0,0,0,0.8)",
          color: "#fff",
          padding: "6px 10px",
          borderRadius: "4px",
          fontSize: "12px",
          pointerEvents: "none", // 避免Tooltip干扰鼠标事件
          zIndex: 1000
        }}
      />
    </div>
  );
};

export default Pie;

关键修改说明

  • 新增Tooltip容器:添加一个绝对定位的div作为Tooltip载体,通过useRef获取DOM引用,设置半透明背景和基础样式,初始状态为隐藏。
  • 交互事件绑定:给每个饼图切片的路径元素添加三个鼠标事件:
    • mouseover:触发时显示Tooltip,内容包含情感标签(d.data.emotion)和格式化后的数值。
    • mousemove:跟随鼠标移动Tooltip,保证提示始终在鼠标附近,提升交互体验。
    • mouseout:鼠标离开切片时隐藏Tooltip。
  • 细节优化:给切片添加cursor: pointer样式,明确提示用户该区域可交互;Tooltip设置pointerEvents: none,避免遮挡切片的鼠标事件。

修改完成后,用户悬停饼图切片时就能清晰看到对应的情感类型和数值啦,完美匹配你的需求!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 13:42:30