Skip to content

feat(studio): metamodel diagram in the metamodel editor - #116

Merged
tomasz-zajac-oss merged 2 commits into
mainfrom
feat/metamodel-diagram
Oct 6, 2026
Merged

tomasz-zajac-oss merged 2 commits into
mainfrom
feat/metamodel-diagram

Conversation

@tomasz-zajac-oss

Copy link
Copy Markdown
Collaborator

What

The metamodel editor gets a List / Diagram switch. The Diagram tab draws the metamodel itself:

  • Node types as boxes (colour, icon, properties), grouped in a frame per category — C4, Domain, Governance, Requirements, UX, Other, Custom (the Elements palette's sections).
  • Containment (dashed, diamond at the parent) and every relation type as edges between the types they connect; each relation carries its name on the line. A relation from a type to itself (ADR supersedes ADR) is a chip on the box, not a loop.
  • Layout = Smart Layout + live WebCoLa physics, the same pipeline as the model canvas (Smart Layout places, LiveColaLayout settles from those positions). Edges use the canvas's allocatePorts + computeRoutedEdge.
  • Legend / filter in the right column: edge kinds, "show properties on boxes", all / none. When the filter hides something, only the types the shown edges connect are drawn and laid out.
  • Selection: clicking a type dims everything it is not connected to and frames it; clicking a relation (edge or legend name) shows only its sources and targets. The inspector lists parents, children, relations in/out and properties; "Edit type" / double-click opens the card in the List tab. Esc clears the selection first, then closes the editor.

Node type categories move to packages/common/src/metamodel/categories.ts; the Elements palette (RightPanel.tsx) uses them too, so both stay in step.

Notes

  • The WebCoLa physics gets a 4 s budget (or stops when nothing moves), since it does not always converge with nested groups — see known-issues.spec.ts.
  • The settled layout is cached per graph, so switching tabs or toggling a filter back does not re-run it.
  • fitBounds on the known frame geometry instead of fitView: fitView returns false while the physics replaces the nodes every frame.
  • apps/studio now declares @radical/layout (it imports Smart Layout's core and the edge routing directly).
  • Open items (dragging with physics, Blueprint having no relation type, dense presets) are in docs/IMPROVEMENTS.md → "Metamodel diagram".

Tests

  • apps/studio/tests/metamodelGraph.test.ts (15): graph rules, categories, filters, Smart Layout input, positions taken unchanged, no overlapping boxes / frames.
  • apps/e2e/tests/studio/metamodel-diagram.spec.ts (2): types, categories, labels, no overlaps after the physics, Contains / properties defaults, filters, relation-only view, framing on selection, inspector → Edit.
  • Local: studio 183, ui 168, common 112 unit tests; Studio e2e 52 passed; typecheck and check:workspaces clean.

🤖 Generated with Claude Code

Tomasz Zajac and others added 2 commits October 6, 2026 13:01
The metamodel editor gets a List / Diagram switch. The Diagram tab draws
the metamodel itself: node types as boxes (colour, icon, properties) in a
frame per palette category, containment and every relation type as edges
that end on the types they connect, with the relation name on each edge.

- Placement is Smart Layout followed by the live WebCoLa physics, the same
  pipeline as the model canvas; edges use the canvas's port allocation and
  routing. The physics has a time budget because it does not always
  converge with nested groups.
- The legend filters edge kinds; a narrowed filter keeps and lays out only
  the types the shown edges connect.
- Clicking a type dims everything it is not connected to and frames it;
  clicking a relation shows only its sources and targets. The inspector
  lists parents, children, relations and properties, and "Edit type" opens
  the card in the list.
- Node type categories move to @radical/common/metamodel/categories.ts and
  the Elements palette uses them too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hines

ReactFlow 11 rebuilds its node state from the node objects it is given and
does not keep the measured size. The diagram hands it new nodes every
physics frame without width/height, so ReactFlow hid the boxes and skipped
their edges until it measured them again; on a slow CI runner the last
frame stayed that way (16 nodes, 0 edges). Every node now carries the size
the layout already knows.

- e2e: a CPU-throttled run (6x) reproduces the bug; it fails without the fix.
- e2e: read the overview zoom only after the post-physics fit has finished.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tomasz-zajac-oss
tomasz-zajac-oss merged commit 8c6831d into main Oct 6, 2026
7 checks passed
@tomasz-zajac-oss
tomasz-zajac-oss deleted the feat/metamodel-diagram branch October 6, 2026 11:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant