VIEW-1: graph camera centering + session persistence + zoom-extents button#100
Merged
Conversation
…tton Camera no longer loads off-screen then jumps in, and the user's view is respected within and across a session instead of being reset on every visit. - Once-per-graph framing guarded by fittedGraphsRef: on first load of a graph, restore the user's saved camera (localStorage graphdone:camera:<id>) or auto-fit ONCE so the graph is framed, never re-fitting a graph already framed (don't fight the user's pan/zoom). - Fit runs through fitViewRef (not the fitViewToNodes callback) so the timer isn't cancelled by the callback's identity churning during physics settle — the bug that left graphs rendered off-screen. - Debounced (600ms) per-graph camera save on pan/zoom — localStorage only, no D1 chatter. (Shared node-position sync to D1 is a separate, server-side item.) - Zoom-extents button (Maximize2) on graph views: under the lock toggle on phones, top-left on desktop (the right corner is the docked inspector). Exposes triggerZoomToFit -> fitViewRef, framing every node without touching the camera-restore state. Tests: tests/e2e/camera.spec.ts @CAMERA (3/3) — loads framed, zoom-extents reframes after a hard zoom-in, pan persists across reload. THE GATE 5/5. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
🧪 Comprehensive Test Suite
Full-stack smoke gate runs in the CI workflow. |
The camera-centering fix lands the graph framed + centred (offMag ~0.05, bbox coverage ~0.93 across desktop/laptop/tablet). Turn the OpenCV balance spec from measurement-only into a gate with wide margins over that good state: - contentPixels > 200 (graph is on-screen, not blank) - bbox coverage > 0.35 (framed, not cornered; pre-fix off-screen read ~0.06) - offMag < 0.30 (centred; pre-fix off-centre read ~0.80) Annotated overlay + raw metrics still attached to the report every run. Runs via `npm run test:geometry` (not in the PR CI gate — needs python+cv2). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
🧪 Comprehensive Test Suite
Full-stack smoke gate runs in the CI workflow. |
mvalancy
added a commit
that referenced
this pull request
Jun 20, 2026
…plitting) From the live audit (#100): - Graph GetWorkItems/GetEdges poll relaxed 2s → 15s and skipped while the tab is hidden (skipPollAttempt); own mutations still refetch instantly. No WS subs, so a slow poll keeps cross-client freshness without the idle hammer. (IGV) - useAdaptiveQuality FPS-sampler rAF loop pauses on tab-hidden (visibilitychange) instead of spinning forever in backgrounded tabs. (useAdaptiveQuality.ts) - Code-splitting: vite manualChunks splits react/apollo/d3/lucide into cacheable vendor chunks + Admin/Backend/Ontology/Agents/Analytics are React.lazy routes. Entry chunk ~1.46MB → 662KB; largest gzip chunk 266KB (budget 450). (vite.config, App.tsx) Verified: typecheck clean; production build succeeds with split chunks; check-bundle-size within budget. (Deeper "stop rAF when graph settled" left for #100.) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
What
Fixes the "graph loads off-screen then jumps in" problem and respects the user's camera within/across a session, plus adds a zoom-extents button.
Camera (#78)
fittedGraphsRef): on first load of a graph, restore the user's saved camera (localStorage graphdone:camera:<id>) or auto-fit once — never re-fitting a graph already framed, so we don't fight the user's pan/zoom.fitViewRef(not the churningfitViewToNodescallback) so the fit timer isn't cancelled mid-settle — the root cause of graphs rendering off-screen.Zoom-extents button (#79)
Maximize2button on graph views: under the lock toggle on phones, top-left on desktop (the right corner is the docked inspector).triggerZoomToFit -> fitViewRef, framing every node without touching the camera-restore state.Tests
tests/e2e/camera.spec.ts@camera— 3/3:test:smoke) 5/5; web typecheck clean.🤖 Generated with Claude Code