| '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; |
|
|
| |
| 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> |
| ); |
| } |