77 lines
1.8 KiB
TypeScript
77 lines
1.8 KiB
TypeScript
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
import { Box } from "@mui/material";
|
|
import { PieChart, Pie, Cell, ResponsiveContainer } from "recharts";
|
|
import "./PieCharts.scss";
|
|
|
|
interface IPieChartData {
|
|
name: string;
|
|
value: number;
|
|
}
|
|
|
|
interface IPieChartsProps {
|
|
data?: IPieChartData[];
|
|
}
|
|
|
|
const COLORS = ["#4caf50", "#ff9800", "#f44336", "#9e9e9e"];
|
|
|
|
const defaultData: IPieChartData[] = [
|
|
{ name: "Group A", value: 100 },
|
|
{ name: "Group B", value: 200 },
|
|
{ name: "Group C", value: 400 },
|
|
{ name: "Group D", value: 300 },
|
|
];
|
|
|
|
const RADIAN = Math.PI / 180;
|
|
const renderCustomizedLabel = ({
|
|
cx,
|
|
cy,
|
|
midAngle,
|
|
innerRadius,
|
|
outerRadius,
|
|
percent,
|
|
// index
|
|
}: any) => {
|
|
const radius = innerRadius + (outerRadius - innerRadius) * 0.5;
|
|
const x = cx + radius * Math.cos(-midAngle * RADIAN);
|
|
const y = cy + radius * Math.sin(-midAngle * RADIAN);
|
|
|
|
return (
|
|
<text
|
|
x={x}
|
|
y={y}
|
|
fill="white"
|
|
textAnchor={x > cx ? "start" : "end"}
|
|
dominantBaseline="central"
|
|
>
|
|
{`${(percent * 100).toFixed(0)}%`}
|
|
</text>
|
|
);
|
|
};
|
|
export default function PieCharts({ data = defaultData }: IPieChartsProps) {
|
|
return (
|
|
<Box className="pie-charts">
|
|
<ResponsiveContainer width="100%" height="100%">
|
|
<PieChart>
|
|
<Pie
|
|
data={data}
|
|
cx="50%"
|
|
cy="50%"
|
|
labelLine={false}
|
|
label={renderCustomizedLabel}
|
|
outerRadius="80%" // Percentage-based radius
|
|
fill="#8884d8"
|
|
dataKey="value"
|
|
>
|
|
{data.map((entry, index) => (
|
|
<Cell
|
|
key={`cell-${index}`}
|
|
fill={COLORS[index % COLORS.length]}
|
|
/>
|
|
))}
|
|
</Pie>
|
|
</PieChart>
|
|
</ResponsiveContainer>
|
|
</Box>
|
|
);
|
|
}
|