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

如何在Recharts LineChart中对齐双Y轴零点并保证数据可读性?

双Y轴LineChart零点对齐且提升可读性的解决方案

问题背景

使用Recharts开发双Y轴折线图,要求两个Y轴的零点对齐并居中显示,但当前通过全局对称域([-maxAbsValue, maxAbsValue])的实现方式,导致数值范围较小的lift系列线条过于紧凑难以辨认,原实现代码如下:

import {
  LineChart,
  Line,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  Legend,
  ResponsiveContainer,
} from 'recharts';

const data = [
  { t: 1, current: 0, lift: 0 },
  { t: 35, current: 300, lift: 2 },
  { t: 55, current: 300, lift: 2 },
  { t: 56, current: 700, lift: 2 },
  { t: 96, current: 700, lift: 2 },
  { t: 97, current: 100, lift: 2 },
  { t: 117, current: 100, lift: 2 },
  { t: 118, current: 0, lift: 0 },
  { t: 119, current: 0, lift: -4 },
  { t: 138, current: 0, lift: -4 },
];

const Overview = () => {
  const minCurrent = Math.min(...data.map((item) => item.current));
  const maxCurrent = Math.max(...data.map((item) => item.current));
  const minLift = Math.min(...data.map((item) => item.lift));
  const maxLift = Math.max(...data.map((item) => item.lift));

  // Domains calculated to center zero
  const maxAbsValue = Math.max(Math.abs(minCurrent), Math.abs(maxCurrent), Math.abs(minLift), Math.abs(maxLift));
  const centeredDomain = [-maxAbsValue, maxAbsValue];

  return (
    <ResponsiveContainer width="100%" height={300}>
      <LineChart data={data}>
        <CartesianGrid strokeDasharray="3 3" />
        <XAxis dataKey="t" />
        <YAxis yAxisId="current" domain={centeredDomain} unit=" A" />
        <YAxis yAxisId="lift" orientation="right" domain={centeredDomain} unit=" mm" />
        <Tooltip />
        <Legend />
        <Line yAxisId="current" type="monotone" dataKey="current" stroke="#a72226" />
        <Line yAxisId="lift" type="monotone" dataKey="lift" stroke="#82ca9d" />
      </LineChart>
    </ResponsiveContainer>
  );
};

export default Overview;

解决方案

1. 按数据比例计算独立域(保持零点对齐)

核心思路是让两个Y轴的零点在图表垂直中心对齐,但各自的上下范围根据自身数据的极值比例调整,避免小范围数据被压缩。具体步骤:

  • 分别计算两个系列的最大绝对值
  • 以其中一个系列的域为基准,按比例缩放另一个系列的域,确保零点位置一致

修改后的域计算代码:

const Overview = () => {
  const currentData = data.map(item => item.current);
  const liftData = data.map(item => item.lift);

  const maxCurrentAbs = Math.max(Math.abs(Math.min(...currentData)), Math.max(...currentData));
  const maxLiftAbs = Math.max(Math.abs(Math.min(...liftData)), Math.max(...liftData));

  // 以current轴的域为基准,计算lift轴的对称域,保证零点在垂直中心
  const currentDomain = [-maxCurrentAbs, maxCurrentAbs];
  // 计算比例,让lift轴的范围适配自身数据,同时零点对齐
  const scaleRatio = maxLiftAbs / maxCurrentAbs;
  const liftDomain = [-maxCurrentAbs * scaleRatio, maxCurrentAbs * scaleRatio];

  return (
    <ResponsiveContainer width="100%" height={300}>
      <LineChart data={data}>
        <CartesianGrid strokeDasharray="3 3" />
        <XAxis dataKey="t" />
        <YAxis yAxisId="current" domain={currentDomain} unit=" A" />
        <YAxis yAxisId="lift" orientation="right" domain={liftDomain} unit=" mm" />
        <Tooltip />
        <Legend />
        <Line yAxisId="current" type="monotone" dataKey="current" stroke="#a72226" />
        <Line yAxisId="lift" type="monotone" dataKey="lift" stroke="#82ca9d" />
      </LineChart>
    </ResponsiveContainer>
  );
};

2. 视觉增强提升小范围数据可见性

针对lift这类数值范围小的系列,通过视觉优化强化辨识度:

  • 增加线条粗细:设置strokeWidth={2}
  • 添加数据标记点:启用dot={{ r: 3 }}
  • 调整线条样式:比如使用strokeDasharray="2 2"区分系列

示例代码:

<Line 
  yAxisId="lift" 
  type="monotone" 
  dataKey="lift" 
  stroke="#82ca9d" 
  strokeWidth={2} 
  dot={{ r: 3, fill: "#82ca9d" }}
/>

3. 自定义Tooltip优化数据展示

通过自定义Tooltip内容,清晰区分两个系列的数值,避免混淆:

const CustomTooltip = ({ active, payload }) => {
  if (active && payload && payload.length) {
    return (
      <div style={{ backgroundColor: '#fff', padding: '8px', border: '1px solid #ccc' }}>
        <p>时间: {payload[0].payload.t}</p>
        <p style={{ color: '#a72226' }}>电流: {payload[0].value} A</p>
        <p style={{ color: '#82ca9d' }}>位移: {payload[1]?.value} mm</p>
      </div>
    );
  }
  return null;
};

// 在LineChart中替换Tooltip
<Tooltip content={<CustomTooltip />} />

内容的提问来源于stack exchange,提问作者said al hendi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 18:45:01