fix(graph): border leaves share the leaf row (no bogus third tier); regen README diagram (v0.20.3)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
dtzp555-max
2026-07-07 13:58:44 +10:00
co-authored by Claude Fable 5
parent dc43b3550d
commit bcf26826b1
4 changed files with 18 additions and 7 deletions
+8
View File
@@ -6,6 +6,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html)
(pre-1.0: minor bumps may include breaking changes to the sim's behavior). (pre-1.0: minor bumps may include breaking changes to the sim's behavior).
## [0.20.3] - 2026-07-07
### Fixed
- `aci-sim graph`: border leaves now share the LEAF row (placed to its
right), matching autoACI's topology view — the previous separate
border-leaf tier under the leaves read as a bogus three-tier
"leaf under leaf" hierarchy. README diagram regenerated.
## [0.20.2] - 2026-07-07 ## [0.20.2] - 2026-07-07
### Fixed ### Fixed
+9 -6
View File
@@ -166,8 +166,11 @@ def _layout(graph: Graph, topo: Topology) -> None:
"""Hand-computed tiered ACI hierarchy layout (mirrors autoACI's preset layout). """Hand-computed tiered ACI hierarchy layout (mirrors autoACI's preset layout).
Tiers (top to bottom): ISN cloud (multi-site only) -> spine -> leaf -> Tiers (top to bottom): ISN cloud (multi-site only) -> spine -> leaf ->
border-leaf -> controller. Sites are spread side by side; each tier's controller. Border leaves share the LEAF row (placed to its right) —
nodes are centered within their site's horizontal band. exactly like autoACI's topology view: a separate border-leaf tier under
the leaves reads as a bogus three-tier "leaf under leaf" hierarchy.
Sites are spread side by side; each tier's nodes are centered within
their site's horizontal band.
""" """
site_names = [s.name for s in topo.sites] site_names = [s.name for s in topo.sites]
multi_site = len(site_names) > 1 multi_site = len(site_names) > 1
@@ -194,16 +197,16 @@ def _layout(graph: Graph, topo: Topology) -> None:
y_isn = 0.0 y_isn = 0.0
y_spine = V_GAP * 1 if not multi_site else V_GAP * 1.6 y_spine = V_GAP * 1 if not multi_site else V_GAP * 1.6
y_leaf = y_spine + V_GAP y_leaf = y_spine + V_GAP
y_border = y_leaf + V_GAP y_ctrl = y_leaf + V_GAP
y_ctrl = y_border + V_GAP
for idx, name in enumerate(site_names): for idx, name in enumerate(site_names):
site_x = idx * SITE_GAP + idx * H_GAP * 2 # extra spread accounts for wide tiers site_x = idx * SITE_GAP + idx * H_GAP * 2 # extra spread accounts for wide tiers
tiers = by_site[name] tiers = by_site[name]
# Recompute site_x based on the widest tier so sites don't overlap. # Recompute site_x based on the widest tier so sites don't overlap.
place_row(tiers["spine"], site_x, y_spine) place_row(tiers["spine"], site_x, y_spine)
place_row(tiers["leaf"], site_x, y_leaf) # Leaves + border leaves share one row (borders to the right, i.e.
place_row(tiers["border-leaf"], site_x, y_border) # ascending node-id order), mirroring autoACI's single leaf tier.
place_row(tiers["leaf"] + tiers["border-leaf"], site_x, y_leaf)
place_row(tiers["controller"], site_x, y_ctrl) place_row(tiers["controller"], site_x, y_ctrl)
# Second pass: re-center each site block using the actual widest tier so # Second pass: re-center each site block using the actual widest tier so
Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 KiB

After

Width:  |  Height:  |  Size: 120 KiB

+1 -1
View File
@@ -1,6 +1,6 @@
[project] [project]
name = "aci-sim" name = "aci-sim"
version = "0.20.2" version = "0.20.3"
description = "Faithful REST simulator of a 2-site Cisco ACI fabric (per-site APIC + ND/NDO)" description = "Faithful REST simulator of a 2-site Cisco ACI fabric (per-site APIC + ND/NDO)"
readme = "README.md" readme = "README.md"
license = "PolyForm-Noncommercial-1.0.0" license = "PolyForm-Noncommercial-1.0.0"