PieChartPanel.tsx 1,69 ko
Newer Older
import { PieChart, Pie } from "recharts";
import { Card, CardContent } from "@/components/ui/card";
import {
	ChartContainer,
	ChartTooltip,
	ChartTooltipContent,
	type ChartConfig,
} from "@/components/ui/chart";
export default function PieChartPanel({
	data,
}: {
	data: { name: string; value: number }[];
}) {
	const BASE_COLORS = [
		"#0B5FFF",
		"#00A78E",
		"#FFB020",
		"#6B21A8",
		"#475569",
		"#EF4444",
		"#10B981",
		"#6366F1",
		"#F59E0B",
		"#E11D48",
		"#06B6D4",
		"#8B5CF6",
	];
	const count = data ? data.length : 0;
	const palette =
		count > 0 && count > BASE_COLORS.length
			? Array.from(
					{ length: count },
					(_, i) => `hsl(${Math.round((i * 360) / count)},65%,50%)`,
				)
			: BASE_COLORS;

	const slug = (s: string) =>
		s
			.toLowerCase()
			.replace(/\s+/g, "-")
			.replace(/[^a-z0-9-_]/g, "");

	const chartData = data.map((d, i) => {
		const key = slug(d.name);
		return {
			key,
			name: d.name,
			taxs: d.value,
			fill: palette[i % palette.length],
		};
	});

	const chartConfig = chartData.reduce(
		(acc: any, d, i) => {
			acc[d.name] = { label: d.name, color: palette[i % palette.length] };
			return acc;
		},
		{} as Record<string, any>,
	) as ChartConfig;

	return (
		<Card className="flex flex-col">
			<CardContent className="flex-1 pb-0">
				<ChartContainer
					config={chartConfig}
					className="mx-auto aspect-square max-h-[300px]"
				>
					<PieChart>
						<ChartTooltip
							cursor={false}
							content={<ChartTooltipContent hideLabel />}
						/>
						<Pie
							data={chartData}
							dataKey="taxs"
							nameKey="name"
							innerRadius={60}
							outerRadius={100}
						/>
					</PieChart>
				</ChartContainer>
			</CardContent>
		</Card>
	);