Cjmaret
Cjmaret

Reputation: 211

Structuring data in Recharts

I have some data is nested, that looks a bit like this:

  let testData = [
    {
      animalType: 'Bird',
      data: [
        {
          animalName: 'Raven',
          animalLength: 120,
        },
        {
          animalName: 'Hawk',
          animalLength: 95,
        },
      ],
    },
    {
      animalType: 'Fish',
      data: [
        {
          animalName: 'Salmon',
          animalLength: 105,
        },
      ],
    },
    {
      animalType: 'Mammal',
      data: [
        {
          animalName: 'Dog',
          animalLength: 120,
        },
        {
          animalName: 'Cat',
          animalLength: 150,
        },
      ],
    },
  ];

I'm trying to create a Recharts Bar Chart using this data, but it's not working. Here's what I need the chart to look like:

enter image description here

So each bar should be the animalLength (and animalName), and should be grouped by animalType on the X Axis. I've been trying every iteration of this, but it seems like the double nested data doesn't allow it to work. There aren't many examples of this for Recharts so I couldn't get a good idea. This one is close, but the values for the X and Y axis are from within the same object.

Here's the BarChart code I'm using currently. Any help would be much appreciated.

 <BarChart
        width={1000}
        height={500}
        data={testData}
        margin={{ top: 40, right: 40, left: 0, bottom: 5 }}>
        <XAxis dataKey='animalType' />
        <YAxis dataKey='animalLength' />
        <CartesianGrid strokeDasharray='3 3' />
        {testData.forEach((agency) => {
          <Bar type='monotone' dataKey='animalName' />;
        })}
      </BarChart>

Upvotes: 0

Views: 655

Answers (1)

stasdes
stasdes

Reputation: 669

something like this will do the work if in each animal type you have 1 or 2 animal names... if you have more you will need to adjust

import { BarChart, Bar, Cell, XAxis, YAxis, ResponsiveContainer } from 'recharts'

let data = [
  {
    animalType: 'Bird',
    animal1Name: 'Raven',
    animal1Length: 120,
    animal1Color: 'red',
    animal2Name: 'Hawk',
    animal2Length: 95,
    animal2Color: 'red',
  },
  {
    animalType: 'Fish',
    animal1Name: 'Salmon',
    animal1Length: 105,
    animal1Color: 'blue',
  },

  {
    animalType: 'Mammal',
    animal1Name: 'Dog',
    animal1Length: 120,
    animal1Color: 'green',
    animal2Name: 'Cat',
    animal2Length: 150,
    animal2Color: 'green',
  },
]

const App = () => {
  const renderBar = ({ x, y, width, height, animal2Name, fill }) => {
    return (
      <rect
        fill={fill}
        width={width}
        height={height}
        x={animal2Name ? x : x + 60}
        y={y}
        className="recharts-rectangle"
      ></rect>
    )
  }
  return (
    <div style={{ width: '1000px', height: '300px' }}>
      <ResponsiveContainer width="100%" height="100%">
        <BarChart
          width={500}
          height={300}
          data={data}
          margin={{
            top: 20,
            right: 30,
            left: 20,
            bottom: 5,
          }}
        >
          <XAxis dataKey="animalType" />
          <YAxis />
          <Bar dataKey="animal1Length" shape={renderBar}>
            {data.map((entry, index) => (
              <Cell key={`cell-${index}`} fill={entry.animal1Color} />
            ))}
          </Bar>
          <Bar dataKey="animal2Length">
            {data.map((entry, index) => (
              <Cell key={`cell-${index}`} fill={entry.animal2Color} />
            ))}
          </Bar>
        </BarChart>
      </ResponsiveContainer>
    </div>
  )
}

export default App

Upvotes: 1

Related Questions