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

如何在Recharts的X轴刻度标签中显示多行文本?

我太懂这种痛点了——Recharts确实好用,但长X轴标签的显示问题真的磨人!你试过的截断、倾斜、单独做div对齐都没完美解决,核心原因是tickFormatter只能处理字符串,SVG里的换行符根本不生效,得用自定义SVG Tick组件来实现真正的自动换行。

解决方案:自定义SVG Tick组件实现自动换行

Recharts允许通过XAxis的tick属性传入自定义组件,我们可以利用SVG的<tspan>元素来拆分长文本为多行,完美解决对齐和换行问题。具体步骤如下:

1. 编写自定义Tick组件

这个组件会接收Recharts传递的坐标、刻度值等props,把长字符串按需求分割后用<tspan>渲染成多行:

const CustomXAxisTick = ({ x, y, payload, color }) => {
  // 可选分割逻辑:按空格拆分(适合短语类标签)
  const lines = payload.value.split(' ');
  // 或者按固定字符数拆分(适合连续长文本,比如每10个字符换一行)
  // const lines = payload.value.match(/.{1,10}/g) || [payload.value];

  return (
    <text
      x={x}
      y={y}
      textAnchor="end"
      fill={color}
      style={{ fontSize: '12px', textAlign: 'center' }}
    >
      {lines.map((line, index) => (
        <tspan key={index} x={x} dy={index === 0 ? 0 : 16}>
          {line}
        </tspan>
      ))}
    </text>
  );
};
  • <tspan>的dy属性控制每行的垂直间距,这里设为16px,你可以根据字体大小调整。
  • 保留textAnchor="end"和x={x}确保每行都对齐到同一个水平位置。

2. 修改XAxis配置

去掉原来的tickFormatter,改用tick属性指向自定义组件,同时调整边距给多行标签留足空间:

<XAxis 
  dataKey={"Claim"}
  interval={"preserveStartEnd"}
  angle={-35} // 保留你原来的倾斜需求,不需要可以删掉
  tick={<CustomXAxisTick color={colorMode === "dark" ? "#FFFFFF" : "#1A202C"} />}
  textAnchor={"end"}
  axisLine={false}
  offset={20} // 增大偏移量,避免标签被图表底部遮挡
  tickMargin={15}
/>

3. 调整图表底部边距

确保LineChart的margin.bottom足够大,防止换行后的标签被截断:

<LineChart data={data} margin={{ top: 50, right: 250, left: 250, bottom: 100 }} >

完整修改后的代码片段

把组件整合到你的现有代码中:

import React from 'react';
import { ResponsiveContainer, LineChart, CartesianGrid, XAxis, YAxis, Tooltip, Line, LabelList } from 'recharts';

// 自定义X轴多行标签组件
const CustomXAxisTick = ({ x, y, payload, color }) => {
  const lines = payload.value.split(' '); // 按空格拆分,可按需替换
  return (
    <text
      x={x}
      y={y}
      textAnchor="end"
      fill={color}
      style={{ fontSize: '12px', textAlign: 'center' }}
    >
      {lines.map((line, index) => (
        <tspan key={index} x={x} dy={index === 0 ? 0 : 16}>
          {line}
        </tspan>
      ))}
    </text>
  );
};

const YourChartComponent = ({ orderOfItems, incrementalReachSummary, colorMode }) => {
  const data = React.useMemo(() => {
    return orderOfItems?.map((claim, i) => ({
      Item: i + 1,
      Claim: claim, // 无需提前加\n,交给自定义组件处理
      Reach: (
        incrementalReachSummary[claim]?.Summary_Metrics.Reach * 100
      ).toFixed(1),
    }));
  }, [orderOfItems, incrementalReachSummary]);

  return (
    <>
      <ResponsiveContainer width={"60%"} height={200} aspect={2} >
        <LineChart data={data} margin={{ top: 50, right: 250, left: 250, bottom: 100 }} >
          <CartesianGrid strokeDasharray="3" opacity={colorMode === "dark" ? 0.3 : 0.9} />
          <XAxis 
            dataKey={"Claim"}
            interval={"preserveStartEnd"}
            angle={-35}
            tick={<CustomXAxisTick color={colorMode === "dark" ? "#FFFFFF" : "#1A202C"} />}
            textAnchor={"end"}
            axisLine={false}
            offset={20}
            tickMargin={15}
          />
          <YAxis 
            type={"number"}
            domain={[0, 100]}
            axisLine={false}
            tickLine={false}
            tickCount={7}
            tickMargin={10}
            tickFormatter={(Reach) => `${Reach}%`}
            style={{ fill: colorMode === "dark" ? "#FFFFFF" : "#1A202C" }}
          />
          <Tooltip content={<CustomToolTip />} />
          <Line type={"monotone"} strokeWidth={3} dataKey={"Reach"} stroke="#3182CE" activeDot={{ r: 9 }} >
            <LabelList dataKey={"Reach"} offset={14} position={"insideTopLeft"} formatter={(Reach) => `${Reach}%`} fill={colorMode === "dark" ? "#FFFFFF" : "#1A202C"} />
          </Line>
        </LineChart>
      </ResponsiveContainer>
    </>
  );
};

export default YourChartComponent;

关键说明

  • 你之前自定义Tick失败的原因:要么是没正确接收Recharts的props,要么是用了普通字符串的\n(SVG不识别),必须用<tspan>配合dy属性实现多行。
  • 分割逻辑可以灵活调整:如果按空格拆分不符合你的标签内容,换成按固定字符数的正则即可。
  • 边距和偏移量可以根据实际标签行数微调,确保显示完整且对齐美观。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 20:17:37