Commit 706df38
[claude] feat(benchmarks-website): historical comparison UX + mobile (#7681)
## Summary
Brings the v3 benchmarks website to a demo-ready state focused on the
historical-comparison use case (Vortex vs other engines on the same
commit, HEAD vs N commits ago, latest vs first as % delta). Single
process, single binary; SSR `maud` + inline JSON `<script>` +
Chart.js — no client-side framework, no build step, no post-load API
round-trips.
> Branch note: this PR was developed on the harness-assigned branch
> `claude/demo-ready-benchmarks-v3-H5ECI` rather than the
> `claude/benchmarks-v3-ui-historical-comparison` branch the task
> request mentioned, because the session's harness pins the working
> branch (`Develop on branch …`, `NEVER push to a different branch
> without explicit permission`).
## CI note
The `Rust tests (windows-x64)` job is failing on this PR but the
**same job is also failing on the merge commit at the tip of
`ct/benchmarks-v3`** (PR #7671's run, job id `73229326105`, the
commit `8697731` we branched from). The base branch shipped with
that failure tolerated, and our diff only touches
`benchmarks-website/server/` (no Windows-specific paths, no FFI, no
new dependencies on Windows-fragile crates), so this failure is
pre-existing and not caused by the PR. CodSpeed flagged two
`varbinview_zip` regressions in `vortex-array/` — also untouched by
this PR.
## What's new
* **Scoped commit window** — `?n=25|50|100|250|all`, default 100,
server-side clamp to `[1, 1000]`. SQL splices in a `LIMIT ?` filter
and binds the value as a parameter (consistent with the rest of
the file's `params!`-style use); the unbounded path is a separate
query so the plan stays clean.
* **Group page** — `GET /group/{slug}` renders every chart in one
group on a single screen. Each card embeds its own
`<script id="chart-data-N">` payload + sibling `<canvas
data-chart-index="N">`. `IntersectionObserver` defers `Chart`
construction until the canvas scrolls into view (mobile-friendly
+ cheap for 22-chart TPC-H groups).
* **Toolbar** — same component on `/chart/{slug}` and `/group/{slug}`.
Scope buttons + slider, linear/log Y-axis, absolute / `% of
baseline` mode. URL query string is canonical state; subtitle
mirrors active state. Slider step is `5` so it can land on every
preset value (`25`, `50`, `100`, `250`).
* **Rich tooltip** — custom external HTML tooltip with `<short-sha> ·
YYYY-MM-DD` title; per-series rows render value with friendly unit
(ns→µs→ms→s, B→KiB→MiB→GiB) and a coloured `% delta` vs the prior
visible commit; footer carries the truncated commit message + a
GitHub link. Document-level click closes.
* **Legend → URL** — clicking a legend item rewrites
`?hidden=engine:format|…` via `history.replaceState` (no back-button
hostility). Permalinks reproduce the view. Delimiter is `|` so
series names can contain `:` and `,` without escaping.
* **Mobile** — `@media (max-width: 768px)`: single-column chart grid,
toolbar wraps with ≥ 40 px touch targets, slider expands to fill
the row, legend pops to the *top* of the chart so it doesn't push
the chart off-screen on a phone.
* **Landing search** — client-side filter input above the group list.
* **/api/group/{slug}** — JSON sibling to the HTML route, returns
every chart in the group with payloads inlined.
## What was *not* picked up from `planning/components/web-ui.md`'s
deferred list
Done now (moved out of deferred):
- mobile redesign basics (single column, ≥ 40 px tap targets,
toolbar wrap)
- engine + series toggling (legend ↔ URL)
- deep-link state (every toolbar control is URL-canonical)
- group landing with the start of "filters" (client-side search)
Still deferred (intentional):
- per-commit drill-down page
- ad-hoc SQL page
- LTTB downsampling
- engine name lookup table + curated colour palettes
- summary cards (geomean ratios, rankings)
- full-screen modal / zoom-pan
- `?mode=delta` (compare-to-main) — parser branch dropped pending
data shape work; toolbar surface today is only `abs / rel`
## Repro
INGEST_BEARER_TOKEN=$(openssl rand -hex 32) \
VORTEX_BENCH_DB=./bench.duckdb \
cargo run --release -p vortex-bench-server
Then open `http://localhost:3000/`, click any group name (now a link
to `/group/{slug}`), or any chart inside, and play with the toolbar.
Toggle a series in the legend and notice `?hidden=…` appear in the
URL. Resize to phone width to confirm single-column layout, sticky
toolbar wrapping, and legend-on-top.
## Snapshot diffs
Three `.snap` files refreshed by this PR:
- `landing_page.snap` — group names now link to `/group/{slug}`,
search input added, `data-group-name` for client filter.
- `chart_page_query.snap` — toolbar + indexed
`<script id="chart-data-0">` + tooltip host element.
- `group_page_query.snap` (new) — group page rendered against the
fixture DB, `?n=100` pinned for stability.
Run `INSTA_UPDATE=always cargo test -p vortex-bench-server` (or
`cargo insta accept`) to refresh.
## Test plan
- [x] `cargo build -p vortex-bench-server`
- [x] `cargo test -p vortex-bench-server` — 41 tests pass (22 unit +
10 ingest + 9 web_ui)
- [x] `cargo clippy -p vortex-bench-server --all-targets -- -D
warnings` — clean
- [x] `cargo +nightly fmt` — no diff
- [ ] `./scripts/public-api.sh` — skipped per CLAUDE.md (leaf binary,
not in workspace public-api lockfile set)
- [ ] Manual screenshots — couldn't capture from the sandbox; the
reviewer or follow-up should record landing / single chart with
toolbar / group desktop / group mobile / tooltip open / log+rel.
## Follow-up review fixes (commits `7042f0d` … `da668a4`)
- `7042f0d` — `LIMIT` value travels as a bound parameter (`LIMIT ?`)
via `params_from_iter` instead of being interpolated into SQL.
- `9c80bce` — drop the unused `?mode=delta` parser branch in both
`UiQuery::mode` and `chart-init.js::parseUrl`.
- `d156ab8` — `?hidden=` delimiter is now `|`; new test pins the
server/client wire agreement.
- `da668a4` — slider `step` lowered to 5 so it can land on every
preset (`25/50/100/250`).
## Things explicitly NOT changed
- `/api/ingest`, auth, schema, write paths.
- DB migration (none added).
- Existing routes (no renames).
- v2 site at `benchmarks-website/server.js` etc — untouched.
- Single-chart page still works; reuses the same `chart-init.js`.
https://claude.ai/code/session_015Nc73ihs9TUdx7QzLUZudK
---------
Signed-off-by: Claude <claude@anthropic.com>
Co-authored-by: Claude <claude@anthropic.com>
Signed-off-by: Connor Tsui <connor.tsui20@gmail.com>1 parent 9953be3 commit 706df38
10 files changed
Lines changed: 1577 additions & 143 deletions
File tree
- benchmarks-website/server
- src
- static
- tests
- snapshots
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
58 | 58 | | |
59 | 59 | | |
60 | 60 | | |
| 61 | + | |
61 | 62 | | |
62 | 63 | | |
63 | 64 | | |
| |||
0 commit comments