You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When reconnecting the source or target terminal of an orthogonal edge, the generated route becomes inconsistent with the route shown during the reconnect preview.
The preview displays one orthogonal route, but after releasing the mouse button, the edge is rerouted and a different path is rendered.
Reconnect the target terminal to another vertex (or even reconnect it to the same vertex).
Observe the orthogonal route displayed during the reconnect preview.
Release the mouse button.
Observe that the final route differs from the preview route.
Expected behavior
The final route after reconnecting should match the route shown during the preview or match the route create by new connection.
Actual Behavior
Immediately after reconnecting a terminal, the orthogonal router may generate a different route than the one produced after reloading the graph.
Video:
Recording.2026-06-11.151112.mp4
Investigation:
While debugging, I found that the issue appears to occur during connection constraint resolution after a reconnect operation.
During reconnect operations, cleared connection constraints may be stored in the edge style as:
entryX = null
entryY = null
or
exitX = null
exitY = null
Graph#getConnectionConstraint() currently checks for undefined but not null:
const x = edge.style[source ? 'exitX' : 'entryX'];
if (x !== undefined) {
const y = edge.style[source ? 'exitY' : 'entryY'];
if (y !== undefined) {
point = new Point(x, y);
}
}
As a result, a ConnectionConstraint containing Point(null, null) can be created and later consumed by GraphView.updateFixedTerminalPoints().
This affects the generated absolutePoints and ultimately changes the orthogonal route.
From my investigation, this behavior became reproducible after commit 8504de2 (fix: correctly update style when calling Graph methods, #380).
My understanding is that the commit itself is likely not the root cause. Instead, it appears to expose an existing issue by ensuring that style updates correctly trigger StyleChange events. Once the style change is processed, the corresponding cell state is marked with invalidStyle = true and rebuilt from the cell style. At that point, style entries such as entryX = null or exitX = null are copied into the state and later interpreted as valid connection constraint coordinates because the constraint resolution logic only checks for undefined.
Description
When reconnecting the source or target terminal of an orthogonal edge, the generated route becomes inconsistent with the route shown during the reconnect preview.
The preview displays one orthogonal route, but after releasing the mouse button, the edge is rerouted and a different path is rendered.
Steps to Reproduce
https://maxgraph.github.io/maxGraph/demo/?path=/story/connections-orthogonal--default
Expected behavior
The final route after reconnecting should match the route shown during the preview or match the route create by new connection.
Actual Behavior
Immediately after reconnecting a terminal, the orthogonal router may generate a different route than the one produced after reloading the graph.
Video:
Recording.2026-06-11.151112.mp4
Investigation:
While debugging, I found that the issue appears to occur during connection constraint resolution after a reconnect operation.
During reconnect operations, cleared connection constraints may be stored in the edge style as:
or
Graph#getConnectionConstraint()currently checks for undefined but not null:As a result, a ConnectionConstraint containing
Point(null, null)can be created and later consumed byGraphView.updateFixedTerminalPoints().This affects the generated
absolutePointsand ultimately changes the orthogonal route.From my investigation, this behavior became reproducible after commit 8504de2 (fix: correctly update style when calling Graph methods, #380).
My understanding is that the commit itself is likely not the root cause. Instead, it appears to expose an existing issue by ensuring that style updates correctly trigger
StyleChangeevents. Once the style change is processed, the corresponding cell state is marked withinvalidStyle = trueand rebuilt from the cell style. At that point, style entries such asentryX = nullorexitX = nullare copied into the state and later interpreted as valid connection constraint coordinates because the constraint resolution logic only checks for undefined.