'use client'; import { Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Line, ComposedChart } from 'recharts'; import { SprintVelocity } from '@/lib/types'; interface ThroughputChartProps { sprintHistory: SprintVelocity[]; className?: string; } interface ThroughputDataPoint { period: string; completed: number; planned: number; throughput: number; // Tickets par jour trend: number; // Moyenne mobile } export function ThroughputChart({ sprintHistory, className }: ThroughputChartProps) { // Calculer les données de throughput const throughputData: ThroughputDataPoint[] = sprintHistory.map((sprint, index) => { const sprintDuration = 14; // 14 jours de travail par sprint const throughput = Math.round((sprint.completedPoints / sprintDuration) * 10) / 10; // Calculer la moyenne mobile sur les 3 derniers sprints const windowStart = Math.max(0, index - 2); const window = sprintHistory.slice(windowStart, index + 1); const avgThroughput = window.reduce((sum, s) => sum + (s.completedPoints / sprintDuration), 0) / window.length; return { period: sprint.sprintName.replace('Sprint ', ''), completed: sprint.completedPoints, planned: sprint.plannedPoints, throughput: throughput, trend: Math.round(avgThroughput * 10) / 10 }; }); const maxThroughput = Math.max(...throughputData.map(d => d.throughput)); const avgThroughput = throughputData.reduce((sum, d) => sum + d.throughput, 0) / throughputData.length; const CustomTooltip = ({ active, payload, label }: { active?: boolean; payload?: Array<{ payload: ThroughputDataPoint; value: number; name: string; color: string; dataKey: string }>; label?: string }) => { if (active && payload && payload.length) { const data = payload[0].payload; return (

Sprint {label}

Complétés: {data.completed} points
Planifiés: {data.planned} points
Throughput: {data.throughput} pts/jour
Tendance: {data.trend} pts/jour
); } return null; }; return (
{/* Graphique */}
} /> {/* Barres de points complétés */} {/* Ligne de throughput */} {/* Ligne de tendance (moyenne mobile) */}
{/* Légende visuelle */}
Points complétés
Throughput
Tendance
{/* Métriques de summary */}
{Math.round(avgThroughput * 10) / 10}
Throughput moyen
{Math.round(maxThroughput * 10) / 10}
Pic de throughput
{throughputData.length > 1 ? Math.round(((throughputData[throughputData.length - 1].throughput / throughputData[throughputData.length - 2].throughput - 1) * 100)) : 0}%
Évolution sprint
); }