feat(replay): foreground line labels, stable anchors, and fixed axes#434
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Inference performance scatter charts create line labels inside the rooflines layer, which renders before the dot groups so roofline paths stay behind the points. That left the labels painted under the scatter points and overlay marks. Add a trailing custom layer that re-raises every `.line-label` to the end of the zoomGroup after all layers render (and on zoom), so they always read as foreground — mirroring GPUGraph, whose line-label layer already renders last. `.raise()` only changes z-order; label placement and the existing de-overlap (hide-on-collision for interactivity, vertical nudge for TTFT/E2EL) are untouched, so labels still never overlap one another. Selects overlay line labels (`overlay-*`) too, so unofficial-run overlays get the same treatment. Adds an E2E assertion that visible labels follow the dot groups in DOM order. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
In "Replay over time", line labels were re-placed every frame by the greedy placement algorithm, so they teleported between candidate positions (and the TTFT/E2EL vertical nudge reshuffled them) as the rooflines animated — visually noisy. Give each label a positional "affinity": add an opt-in `pinLineLabels` prop (set by ReplayPanel, like `transitionDuration`/`niceAxes`). When pinned, each label remembers a data-space x anchor the first time its series is seen and, on every later frame, resolves that anchor to the nearest current point on the line — so the label tracks the same spot as the line moves instead of hopping. The TTFT/E2EL de-overlap nudge is skipped while pinned so endpoint labels stay glued to their (smoothly moving) endpoints. Anchors are pruned when a series disappears. The static (non-pinned) chart is unchanged: the default branch of the shared placeLabel helper keeps the exact greedy-place + hide-on-collision behavior, preserving the no-overlap guarantee. Works for both official and overlay (`?unofficialrun=`) line labels. Extracts pointNearestX into its own module with unit tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
50fb34f to
ed3e7a3
Compare
By default the replay axes now stay fixed to the whole run's extent (for the active hardware) instead of refitting to each frame, so you can watch the frontier expand toward a constant coordinate space over time. A "Fixed axes" switch in the replay controls flips back to per-frame (dynamic) axes that hug the current frontier. - buildReplayTimeline: add computeFullRunDomain(timeline, hwFilter) — the bounding box across every step for the filtered configs. - ScatterGraph: add optional xExtentOverride/yExtentOverride; when set, the axis domain is based on them (normal padding + log/zero-baseline handling still applied) instead of the current points. Undefined for every non-replay caller, so the static chart is unchanged. - ReplayPanel: compute the full-run extent for the active hardware and pass it when "Fixed axes" is on (default); pass undefined when off. Unit tests cover computeFullRunDomain (spans all steps, respects the hw filter). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…reground # Conflicts: # packages/app/src/components/inference/types.ts # packages/app/src/components/inference/ui/ScatterGraph.tsx
…identity zoom replay
…reground + fixed-axes toggle
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit c3c0144. Configure here.
…are x|y pair, assert fixed stays constant)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Improvements to inference performance chart line labels and the Replay over time view. Rebased on latest
master(preserves #426's per-precision line labels).1. Line labels always render in the foreground
Line labels are built in the rooflines layer (which renders before the dot groups), so they were painted under the scatter points/overlay marks. A trailing custom layer re-raises every
.line-labelto the top after all layers render (and on zoom), mirroring GPUGraph..raise()only changes z-order, so the existing label de-overlap is preserved.2. Positional "affinity" for line labels during replay
In replay, labels were re-placed every frame by the greedy algorithm, so they teleported between candidate positions. New
pinLineLabelsprop (set byReplayPanel): each label remembers a data-space x anchor the first time its series appears, then resolves it to the nearest current point each frame so it tracks its line instead of hopping. TTFT/E2EL endpoint labels skip the vertical de-overlap nudge while pinned. The static chart keeps its exact greedy + hide-on-collision behavior.3. Fixed axes across the whole run (with a toggle)
Previously the replay axes refit to each frame. Now, by default, the axes stay fixed to the whole run's extent (for the active hardware), so you can watch the frontier expand toward a constant coordinate space over time. A "Fixed axes" switch in the replay controls flips back to per-frame dynamic axes that hug the current frontier.
computeFullRunDomain(timeline, hwFilter)— bounding box across every step for the filtered configs.ScatterGraphgains optionalxExtentOverride/yExtentOverride; undefined for every non-replay caller, so the static chart is unchanged.Overlay support
Foreground raise + per-precision labels + affinity all apply to overlay (
?unofficialrun=…) line labels.Tests
line-labels.cy.ts): labels render in DOM order after the scatter points (foreground); plus master's per-precision test.pointNearestX(affinity anchor resolution) andcomputeFullRunDomain(spans all steps, respects hw filter).pnpm typecheck,pnpm lint,pnpm fmt, fullpnpm test:unit(2020 app tests) all pass.🤖 Generated with Claude Code
Note
Low Risk
Chart rendering and replay UX changes with opt-in props and replay-only defaults; static inference charts are unchanged unless new props are passed.
Overview
Improves line label rendering and inference replay chart behavior.
Foreground z-order: The shared D3 renderer now raises
.line-labelafter dots on every full render and after zoom, so roofline labels are not buried under scatter points (static chart and replay).Replay label stability:
ScatterGraphadds optionalpinLineLabels(enabled inReplayPanel). Labels store a data-space x anchor via newpointNearestXand track the line each frame instead of re-running greedy placement; pinned mode skips collision hiding and TTFT/E2EL vertical de-overlap nudges. Static charts keep the existing greedy behavior.Fixed replay axes:
computeFullRunDomainbounds the run across all steps (respecting active hardware). Replay defaults to Fixed axes (xExtentOverride/yExtentOverride); a new switch restores per-frame refit. Extent recomputes when the legend hardware filter changes.Tests: Cypress checks DOM order after points (including post-zoom) and replay fixed-axes scrubbing; Vitest covers
pointNearestXandcomputeFullRunDomain.Reviewed by Cursor Bugbot for commit 447d2a6. Bugbot is set up for automated code reviews on this repo. Configure here.