nordisk/facett
.nornir/facett-pipeline-flow.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1180 560" font-family="'DejaVu Sans', 'Segoe UI', sans-serif">
<defs>
<linearGradient id="board" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#15101f"/>
<stop offset="1" stop-color="#0a0712"/>
</linearGradient>
<linearGradient id="chip" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#2a1f3f"/>
<stop offset="1" stop-color="#1a1330"/>
</linearGradient>
<linearGradient id="rail" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#3a2a55"/>
<stop offset="1" stop-color="#221838"/>
</linearGradient>
<linearGradient id="slot" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#2e2247"/>
<stop offset="1" stop-color="#1a1230"/>
</linearGradient>
<radialGradient id="glow" cx="0.5" cy="0.5" r="0.5">
<stop offset="0" stop-color="#f0a040" stop-opacity="0.55"/>
<stop offset="1" stop-color="#f0a040" stop-opacity="0"/>
</radialGradient>
<marker id="flow" markerWidth="9" markerHeight="9" refX="7" refY="4" orient="auto">
<path d="M0 0 L8 4 L0 8 Z" fill="#c89cff"/>
</marker>
</defs>
<rect x="0" y="0" width="1180" height="560" fill="url(#board)"/>
<text x="40" y="44" fill="#f3e9ff" font-size="22" font-weight="700">facett-pipeline · PipelineView</text>
<text x="430" y="44" fill="#c3a9e0" font-size="15">source-agnostic: it draws the <tspan fill="#e7d3ff" font-weight="700">picture</tspan>, knows nothing of Spark</text>
<!-- legend -->
<g font-size="12.5">
<line x1="804" y1="60" x2="844" y2="60" stroke="#c89cff" stroke-width="3" stroke-dasharray="6 4" marker-end="url(#flow)"/>
<text x="852" y="64" fill="#d8c4ee">marching-ants flow edge</text>
<circle cx="1014" cy="60" r="7" fill="url(#glow)"/>
<text x="1028" y="64" fill="#d8c4ee">status glow</text>
</g>
<!-- INPUT: host mapping -->
<rect x="36" y="110" width="220" height="340" rx="11" fill="url(#chip)" stroke="#7a5fb0" stroke-width="2"/>
<text x="146" y="136" fill="#f3e9ff" font-size="13.5" font-weight="700" text-anchor="middle">host model → input</text>
<text x="146" y="154" fill="#b79edb" font-size="9.5" text-anchor="middle">(e.g. knut ViewerState)</text>
<g font-family="'DejaVu Sans Mono', monospace" font-size="9.5">
<rect x="56" y="170" width="180" height="50" rx="6" fill="url(#slot)" stroke="#9a7fd0" stroke-width="1.2"/>
<text x="66" y="188" fill="#e7d3ff">nodes:</text>
<text x="66" y="202" fill="#b79edb">Vec<(String, Status)></text>
<text x="66" y="214" fill="#8d76b3" font-size="8.5">name + idle/running/done/failed</text>
<rect x="56" y="228" width="180" height="50" rx="6" fill="url(#slot)" stroke="#9a7fd0" stroke-width="1.2"/>
<text x="66" y="246" fill="#e7d3ff">edges:</text>
<text x="66" y="260" fill="#b79edb">Vec<(reads_idx, target_idx)></text>
<text x="66" y="272" fill="#8d76b3" font-size="8.5">flows: source → consumer</text>
<rect x="56" y="286" width="180" height="50" rx="6" fill="url(#slot)" stroke="#9a7fd0" stroke-width="1.2"/>
<text x="66" y="304" fill="#e7d3ff">JobProgress (opt):</text>
<text x="66" y="318" fill="#b79edb">fraction · tasks_done/total</text>
</g>
<text x="146" y="362" fill="#8d76b3" font-size="9" text-anchor="middle">knut NodeStatus → Status (1:1)</text>
<text x="146" y="376" fill="#8d76b3" font-size="9" text-anchor="middle">ExecutionProgress → JobProgress</text>
<text x="146" y="406" fill="#b79edb" font-size="10" text-anchor="middle">PipelineView::new(title, nodes, edges)</text>
<text x="146" y="424" fill="#8d76b3" font-size="9" text-anchor="middle">.with_progress / .with_throughput</text>
<text x="146" y="438" fill="#8d76b3" font-size="9" text-anchor="middle">.with_animation / .with_speed</text>
<!-- arrow -->
<line x1="256" y1="280" x2="316" y2="280" stroke="#c89cff" stroke-width="3" marker-end="url(#flow)"/>
<!-- LAYOUT: facett_graph -->
<rect x="316" y="180" width="200" height="200" rx="11" fill="url(#chip)" stroke="#7a5fb0" stroke-width="2"/>
<text x="416" y="206" fill="#f3e9ff" font-size="13" font-weight="700" text-anchor="middle">facett_graph</text>
<text x="416" y="224" fill="#b79edb" font-size="9.5" text-anchor="middle">DepGraphView (compose)</text>
<g font-family="'DejaVu Sans Mono', monospace" font-size="9.5">
<rect x="334" y="238" width="164" height="34" rx="5" fill="url(#slot)" stroke="#9a7fd0" stroke-width="1.1"/>
<text x="344" y="252" fill="#e7d3ff">toposort columns</text>
<text x="344" y="265" fill="#8d76b3" font-size="8.5">left → right layered layout</text>
<rect x="334" y="278" width="164" height="34" rx="5" fill="url(#slot)" stroke="#9a7fd0" stroke-width="1.1"/>
<text x="344" y="292" fill="#e7d3ff">state_json (dag)</text>
<text x="344" y="305" fill="#8d76b3" font-size="8.5">nodes · edges · columns</text>
</g>
<text x="416" y="340" fill="#8d76b3" font-size="9" text-anchor="middle">layout reused, NOT its painter</text>
<text x="416" y="356" fill="#8d76b3" font-size="9" text-anchor="middle">paint_dag draws our own look</text>
<line x1="516" y1="280" x2="576" y2="280" stroke="#c89cff" stroke-width="3" marker-end="url(#flow)"/>
<!-- RENDER: paint_dag -->
<rect x="576" y="110" width="560" height="340" rx="12" fill="url(#rail)" stroke="#9a7fd0" stroke-width="2.5"/>
<text x="856" y="136" fill="#f3e9ff" font-size="14" font-weight="700" text-anchor="middle">PipelineView::ui → paint_dag (per frame)</text>
<!-- legend chip row -->
<rect x="596" y="150" width="520" height="26" rx="6" fill="url(#slot)" stroke="#7a5fb0" stroke-width="1"/>
<text x="606" y="167" fill="#7ad6a0" font-size="11">● done</text>
<text x="680" y="167" fill="#e8b048" font-size="11">● running</text>
<text x="770" y="167" fill="#e84848" font-size="11">● failed</text>
<text x="852" y="167" fill="#8d76b3" font-size="11">● idle</text>
<text x="950" y="167" fill="#b79edb" font-size="10">+ progress bar (tasks_done/total)</text>
<!-- DAG sample: 3 nodes, glow + flow -->
<circle cx="660" cy="300" r="46" fill="url(#glow)"/>
<rect x="620" y="278" width="80" height="44" rx="6" fill="#1a1330" stroke="#7ad6a0" stroke-width="2"/>
<text x="660" y="298" fill="#f3e9ff" font-size="11" text-anchor="middle">bronze</text>
<text x="660" y="312" fill="#7ad6a0" font-size="9" text-anchor="middle">done</text>
<circle cx="840" cy="300" r="50" fill="url(#glow)"/>
<rect x="800" y="278" width="80" height="44" rx="6" fill="#1a1330" stroke="#e8b048" stroke-width="2"/>
<text x="840" y="298" fill="#f3e9ff" font-size="11" text-anchor="middle">silver</text>
<text x="840" y="312" fill="#e8b048" font-size="9" text-anchor="middle">running</text>
<rect x="980" y="278" width="80" height="44" rx="6" fill="#1a1330" stroke="#8d76b3" stroke-width="2"/>
<text x="1020" y="298" fill="#f3e9ff" font-size="11" text-anchor="middle">gold</text>
<text x="1020" y="312" fill="#8d76b3" font-size="9" text-anchor="middle">idle</text>
<!-- flow edges (marching ants) -->
<g stroke="#c89cff" stroke-width="2.5" stroke-dasharray="9 7">
<line x1="700" y1="300" x2="794" y2="300" marker-end="url(#flow)"/>
<line x1="880" y1="300" x2="974" y2="300" marker-end="url(#flow)"/>
</g>
<text x="747" y="288" fill="#b79edb" font-size="9" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">12k rows/s</text>
<text x="856" y="380" fill="#8d76b3" font-size="9.5" text-anchor="middle">nodes: themed box + status stroke + glow_rect (running pulses · done steady · failed blooms)</text>
<text x="856" y="396" fill="#8d76b3" font-size="9.5" text-anchor="middle">edges: faint base line + marching-ants dashes (source → consumer) + arrowhead + throughput label</text>
<text x="856" y="412" fill="#8d76b3" font-size="9.5" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">edge_phase(time, speed) · status_glow(status, time, speed) — pure, unit-tested</text>
<text x="856" y="434" fill="#c3a9e0" font-size="10" text-anchor="middle">every colour from the active Theme · state_json mirrors statuses/progress/animated/dag</text>
<rect x="36" y="500" width="1100" height="34" rx="8" fill="url(#rail)" stroke="#9a7fd0" stroke-width="1.5"/>
<text x="56" y="521" fill="#d8c4ee" font-size="11">a Facet: themeable + resizable · animation off → still frame for screenshots/headless · no Spark/gRPC knowledge — host maps the model</text>
</svg>