Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/facett

.nornir/graph-design.md

The graph subsystem — design

Class: design · Function axis: f0 (the whole) · f1 GraphView/DepGraphView · f2 graphview engine · f3 graphpan · f4 graph3d · f5 syschart. Strict: this file states only the shape that is built. Every why, every alternative, lives in graph-reasoning.md.

f0 — the whole: five node/edge surfaces, one shared shape

Every facett component that draws nodes joined by edges — the 2D scene viewer, the scalable render engine, the pan/zoom canvas, the 3D viewer, and the system map — is built from the same three-part shape: a domain-agnostic model (nodes + edges, laid out by the caller), a camera/transform (pan, zoom, or orbit), and a Facet that paints the model under the transform and returns Msgs (FC-2/FC-9, see elm-design.md). None of the five crates learns what a node means — a "release gate", a "kommun", a "PKI service" are all just an id, a label, a colour, and a position.

crate f shape model type camera
facett-graph f1 2D scene / layered DAG Scene (core) / DepGraphState none (static) / none
facett-graphview f2 scalable render engine, CPU/GPU GraphModel + Decorations Camera (pan+zoom)
facett-graphpan f3 pan/zoom canvas (borrowed) GraphModel + Decorations GraphView (pan+zoom+select)
facett-graph3d f4 3D node cloud Node3 cloud + edges Graph3DView (orbit yaw+spin)
facett-syschart f5 free-positioned peer map SysChartModel none (normalized 0..1 positions)

Reuse graph (uses): f1/f3/f5 sit directly on facett_core::{Elm, Facet, theme, a11y} (facett-graph/src/lib.rs:28, facett-graphpan/src/lib.rs, facett-syschart/src/lib.rs:26-28). f2 additionally sits on facett_core::render (the shared L0 SDF kernel: Canvas, CpuRenderer, QuadInstance/LineInstance, facett-graphview/src/l0.rs:23-26) and on vello/vello_cpu for its own reference rasterizer (facett-graphview/src/cpu.rs:11-13). f4 sits on facett_core::render::decor (the neon/glow/particle kernel, facett-graph3d/src/lib.rs:35) and, under the wgpu feature, on facett_core::render::gpu::{OffscreenColorDepth, GaussianBlur} (facett-graph3d/src/graph_gpu.rs:16-27). DepGraphView and DepGraphLayout delegate layered placement to facett_core::layered, retaining their existing edge conventions and public APIs. Pipeline, plandag and Brokkr additionally share persistent facett_flow::FlowScene rendering and core navigation gestures.

The shared decorations contract. f2 and f3 both define an identical caller-supplied overlay type — Decorations { nodes: HashMap<id, NodeDecoration>, edges: Vec<GraphEdge> }, where NodeDecoration carries an optional ring colour, an optional badge, and an optional scale multiplier (facett-graphview/src/model.rs:119-144, mirrored in facett-graphpan/src/lib.rs). The engine never learns what a ring or badge means — the host draws meaning on top of opaque shapes. f4's DecorPolicy and f1/f5 have no decorations layer; they carry status via plain node colour/border/badge fields on the model itself.

The shared backend-select policy. f2's runtime GPU/CPU choice (facett-graphview/src/backend.rs) is a direct re-export of facett_core::render::backend::{decide, Backend, GpuProbe} — the same policy the map skins use (facett-graphview/src/backend.rs:19). f4's GPU lane (graph_gpu.rs) is feature-gated independently (wgpu) and does not go through decide; it is a headless-offscreen-only lane today (see f4).

f1 — GraphView / DepGraphView (facett-graph)

Two Facets in one crate, both on facett_core::draw/Scene/Layout (the original facett-core scene-graph primitives), not on facett-graphview's GraphModel:

Both facets are wired through impl_facet_via_elm! form 3 (custom_state_json, facett-graph/src/lib.rs:249-266, facett-graph/src/depgraph.rs:371-396): the state_json a driver reads (node/edge counts, DepGraphView's column depth) is derived from the input data, not a plain serde dump of the Model, so the macro's richer form supplies it verbatim.

f2 — the graphview render engine (facett-graphview)

The scalable engine: a domain-agnostic model + a runtime-selected raster backend, aimed at the eventual single home for every graph surface in the constellation. Nine sibling modules, one entry point:

GraphModel + Decorations + Camera → decide(GpuProbe) → Backend → render_to_rgba() → RGBA8

f3 — graphpan (facett-graphpan)

The minimal counterpart to f2: a free function, not an owning engine. Same GraphModel/GraphNode/GraphEdge/Decorations/NodeDecoration shapes (re-declared, not re-exported, facett-graphpan/src/lib.rs:65-125), but the transform (GraphView { pan: Vec2, zoom: f32, selected: Option<String> }, :141-147) is caller-owned and the paint is a borrowed call the host makes every frame:

f2's DecoratedGraphView and f3's GraphPanView are two independently-built Facets over near-identical data: f2 is part of the consolidated render-engine crate (CPU/GPU rasterizer + this egui pane); f3 is a standalone, dependency-light crate exposing the bare draw_graph function a host can call without pulling in f2's vello/wgpu machinery.

f4 — graph3d (facett-graph3d)

A 3D node cloud viewer, CPU-projected today (orthographic + Y-rotation, depth → size/brightness), themed via facett_core::look/render::decor:

f5 — syschart (facett-syschart)

A monitoring map of a handful of free-positioned peer nodes — the shape none of f1–f4 cover: f1's GraphView/core Scene is non-interactive, f1's DepGraphView and f2's depgraph_layout are layered DAGs with a fixed deps/dependents drill-down, not a free triangle of peers.