import { useMemo } from 'react'; import type { HeatmapProps } from '../types'; import { categorySort} from '../utils/chartUtils'; const Heatmap: React.FC = ({ matrix, judge1, judge2, onCellClick }) => { const { judge1Cat, judge2Cat, maxValue } = useMemo(() => { const j1Categories = Object.keys(matrix).sort(categorySort); let newMaxValue = 1; const allSubCats = new Set(); j1Categories.forEach(cat => { Object.keys(matrix[cat] || {}).forEach(subCat => { allSubCats.add(subCat); const value = matrix[cat][subCat]; if (value > newMaxValue) newMaxValue = value; }); }); // Convert Set to Array and sort const j2Categories = Array.from(allSubCats).sort(categorySort); return { judge1Cat: j1Categories, judge2Cat: j2Categories, maxValue: newMaxValue }; }, [matrix]); const getOpacity = (value: number) => { return value === 0 ? 0.05 : 0.05 + (value / maxValue) * 0.95; }; return (

Transition Matrix

{judge1.split('/')[1] || judge1}
{judge1Cat.map(cat => (
{cat}
))}
{judge1Cat.map(fromCat => (
{judge2Cat.map(toCat => { const value = matrix[fromCat]?.[toCat] || 0; return (
value < 100000 ? onCellClick(fromCat, toCat) : alert("Details only available for values < 100000. Please refine your selection.") } title={`${fromCat} → ${toCat}: ${value}`} >
{value > 0 && {value}}
); })}
))}
{judge2Cat.map(cat => (
{cat}
))}
{judge2.split('/')[1] || judge2}
); }; export default Heatmap;