import { useCallback } from 'react'; import { Treemap as RechartsTreemap, ResponsiveContainer, Tooltip } from 'recharts'; import { rechartsTheme } from '@cameleer/design-system'; export interface TreemapItem { id: string; label: string; value: number; /** 0-100, drives green→yellow→red color */ slaCompliance: number; } interface TreemapProps { items: TreemapItem[]; onItemClick?: (id: string) => void; } function slaColor(pct: number): string { if (pct >= 99) return 'hsl(120, 45%, 85%)'; if (pct >= 97) return 'hsl(90, 45%, 85%)'; if (pct >= 95) return 'hsl(60, 50%, 85%)'; if (pct >= 90) return 'hsl(30, 55%, 85%)'; return 'hsl(0, 55%, 85%)'; } function slaBorderColor(pct: number): string { if (pct >= 99) return 'hsl(120, 40%, 45%)'; if (pct >= 97) return 'hsl(90, 40%, 50%)'; if (pct >= 95) return 'hsl(60, 45%, 45%)'; if (pct >= 90) return 'hsl(30, 50%, 45%)'; return 'hsl(0, 50%, 45%)'; } function slaTextColor(pct: number): string { if (pct >= 95) return 'hsl(120, 20%, 25%)'; return 'hsl(0, 40%, 30%)'; } /** Custom cell renderer for the Recharts Treemap */ function CustomCell(props: Record) { const { x, y, width, height, name, slaCompliance, onItemClick } = props as { x: number; y: number; width: number; height: number; name: string; slaCompliance: number; onItemClick?: (id: string) => void; }; const w = width ?? 0; const h = height ?? 0; if (w < 2 || h < 2) return null; const showLabel = w > 40 && h > 20; const showSla = w > 60 && h > 34; const sla = slaCompliance ?? 100; return ( onItemClick?.(name)} style={{ cursor: onItemClick ? 'pointer' : 'default' }} > {showLabel && ( {name.length > w / 6.5 ? name.slice(0, Math.floor(w / 6.5)) + '\u2026' : name} )} {showSla && ( {sla.toFixed(1)}% SLA )} ); } export function Treemap({ items, onItemClick }: TreemapProps) { // Recharts Treemap expects { name, size, ...extra } const data = items.map(i => ({ name: i.label, size: i.value, slaCompliance: i.slaCompliance, })); const renderContent = useCallback( (props: Record) => , [onItemClick], ); if (items.length === 0) { return
No data
; } return ( { const sla = entry.payload?.slaCompliance ?? 0; return [`${value.toLocaleString()} exchanges · ${sla.toFixed(1)}% SLA`]; }} /> ); }