Skip to content

fix: a moved node's edges keep the layout's routes; only their ends follow the ports - #112

Merged
endrix merged 1 commit into
mainfrom
fix/reroute-keeps-the-layouts-trunk
Nov 6, 2026
Merged

endrix merged 1 commit into
mainfrom
fix/reroute-keeps-the-layouts-trunk

Conversation

@endrix

@endrix endrix commented Nov 5, 2026

Copy link
Copy Markdown
Owner

What

After a node moves, its edges keep the routes the layout gave them and only their ends follow the ports. The router runs only for an edge whose kept route would not do.

Why

ELK routes edges together, so edges into one port share a trunk. After a move the server routed the moved node's edges anew with its own router, each edge on its own and each in its own channel, so the trunk came back as a comb of parallel lines with a knot at the port. A move of a few pixels (4px counts, so does an arrow key on a selected node) scrambled the picture, and only a new Layout undid it.

How

  • The dead-zone slide, which kept a route only for a move under 5px and only when every incident edge could be slid, now applies at any distance and edge by edge. The end goes to the port's anchor; the bend next to it follows on the movement axis so the stub stays straight.
  • An edge goes to the router only when the kept route would not do: no interior bend (a slid straight line is a diagonal), a stub turned back through its own node, a segment through a node (the moved node included), or a non-orthogonal result.
  • A foreign edge is rerouted only when the moved node covers it, not when it came within the router's 15px padding.
  • Only the node that moved counts as moved: the end whose port anchor left the route's end. Before, both ends of every incident edge counted, so edges near the far-end node were rerouted too.

Checked

  • On the gemmini state document that showed the comb: of the nine edges of the moved node, eight keep ELK's trunk, the ninth (a straight edge) is routed; no other edge changes.
  • reroute-keeps-the-layouts-trunk.test.ts: five tests, two fail on the old handler.
  • Server 440, client 351 tests pass; typecheck passes.

https://claude.ai/code/session_01EToj6RJRMSSHQiqGNMU9wv

…ollow the ports

The layout routes the edges together, so edges into one port share a
trunk. After a move the server routed the moved node's edges anew, each
on its own and each in its own channel, so the trunk came back as a comb
of parallel lines with a knot at the port, and the picture drifted from
the layout with every nudge.

The dead-zone slide, which kept a route only for a move under 5px and
only when every incident edge could be slid, now applies at any distance
and edge by edge: an edge keeps its route with its ends moved onto the
ports and the bend next to each end following on the movement axis. It
goes to the router only when the kept route would not do: no interior
bend to carry (a slid straight line is a diagonal), a stub turned back
through its own node, a segment through a node (the moved node included),
or a result that is not orthogonal.

Two more causes of edges changing that nobody touched: a foreign edge
was rerouted when a moved node came within the router's 15px padding of
it, now only when the node covers it; and both ends of every incident
edge counted as moved, so an edge passing close to the far-end node was
rerouted too. The moved end is now the one whose port anchor left the
route's end.

Verified on the gemmini state document that showed the comb: of the nine
edges of the moved node, eight keep ELK's trunk and the ninth, a straight
edge, is routed; no edge not incident to the node changes. Five tests,
two of which fail on the old handler.

Claude-Session: https://claude.ai/code/session_01EToj6RJRMSSHQiqGNMU9wv
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant