Skip to content
Sign in
EvalsConfusion matrixMenu

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.

ProA ticket intent classifier on 1,265 cases, drilled into refunds read as exchanges.

Installation

$ pnpm dlx shadcn@latest add @chatcn-pro/confusion-matrix

Usage

tsx
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

ProBinary as recall, loading, empty and error.

Props

PropTypeNotes
labelsstring[]Class names, same order for rows and columns
matrixnumber[][]matrix[actual][predicted] counts
examplesRecord<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] | nullThe drilled cell
loadingbooleanStatic skeleton at the final size
error, onRetryReactNode, () => voidSay how to fix it
localestringNumber and percent formatting

Keyboard

KeyAction
Arrow keysMove between cells (mirrored in right to left)
Home, EndFirst or last cell in the row
Enter, SpaceOpen or close the cases behind the cell
EscapeClose 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.