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;
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