Search code examples
cssreactjsrecharts

Recharts - 2 Pies, disabled Tooltip for one? Or: How to style ResponsiveContainer


enter image description here

enter image description here

I have a React component where I'm trying to (currently) render 2 pie charts. I have a custom Label Text that is working well, that works on the activeIndex of which pie is selected for the chart on the right. However, if both components are inside of 1 , then the that is meant for the chart on the left starts stomping all over my custom label on the right. I'm not sure how to conditionally show the for just 1 .

Alternatively, I tried separating the components into their own , but if you put 2 components inside the same , you get errors. I also tried putting 2 components in there, with their own and components. This works, but the is a bear to style and I can't seem to get the 2 s to be next to each other.

Looking for some guidance as to how to get around either or both of these problems.

const AccountSummary = (props) => {
   const [activeIndex, setActiveIndex] = useState();

   let data = [];
   let total_balance = 0;
   props.accounts.forEach((account) => {
       data.push({ name: account.name, value: account.current_balance });
       total_balance += account.current_balance;
   });
   console.log(props.accounts);
   const formatCurrency = (value) =>
       new Intl.NumberFormat("en-US", {
           maximumSignificantDigits: 10,
           style: "currency",
           currency: "USD",
       }).format(value);

   const data2 = [
       { name: "Equities", value: 800 },
       { name: "Bonds", value: 400 },
   ];

   const onPieEnter = (_, index) => {
       setActiveIndex(index);
   };

   return (
       <div>
        <h4>Total Account Value: {formatCurrency(total_balance)}</h4>

        <ResponsiveContainer width="25%" height={300} style={{ margin: 0 }}>
            <PieChart width={"50%"}>
                <Pie
                    data={data}
                    cx={120}
                    cy={120}
                    innerRadius={70}
                    outerRadius={90}
                    fill="#8884d8"
                    paddingAngle={5}
                    dataKey="value"
                >
                    {data.map((entry, index) => (
                        <Cell
                            key={`cell-${index}`}
                            fill={COLORS[index % COLORS.length]}
                        />
                    ))}
                    <Label
                        value={total_balance}
                        offset={0}
                        position="center"
                        formatter={(value) =>
                            new Intl.NumberFormat("en-US", {
                                maximumSignificantDigits: 10,
                                style: "currency",
                                currency: "USD",
                            }).format(value)
                        }
                    />
                </Pie>
                <Tooltip
                    formatter={(value) =>
                        new Intl.NumberFormat("en-US", {
                            maximumSignificantDigits: 10,
                            style: "currency",
                            currency: "USD",
                        }).format(value)
                    }
                />
                <Pie
                    data={data2}
                    cx={380}
                    cy={120}
                    labelLine={false}
                    outerRadius={80}
                    fill="#8884d8"
                    dataKey="value"
                    activeShape={renderActiveShape}
                    activeIndex={activeIndex}
                    onMouseEnter={onPieEnter}
                >
                    {data2.map((entry, index) => (
                        <Cell
                            key={`cell-${index}`}
                            fill={COLORS[index % COLORS.length]}
                        />
                    ))}
                </Pie>
            </PieChart>
        </ResponsiveContainer>
       </div>
    );
};

export default AccountSummary;

Solution

  • you can use 2 responsive containers for each pie chart, to make them aligned in one line you can use flex box that is wrapping each chart, some thing like this:

    import { useState } from 'react'
    import { ResponsiveContainer, Tooltip, Pie, PieChart, Cell, Label } from 'recharts'
    
    const COLORS = ['red', 'blue', 'green', 'purple']
    
    const AccountSummary = (props) => {
      const [activeIndex, setActiveIndex] = useState()
    
      let data = []
      let total_balance = 0
      props.accounts.forEach((account) => {
        data.push({ name: account.name, value: account.current_balance })
        total_balance += account.current_balance
      })
      console.log(props.accounts)
      const formatCurrency = (value) =>
        new Intl.NumberFormat('en-US', {
          maximumSignificantDigits: 10,
          style: 'currency',
          currency: 'USD',
        }).format(value)
    
      const data2 = [
        { name: 'Equities', value: 800 },
        { name: 'Bonds', value: 400 },
      ]
    
      const onPieEnter = (_, index) => {
        setActiveIndex(index)
      }
    
      return (
        <div style={{ maxWidth: 1000, height: 350 }}>
          <h4>Total Account Value: {formatCurrency(total_balance)}</h4>
          <div style={{ display: 'flex', justifyContent: 'center'}}>
            <div style={{ width: '50%'}}>
              <ResponsiveContainer width="100%" height={300}>
                <PieChart>
                  <Pie
                    data={data}
                    innerRadius={70}
                    outerRadius={90}
                    fill="#8884d8"
                    paddingAngle={5}
                    dataKey="value"
                  >
                    {data.map((entry, index) => (
                      <Cell key={`cell-${index}`} fill={COLORS[index % COLORS.length]} />
                    ))}
                    <Label
                      value={total_balance}
                      offset={0}
                      position="center"
                      formatter={(value) =>
                        new Intl.NumberFormat('en-US', {
                          maximumSignificantDigits: 10,
                          style: 'currency',
                          currency: 'USD',
                        }).format(value)
                      }
                    />
                  </Pie>
                  <Tooltip
                    formatter={(value) =>
                      new Intl.NumberFormat('en-US', {
                        maximumSignificantDigits: 10,
                        style: 'currency',
                        currency: 'USD',
                      }).format(value)
                    }
                  />
                </PieChart>
              </ResponsiveContainer>
            </div>
            <div style={{ width: '50%' }}>
              <ResponsiveContainer width="100%" height={300}>
                <PieChart>
                  <Tooltip
                    formatter={(value) =>
                      new Intl.NumberFormat('en-US', {
                        maximumSignificantDigits: 10,
                        style: 'currency',
                        currency: 'USD',
                      }).format(value)
                    }
                  />
                  <Pie
                    data={data2}
                    labelLine={false}
                    outerRadius={80}
                    fill="#8884d8"
                    dataKey="value"
                    // activeShape={renderActiveShape}
                    activeIndex={activeIndex}
                    onMouseEnter={onPieEnter}
                  >
                    {data2.map((entry, index) => (
                      <Cell key={`cell-${index}`} fill={COLORS[index % COLORS.length]} />
                    ))}
                  </Pie>
                </PieChart>
              </ResponsiveContainer>
            </div>
          </div>
        </div>
      )
    }
    
    export default AccountSummary
    
    

    example