I want to word-wrap long labels like in this demo. Supposedly this PR supports it, but I couldn't get it to work with
<XAxis dataKey="name" interval={0} width={30} label={<Text width={30} />} />
There is an example here done by lisamartin00
She used a custom axis tick:
const CustomizedAxisTick = React.createClass({
render () {
const {x, y, payload} = this.props;
return <Text x={x} y={y} width={75} textAnchor="middle" verticalAnchor="start">{payload.value}</Text>
}
});
The above answer might do it if your tick is large, but for me it didn't work.
Although the docs mention that the width
prop on the <Text/>
component (from recharts) receives a Number
, you can also pass in width as px
.
Keep the fontSize
and width
prop the same on your custom Tick component to get a break-word feature.
const CustomXAxisTick = ({ x, y, payload }: any) => {
if (payload && payload.value) {
return (
<Text
fontSize={"12px"}
width={"12px"}
x={x}
y={y}
textAnchor="middle"
verticalAnchor="start"
>{payload.value}</Text>
);
}
return null;
};
<XAxis interval={0} tick={<CustomXAxisTick/>} dataKey="name" />
Bonus: interval={0}
prevents your ticks from disappearing easily.
I ended up using a CustomXAxisTick like in J.E.C's answer, but with a dynamically calculated width:
import {BarChart, XAxis, Text /*...*/} from "recharts";
import AutoSizer from "react-virtualized-auto-sizer";
const Y_AXIS_WIDTH = 80; // (approximation)
const CustomXAxisTick = ({ x, y, payload, width }) => {
if (payload?.value) {
return (
<Text
width={width}
x={x}
y={y}
textAnchor="middle"
verticalAnchor="start"
>{payload.value}</Text>
);
}
return null;
};
const MyBarChart = ({barData}) => {
return (
<AutoSizer>
{({height, width}) => (
<BarChart data={barData}>
<XAxis /*...*/
tick={<CustomXAxisTick width={(width - Y_AXIS_WIDTH) / barData.length} />}
/>
{/*...*/}
</BarChart>
)}
</AutoSizer>
);
}