File size: 2,960 Bytes
bb909a5 66ed0c8 bb909a5 66ed0c8 bb909a5 66ed0c8 bb909a5 bf5a50c bb909a5 1d1e96d bb909a5 bf5a50c bb909a5 bf5a50c bb909a5 bf5a50c bb909a5 66ed0c8 bf5a50c bb909a5 66ed0c8 bb909a5 1d1e96d bb909a5 | 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 | 'use client';
import { ChartData } from '@/types/chart';
import {
Cell,
Legend,
Pie,
PieChart,
ResponsiveContainer,
Tooltip,
} from 'recharts';
type ChartPieProps = {
loading: boolean
data: ChartData[]
}
export function ChartPie({ loading, data }: ChartPieProps) {
const items = 5;
// Calculate percentages
const dataWithPercentages = data ? (() => {
const total = data.reduce((sum, item) => sum + item.value, 0);
return data.map(item => ({
...item,
percentage: total > 0 ? Number(((item.value / total) * 100).toFixed(1)) : 0
}));
})() : [];
const total = dataWithPercentages.reduce((sum, item) => sum + item.value, 0);
if (loading) {
return (
<div className="w-full flex items-center justify-center gap-10 animate-pulse">
<div className="relative">
<div className="w-48 h-48 bg-gray-200 rounded-full" />
<div className="absolute inset-6 bg-white rounded-full" />
</div>
<div className="flex flex-col gap-4">
{Array.from({ length: items }).map((_, index) => (
<div key={index} className="flex items-center gap-3">
<div className="w-4 h-4 bg-gray-200 rounded-sm" />
<div className="h-4 bg-gray-200 rounded w-32" />
</div>
))}
</div>
</div>
);
}
if (!data || data.length === 0) {
return (
<div className="w-full h-60 flex flex-col items-center justify-center text-gray-400">
<div className="w-40 h-40 border-4 border-dashed border-gray-200 rounded-full mb-4" />
<p className="text-sm">No data available</p>
</div>
);
}
return (
<div className="space-y-4">
{/* Total Count */}
<div className="text-center">
<p className="text-sm text-gray-600">Total</p>
<p className="text-2xl font-bold text-gray-800">{total}</p>
</div>
<ResponsiveContainer width="100%"
height={Math.max(250, dataWithPercentages.length * 40)}
// height={300}
>
<PieChart>
<Pie
data={dataWithPercentages}
dataKey="value"
label={({ percentage }) => `${percentage}%`}
>
{dataWithPercentages.map((entry, index) => (
<Cell key={`cell-${index}`} fill={entry.color} />
))}
</Pie>
<Tooltip
formatter={(value: number, name: string, props: any) => [
`${value} (${props.payload.percentage}%)`,
name
]}
/>
<Legend
formatter={(value: string, entry: any) =>
`${value}: ${entry.payload.value} (${entry.payload.percentage}%)`
}
/>
</PieChart>
</ResponsiveContainer>
</div>
);
} |