Closes#115.
The map gave every leaf its own column, so a subtree's width was simply its leaf
count. That is reasonable for a deep branching network and useless for a real
one: a core switch with fifty-eight access switches under it produced a single
row fifty-eight slots wide — over ten thousand pixels, which is exactly how it
was reported.
Real networks are shallow and wide, so breadth had to stop translating directly
into horizontal distance. Large groups of sibling leaves are now laid out as a
block rather than a row, trading width for height and turning linear growth into
roughly square-root. The reported shape goes from 58 slots to 10, six rows deep.
Children that have subtrees of their own keep the classic tidy-tree treatment,
because there the hierarchy is the information and flattening it would destroy
meaning. Only leaf groups — where the sibling order carries nothing — are packed.
Block proportions are deliberately wider than tall: screens are landscape, and a
column of forty reads worse than a band four rows deep.
The layout moved to utils/topologyLayout.ts in slot and row units, with pixels
left to the renderer, and 12 tests. That split is what makes the fix checkable at
all — the old arithmetic was only observable by looking at a rendered graph of a
network none of us has. The tests pin the reported case and, as importantly, the
shapes that must not regress: a three-node row stays a row, a branching tree
keeps its levels, a deep chain stays one slot wide, and no two nodes land on the
same coordinate.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>