Layout
These examples document the layout behaviors from the canonical TopoViewer test-case catalog. Each section is generated from one test case and keeps the live viewport, topology YAML, and stylesheet YAML together.
Manual layout
What This Demonstrates
Manual layout means the author supplies coordinates. This is the right mode for diagrams where placement carries meaning.
Expected Result
The live viewport should render "Manual layout" without blocking diagnostics. It should show: Manual layout preserves authored positions. The test metadata expects graphNodes: 3, minVisibleEdges: 2.
What To Inspect
- Inspect
layoutoptions and node positions. - Check whether positions are authored manually, inferred, or preserved by layout settings.
Use When
Use this pattern when positions should be repeatable, inferred, or constrained by topology structure.
graph:
id: manual-layout
layers:
- id: physical
name: Physical
nodes:
- id: A
name: A
labels:
node: router
layers:
- physical
position:
- 120
- 140
- id: B
name: B
labels:
node: router
layers:
- physical
position:
- 330
- 230
- id: C
name: C
labels:
node: router
layers:
- physical
position:
- 540
- 140
links:
- id: a-b
name: A to B
source: A
target: B
labels:
link: physical
layers:
- physical
- id: b-c
name: B to C
source: B
target: C
labels:
link: physical
layers:
- physical
layout:
mode: manual
width: 680
height: 340
icons:
router:
glyph: R
fill: "#2563eb"
stroke: "#bfdbfe"
service:
glyph: VPN
fill: "#7c3aed"
stroke: "#ddd6fe"
controller:
glyph: NSP
fill: "#f59e0b"
stroke: "#fde68a"
labelFields:
- name
stylesheet:
- selector: node
style:
icon: router
width: 84
height: 60
borderWidth: 3
labelColor: var(--topoviewer-fg-strong)
labelFontWeight: 800
- selector: link
style:
label: Link
lineColor: "#60a5fa"
lineWidth: 1
targetArrowShape: none
labelColor: var(--topoviewer-fg-strong)
textBackgroundColor: var(--topoviewer-edge-label-bg)
Force layout
What This Demonstrates
Force layout is auto-layout assistance. It is useful when topology data exists but the author does not want to maintain coordinates by hand.
Expected Result
The live viewport should render "Force layout" without blocking diagnostics. It should show: Force layout computes positions when the author omits coordinates. The test metadata expects graphNodes: 5, minVisibleEdges: 5.
What To Inspect
- Inspect
layoutoptions and node positions. - Check whether positions are authored manually, inferred, or preserved by layout settings.
Use When
Use this pattern when positions should be repeatable, inferred, or constrained by topology structure.
graph:
id: force-layout
layers:
- id: physical
name: Physical
nodes:
- id: A
name: A
labels:
node: router
layers:
- physical
- id: B
name: B
labels:
node: router
layers:
- physical
- id: C
name: C
labels:
node: router
layers:
- physical
- id: D
name: D
labels:
node: router
layers:
- physical
- id: E
name: E
labels:
node: router
layers:
- physical
links:
- id: A-B
name: A to B
source: A
target: B
labels:
link: physical
layers:
- physical
- id: A-C
name: A to C
source: A
target: C
labels:
link: physical
layers:
- physical
- id: B-D
name: B to D
source: B
target: D
labels:
link: physical
layers:
- physical
- id: C-D
name: C to D
source: C
target: D
labels:
link: physical
layers:
- physical
- id: D-E
name: D to E
source: D
target: E
labels:
link: physical
layers:
- physical
layout:
mode: force
width: 700
height: 380
iterations: 180
linkDistance: 130
chargeStrength: -420
collideRadius: 55
icons:
router:
glyph: R
fill: "#2563eb"
stroke: "#bfdbfe"
service:
glyph: VPN
fill: "#7c3aed"
stroke: "#ddd6fe"
controller:
glyph: NSP
fill: "#f59e0b"
stroke: "#fde68a"
labelFields:
- name
stylesheet:
- selector: node
style:
icon: router
width: 84
height: 60
borderWidth: 3
labelColor: var(--topoviewer-fg-strong)
labelFontWeight: 800
- selector: link
style:
label: Link
lineColor: "#60a5fa"
lineWidth: 1
targetArrowShape: none
labelColor: var(--topoviewer-fg-strong)
textBackgroundColor: var(--topoviewer-edge-label-bg)
CLOS layout
What This Demonstrates
CLOS layout infers staged placement from graph structure.
This example intentionally uses generic node names and directed links:
- no manual node positions are authored
source->targetlink direction defines the preferred root-to-leaf order- no network-specific labels such as spine or leaf are required
If your topology already has explicit stages, use layout.clos.stageKey and
stageOrder. If the graph is not staged, use force; if placement must be
operator-approved, use manual.
Expected Result
The live viewport should render "CLOS layout" without blocking diagnostics. It should show: CLOS layout infers staged placement from graph structure. The test metadata expects graphNodes: 6, minVisibleEdges: 8.
What To Inspect
- Inspect
layoutoptions and node positions. - Check whether positions are authored manually, inferred, or preserved by layout settings.
Use When
Use this pattern when positions should be repeatable, inferred, or constrained by topology structure.
graph:
id: clos-layout
layers:
- id: fabric
name: Fabric
nodes:
- id: A1
name: Stage A1
layers:
- fabric
- id: A2
name: Stage A2
layers:
- fabric
- id: B1
name: Stage B1
layers:
- fabric
- id: B2
name: Stage B2
layers:
- fabric
- id: C1
name: Stage C1
layers:
- fabric
- id: C2
name: Stage C2
layers:
- fabric
links:
- id: A1-B1
name: Stage A1 to Stage B1
source: A1
target: B1
layers:
- fabric
- id: A1-B2
name: Stage A1 to Stage B2
source: A1
target: B2
layers:
- fabric
- id: A2-B1
name: Stage A2 to Stage B1
source: A2
target: B1
layers:
- fabric
- id: A2-B2
name: Stage A2 to Stage B2
source: A2
target: B2
layers:
- fabric
- id: B1-C1
name: Stage B1 to Stage C1
source: B1
target: C1
layers:
- fabric
- id: B1-C2
name: Stage B1 to Stage C2
source: B1
target: C2
layers:
- fabric
- id: B2-C1
name: Stage B2 to Stage C1
source: B2
target: C1
layers:
- fabric
- id: B2-C2
name: Stage B2 to Stage C2
source: B2
target: C2
layers:
- fabric
layout:
mode: clos
width: 760
height: 420
clos:
direction: topToBottom
maxStages: 10
nodeGap: 180
groupGap: 220
icons:
stage:
glyph: "•"
fill: "#1976d2"
stroke: "#90caf9"
labelFields:
- name
stylesheet:
- selector: node
style:
icon: stage
shape: rectangle
width: 72
height: 56
borderWidth: 3
labelColor: var(--topoviewer-fg-strong)
labelFontWeight: 800
labelBackgroundColor: var(--topoviewer-panel-bg)
labelBackgroundOpacity: 0.92
labelPadding: 3
- selector: link
style:
curveStyle: straight
lineColor: "#42a5f5"
lineWidth: 3
targetArrowShape: none