You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[API] Add multi-value test to POST /query and machine/metric filters to /tests
Change the /query endpoint from GET to POST with a JSON body to
eliminate URL length limits when querying many tests with long names.
The test field accepts a list for disjunction queries. Unknown test
names are silently skipped. The schema uses marshmallow's unknown=RAISE
to reject unknown fields (returning 422 instead of the previous 400).
Add optional machine= and metric= query parameters to GET /tests so
clients can discover which tests have actual data for a given machine
and/or metric combination, joining through Sample -> Run with DISTINCT.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Copy file name to clipboardExpand all lines: docs/design/v5-ui.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -181,11 +181,11 @@ The primary performance-over-time visualization. Replaces v4's graph page. This
181
181
- **Zoom preservation during progressive loading**: If the user zooms into the chart while data is still loading, the zoom is preserved across incremental updates. The x-axis range is always preserved (it was established by the scaffold or by user zoom). The y-axis range is preserved only when the user has explicitly zoomed; otherwise, it auto-ranges to accommodate new data as it arrives. Double-clicking the chart resets the zoom to the full range as usual.
182
182
- **Legend table**: Below the chart, a table lists traces sorted alphabetically by name (not in a scrollable container — the table is part of the page flow, like the Compare page's table). A message line above the table rows always shows a matching count (e.g., "42 of 150 tests matching"); when the 20-cap is active, the cap warning replaces it. Each row represents one trace (`{test name} - {machine name}`), with a colored marker symbol character (●, ▲, ■, etc. in the trace's color) identifying both the test (by color) and the machine (by shape). The test filter matches on test name only — matching test names show all their machine variants; non-matching names are hidden entirely. Tests that are inactive (manually hidden or beyond the 20-cap) are grayed out in place. Clicking a row toggles the test's visibility on the chart. Double-clicking a row is a shortcut for hiding all other visible tests (equivalent to single-clicking every other test one by one) — it populates `manuallyHidden` with all visible tests except the double-clicked one. Double-clicking the same test again when it is the only visible test restores all tests. Subsequent single-clicks work naturally against the `manuallyHidden` set. Plotly's built-in legend is disabled; the table replaces it. Bidirectional hover highlighting: hovering a table row highlights the corresponding chart trace by emphasizing the entire trace line (thicker line, full opacity) while dimming all other traces via `Plotly.restyle()`; hovering a chart trace highlights the table row.
183
183
- **Active state and 20-cap**: A trace is active (plotted) when its test name matches the text filter and it has not been manually hidden by clicking its row. A default 20-test cap auto-activates the first 20 alphabetical trace names when there is no text filter and no manual toggles. As soon as the user types a filter or manually toggles any row, the cap is permanently disabled for the rest of the page session. Colors are assigned by alphabetical index of all **test names** (not trace names) using a fixed palette, ensuring the same test on different machines shares the same color.
184
-
- **Baselines**: Users can overlay one or more baselines as horizontal dashed lines on the chart. Each baseline is a (suite, machine, order) tuple, allowing cross-suite comparisons. The selector is an expandable panel with cascading dropdowns: Suite (populated from `data-testsuites`) → Machine (populated from the selected suite's machines endpoint) → Order (populated from the selected machine's orders). Added baselines appear as removable chips labeled `{suite}/{machine}/{order} ({tag})`. Baseline data is fetched from the baseline's suite via `GET /api/v5/{suite}/query?machine=...&metric=...&order=...`. Each baseline renders as a horizontal dashed line per test trace, spanning the full chart width, in a distinct color per baseline. The baseline's Y value for each test is computed using the same run aggregation function as the main trace (e.g., median of all runs at that order), so the dashed line aligns exactly with the trace point at that order. Hovering a dashed line shows a tooltip with: the baseline suite, machine, order value, tag (if set), test name, and metric value. Baselines are encoded in the URL query string for shareability (e.g., `&baseline=nts::machine1::abc123&baseline=other_suite::machine2::def456`). Baseline data is fetched asynchronously after the first render, so it does not block initial chart display.
184
+
- **Baselines**: Users can overlay one or more baselines as horizontal dashed lines on the chart. Each baseline is a (suite, machine, order) tuple, allowing cross-suite comparisons. The selector is an expandable panel with cascading dropdowns: Suite (populated from `data-testsuites`) → Machine (populated from the selected suite's machines endpoint) → Order (populated from the selected machine's orders). Added baselines appear as removable chips labeled `{suite}/{machine}/{order} ({tag})`. Baseline data is fetched from the baseline's suite via `POST /api/v5/{suite}/query` with `{machine, metric, order, test}` in the JSON body. Each baseline renders as a horizontal dashed line per test trace, spanning the full chart width, in a distinct color per baseline. The baseline's Y value for each test is computed using the same run aggregation function as the main trace (e.g., median of all runs at that order), so the dashed line aligns exactly with the trace point at that order. Hovering a dashed line shows a tooltip with: the baseline suite, machine, order value, tag (if set), test name, and metric value. Baselines are encoded in the URL query string for shareability (e.g., `&baseline=nts::machine1::abc123&baseline=other_suite::machine2::def456`). Baseline data is fetched asynchronously after the first render, so it does not block initial chart display.
185
185
- **Concurrent background fetches**: Each machine×metric fetch uses its own AbortController, so navigating away or removing a machine cancels its in-flight requests cleanly without affecting other machines' fetches.
186
186
- **Hover** a data point: tooltip showing test name, machine name, order value, aggregated metric value, run count. Hover distance is reduced (`hoverdistance: 5`, less sticky tooltips) so the tooltip only appears when the cursor is close to a data point. When hovering over an aggregated point that represents multiple runs, the individual pre-aggregation values are shown as a scatter of markers at the same x-position, in the same trace color but faded (opacity 0.3). This scatter is computed lazily via a callback and displayed as a temporary Plotly trace that is added on hover and removed on unhover.
187
187
- **"No data to plot" annotation**: When no traces match the current filter/settings, the chart displays a Plotly annotation overlay ("No data to plot") centered on the chart area, preserving the x-axis scaffold so the user can see the order range.
188
-
- API: `GET query?machine=...&metric=...&sort=-order&limit=10000` (one fetch pipeline per machine, newest-first with cursor pagination — returns data for all tests, filtered client-side), `GET machines/{name}/runs?sort=order` (x-axis scaffold, per machine), `GET orders` (tags for baseline suggestions), `GET machines` (machine combobox), `GET test-suites/{ts}` (fields/metrics)
188
+
- API: `POST query` with JSON body `{machine, metric, test, sort, limit, cursor}` (one fetch pipeline per machine, targeted to discovered tests via multi-value `test`), `GET tests?machine=...&metric=...&name_contains=...` (test name discovery), `GET machines/{name}/runs?sort=order` (x-axis scaffold, per machine), `GET orders` (tags for baseline suggestions), `GET machines` (machine combobox), `GET test-suites/{ts}` (fields/metrics)
189
189
- **URL state**: `?suite={ts}&machine={name}&machine={name2}&metric={name}&test_filter={text}&run_agg={fn}&sample_agg={fn}&baseline={suite}::{machine}::{order}&baseline={suite2}::{machine2}::{order2}` — the `machine` parameter is repeated for each selected machine; the `baseline` parameter is repeated for each baseline.
0 commit comments