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

问题描述 投票:0回答:3

我被要求将长字符串值作为我的 X 轴刻度标签。

我尝试了其他图表库,但总的来说,这个库最适合我的情况。我只是不知道如何处理 x 轴标签。

我尝试通过图表下方的值创建单独的

div
map
,但是当 x 轴值超过 7 或 8 个时,我无法保持图表和值之间的对齐。

我有一个

tickFormatter
函数,可以按一定数量的字符切割字符串/隐藏溢出,并在 x 轴上设置一定角度,但他们仍然对此不满意。

这是我目前的代码,我觉得它非常接近可行,我只是希望我能让文本换行到更多行。

使用 SVG 对我来说非常令人困惑,我尝试编写将 SVG 文本元素作为自定义刻度返回的函数,但我无法让它工作。或者当我传递某些东西时,它返回 [object Object] 作为标签。

 const data = React.useMemo(() => {
 return orderOfItems?.map((claim, i) => ({
  Item: i + 1,
  Claim: claim.split(" ").join("\n"),
  Reach: (
    incrementalReachSummary[claim]?.Summary_Metrics.Reach * 100
  ).toFixed(1),
}));
}, [orderOfItems, incrementalReachSummary]);

const tickFormatter = (value: string) => {
const limit = 10; // put your maximum character

if (value.length < limit) return value;
return `${value.split(" ").join("\n")}...`;
};

return (
 <>
  <ResponsiveContainer
    align={"end"}
    w={"60%"}
    height={200}
    aspect={2}
    minWidth={"undefined"}
    maxHeight={"undefined"}
  >
    <LineChart
      data={data}
      margin={{
        top: 50,
        right: 250,
        left: 250,
        bottom: 500,
      }}
    >
      <CartesianGrid
        strokeDasharray="3"
        opacity={colorMode === "dark" ? 0.3 : 0.9}
      />
      <XAxis
        // hide={true}
        dataKey={"Claim"}
        interval="preserveStartEnd"
        angle={-35}
        tickFormatter={tickFormatter}
        textAnchor={"end"}
        axisLine={false}
        offset={5}
        tickMargin={10}
        style={{
          fill: colorMode === "dark" ? "#FFFFFF" : "#1A202C",
          textAlign: "center",
        }}
      >
        {/*<Label value="Claim" offset={100} position="bottom" />*/}
      </XAxis>
      <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>

enter image description here

reactjs charts recharts
3个回答
4
投票

您需要创建一个自定义 tick 反应组件。换行符将不起作用。您将需要使用具有正确

<tspan>
或垂直位置的多个
dy
组件。同时增加图表
bottom
,这样线条就不会被隐藏。

使用

payload.value
访问原始值并创建所需数量的
tspans

<XAxis tick={<CustomizedTick />} />

示例

function CustomizedTick(props) {
    const { x, y, stroke, payload } = props;
    return (
        <g transform={`translate(${x},${y})`}>
        <text x={0} y={0} dy={16} fill="#666">
          <tspan textAnchor="middle" x="0">
            Line 1
          </tspan>
          <tspan textAnchor="middle" x="0" dy="20">
            Line 2
          </tspan>
          <tspan textAnchor="middle" x="0" dy="40">
            Line 3
          </tspan>
        </text>
      </g>
    );
  }

工作codesandbox


0
投票

实际上,仅使用 组件并设置宽度以强制换行会更简单、更清晰。请参阅https://recharts.org/en-US/api/Text

就我而言,我还需要交替 y 位置以防止文本重叠。

<Text x={x} y={y+offset} style={{fontSize: "12px"}} fill="#000000" textAnchor="middle" width="170" verticalAnchor="start">
   {payload.value}
</Text>

0
投票

我编写了一个组件,可以更准确地输出多行字符串。只需在标签字符串中添加

\n
,它就会将标签输出为多行字符串。

你可以这样使用

<XAxis tick={<CustomizedAxisTick />} />

这是自定义刻度组件

function CustomizedAxisTick(props: TickProps) {
  const { fill, height, orientation, payload, stroke, textAnchor, type, width, x, y } = props;

  return (
    <text
      {...{ fill, height, orientation, stroke, textAnchor, type, width, x, y }}
      className="recharts-text recharts-cartesian-axis-tick-value"
    >
      {payload.value.split('\n').map((value: string, index: number) => {
        const dy = 0.71 * (index + 1) + 'em';
        return (
          <tspan dy={dy} key={index} x={payload.tickCoord}>
            {value}
          </tspan>
        );
      })}
    </text>
  );
}
© www.soinside.com 2019 - 2024. All rights reserved.