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
Check · Review · Land · Live done — Landed and live in production.
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
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:
- 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.
- 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.
The full gate on land was red and named no test; the pull is open again.
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/dataand in the add/edit panel forms, and a saved panel keeps it.src/boards/query.ts): it takes an optionalseriescolumn, 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 includeserieswhen the query asks for it, soPOST /api/v1/boards/queryanswers exactly as before for existing queries.src/boards/chart.ts): each type has its own function, anddrawChart(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).runForhelper 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.- 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.tsdraws 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 forchecklists 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.tscoversseries.test/boards-store.test.tschecks 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