Skip to content

Atlas renderer

The atlas is the visual layer behind the Canva. It renders up to ~1,925 course nodes and several thousand edges interactively.

Three layers

  • Renderer — Three.js, WebGL baseline. Optional WebGPU progressive enhancement when the browser supports it.
  • Layout worker — Rust compiled to WASM (crates/atlas-layout-wasm). Computes positions for small active subgraphs, expand-node ripples, and interaction-local jobs.
  • FallbackAtlasFallbackView, a structured list rendering used when WebGL is unavailable. Same source references, same status overlays, same omitted-counts.

Where the layout actually happens

For the dense full-universe view (1,925+ Math + support courses), layout is generated server-side at index build time and bundled into the graph view response. The browser worker handles only small active subgraphs — typically when you focus on a node and ask “what’s around this?”. This split is mandated by ADR 0026; without it, browser-side layout for the dense view would not be interactive on mid-range laptops.

Worker contract

The Rust/WASM worker speaks a fixed protocol — init, job, cancel, error, terminate — and is forbidden from doing requirement evaluation. Worker payloads never carry state_token or raw student state; the worker computes node positions, nothing else. (ADR 0023)

Determinism

Identical inputs and seeds produce identical positions. This is checked in CI. Two consequences:

  • Shareable view URLs reconstruct the exact frame on any client.
  • A test that snapshots a layout can fail meaningfully when the worker drifts.

Graceful degradation

The atlas degrades along three axes independently:

FailureWhat still works
No WebGPUFalls back to WebGL baseline. App fully usable.
No WebGLFalls back to AtlasFallbackView — list-based, same source references, same statuses.
Worker init or job failureStatic last-known positions, no interactive re-layout. App still usable.

WebGPU absence cannot block the app — explicit ADR (ADR 0022).

Semantic zoom

The atlas controls label density by zoom level:

  • Far out — subject codes only, edges thin.
  • Mid — course codes appear, edges weight by relationship kind.
  • Close — full course titles, sub-credential breakdowns.

Dense hover uses a render-only path instead of rebuilding the scene.

Picking, focus, selection

Click and keyboard interactions map back to backend ids — every node the user can click resolves to a course_id or credential_id that the inspector panel can fetch detail for. The atlas never invents an id the backend doesn’t recognize.

Shareable view state

URL params carry view-mode, selected course, target credential, and selected node. They explicitly never carry state_token, raw student state, grades, or notes — this is gate 4 in every phase’s success criteria.

Want the full spec?