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

如何在React Victory中创建吸附于垂直光标线数据坐标的两个圆点?

解决方案

要实现同时在VictoryArea和VictoryLine上显示对应圆点,核心是让Tooltip能捕获多个数据系列的激活点,然后批量渲染圆点。以下是具体实现步骤:

1. 父组件配置共享交互事件

给两个图表组件绑定同一个sharedEvents,确保鼠标交互时能同时激活两个系列的数据点,并用VictoryVoronoiContainer来捕获多系列的点数据:

import { VictoryArea, VictoryLine, VictoryChart, VictoryTooltip, VictoryVoronoiContainer } from "victory";

const FinanceChart = () => {
  // 共享交互事件,同步两个系列的鼠标状态
  const sharedEvents = {
    target: "parent",
    events: [{
      childName: ["area-series", "line-series"], // 给两个系列命名,用于区分
      target: "data",
      eventHandlers: {
        onMouseMove: () => [{
          target: "parent",
          mutation: () => ({ active: true })
        }],
        onMouseLeave: () => [{
          target: "parent",
          mutation: () => ({ active: false })
        }]
      }
    }]
  };

  return (
    <VictoryChart
      containerComponent={
        <VictoryVoronoiContainer
          labels={() => ""} // 关闭默认文本标签,只用自定义flyout
          labelComponent={<VictoryTooltip flyoutComponent={<MyTooltip />} />}
        />
      }
      sharedEvents={sharedEvents}
    >
      <VictoryArea name="area-series" data={yourAreaData} />
      <VictoryLine name="line-series" data={yourLineData} />
    </VictoryChart>
  );
};

2. 修改自定义Tooltip组件

通过activePoints属性获取所有激活的多系列数据点,遍历渲染对应圆点,垂直线共用同一个x坐标:

const MyTooltip = ({ activePoints }) => {
  const cursorLine = {
    stroke: "#ccc",
    strokeDasharray: "4,4",
    strokeWidth: 1
  };

  // 根据系列名称区分圆点样式(对应谷歌财经的蓝黄配色)
  const getPointStyle = (seriesName) => {
    return seriesName === "area-series" 
      ? { fill: "#4285F4", stroke: "#fff", strokeWidth: 2 } 
      : { fill: "#FBBC05", stroke: "#fff", strokeWidth: 2 };
  };

  if (!activePoints?.length) return null;

  // 取第一个点的x坐标作为垂直线位置(同一条垂直线)
  const verticalLineX = activePoints[0].x;

  return (
    <g>
      {/* 垂直虚线光标线 */}
      <line x1={verticalLineX} y1={0} x2={verticalLineX} y2={540} style={cursorLine} />
      {/* 遍历所有激活点,渲染对应系列的圆点 */}
      {activePoints.map((point, idx) => (
        <circle
          key={idx}
          cx={point.x}
          cy={point.y}
          r="8"
          style={getPointStyle(point.seriesName)}
        />
      ))}
    </g>
  );
};

关键说明

  • sharedEvents实现了多系列交互同步,确保鼠标移动时两个系列的数据点都被标记为激活状态。
  • VictoryVoronoiContainer会把所有激活的点打包成activePoints数组传给Tooltip,这是多系列圆点渲染的核心。
  • 通过系列名称区分圆点样式,完美匹配谷歌财经的蓝黄点交互效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 13:50:07