Files
towercontrol/components/dashboard/charts/StatusDistributionChart.tsx
2025-09-19 17:05:13 +02:00

110 lines
3.1 KiB
TypeScript

'use client';
import { PieChart, Pie, Cell, ResponsiveContainer, Tooltip, Legend } from 'recharts';
interface StatusDistributionData {
status: string;
count: number;
percentage: number;
color: string;
}
interface StatusDistributionChartProps {
data: StatusDistributionData[];
className?: string;
}
export function StatusDistributionChart({ data, className }: StatusDistributionChartProps) {
// Transformer les statuts pour l'affichage
const getStatusLabel = (status: string) => {
const labels: { [key: string]: string } = {
'pending': 'En attente',
'in_progress': 'En cours',
'blocked': 'Bloquées',
'done': 'Terminées',
'archived': 'Archivées'
};
return labels[status] || status;
};
const chartData = data.map(item => ({
...item,
name: getStatusLabel(item.status),
value: item.count
}));
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const CustomTooltip = ({ active, payload }: { active?: boolean; payload?: any[] }) => {
if (active && payload && payload.length) {
const data = payload[0].payload;
return (
<div className="bg-[var(--card)] border border-[var(--border)] rounded-lg p-3 shadow-lg">
<p className="font-medium mb-1">{data.name}</p>
<p className="text-sm text-[var(--foreground)]">
{data.count} tâches ({data.percentage}%)
</p>
</div>
);
}
return null;
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const CustomLabel = (props: any) => {
const { cx, cy, midAngle, innerRadius, outerRadius, percent } = props;
if (percent < 0.05) return null; // Ne pas afficher les labels pour les petites sections
const RADIAN = Math.PI / 180;
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"
fontSize={12}
fontWeight="medium"
>
{`${(percent * 100).toFixed(0)}%`}
</text>
);
};
return (
<div className={className}>
<ResponsiveContainer width="100%" height={250}>
<PieChart>
<Pie
data={chartData}
cx="50%"
cy="50%"
labelLine={false}
label={CustomLabel}
outerRadius={80}
fill="#8884d8"
dataKey="value"
>
{chartData.map((entry, index) => (
<Cell key={`cell-${index}`} fill={entry.color} />
))}
</Pie>
<Tooltip content={<CustomTooltip />} />
<Legend
verticalAlign="bottom"
height={36}
formatter={(value, entry: { color?: string }) => (
<span style={{ color: entry.color, fontSize: '12px' }}>
{value}
</span>
)}
/>
</PieChart>
</ResponsiveContainer>
</div>
);
}