6.6 KiB
Rack Presentation Improvements Design
Date: 2026-06-24
Status: Approved
Parent spec: notes/dev/specs/2026-06-24-rack-documentation-design.md (extension)
Goal
Improve the graphical presentation of the generated rack page: make the
elevation interactive (inline SVG, clickable boxes, hover tooltips), encode
device status visually, add a legend, and polish both the elevation
and the mermaid power/network graphs. No new data is modelled; this is a
rendering upgrade of what gen_rack.py already produces.
Context
render_svgwrites a standalonerack01-elevation.svg, embedded inrack01.mdas— i.e. an<img>, which is a flat image: links and tooltips inside it do not work.render_power/render_networkemit default-themed mermaid flowcharts with uncoloured, non-clickable nodes.- The occupancy table already links to host pages; the SVG and graphs do not.
md_in_htmlis enabled inmkdocs.yml, so raw inline HTML/SVG in a Markdown page is rendered. Mermaid is enabled (Phase 2).use_directory_urlsis unset → defaults to true: pages build to/<path>/index.html, so a host page is served at/hardware/<host>/and the rack page at/infrastructure/racks/rack01/. The site is served at the domain root (docs.makerfloss.eu).KIND_COLORSalready maps kinds → fill colours. There is no status encoding, legend, link, or tooltip today.
Decisions
A. Inline, interactive elevation
render_pageembeds the SVG markup inline inrack01.md, inside a<div class="rack-elevation"> … </div>block, replacing theimage line. (md_in_htmlpasses the raw block through.)- The standalone
rack01-elevation.svgis still generated (identical markup, still drift-checked) and offered below the diagram as a[Download SVG](rack01-elevation.svg)link. - The
<svg>opening tag gainsstyle="max-width:100%;height:auto"so it scales on narrow screens. - Clickable boxes: every device drawing (rail box, shelf-occupant box, 0U
rail bar, shelf strip) is wrapped in
<a href="/hardware/<hostname>/"> … </a>. URLs are root-relative final URLs — mkdocs does not rewrite.md/source-relative hrefs inside raw inline SVG, anduse_directory_urls+ domain-root hosting make/hardware/<host>/correct and robust. - Tooltips: the
<a>wrapper's first child is an SVG<title>carrying full details:"<hostname> · <kind> · <status> · cluster: <cluster|—> · <placement>", where<placement>is the U-range (rail item),0U <left|right>(0U rail), or<shelf>/<face>/slot <slot>(mounted item). Text run through_esc.
B. Status encoded as border
Fill stays the kind colour; the box border encodes status via a
_status_stroke(status) -> (stroke, stroke_width, dash) helper:
| status | stroke | width | dash |
|---|---|---|---|
| in-use | #333 |
1.5 | none |
| staging | #333 |
1.5 | 4 2 (dashed) |
| broken | #e15759 |
3 | none |
| spare | #bbbbbb |
1.5 | none |
| donated | #bbbbbb |
1.5 | none |
| (other/missing) | #333 |
1.5 | none |
Applied to every device rect (rail draw_device and shelf-occupant boxes). The
shelf strip and the faint empty-U slots keep their existing styling.
C. Legend
A legend strip is drawn at the bottom of the SVG canvas, below the columns;
the canvas height grows by a fixed LEGEND_H band:
- Kind swatches: for each
kindactually present in the rack (sorted), a small colour rect + the kind name. - Status key: four small sample borders (solid, dashed, red-thick, grey) with
labels
in-use,staging,broken,spare.
D. Aesthetic polish
- U-numbers in both gutters: the existing left-gutter U-number column is mirrored to the right of the rear column.
- Column frame: a thin outer stroke rectangle around each column's full body (front and rear).
- Mermaid graphs (
render_power/render_network):- Colour nodes by kind: emit a
style <id> fill:<kind-colour>,stroke:#333,color:#ffffffline per node, looking the kind up from the rack items (KIND_COLORS, falling back toDEFAULT_COLOR). - Clickable nodes: emit
click <id> "/hardware/<host>/"for every node whose hostname resolves to a rack item; off-rack nodes get no click. - Edge labels and layout are unchanged.
- Colour nodes by kind: emit a
Technical constraints (rationale carried into implementation)
<img>-embedded SVG is inert → inlining is required for links/tooltips.- mkdocs rewrites Markdown
.mdlinks but not rawhref/clickURLs inside inline SVG or mermaid → emit final root-relative URLs/hardware/<host>/. md_in_html(already enabled) renders the raw<div><svg>…</svg></div>block.
Integration
| File | Change |
|---|---|
scripts/gen_rack.py |
helpers _host_url, _status_stroke, _tooltip; render_svg (status borders, <a>+<title> wrapping, both-gutter U-numbers, column frame, legend, style= on <svg>); render_page (inline SVG <div> + download link); render_power/render_network (per-node style + click) |
tests/test_gen_rack.py |
assertions for links, titles, status strokes, legend, both-gutter numbers, inline page block, mermaid style/click |
docs/infrastructure/racks/rack01.md, rack01-elevation.svg |
regenerated |
No mkdocs.yml, Makefile, .forgejo/workflows/docs.yml, or
overview_config.yml changes. Occupancy table and all validation unchanged.
Test plan
render_svg: output contains<a href="/hardware/srv04/", a<title>with the host details, a dashed stroke for astagingfixture and a thick red stroke for abrokenfixture, kind swatches for the kinds present, U-number text on both sides; deterministic for reordered input.render_page: contains<div class="rack-elevation">and<svg, the[Download SVG](rack01-elevation.svg)link, and no![-image embed of the elevation.render_power/render_network: containstyle <id> fill:lines coloured by kind andclick <id> "/hardware/<host>/"lines; still start with```mermaid+flowchart LR.- Drift / build / visual:
make docs-checkexits 0;mkdocs build --strictpasses; on the rendered page the elevation boxes are clickable, hovering shows the tooltip, the legend is visible, and the mermaid nodes are coloured and clickable.
Out of scope
- The summary dashboard (U-utilisation / counts) — not selected.
- Dark-mode-specific palettes.
- A cluster colour system — cluster appears in the tooltip only.