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

如何实现Recharts折线图鼠标悬停时线条变色?

问题分析与修复方案

你的代码存在几个关键问题导致悬停变色失效:

  1. ChartWrapper是函数组件,但你混用了类组件的this.setState和this.handleHover写法,函数组件没有this上下文,状态管理需用useState钩子。
  2. activeIndex变量未在函数组件内定义,导致stroke属性的三元表达式无法获取正确的激活状态。
  3. 缺少鼠标移出事件处理,鼠标离开线条后无法恢复原颜色。

修复后的完整代码

import { useState } from 'react';
import { ResponsiveContainer, LineChart, CartesianGrid, XAxis, Tooltip, Brush, YAxis, Line } from 'recharts';
import numeral from 'numeral';

export const colorSchemeFill = [
  'rgba(253, 127, 111, 0.6)',
  'rgba(126, 176, 213, 0.6)',
  'rgba(178, 224, 97, 0.6)',
  'rgba(189, 126, 190, 0.6)',
  'rgba(255, 181, 90, 0.6)',
  'rgba(255, 238, 101, 0.6)',
  'rgba(190, 185, 219, 0.6)',
  'rgba(253, 204, 229, 0.6)',
  'rgba(139, 211, 199, 0.6)',
];

export const ChartWrapper = ({ Metrics, Data, width, height, renderTooltipContent }) => {
  const [activeIndex, setActiveIndex] = useState(null);

  const handleHover = (index) => {
    setActiveIndex(index);
  };

  const handleMouseOut = () => {
    setActiveIndex(null);
  };

  return (
    <ResponsiveContainer width={width} height={height - 70}>
      <LineChart data={Data}>
        <CartesianGrid
          style={{ stroke: 'rgba(215, 215, 215, 0.2)' }}
          vertical={false}
        />
        <XAxis dataKey='date' />
        <Tooltip content={renderTooltipContent} />
        <Brush dataKey='date' height={30} stroke='rgb(33, 37, 41)' />
        {Metrics.map((metric, index) => {
          const orientation = index % 2 === 0 ? 'left' : 'right';
          return (
            <React.Fragment key={metric.APIProperty}>
              <YAxis
                domain={['auto', 'auto']}
                yAxisId={`${metric.APIProperty}_axis`}
                orientation={orientation}
                tick={{
                  stroke: metric.color,
                  strokeWidth: 1,
                }}
                tickFormatter={(tick) => numeral(tick).format('0.00 a')}
                axisLine={{
                  stroke: colorSchemeFill[index % 8],
                  strokeWidth: 1,
                }}
              />
              <Line
                type='monotone'
                yAxisId={`${metric.APIProperty}_axis`}
                dataKey={metric.APIProperty}
                strokeWidth={2}
                stroke={index === activeIndex ? 'yellow' : colorSchemeFill[index % 8]}
                onMouseOver={() => handleHover(index)}
                onMouseOut={handleMouseOut}
                dot={true}
              />
            </React.Fragment>
          );
        })}
      </LineChart>
    </ResponsiveContainer>
  );
};

关键修复点说明

  • 用useState定义activeIndex状态,初始值设为null表示无激活线条。
  • 将handleHover改为函数组件内的普通函数,直接调用setActiveIndex更新状态,无需this。
  • 添加onMouseOut事件,鼠标离开线条时重置activeIndex为null,恢复原颜色。
  • 给列表渲染的React.Fragment添加唯一key属性,符合React渲染规范。
  • 用模板字符串替代字符串拼接,提升代码可读性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 18:10:26