Cube-view: UCIe position/size from topology.yaml (ucie_mm.size=2.0)
UCIe components placed at defined positions from _cube_local_positions with size from cube.geometry.ucie_mm.size. N/S horizontal, E/W vertical. Connection ports rendered as color-coded boxes inside UCIe component. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -683,9 +683,18 @@ def _render_cube_view_svg(view: ViewGraph, spec: dict) -> str:
|
||||
f'{agg_bw:.0f}GB/s</text>'
|
||||
)
|
||||
|
||||
# ── UCIe port components (inside cube boundary, on edges) ──
|
||||
# ── UCIe port components (position/size from topology.yaml) ──
|
||||
# ucie_mm.size = 2.0mm, positions from _cube_local_positions
|
||||
ucie_size_mm = cube.get("geometry", {}).get("ucie_mm", {}).get("size", 2.0)
|
||||
ucie_positions = {
|
||||
"N": (cube_w / 2, ucie_size_mm / 2), # top center
|
||||
"S": (cube_w / 2, cube_h - ucie_size_mm / 2), # bottom center
|
||||
"W": (ucie_size_mm / 2, cube_h / 2), # left center
|
||||
"E": (cube_w - ucie_size_mm / 2, cube_h / 2), # right center
|
||||
}
|
||||
|
||||
# Collect UCIe connections per direction
|
||||
ucie_by_dir: dict[str, list[tuple[str, str, float, float]]] = {} # dir → [(conn, rkey, rx, ry)]
|
||||
ucie_by_dir: dict[str, list[tuple[str, str, float, float]]] = {}
|
||||
for rkey, rval in routers.items():
|
||||
if rval is None:
|
||||
continue
|
||||
@@ -699,123 +708,86 @@ def _render_cube_view_svg(view: ViewGraph, spec: dict) -> str:
|
||||
ucie_by_dir.setdefault(direction, []).append((conn, rkey, rx, ry))
|
||||
|
||||
ucie_colors = ["#818cf8", "#a78bfa", "#c084fc", "#e879f9"]
|
||||
ucie_port_inset = 3 # mm inset from cube edge
|
||||
|
||||
for direction, conns in ucie_by_dir.items():
|
||||
conns.sort(key=lambda x: x[0]) # sort by conn name
|
||||
conns.sort(key=lambda x: x[0])
|
||||
n_conn = len(conns)
|
||||
ucx_mm, ucy_mm = ucie_positions.get(direction, (cube_w / 2, cube_h / 2))
|
||||
ucx, ucy = mm2px(ucx_mm, ucy_mm)
|
||||
|
||||
# UCIe component box position (inside cube, along edge)
|
||||
if direction == "N":
|
||||
# Horizontal bar along top edge
|
||||
# Find X span from attached routers
|
||||
xs = [mm2px(rx, ry)[0] for _, _, rx, ry in conns]
|
||||
ux1 = min(xs) - 15
|
||||
ux2 = max(xs) + 15
|
||||
uw = ux2 - ux1
|
||||
uh = 18
|
||||
ux = ux1
|
||||
uy = pad + ucie_port_inset * scale
|
||||
elif direction == "S":
|
||||
xs = [mm2px(rx, ry)[0] for _, _, rx, ry in conns]
|
||||
ux1 = min(xs) - 15
|
||||
ux2 = max(xs) + 15
|
||||
uw = ux2 - ux1
|
||||
uh = 18
|
||||
ux = ux1
|
||||
uy = pad + cube_h * scale - ucie_port_inset * scale - uh
|
||||
elif direction == "W":
|
||||
ys = [mm2px(rx, ry)[1] for _, _, rx, ry in conns]
|
||||
uy1 = min(ys) - 15
|
||||
uy2 = max(ys) + 15
|
||||
uw = 18
|
||||
uh = uy2 - uy1
|
||||
ux = pad + ucie_port_inset * scale
|
||||
uy = uy1
|
||||
elif direction == "E":
|
||||
ys = [mm2px(rx, ry)[1] for _, _, rx, ry in conns]
|
||||
uy1 = min(ys) - 15
|
||||
uy2 = max(ys) + 15
|
||||
uw = 18
|
||||
uh = uy2 - uy1
|
||||
ux = pad + cube_w * scale - ucie_port_inset * scale - uw
|
||||
uy = uy1
|
||||
# UCIe box: size from topology, N/S horizontal, E/W vertical
|
||||
us = ucie_size_mm * scale
|
||||
if direction in ("N", "S"):
|
||||
uw, uh = us, us * 0.5
|
||||
else:
|
||||
continue
|
||||
uw, uh = us * 0.5, us
|
||||
|
||||
ux = ucx - uw / 2
|
||||
uy = ucy - uh / 2
|
||||
|
||||
# UCIe component background
|
||||
parts.append(
|
||||
f' <rect x="{ux:.0f}" y="{uy:.0f}" '
|
||||
f'width="{uw:.0f}" height="{uh:.0f}" '
|
||||
f'rx="3" fill="#1e1b4b" stroke="#8b5cf6" stroke-width="1.5" opacity="0.8"/>'
|
||||
f'rx="3" fill="#1e1b4b" stroke="#8b5cf6" stroke-width="1.5" opacity="0.9"/>'
|
||||
)
|
||||
# UCIe direction label
|
||||
parts.append(
|
||||
f' <text x="{ucx:.0f}" y="{uy - 3:.0f}" text-anchor="middle" '
|
||||
f'font-family="monospace" font-size="7" font-weight="bold" fill="#8b5cf6">'
|
||||
f'UCIe-{direction}</text>'
|
||||
)
|
||||
# UCIe label
|
||||
if direction in ("N", "S"):
|
||||
parts.append(
|
||||
f' <text x="{ux + uw / 2:.0f}" y="{uy - 3:.0f}" text-anchor="middle" '
|
||||
f'font-family="monospace" font-size="7" font-weight="bold" fill="#8b5cf6">'
|
||||
f'UCIe-{direction}</text>'
|
||||
)
|
||||
else:
|
||||
parts.append(
|
||||
f' <text x="{ux + uw / 2:.0f}" y="{uy - 3:.0f}" text-anchor="middle" '
|
||||
f'font-family="monospace" font-size="7" font-weight="bold" fill="#8b5cf6">'
|
||||
f'UCIe-{direction}</text>'
|
||||
)
|
||||
|
||||
# Connection port boxes inside UCIe component
|
||||
for ci, (conn, rkey, crx, cry) in enumerate(conns):
|
||||
c_color = ucie_colors[ci % len(ucie_colors)]
|
||||
if direction in ("N", "S"):
|
||||
# Horizontal layout
|
||||
cw = max((uw - 4) / n_conn - 1, 6)
|
||||
ch = uh - 4
|
||||
cx = ux + 2 + ci * (cw + 1)
|
||||
cy = uy + 2
|
||||
cy_box = uy + 2
|
||||
else:
|
||||
# Vertical layout
|
||||
cw = uw - 4
|
||||
ch = max((uh - 4) / n_conn - 1, 6)
|
||||
cx = ux + 2
|
||||
cy = uy + 2 + ci * (ch + 1)
|
||||
cy_box = uy + 2 + ci * (ch + 1)
|
||||
|
||||
parts.append(
|
||||
f' <rect x="{cx:.0f}" y="{cy:.0f}" '
|
||||
f' <rect x="{cx:.0f}" y="{cy_box:.0f}" '
|
||||
f'width="{cw:.0f}" height="{ch:.0f}" '
|
||||
f'rx="2" fill="{c_color}" opacity="0.7"/>'
|
||||
)
|
||||
# Connection label
|
||||
lx = cx + cw / 2
|
||||
ly_t = cy + ch / 2 + 3
|
||||
ly_t = cy_box + ch / 2 + 3
|
||||
parts.append(
|
||||
f' <text x="{lx:.0f}" y="{ly_t:.0f}" text-anchor="middle" '
|
||||
f'font-family="monospace" font-size="5" fill="white">'
|
||||
f'{conn}</text>'
|
||||
)
|
||||
|
||||
# Connector line: port box → attached router
|
||||
# Connector line: port → router
|
||||
rpx, rpy = mm2px(crx, cry)
|
||||
if direction == "N":
|
||||
parts.append(
|
||||
f' <line x1="{lx:.0f}" y1="{cy + ch:.0f}" '
|
||||
f' <line x1="{lx:.0f}" y1="{cy_box + ch:.0f}" '
|
||||
f'x2="{rpx:.0f}" y2="{rpy - r_size:.0f}" '
|
||||
f'stroke="{c_color}" stroke-width="1" opacity="0.5"/>'
|
||||
)
|
||||
elif direction == "S":
|
||||
parts.append(
|
||||
f' <line x1="{lx:.0f}" y1="{cy:.0f}" '
|
||||
f' <line x1="{lx:.0f}" y1="{cy_box:.0f}" '
|
||||
f'x2="{rpx:.0f}" y2="{rpy + r_size:.0f}" '
|
||||
f'stroke="{c_color}" stroke-width="1" opacity="0.5"/>'
|
||||
)
|
||||
elif direction == "W":
|
||||
parts.append(
|
||||
f' <line x1="{cx + cw:.0f}" y1="{cy + ch / 2:.0f}" '
|
||||
f' <line x1="{cx + cw:.0f}" y1="{cy_box + ch / 2:.0f}" '
|
||||
f'x2="{rpx - r_size:.0f}" y2="{rpy:.0f}" '
|
||||
f'stroke="{c_color}" stroke-width="1" opacity="0.5"/>'
|
||||
)
|
||||
elif direction == "E":
|
||||
parts.append(
|
||||
f' <line x1="{cx:.0f}" y1="{cy + ch / 2:.0f}" '
|
||||
f' <line x1="{cx:.0f}" y1="{cy_box + ch / 2:.0f}" '
|
||||
f'x2="{rpx + r_size:.0f}" y2="{rpy:.0f}" '
|
||||
f'stroke="{c_color}" stroke-width="1" opacity="0.5"/>'
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user