Glenncito
Glenncito

Reputation: 930

Bar items in Recharts Stacked Bar Graph do not render when being returned through iteration

I want to iterate through my data object array and return a Bar item for each property, but for some reason rendering does not occur when attempted through mapping.

Heres my code snippet:

const staticData = [{name: '0-30 days', 'To Do': 4000, 'Doing': 2003}, {name: '31-60 days', 'To Do': 1000, 'Doing': 1200}, {name: '61-90 days', 'To Do': 2500, 'Doing': 1500}, {name: '91+ days', 'To Do': 4000, 'Doing': 2400}];

<BarChart width={340} height={180} data={staticData}
                    margin={{top: 5, right: 30, left: -30, bottom: 0}}>
                    <CartesianGrid strokeDasharray="3 3 "/>
                    <XAxis dataKey="name"  interval={0} tick={{fontSize: 8}}/>
                    <YAxis  tick={{fontSize: 8}} allowDataOverflow={true}/>
                    <Tooltip/>
                    {
                        staticData.map((element) => {
                            Object.keys(element).map((s) => {
                                if (s!=="name"){
                                    return (
                                        <Bar barSize={30} dataKey={s} name={s} key={s} stackId="a" fill="#449FDB" />
                                    );
                                }
                                return "";
                            });
                            return "";
                        })
                    }
                </BarChart> 

If I output the values to console, it shows that they are being picked up:

enter image description here

If i replace the iteration with this approach, it works:

<Bar barSize={30} dataKey="To Do" stackId="a" fill="#449FDB" />
<Bar barSize={30} dataKey="Doing" stackId="a"fill="#E67E23" />

The reason I need the iterative approach is because in practice I will be receiving data from an API, and its DataKey properties will vary.

What am I doing wrong?

Thanks.

Upvotes: 0

Views: 1687

Answers (1)

Hein Haraldson Berg
Hein Haraldson Berg

Reputation: 1147

What you need to do is to loop over the keys/labels/names of the segments each stacked bar should consist of; in your case ‘Doing’ and ‘To Do’. If you loop over your data like you suggest, you’ll get it laid out with the opposite perspective, and if you were to include a <Legend /> later on, it would display the day duration ranges, which would already be labels on the axis in your chart, and not what needed explaining in the first place, namely the colored segments in your stacked bars.

Your API should optimally return some kind of reference so you know all the different data points beforehand – alternatively you can loop over your data first and gather all known data point labels in the current data set:

const labels = new Set(data.flatMap(({ name, ...labels }) => Object.keys(labels)))
// -> ['Doing', 'To Do']

You then loop over this array of labels, and render out one <Bar /> for each:

{labels.map((label, index) => (
    <Bar
        dataKey={label}
        stackId="x"
        fill={colors[index]}
        key={label} />
))}

…and that’s pretty much it. Recharts will now generate all the stack segments using magic.

Upvotes: 1

Related Questions