Confusion matrixPro
A classification eval matrix with counts on one sequential tint, row and column totals, recall and precision, and a click to drill into the cases behind any cell.
On this page
Installation
Usage
import { ConfusionMatrix } from "@/components/ui/chatcn/pro/confusion-matrix"
<ConfusionMatrix
labels={["Refund", "Exchange", "Shipping delay"]}
matrix={counts}
examples={casesByCell}
/>Rows are the actual class, columns the predicted one: matrix[actual][predicted]. Every cell is tinted by its share of the row, so a row reads the same at any volume; switch the cells to recall (share of the row) or precision (share of the column). The diagonal carries a hairline ring, so correct cells read without color. The largest off diagonal cell is named above the matrix as the confusion to read first. Pass examples keyed by "actual,predicted" indexes to show the cases behind a cell.
Examples
States
Props
| Prop | Type | Notes |
|---|---|---|
labels | string[] | Class names, same order for rows and columns |
matrix | number[][] | matrix[actual][predicted] counts |
examples | Record<string, ConfusionExample[]> | { id, text, confidence?, note? } keyed "2,0" |
normalize, defaultNormalize, onNormalizeChange | "count" | "recall" | "precision" | What a cell shows. Default count |
selected, defaultSelected, onSelectedChange | [actual, predicted] | null | The drilled cell |
loading | boolean | Static skeleton at the final size |
error, onRetry | ReactNode, () => void | Say how to fix it |
locale | string | Number and percent formatting |
Keyboard
| Key | Action |
|---|---|
| Arrow keys | Move between cells (mirrored in right to left) |
| Home, End | First or last cell in the row |
| Enter, Space | Open or close the cases behind the cell |
| Escape | Close the cases |
Accessibility
- The matrix is an ARIA grid with one tab stop and roving focus.
- Every cell is named in full: actual class, predicted class, count, share and whether it is correct.
- The drill down is a polite live region; the tint never carries meaning alone.
Motion
None. Hover and focus crosshair the two classes instantly, because a reader sweeps across dozens of cells; the loading skeleton pulses only when motion is allowed.