SVG diagram viewer — interactive JS wrapper for ores.diagrams SVGs
Table of Contents
This page is a capture in the inbox bucket of the product backlog — a pre-sprint idea, not yet pulled into a sprint as a story.
Depends on: ores.diagrams must exist and produce SVGs before this app is useful.
What
A lightweight JavaScript web app (in projects/ores.org-js/ or as a standalone
projects/ores.org-js/diagrams/ sub-app) that serves as an interactive viewer for the
SVG diagrams produced by ores.diagrams. The app itself contains no layout or
diagram-generation logic — all of that is done at build time by ores.diagrams.
The JS layer adds:
- Diagram selector — right-hand panel listing available SVG diagrams by name and short description; clicking switches the centre view.
- Pan / zoom — the SVG canvas supports scroll-wheel zoom and click-drag pan in all four directions (identical UX to the knowledge-graph app).
- Detail panel — clicking a node inside the SVG opens a right-hand panel showing the associated documentation (org-mode HTML page or GitHub source link).
Why
The ores.diagrams component generates correct, well-laid-out UML SVGs, but a
raw SVG file in a browser provides no interactivity: the default <a> link
behaviour navigates away from the page, there is no pan/zoom, and there is no
way to browse multiple diagrams without multiple browser tabs.
This viewer provides the interactive layer that was the original goal of the
now-abandoned codegen_model_dashboard story. Key lessons from that
investigation:
- The iframe sidebar pattern (load node's HTML page, hide
#preamble, show#content) was prototyped and works well. It should be reused directly. - The KG app and agile board already establish the right-panel UX pattern:
a floating panel with a ×-close button appears on click, does not reduce the
diagram canvas size (
position: absoluteoverlay), and shows rendered HTML. Screenshot: knowledge-graph right panel pattern. Screenshot: agile board detail popup pattern. - Force-directed layout is the wrong approach for structured UML diagrams; using pre-rendered SVG from PlantUML eliminates the layout problem entirely.
Layout specification
┌─────────────────────────────────────────────────────┬──────────────────┐ │ Toolbar: title [diagram selector ▼] [Fit] stats │ │ ├─────────────────────────────────────────────────────┤ │ │ │ Diagram list │ │ │ ───────────── │ │ SVG canvas (pan/zoom) │ • C++: ores.cli │ │ │ • C++: ores.gui │ │ Click on class/entity → opens detail panel │ • SQL: schema │ │ (overlays right side of canvas) │ • Codegen model │ │ │ • ... │ │ │ │ └─────────────────────────────────────────────────────┴──────────────────┘
When a node is clicked, the diagram selector panel slides away and the detail panel takes its place (or they co-exist if the screen is wide enough):
┌─────────────────────────────────────────────────────┬──────────────────┐ │ Toolbar │ × │ ├─────────────────────────────────────────────────────┤ «entity» │ │ │ fx_convention │ │ SVG canvas (same, still pannable) │ ───────────── │ │ │ <iframe of the │ │ │ node's HTML │ │ │ page, preamble │ │ │ hidden> │ │ │ │ └─────────────────────────────────────────────────────┴──────────────────┘
Click behaviour per node type
| Source | Click action |
|---|---|
| org-mode entity | Load /OreStudio/<file>.html in sidebar iframe; hide #preamble |
| C++ class | Open https://github.com/OreStudio/OreStudio/blob/main/<path>#L<line> in new tab (embed widget if feasible) |
| SQL table | Load /OreStudio/projects/ores.sql/...html in sidebar iframe |
The SVG nodes carry embedded <a href"…">= links (from ores.diagrams [[url]]
syntax). The viewer intercepts these clicks via an event listener on the SVG
container before the default navigation fires.
Technical approach
SVG embedding
Embed each diagram as an inline SVG (fetched and injected into the DOM) rather
than <img> or <object>:
- Inline SVG allows JavaScript to access
<a>elements inside the diagram for click interception. - Inline SVG supports
d3.zoom()transform on the SVG root<g>(same approach as the KG app).
Pan / zoom
Use d3.zoom() on the SVG element, applying the transform to the root <g>
containing the diagram content. Scroll-wheel zooms; click-drag pans. A "Fit"
button resets to a zoom-to-fit transform (same as KG).
Diagram selector
A JSON index file (e.g. diagrams/index.json) lists available SVGs with name,
description, and path. Generated by ores.diagrams alongside the SVG files.
The selector panel renders this list; selecting a diagram fetches the SVG,
injects it inline, and wires up click handlers.
Sidebar detail panel
Reuse the iframe + hide-preamble approach prototyped in the abandoned dashboard:
iframe.addEventListener('load', () => { const d = iframe.contentDocument; const pre = d.getElementById('preamble'); if (pre) pre.style.display = 'none'; const post = d.getElementById('postamble'); if (post) post.style.display = 'none'; });
Panel is position: absolute; right: 0; top: 0; bottom: 0 so it overlays the
diagram rather than shrinking the canvas.
Deploy
Wire as a new ores-deploy-web-app call in ores-build-site.el under the key
diagrams, deploying to /OreStudio/diagrams/. Depends on the diagram SVGs
being generated first (order-of-operations in the deploy script).
References
- ores.diagrams — the diagram generation component this app wraps
- Abandoned story: Codegen Model Dashboard — iframe sidebar pattern, UX experiments
projects/ores.org-js/agile/— reference implementation for deploy patternexternal/org-roam-ui/— reference implementation for pan/zoom SVG pattern
See also
- Codegen Model Dashboard — sprint 20 investigation that produced the iframe sidebar pattern and UX experiments this app inherits