Skip to content

feat(ui): add the maintainer view, with release changes and change points - #97

Merged
simonvanlierde merged 15 commits into
mainfrom
feat/ui-p1
Oct 30, 2026
Merged

simonvanlierde merged 15 commits into
mainfrom
feat/ui-p1

Conversation

@simonvanlierde

@simonvanlierde simonvanlierde commented Oct 30, 2026 •

Copy link
Copy Markdown
Owner

Phase 1 of our own benchmark UI (decision 0001).

  • just ui-data now lists changes: a move between two releases counts past three times the case's spread, never under 2%, and Apache Otava 0.8.0 marks change points. just release-changes uses the same rule instead of a flat 5%.
  • Each benchmark gets a page: its history over releases, one line per solver or environment, in Observable Plot, with changes marked and listed, a data table, and the view in the URL.
  • A start page lists what moved beyond its noise in each package's latest release, worse first.
  • Keyboard tooltip, SVG download, light and dark, phone width.

Tests: pytest for the detection, vitest for the contract, and Playwright on the real data with axe (no WCAG 2.2 AA violations), screenshots and a 170 KB size budget.

- export_ui.py adds `changes` to the index: moves between two releases in a row larger than
  three times the case's spread (asv's interquartile range over the median), never under 2%,
  and Apache Otava's change points along each series
- scripts/change_points.py runs Otava 0.8.0 through uv in its own environment, since it pins
  its own numpy and scipy; the exporter stays on the standard library
- the index schema gains an optional `changes` list, so format_version stays 1, and the UI's
  contract checks the ids each change names

Signed-off-by: Simon van Lierde <simonvanlierde@gmail.com>
- each benchmark's history over its releases, one line per environment, in Observable Plot,
  with parameters, measure and machine in the URL, a keyboard tooltip, SVG download and a data
  table behind every chart
- the changes the index lists are ringed or drawn as level shifts and listed under the chart;
  a start page lists what moved beyond its noise in each package's latest release
- light and dark themes, phone width, and Playwright tests with axe (WCAG 2.2 AA) and
  screenshots, on a copy of the real exported data
- a size budget of 170 KB gzipped for what a page loads, checked in CI

Signed-off-by: Simon van Lierde <simonvanlierde@gmail.com>
… solver

- a time's lower and upper values are now the middle half of its samples: asv's 99% interval
  from a handful of samples ran below zero; a quartile below zero is left out
- bw2calc's environments get a `label` from what their names pin: KLU, PyPardiso, UMFPACK,
  UMFPACK on Aᵀ or SuperLU, with MKL or OpenBLAS where named; a group whose names pin no
  solver gets none
- measures say what their bounds are, so the UI can caption them

Signed-off-by: Simon van Lierde <simonvanlierde@gmail.com>
…name

- the band and the table's ranges are now whatever bounds the measure describes, captioned with
  its words; for times that is the middle half of the samples
- legends, tips and table columns use an environment's label where every line has its own, and
  the data table lists each label's full environment name
- the real fixture data is exported again with both changes

Signed-off-by: Simon van Lierde <simonvanlierde@gmail.com>
…f the fixtures

Signed-off-by: Simon van Lierde <simonvanlierde@gmail.com>
…ts ids

The typos hook had autocorrected hex in three case ids ("daa" to "data", "ede" to "edge",
"dbe" to "be"), so the index broke the 64-character id rule and reports named cases the index
lacks; the page refused the data and the browser tests timed out. The fixture schema test
now covers the real fixture too and checks every report key is a case in its index.

Signed-off-by: Simon van Lierde <simonvanlierde@gmail.com>
…the ui data does

- release_changes.py drops its flat 5% for noise_threshold: three times the larger spread of
  the two results' samples (interquartile range over the value), and at least 2%
- export_ui.py uses the same function instead of its own copy of the rule
- the site's front-page text and the changelog describe the new rule; the table's columns stay

Signed-off-by: Simon van Lierde <simonvanlierde@gmail.com>
…nvironment

- changes come grouped by series, each in its commits' order, as the index schema says;
  before, every release change came before every change point
- the export empties OUT/reports/ first, so no report from an earlier run lingers unlisted
- change_points.py.lock pins Otava's numpy and scipy, and the export runs it with --locked
- the fixture test checks the order and that every report file is listed

Signed-off-by: Simon van Lierde <simonvanlierde@gmail.com>
- the changes tables scroll by keyboard (focusable region); axe also runs at 375 px
- the start page lists worse before better, then by size, and counts each
- symbols are outlined and change rings at one release grow by a step each, so coinciding
  lines stay visible; the keyboard tip is no longer clipped at the right edge
- light-mode series colours and control borders reach 3:1, checked by a test that reads
  the stylesheet
- the error state sits in the main column with a hint for its kind (missing data, another
  format version, wrong shape)
- one missing report no longer blanks the chart; data without changes says so
- a skip link, rail headings in their own case, one-value axes as plain text, long names
  break after dots and underscores, axis ticks prefer release names, p < 0.001 for tiny p

Signed-off-by: Simon van Lierde <simonvanlierde@gmail.com>
* origin/main:
  feat(compat): draft issue text when a compat column fails (#96)
  fix(compat): skip the UMFPACK refinement case where another solver runs (#95)
  feat(useeio): add a useeio size, the real USEEIO 1.1 system (#94)

Signed-off-by: Simon van Lierde <simonvanlierde@gmail.com>

# Conflicts:
#	_typos.toml
* origin/main:
  docs: mention solver_factorize --cudss in the changelog, roadmap and method (#99)
  feat(solvers): time cuDSS on the GPU in solver_factorize (#98)

Signed-off-by: Simon van Lierde <simonvanlierde@gmail.com>
…port names

- the index schema refuses project, link and group urls that are not http or https, so a
  javascript: url in the data cannot become a link on the site
- the exporter stops on a result whose commit_hash is not a full hash, since the hash
  becomes part of a report's path

Signed-off-by: Simon van Lierde <simonvanlierde@gmail.com>
…d unused styles

- change_points.py leaves out Otava's CLI, database and Slack dependencies, so its lock holds
  three packages instead of 44
- the exporter works out each value's spread from the metric's quartiles where it builds the
  series, instead of passing dicts through metrics() and report()
- solver_labels no longer drops clashing labels; the UI already falls back to full names
- styles.css loses the dark palette copy for a data-theme attribute nothing sets, and the
  legend rules that matched nothing

Signed-off-by: Simon van Lierde <simonvanlierde@gmail.com>
- paramLabels, commitName and noiseText in history.ts replace their copies in the page,
  the chart and latestChanges; the tip uses the verdict word as it is
- the chart component is imported on the first benchmark page, so the start page loads
  about 67 KB gzipped instead of 160 KB
- the data table is built when its disclosure opens, and finds each cell through a map
  by commit

Signed-off-by: Simon van Lierde <simonvanlierde@gmail.com>
Signed-off-by: Simon van Lierde <simonvanlierde@gmail.com>
@simonvanlierde
simonvanlierde merged commit 4050a6b into main Oct 30, 2026
10 checks passed
@simonvanlierde
simonvanlierde deleted the feat/ui-p1 branch October 30, 2026 20:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant