我被要求将长字符串值作为我的 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>
您需要创建一个自定义 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。
实际上,仅使用
就我而言,我还需要交替 y 位置以防止文本重叠。
<Text x={x} y={y+offset} style={{fontSize: "12px"}} fill="#000000" textAnchor="middle" width="170" verticalAnchor="start">
{payload.value}
</Text>
我编写了一个组件,可以更准确地输出多行字符串。只需在标签字符串中添加
\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>
);
}