Skip to content

ui: improve topology graph readability (#136) - #153

Merged
antoncxx merged 1 commit into
NullNet-ai:mainfrom
antoncxx:feature/topology-readability-136
Aug 10, 2026
Merged

ui: improve topology graph readability (#136)#153
antoncxx merged 1 commit into
NullNet-ai:mainfrom
antoncxx:feature/topology-readability-136

Conversation

@antoncxx

@antoncxx antoncxx commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

Summary

Dense service meshes made the layered Topology view hard to read: edges
routinely cut straight through unrelated nodes and labels, egress edges swept
diagonally across the whole diagram to reach the proxy, and a cycle between
two nodes could draw both directions as literally the same overlapping curve
and label. This PR fixes the routing itself rather than just adding another
view on top of it, and adds an adjacency-matrix view as a genuinely different
way to read a dense graph.

What changed

Layered mode — long-edge routing
Any edge that spans more than one layer (a proxy hop straight into a service
several dependency-layers deep, a deep service-to-service edge, or an egress
hop back to a distant proxy) now reserves a dummy waypoint slot in every
intermediate layer it crosses. The existing crossing-reduction sweep treats
those slots like real nodes, so it pushes actual nodes out of the way instead
of letting the edge draw a raw curve through them. Default edge labels anchor
to that same reserved slot instead of the raw endpoint midpoint, which — for
a waypoint-routed edge — could land squarely on top of an unrelated node.

Mutual-pair separation
A→B and B→A between the same two nodes (e.g. a two-node cycle) hit a
midpoint-symmetric formula: both directions computed the identical curve and
the identical label position, so one fully occluded the other. They now
separate into two parallel tracks — a modest bow for the curves, a larger
offset for the labels since text needs more clearance than a stroke does.

Egress edges
Previously bowed a fixed 46px past the source's own right edge before
curving to the proxy — fine when the proxy is close, but since it usually
sits far to one side, the curve had to sweep across the whole diagram to
reach it. Layer-skipping egress edges now use the same reserved-lane
mechanism as the long-edge fix above instead of a special-cased bow.

Node highlighting
Reverted to click-only (selectedNodeId). It previously highlighted a
node's connections on hover, which dimmed the rest of the graph on every
mouse pass.

New: matrix view
An adjacency-grid alternative to the node-link diagram — rows/columns
ordered proxies-then-services, a filled cell means an edge exists. Row and
column hover highlighting track independently (a node's row and its column
are usually different indices for an actual edge — an earlier iteration
shared one index for both, which meant only the diagonal could ever
highlight).

New: /debug/topology page
Unauthenticated, not linked from the sidebar. Paste or load a GraphJson
file and it renders through the exact same components the real Topology page
uses, with no backend involved — for iterating on layout math against
arbitrary topologies without a running stack.

Explored and dropped
Star (hub-and-spoke) and radial (ego-network) hub-focused layouts, and a
grouped (connected-components) layout, were implemented and evaluated
alongside the above but ultimately removed — layered (now fixed) plus matrix
covered the actual need better than either.


Relates to #136 .

Adds a matrix (adjacency-grid) view alongside the existing layered
mode, and reworks layered-mode edge routing to stop cutting through
unrelated nodes and labels:

- Layered mode: multi-layer-spanning edges (a proxy hop straight into
  a service several dependency-layers deep, a deep service-to-service
  edge, or an egress hop back to a distant proxy) now reserve a dummy
  waypoint slot in every intermediate layer, so the crossing-reduction
  sweep pushes real nodes out of the way instead of letting the edge
  draw a raw curve through them. Default edge labels anchor to that
  same reserved slot rather than the raw (and potentially occupied)
  endpoint midpoint.
- Mutual pairs (A->B and B->A between the same two nodes, e.g. a
  two-node cycle) get separated into two parallel tracks - their
  curves and labels used to be geometrically identical and fully
  overlap.
- Node highlighting is click-only (selectedNodeId), not hover.
- Matrix mode: adjacency grid ordered proxies-then-services, filled
  cell = edge, independent row/column hover highlighting (previously
  a single shared index meant only the diagonal could ever highlight).

Also adds a /debug/topology page (unauthenticated, not in the sidebar)
that renders a pasted or file-loaded GraphJson through the real
topology components with no backend, for iterating on layout math
against arbitrary topologies.

Star, radial, and grouped layout modes were explored and implemented
along the way but ultimately dropped in favor of layered + matrix.
@antoncxx
antoncxx marked this pull request as ready for review August 10, 2026 21:34
@antoncxx
antoncxx merged commit 18c2298 into NullNet-ai:main Aug 10, 2026
4 checks passed
@antoncxx
antoncxx deleted the feature/topology-readability-136 branch August 10, 2026 21:53
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