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

Rechart Tooltip无法正确渲染数据 求助解决

Recharts LineChart Tooltip 渲染异常,如何修改为仅显示对应数值的“X min”格式?

问题描述

使用Rechart的LineChart组件时遇到Tooltip渲染异常:当前Tooltip横向显示“SessionLength: 0min”(所有日期均如此),纵向显示鼠标指向日期的字母标识,期望Tooltip仅显示“X min”,其中X为该日期对应的sessionLength数值。

相关代码片段

1. data.js 相关部分

const USER_AVERAGE_SESSIONS = [
    {
        userId: 12,
        sessions: [
            {
                day: 1,
                sessionLength: 30
            },
            {
                day: 2,
                sessionLength: 23
            },
            {
                day: 3,
                sessionLength: 45
            },
            {
                day: 4,
                sessionLength: 50
            },
            {
                day: 5,
                sessionLength: 0
            },
            {
                day: 6,
                sessionLength: 0
            },
            {
                day: 7,
                sessionLength: 60
            }
        ]
    },
    {
        userId: 18,
        sessions: [
            {
                day: 1,
                sessionLength: 30
            },
            {
                day: 2,
                sessionLength: 40
            },
            {
                day: 3,
                sessionLength: 50
            },
            {
                day: 4,
                sessionLength: 30
            },
            {
                day: 5,
                sessionLength: 30
            },
            {
                day: 6,
                sessionLength: 50
            },
            {
                day: 7,
                sessionLength: 50
            }
        ]
    }
]

2. SessionLengthChart 组件代码

import React, { useState, useEffect } from "react";
import PropTypes from "prop-types";
import { getUserAverageSessions } from "../../../dataManager/dataManager";
import { useParams } from "react-router-dom";
import {
  LineChart,
  XAxis,
  YAxis,
  Tooltip,
  Line,
  CartesianGrid,
} from "recharts";
import "./SessionLengthChart.css";

/**
 * SessionLengthChart component displays a line chart of a user's average session length per day.
 * @returns {JSX.Element}
 */
function SessionLengthChart() {
  // Define PropTypes for the component
  SessionLengthChart.propTypes = {
    userId: PropTypes.string.isRequired,
  };

  // Extract userId from the URL using useParams
  const { userId } = useParams();

  // Initialize state variables for user sessions and error
  const [userSessions, setUserSessions] = useState(null);
  const [error, setError] = useState(false);

  // Fetch user average session data when the component mounts or when userId changes
  useEffect(() => {
    /**
     * Fetches user average session data and updates the state.
     * @async
     */
    async function fetchData() {
      try {
        // Get user average session data from the data manager
        const userData = await getUserAverageSessions(userId);

        // Update the userSessions state with the fetched data
        const updatedData = userData[1].map((dayData) => {
          const sessionLengthStr = dayData.sessionLength.toString();
          const sessionLengthNum = Number(sessionLengthStr.match(/\d+/)[0]);
          const daysOfWeek = ["", "L", "M", "M", "J", "V", "S", "D"];
          const day = daysOfWeek[dayData.day];
          return {
            ...dayData,
            day: day,
            sessionLength: sessionLengthNum,
          };
        });
        setUserSessions(updatedData);
      } catch (err) {
        console.log("Error fetching user data:", err);
        setError(true);
      }
    }
    fetchData();
  }, [userId]);

  // Display an error message if the data failed to load
  if (error) {
    return (
      <div>Error: Failed to load user data for session length chart.</div>
    );
  }

  // Display a loading message if user session data is not yet loaded
  if (!userSessions) {
    return <div>Loading...</div>;
  }

  // Format the label for X and Y axes of the chart
  const formatLabel = (value) => {
    if (value === 0) {
      return "0 min";
    }
    const hours = Math.floor(value / 60);
    const minutes = value % 60;
    return `${hours > 0 ? `${hours}h ` : ""}${minutes}min`;
  };

  // Format the tooltip for the chart
  const formatTooltip = (value) => {
    const hours = Math.floor(value / 60);
    const minutes = value % 60;
    return `${hours > 0 ? `${hours}h ` : ""}${minutes}min`;
  };

  // Render the line chart with the user session data
  return (
    <div className="Session">
      <h3 className="sessionTitle">Durée moyenne des <br></br>sessions</h3>
      <LineChart
        width={268}
        height={263}
        data={userSessions}
        cursor="default"
        margin={{ top: 20, right: 10, left: 10, bottom: 30 }}
      >
        <XAxis
          dataKey="day"
          tick={{ stroke: "white", strokeWidth: 0.4, fontSize: 12 }}
          style={{ textAnchor: "middle", transform: "translateY(-0px) " }}
        />
        <YAxis
          type="number"
          domain={[0, "dataMax"]}
          tickCount={5}
          width={0}
          stroke="transparent"
          axisline={false}
        />
  <Tooltip
  formatter={(value) => {
    console.log(value);
    const sessionLength = value && value.payload ? value.payload.sessionLength : 0;
    return `${sessionLength} min`;
  }}
  contentStyle={{ width: 50, height: 30 }}
  label={null}
  isAnimationActive={false}
/>
        <CartesianGrid stroke="#f5f5f5" vertical={false} />
        <CartesianGrid stroke="#f5f5f5" horizontal={false} />
        <Line type="monotone" data={userSessions} stroke="#fff" yAxis={null} dot={false} strokeWidth={2}  dataKey="sessionLength" />
        {console.log(userSessions, "achemene")}


      </LineChart>
    </div>
  );
}

export default SessionLengthChart;

3. dataManager.js 相关部分

/**
 * Fetches user average sessions data from the server or mocked data.
 * @async
 * @returns {Array} - The user average sessions data.
 */
async function getUserAverageSessions(id) {
  const rawUserData = useMockedData
    ? await getMockedData("USER_AVERAGE_SESSIONS", id)
    : await importFromBackEnd("average-sessions", id);
  const userData = Object.values(rawUserData); // Transform the object into an array
  return userData;
}

export { getUserAverageSessions };

解决方案

问题出在Tooltip的formatter函数参数处理错误:Recharts中单个数据系列的formatter第一个参数直接对应dataKey的值(即sessionLength的数值),而非包含payload的对象,你之前的写法导致sessionLength始终取到默认值0。

修改Tooltip部分的代码即可解决:

基础版(仅显示“X min”)

<Tooltip
  formatter={(value) => [`${value} min`]}
  contentStyle={{ width: 50, height: 30 }}
  label={null}
  isAnimationActive={false}
/>

进阶版(支持小时+分钟格式,复用你定义的formatTooltip函数)

<Tooltip
  formatter={(value) => [formatTooltip(value)]}
  contentStyle={{ width: 50, height: 30 }}
  label={null}
  isAnimationActive={false}
/>

说明

  • formatter需要返回数组,每个元素对应一个数据系列的显示内容,这里只有一个Line系列,所以返回包含单个字符串的数组。
  • label={null}用于隐藏Tooltip顶部的日期标识,符合你的需求。
  • 修正后,Tooltip会正确显示当前鼠标指向日期对应的sessionLength数值格式,不再出现固定的0min和多余的键名。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 22:27:01