import { ComposedChart, Bar, Cell, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, ReferenceLine, LabelList } from 'recharts'; export interface WaterfallDataPoint { label: string; value: number; cumulative: number; type: 'initial' | 'increase' | 'decrease' | 'total'; } export interface WaterfallChartProps { data: WaterfallDataPoint[]; title?: string; height?: number; formatValue?: (value: number) => string; } interface ProcessedDataPoint { label: string; value: number; cumulative: number; type: 'initial' | 'increase' | 'decrease' | 'total'; start: number; end: number; displayValue: number; } export function WaterfallChart({ data, title, height = 300, formatValue = (v) => `€${Math.abs(v).toLocaleString()}` }: WaterfallChartProps) { // Process data for waterfall visualization const processedData: ProcessedDataPoint[] = data.map((item) => { let start: number; let end: number; if (item.type === 'initial' || item.type === 'total') { start = 0; end = item.cumulative; } else if (item.type === 'decrease') { // Savings: bar goes down from previous cumulative start = item.cumulative; end = item.cumulative - item.value; } else { // Increase: bar goes up from previous cumulative start = item.cumulative - item.value; end = item.cumulative; } return { ...item, start: Math.min(start, end), end: Math.max(start, end), displayValue: Math.abs(item.value) }; }); const getBarColor = (type: string): string => { switch (type) { case 'initial': return '#64748B'; // slate-500 case 'decrease': return '#059669'; // emerald-600 (savings) case 'increase': return '#DC2626'; // red-600 (costs) case 'total': return '#6D84E3'; // primary blue default: return '#94A3B8'; } }; const CustomTooltip = ({ active, payload }: { active?: boolean; payload?: Array<{ payload: ProcessedDataPoint }> }) => { if (active && payload && payload.length) { const data = payload[0].payload; return (
{data.label}
{data.type === 'decrease' ? '-' : data.type === 'increase' ? '+' : ''} {formatValue(data.value)}
{data.type !== 'initial' && data.type !== 'total' && (Acumulado: {formatValue(data.cumulative)}
)}