The graph view resets when the window gets resized or another window gets drawn over it.
Done 2026-09-20. The panel reloads its graph whenever an input changes — the active document, the index epoch, the filters — and on desktop a focus change or a relayout of the window can trigger such a reload; until now every set_graph discarded the positions, restarted the force layout from the spiral and refitted the camera, which looked like a reset. Now GraphView::set_graph is incremental: when the new graph shares at least half its nodes with the current one, known nodes keep their positions and pins, only new nodes are placed (at the mean of their known neighbours, nudged apart), the layout is warmed (temperature 3) instead of restarted — and not even that when nothing changed — and the camera is left exactly where the user put it. A graph with nothing in common (another folder, a database schema) still starts fresh with a fit. The earlier resize rule stays: a view the user never panned or zoomed re-fits when its canvas is resized (P-091); a touched view does not. Verified in graph3d.mjs: zoom, change the active document (a reload), camera identical afterwards.
Follow-up the same day, while taking the screenshots (the vault’s own graph looked like a white smear): four graph-quality fixes. (1) [core.md](https://github.com/…) links to other sites were indexed as phantom pages with the URL as label — 28 of them in this vault; the index skips targets with :// now. (2) Labels are placed with a screen-space collision test, most important first (hovered, then degree), so a dense cluster shows the hubs’ names instead of a pile. (3) Hubs pull less per edge (ForceAtlas2’s “dissuade hubs”: attraction ÷ (1 + ½ ln(1 + degree))) so a vault whose Home/index link to everything no longer folds onto one line; isolated nodes feel stronger gravity. (4) Camera::fit measures the connected part when it is the majority, so a few isolated notes no longer shrink the picture. GraphView::layout_state() joins camera_state() for tests.