Rechartd: Vertical bar chart - set bar thickness - reactjs

How to set the bars thickness?
<ResponsiveContainer width='100%' aspect={4.0 / 3.0}>
<BarChart data={data} layout="vertical">
<XAxis type="number" hide />
<YAxis dataKey="name" hide reversed type="category" />
<Tooltip />
<Legend />
<Bar legendType="star" dataKey="1" fill="#ff6f31" />
<Bar legendType="star" dataKey="2" fill="#ff9f02" />
<Bar legendType="star" dataKey="3" fill="#ffcf02" />
<Bar legendType="star" dataKey="4" fill="#99cc00" />
<Bar legendType="star" dataKey="5" fill="#88b131" />
</BarChart>
</ResponsiveContainer>
Current Result
Data set
[{1: 0, name: "1"},
{2: 0, name: "2"},
{3: 1, name: "3"},
{4: 1, name: "4"},
{5: 2, name: "5"}]

By using the barSize key in the Bar tag:
<Bar dataKey="pv" barSize={20} fill="#8884d8" />

You can use barSize api to set width on each Bar element
Refer Recharts-Bar for more reference and examples

Use barCategoryGap={30} barGap={5}

Related

Recharts bar label inner padding from top

I'm using recharts and trying to use the position property of the label object in the Bar component to set the label at the top-inner position but I couldn't find the correct approach for it.
code:
<ResponsiveContainer width="100%" height="100%">
<BarChart
data={data}
>
<XAxis
type={"category"}
hide={false}
tickLine={false}
axisLine={false}
dataKey={"age"}
/>
<YAxis hide={true} dataKey={""} axisLine={false} tickLine={false} type={"number"} />
<Bar
dataKey="age"
background={{ fill: "theme.darkblue" }}
label={{ position: "top" }}
>
{data.bar.map((d: IData, index: number) => (
<Cell
key={index}
fill={"green"}
/>
))}
</Bar>
</BarChart>
</ResponsiveContainer>
current:
desirable:

How to sort values in Rechart on x-axis in ascending order

I've 3 demo datasets to visualize in React using Recharts.js.
{ x: 80, y: 50, name: "Page A" },
{ x: 14, y: 80, name: "Page B" },
{ x: 70, y: 38, name: "Page C" },
Unfortunately, the values on the x-axis are not ordered correctly (80 -> 14 -> 70), but follow the order of objects in the data array.
const rechart = () => {
return (
<div>
<ScatterChart width={400} height={400} data={data}>
<XAxis dataKey="x" domain={[0, 100]} />
<YAxis dataKey="y" domain={[0, 100]} axisLine={false} tick={false} />
<Scatter data={data}>
<LabelList dataKey="name" position="right" />
</Scatter>
</ScatterChart>
</div>
);
};
What can I do to sort the values from 0 to 100, not Page A to Page C?
Try sorting your data before passing it as props to the Scatter component
data.sort((a,b) => a.x - b.x)
const rechart = () => {
const sortedData = data.sort((a,b) => a.x - b.x)
return (
<div>
<ScatterChart width={400} height={400} data={data}>
<XAxis dataKey="x" domain={[0, 100]} />
<YAxis dataKey="y" domain={[0, 100]} axisLine={false} tick={false} />
<Scatter data={sortedData}>
<LabelList dataKey="name" position="right" />
</Scatter>
</ScatterChart>
</div>
);
};

Recharts Bar Size not calculated automatically when scale is point

I am using recharts to display a composite chart.
const Chart = ({ responseAverage }) => {
responseAverage = responseAverage.sort((a, b) => a.label - b.label);
return (
<ResponsiveContainer width={700} height={400}>
<ComposedChart
data={responseAverage}
>
<CartesianGrid horizontal={false} strokeDasharray="4 4" />
<XAxis scale="point" dataKey="label" />
<YAxis label={{ value: 'No.Of Employees', angle: -90, position: 'insideLeft' }} tick={false} height={20} />
{/* <Tooltip cursor={false} content={<CustomTooltip teamData={teamData} />} /> */}
<Bar dataKey="count" barSize={40} fill="#AAE5F9" />
<Line connectNulls={true} strokeWidth={3} dot={false} type="monotone" dataKey="count" stroke="#3080ED" />
{/* <LabelList dataKey="name" position="insideTop" /> */}
</ComposedChart>
</ResponsiveContainer>
);
};
In this I am specifying the barSize. But it dosent work in all cases. I want the Bar size to calculate automatically based on the number of values
Is there any workaround for this problem ?
Any help would be really thankfull
If you want to remove the gaps between the bars, you need to remove the barSize parameter from the Bar and add the barCategoryGap={0} parameter to the ComposedChart component.
const Chart = ({ responseAverage }) => {
responseAverage = responseAverage.sort((a, b) => a.label - b.label);
return (
<ResponsiveContainer width={700} height={400}>
<ComposedChart
barCategoryGap={0}
data={responseAverage}
>
<CartesianGrid horizontal={false} strokeDasharray="4 4" />
<XAxis scale="point" dataKey="label" />
<YAxis label={{ value: 'No.Of Employees', angle: -90, position: 'insideLeft' }} tick={false} height={20} />
{/* <Tooltip cursor={false} content={<CustomTooltip teamData={teamData} />} /> */}
<Bar dataKey="count" fill="#AAE5F9" />
<Line connectNulls={true} strokeWidth={3} dot={false} type="monotone" dataKey="count" stroke="#3080ED" />
{/* <LabelList dataKey="name" position="insideTop" /> */}
</ComposedChart>
</ResponsiveContainer>
);
};
If as a result, thin lines remain between the bars, then you can do this:
<Bar dataKey="count" fill="#AAE5F9" stroke="#AAE5F9" strokeWidth={2} />

