Reputation: 816
I have a bar graph on one of my React pages. It gets data from props that are passed on from another page. I have a bar graph showing three different pieces of data. One shows, "Correct", the other shows, "Incorrect", and the last shows, "Total". I would like to have the color of each bar be different. I've tried using the Cell feature but couldn't get it to work. I also tried changing the name of each piece of data but no luck. Unfortunately, there's not a lot of documentation out there for Recharts. Anybody have any ideas?
import React from 'react';
import {
ResponsiveContainer, BarChart, Bar, Cell, XAxis, YAxis, CartesianGrid, Tooltip, Legend,
} from 'recharts';
export default class GameChart extends React.Component {
constructor(props) {
super(props);
this.state = {
axes: [
{ primary: true, type: 'ordinal', position: 'left' },
{ position: 'bottom', type: 'linear', stacked: true }
],
series: {
type: 'bar'
},
chartData: [
{
name: 'Correct',
total: 0,
},
{
name: 'Incorrect',
total: 0,
},
{
name: 'Total',
total: 0,
},
],
chartLayout: {
title: 'Math Game Results',
yaxis: {
showticklabels: false
},
}
}
}
componentDidUpdate(prevProps) {
if (prevProps.chartData.totalCounter !== this.state.chartData[2].total) {
let tempState = this.state;
tempState.chartData = [
{
name: 'Correct',
total: this.props.chartData.correctCounter,
},
{
name: 'Incorrect',
total: this.props.chartData.incorrectCounter,
},
{
name: 'Total',
total: this.props.chartData.totalCounter,
},
];
this.setState(tempState);
}
}
render () {
return (
<div>
{
(this.state.chartData[2].total > 0) ?
(<ResponsiveContainer width="95%" height={225}>
<BarChart
data={this.state.chartData.slice()}
layout="vertical" barCategoryGap={5}
margin={{top: 5, right: 30, left: 20, bottom: 5,}}
>
<XAxis
type="number"
stroke="#000000"
/>
<YAxis
type="category"
stroke="#000000"
dataKey="name"
/>
<Tooltip
wrapperStyle={{ width: 100, backgroundColor: '#ccc' }}
formatter={function(name) {return `${name}`}}
/>
<Bar
dataKey="total"
fill="#00a0fc"
stroke="#000000"
strokeWidth={1}
/>
</BarChart>
</ResponsiveContainer>
):
(null)
}
</div>
);
}
}
Here's a picture of the current setup. As you can see, each bar has the same color.
Upvotes: 14
Views: 31184
Reputation: 1463
You can add the fill color to the chartData
directly using the fill
key:
[
{
name: 'Correct',
total: 0,
fill: '#1f77b4',
},
{
name: 'Incorrect',
total: 0,
fill: '#ff7f0e',
},
{
name: 'Total',
total: 0,
fill: '#2ca02c',
},
]
Upvotes: 18
Reputation: 816
Ok, thanks to @c0m1t I got it working. All I had to do was make a list of colors above the state class!
import React from 'react';
import {
BarChart, Bar, XAxis, Cell, YAxis, Tooltip, ResponsiveContainer,
} from 'recharts';
const barColors = ["#1f77b4", "#ff7f0e", "#2ca02c"]
export default class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
chartData: [
{
name: "Correct",
total: this.props.chartData.correctCounter
},
{
name: "Incorrect",
total: this.props.chartData.incorrectCounter
},
{
name: "Total",
total: this.props.chartData.totalCounter
}
]
}
}
render() {
return (
<ResponsiveContainer width="95%" height={450}>
<BarChart
data={this.state.chartData.slice()}
margin={{ top: 20, right: 20, left: 20, bottom: 5, }}
data={this.state.chartData}
>
<XAxis
dataKey="name"
stroke="#000000"
/>
<YAxis
stroke="#000000"
/>
<Tooltip
wrapperStyle={{ width: 100, backgroundColor: '#ccc' }}
formatter={function(total) {return `${total}`}}
/>
<Bar
dataKey="total"
fill="#00a0fc"
stroke="#000000"
strokeWidth={1}
>
{
this.state.chartData.map((entry, index) => (
<Cell key={`cell-${index}`} fill={barColors[index % 20]} />
))
}
</Bar>
</BarChart>
</ResponsiveContainer>
);
}
}
Now each bar has a different color.
Upvotes: 26