One canvas, drawn once - #499
Merged
Merged
Conversation
This was referenced Sep 8, 2026
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Signed-off-by: WaylandYang <wayland0916@gmail.com>
WaylandYang
force-pushed
the
feat/one-canvas
branch
from
September 9, 2026 02:33
f5f9c6b to
3bf060c
Compare
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.
Closes #496. Prerequisite for #497.
Graph.tsxandOntologySchemaGraph.tsxeach built a full sigma renderer, and the two were the same machine with different data.graphCanvas.tsis now that machine, once.What moved
The constructor.
sigmaOptions()holds every setting that decides how a canvas looks and behaves: the four-layer node program, the square program, the fonts, the three label-visibility settings, the label and hover drawing functions, edge events. Six things genuinely differ between the two pages and are parameters — the edge program set, the camera ratio limits,renderEdgeLabels,minEdgeThickness— each with a comment saying why. The comment recording the two label-threshold experiments now exists once instead of verbatim twice.The interaction state table.
hoveredNode,selectedNode,neighborNode,mutedNode,softMutedNode. Each page's reducer keeps its own logic — which node is in which state is a page question, and the two answer it differently — and calls these to paint. The graph page's reducer keeps its time filter and playback fade; the schema page's keeps its "a selected relation lights its endpoints" branch.The camera.
nodePosition,nodeInView,focusNodewere on the schema page and are now shared, because #497 needs them on the graph page.The drag.
attachDragholds the shape both had: press records a candidate, four pixels of movement promotes it to a drag, the bounding box freezes for the duration and is released on mouseup. What the two pages do during a drag differs and stays theirs, as three callbacks — the graph page feeds the cursor into the force simulation, the schema page records the position into its own map.lerpColorandparseRgbamove tographVisuals.tsbesidemix, with a note on the division of labour:mixtakes hex and drives the node tint recipe,lerpColortakesrgba()too and drives fades.One behaviour changes
The mute factor was 0.52 on one page and 0.55 on the other, with nothing anywhere saying why. The design notes say 0.52, so that is what the shared
MUTE_SCALEis, and the schema page's muted nodes are now 3% smaller. Invisible at that size — and it is exactly the drift this extraction exists to stop.Everything else is a move. The reducers, the drag, the camera helpers are the same code in a different file.
Verified
Against a copy of the benchmark base — 1415 entities, 916 classes — with a dev server on this branch:
×0.7default); selected at 13.26 (×1.02) withzIndex3 and its ring; a neighbour with base 8.2 at 6.232 (×0.76); a non-neighbour at 6.76 (×0.52) with its label cleared. Hover puts a node atzIndex4.downNodefired, the node moved 117 graph units, and the custom bounding box was set during the drag and cleared on release. On the schema page a node dragged from the right edge to the bottom right and stayed there.focusNodeandnodeInView.pnpm buildclean: style guard,tsc, vite.No visual change is expected, so there is nothing new to look at; the screenshots above are the two pages rendering as before.
🤖 Generated with Claude Code