Recharts grouping x-axis Labels

I have a requirement where I need to show the values between 1,2 as a group and 2,3 as a seperate group. I am trying to customise the x-axis but it's not working
In the above picture I need to show the bars 3 and 3.5 together with miminum gap between them and in sameway 4 and 4.5 together
and this is my code
<ResponsiveContainer width="100%" height="100%">
<ComposedChart
width={500}
height={400}
data={data}
>
<CartesianGrid horizontal={false} strokeDasharray="4 4" />
<XAxis scale="point" dataKey="label" />
<YAxis label={{ value: 'No.Of Employees', angle: -90, position: 'insideLeft' }} tick={false} />
<Tooltip />
<Bar dataKey="count" barSize={40} fill="#AAE5F9" />
<Line connectNulls={true} strokeWidth={3} dot={false} type="monotone" dataKey="count" stroke="#3080ED" />
</ComposedChart>
</ResponsiveContainer>
Any help would be thankfull
I assume your data looks like this:
const data = [
{label: "0", count: 0},
{label: "1", count: null},
{label: "2", count: 1},
{label: "3", count: 1},
{label: "3.5", count: 1},
{label: "4", count: 2},
{label: "4.5", count: 1},
{label: "5", count: 0},
];
They must be converted to the following form:
const data = [
{label: "0", countA: 0, countB: null},
{label: "1", countA: null, countB: null},
{label: "2", countA: 1, countB: null},
{label: "3-3.5", countA: 1, countB: 1},
{label: "4-4.5", countA: 2, countB: 1},
{label: "5", countA: 0, countB: 0},
];
The first method
Add another Bar component to display values in group.
export default function App() {
return (
// <ResponsiveContainer width="100%" height="100%">
<ComposedChart
width={500}
height={400}
data={data}
>
<CartesianGrid horizontal={false} strokeDasharray="4 4" />
<XAxis scale="point" dataKey="label" />
<YAxis label={{ value: 'No.Of Employees', angle: -90, position: 'insideLeft' }} tick={false} />
<Tooltip />
<Bar dataKey="countA" barSize={20} fill="#AAE5F9" />
<Bar dataKey="countB" barSize={20} fill="#79B473" />
<Line connectNulls={true} strokeWidth={3} dot={false} type="monotone" dataKey="countA" stroke="#3080ED" />
</ComposedChart>
// </ResponsiveContainer>
);
}
Result:
The second method
If you want the columns in the groups to be the same width regardless of how many elements are in the group, then you can draw the rectangle for the group yourself.
const getPath = (x, y, width, height, uv, pv) => {
const height1= pv?(height/uv)*pv:height;
return `M${x},${y}
v${height}
h${width}
v${-height1}
h${-width/2}
v${(height1-height)}
h${-width/2}
Z`;
};
const MultiBar: FunctionComponent = (props) => {
const { fill, x, y, width, height, countA, countB } = props;
return <path d={getPath(x, y, width, height, countA, countB)} stroke="none" fill={fill} />;
};
export default function App() {
return (
<ComposedChart
width={500}
height={400}
data={data}
>
<CartesianGrid horizontal={false} strokeDasharray="4 4" />
<XAxis dataKey="label" />
<YAxis type="number" domain={[0, 2]} label={{ value: 'No.Of Employees', angle: -90, position: 'insideLeft' }} tick={false} />
<Bar
dataKey="countA"
fill="#AAE5F9"
shape={<MultiBar />}
>
</Bar>
<Line connectNulls={true} strokeWidth={3} dot={false} type="monotone" dataKey="countA" stroke="#3080ED" />
</ComposedChart>
);
}
Result:
The getPath function returns the path of the SVG element for drawing each bar of the chart. If required, you can add a stroke or make a gap between the bars in the group.
Also, you need to set the domain for the Y-axis by the maximum value of all countA and countB values:
<YAxis type="number" domain={[0, 2]} ... />

Remove Y Axis line but keep the values in recharts

So I have created this chart using recharts:
Is there a way to remove the YAxis line but keep the values visible? Like remove the line but keep 135, 190, etc.
<div className={styles.lineChart}>
<h3 className={styles.title}>Body Weight</h3>
<LineChart
width={800}
height={300}
data={props.data}
margin={{
top: 5, right: 30, left: 20, bottom: 5,
}}
>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="day" />
<YAxis />
<Tooltip />
<Legend layout="horizontal" verticalAlign="top" align="center"/>
<Line type="monotone" dataKey="body weight" stroke="#57c0e8" activeDot={{ r: 8 }} />
</LineChart>
</div>
To hide the YAxis line, you just need to use the props axisLine on the YAxis, and set it to false.
Like this:
<YAxis axisLine={false} />
Update: set tick to false
<XAxis tick={false} hide dataKey="name" />

Resources