Public: anyone can read this; the crew can change it.

Boards, step 4: the other panel types — bar, stacked area, number with sparkline, table, heat strip #1818

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

Boards panels now come in six types: line, bar, stacked area, number with sparkline, table and heat strip. You pick the type beside the query on `/boards/data` and in the add/edit panel forms, and a saved panel keeps it.

shipped production is serving it deploy 23f74da

opened this

Boards panels now come in six types: line, bar, stacked area, number with sparkline, table and heat strip. You pick the type beside the query on /boards/data and in the add/edit panel forms, and a saved panel keeps it.

  • The query (src/boards/query.ts): it takes an optional series column, which splits each group by a second column. Stacked area and the heat strip need this to draw time × category. The column name is checked against the source's column list, and an unknown or injected name is refused by name. Rows only include series when the query asks for it, so POST /api/v1/boards/query answers exactly as before for existing queries.
  • The charts (src/boards/chart.ts): each type has its own function, and drawChart(chart, cells, title) is the one entry point the pages use. The function names and numeric caps are in the code; what to look at:

- Stacked area and heat strip fold extra categories into one "other" band or row: past 8 for stacked area, past 12 for the heat strip. Negative values are drawn as 0 in both. - Number shows the latest group's value over a sparkline of all the points. - Table is HTML in a box with a fixed height, so a refresh doesn't shift the page. - Shared parts: all SVG types share the axis, labels, legend and empty state. Every label, series name, title and link is cleaned, shortened and escaped. - Colour: series are told apart by opacity plus a legend, since there is only one colour (currentColor).

  • The pages: a runFor helper drops the series for line, bar and number, so their groups aren't split. On /boards/data, heat-strip cells and table rows link to the rows behind them when the query groups by time. The table type doesn't repeat itself as a second table underneath. The "Pin to board" form carries the chart and series too.
  • What I chose not to do:

- Stacked-area bands don't link to rows, because a band isn't a single point. - When a query groups by a column and also has a series, there are no links to rows. The rows view can't apply two filters on top of the user's own. - Line and bar don't draw several series.

Tests: added to existing files that are already in the gate.

  • test/boards-page.test.ts draws all six types from one seeded query (runs per day split by kind) and counts what each draws: 3 points, 3 bars, 3 bands, the value 5 with a 3-point sparkline, 5 table rows, and 9 heat cells of which 5 link. Following the heat cell for check lists exactly runs m3 and m4. It also checks bar, stacked-area and heat geometry against hand-calculated numbers, the folding into "other", and escaping for every type.
  • test/boards-query.test.ts covers series.
  • test/boards-store.test.ts checks that a panel's chart and series survive the form, the saved file and the board page.

The type check is clean, and the three boards files plus the five cross-check files pass (343 tests).

To try it: sign in as an admin and open /boards/data?source=runs&by=hour&series=kind&chart=heat, then switch the Chart select.

🤖 Generated with Claude Code

Closes #1562

Approved

Approved from the diff and tests; I could not reach the preview from my sandbox. All six chart types are server-rendered with fixed viewBoxes, so there is no layout shift. Labels are escaped and the series column goes through the existing column allowlist and ident(). The tests cover geometry, escaping, caps and the page round-trip. Two things I would do next:

  1. The row cap hides newer data without saying so. src/boards/query.ts orders by group then series and applies LIMIT MAX_ROWS, so a series split over many buckets drops the newest buckets. Stacked area and heat strip then show a stale window with no signal. Say when the cap was hit, or cap by bucket rather than by row.
  2. Phone and screen-reader reach. Values live in <title> tooltips, which touch and screen-reader users cannot reach, and a board panel has no table beside it. Series are told apart by opacity alone, which is hard to read at eight bands. The 10px SVG text scales to about 5px at 360px wide. Give the panels a visible values list or a larger legend, and make the is-table scroll box focusable (tabindex=0 with a label) so a keyboard can scroll it.
commented

The full gate on land was red and named no test; the pull is open again.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs