Files
towercontrol/components/charts/PriorityDistributionChart.tsx
Julien Froidefond 3c7f5ca2fa feat: update package dependencies and integrate Recharts
- Changed project name from "towercontrol-temp" to "towercontrol" in package-lock.json and package.json.
- Added Recharts library for data visualization in the dashboard.
- Updated TODO.md to reflect completion of analytics and metrics integration tasks.
- Enhanced RecentTasks component to utilize TaskPriority type for better type safety.
- Minor layout adjustments in RecentTasks for improved UI.
2025-09-18 12:48:06 +02:00

101 lines
3.2 KiB
TypeScript

'use client';
import { PieChart, Pie, Cell, ResponsiveContainer, Tooltip, Legend, PieLabelRenderProps } from 'recharts';
import { Card } from '@/components/ui/Card';
interface PriorityData {
priority: string;
count: number;
percentage: number;
[key: string]: string | number; // Index signature pour Recharts
}
interface PriorityDistributionChartProps {
data: PriorityData[];
title?: string;
}
// Couleurs pour chaque priorité
const PRIORITY_COLORS = {
'Faible': '#10b981', // green-500
'Moyenne': '#f59e0b', // amber-500
'Élevée': '#8b5cf6', // violet-500
'Urgente': '#ef4444', // red-500
'Non définie': '#6b7280' // gray-500
};
export function PriorityDistributionChart({ data, title = "Distribution des Priorités" }: PriorityDistributionChartProps) {
// Tooltip personnalisé
const CustomTooltip = ({ active, payload }: { active?: boolean; payload?: Array<{ payload: PriorityData }> }) => {
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="text-sm font-medium mb-1">{data.priority}</p>
<p className="text-sm text-[var(--muted-foreground)]">
{data.count} tâches ({data.percentage}%)
</p>
</div>
);
}
return null;
};
// Légende personnalisée
const CustomLegend = ({ payload }: { payload?: Array<{ value: string; color: string }> }) => {
return (
<div className="flex flex-wrap justify-center gap-4 mt-4">
{payload?.map((entry, index: number) => (
<div key={index} className="flex items-center gap-2">
<div
className="w-3 h-3 rounded-full"
style={{ backgroundColor: entry.color }}
></div>
<span className="text-sm text-[var(--muted-foreground)]">
{entry.value}
</span>
</div>
))}
</div>
);
};
// Label personnalisé pour afficher les pourcentages
const renderLabel = (props: PieLabelRenderProps) => {
const percentage = typeof props.percent === 'number' ? props.percent * 100 : 0;
return percentage > 5 ? `${Math.round(percentage)}%` : '';
};
return (
<Card className="p-6">
<h3 className="text-lg font-semibold mb-4">{title}</h3>
<div className="h-64">
<ResponsiveContainer width="100%" height="100%">
<PieChart>
<Pie
data={data}
cx="50%"
cy="50%"
labelLine={false}
label={renderLabel}
outerRadius={80}
fill="#8884d8"
dataKey="count"
nameKey="priority"
>
{data.map((entry, index) => (
<Cell
key={`cell-${index}`}
fill={PRIORITY_COLORS[entry.priority as keyof typeof PRIORITY_COLORS] || '#6b7280'}
/>
))}
</Pie>
<Tooltip content={<CustomTooltip />} />
<Legend content={<CustomLegend />} />
</PieChart>
</ResponsiveContainer>
</div>
</Card>
);
}