Matrix

A matrix sets one list against another: products against the parts they are made of, people against the projects they work on. Each pair meets in a square, and a mark in the square says how. Read across a row for what it has, and down a column for who has it.

Columns stand in groups. A group’s colour fills its bar and tints the squares below it, and each column’s name rises at 45° from the middle of its square, so many narrow columns can still be named. Under the pointer or the keyboard, the row and the column light up as a crosshair.

Workshop equipment

A small matrix compares materials across activities, using marks rather than repeated words.

Products against their parts

Hover or move with the arrow keys: the row and the column light up. Pressing a square fires cell-press.

<ds-matrix label="Products and parts" literal totals></ds-matrix>
const matrix = document.querySelector("ds-matrix");
matrix.groups = [
{ id: "stack", label: "Stack", color: "var(--ds-orange)" },
{ id: "parts", label: "Parts", color: "var(--ds-pink)" },
];
matrix.columns = [
{ id: "typescript", label: "TypeScript", group: "stack" },
{ id: "sign-in", label: "Sign-in", group: "parts" },
];
matrix.rows = [{ id: "atlas", label: "Atlas" }, { id: "harbor", label: "Harbor" }];
matrix.cells = [
{ row: "atlas", column: "typescript", mark: "fill" },
{ row: "atlas", column: "sign-in", mark: "triangle", note: "From the shared source" },
];
matrix.marks = [
{ mark: "fill", label: "Uses" },
{ mark: "triangle", label: "Shares one copy" },
];
matrix.addEventListener("cell-press", event => open(event.detail.row, event.detail.column));

A column without a group stands after the groups, untinted. marks names what each mark means: it is drawn as the legend below, and gives each square its name (“Atlas, Sign-in: Shares one copy”).

MarkDrawn as
fillThe square filled with its column’s colour.
outlineA 1px outline in a darker shade of the colour, over a lighter fill.
stripesDiagonal stripes in the darker shade, on a 4px tile that runs on from square to square.
triangleA small triangle in the darker shade.
dotA small dot in the darker shade.
dashA short dash in the title grey: the pair does not apply. It is not counted.

The darker shade is the column’s colour mixed with the ink, so a column of marks stays calm instead of turning black.

ThingSize
A squareOne square: 19px inside and a 1px line at its end and foot, so a mark fills the inside exactly.
The row namesEight squares (names), ending 4px clear of the squares, cut short with an ellipsis.
A group’s barOne square high over its columns, its name in the ink on the sixteen, fading over its last 12px.
The column namesSix squares high, rising at 45° from the middle of their square.
The tintThe group’s colour at 22% under its column names and squares.
The outlineOne 1px line round the squares, with the system’s 4px corners.
The totalsWith totals, a last row counting each column’s marks, in small type.
The legendSmall type on one-square lines, starting where the squares start, each mark in a 16px box.
  • The matrix is a grid named by label, with the column names as column headers and the row names as row headers.
  • One square holds the Tab stop. The arrow keys move between squares, Home and End to a row’s first and last square, and with ⌘ (Ctrl) to the matrix’s first and last.
  • Each square is named by its row, its column, its mark’s meaning and its note; the same words show as its tooltip when the page loads the tooltips.
  • Enter or Space presses the square. Pressing a row’s or a column’s name fires row-press or column-press.
AttributeTypeDefaultWhat it does
labelstring—The grid’s name; literal shows it as written.
totalsbooleanfalseA last row counting each column’s marks.
totals-labelstringThe shared word “Total”That row’s name.
namesnumber8Squares for the row names.
PropertyTypeWhat it is
rows{ id, label }[]The rows.
columns{ id, label, group? }[]The columns.
groups{ id, label, color }[]The column groups, in order. Take the colours from the palette.
cells{ row, column, mark, note? }[]The marks.
marks{ mark, label }[]The legend.
EventDetailWhat it means
cell-press{ row, column, cell }A square was pressed; cell is undefined when it is empty.
row-press{ row }A row’s name was pressed.
column-press{ column }A column’s name was pressed.
PartWhat it is
grid, group, column, name, cell, count, legendThe pieces above.
Custom propertyDefaultWhat it sets
--ds-matrix-linevar(--ds-border-color)The squares’ lines and the outline.
--ds-matrix-colourvar(--ds-accent-color)A column’s colour when it has no group.