-
Notifications
You must be signed in to change notification settings - Fork 151
Expand file tree
/
Copy pathpie-chart.tsx
More file actions
98 lines (90 loc) · 2.89 KB
/
pie-chart.tsx
File metadata and controls
98 lines (90 loc) · 2.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import {
PieChart as RechartsPieChart,
Pie,
Tooltip,
ResponsiveContainer,
} from "recharts";
import { z } from "zod";
import { CHART_COLORS, CHART_CONFIG } from "./config";
import { ExportOverlay } from "../export-overlay";
export const PieChartProps = z.object({
title: z.string().describe("Chart title"),
description: z.string().describe("Brief description or subtitle"),
data: z.array(
z.object({
label: z.string(),
value: z.number(),
}),
),
});
type PieChartProps = z.infer<typeof PieChartProps>;
export function PieChart({ title, description, data }: PieChartProps) {
const hasData = data && Array.isArray(data) && data.length > 0;
if (!hasData) {
return (
<div className="rounded-xl border dark:border-zinc-700 shadow-sm p-6 max-w-lg mx-auto my-6 bg-[var(--background)]">
<div className="mb-4">
<h3 className="text-xl font-bold dark:text-white">{title}</h3>
<p className="text-sm text-gray-600 dark:text-zinc-400">
{description}
</p>
</div>
<p className="text-gray-500 dark:text-zinc-400 text-center py-8">
No data available
</p>
</div>
);
}
// Add colors to data
const coloredData = data.map((entry, index) => ({
...entry,
fill: CHART_COLORS[index % CHART_COLORS.length],
}));
return (
<ExportOverlay
title={title}
componentType="pieChart"
componentData={{ title, description, data }}
>
<div className="rounded-xl border dark:border-zinc-700 shadow-sm p-6 max-w-lg mx-auto my-6 bg-[var(--background)]">
<div className="mb-4">
<h3 className="text-xl font-bold dark:text-white">{title}</h3>
<p className="text-sm text-gray-600 dark:text-zinc-400">
{description}
</p>
</div>
<ResponsiveContainer width="100%" height={300}>
<RechartsPieChart>
<Pie
data={coloredData}
dataKey="value"
nameKey="label"
cx="50%"
cy="50%"
outerRadius={100}
isAnimationActive={true}
animationDuration={800}
animationEasing="ease-out"
animationBegin={200}
/>
<Tooltip contentStyle={CHART_CONFIG.tooltipStyle} />
</RechartsPieChart>
</ResponsiveContainer>
{/* Legend */}
<div className="mt-4 grid grid-cols-2 gap-2">
{data.map((item, index) => (
<div key={index} className="flex items-center gap-2">
<div
className="w-3 h-3 rounded-sm"
style={{
backgroundColor: CHART_COLORS[index % CHART_COLORS.length],
}}
/>
<span className="text-sm dark:text-zinc-300">{item.label}</span>
</div>
))}
</div>
</div>
</ExportOverlay>
);
}