Repository navigation
feat(c4): Structurizr-style visuals for the unified renderer - #7865
filipsajdak wants to merge 26 commits into
Conversation
🦋 Changeset detectedLatest commit: 45ee69d The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
✅ Deploy Preview for mermaid-js ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
@mermaid-js/examples
mermaid
@mermaid-js/layout-elk
@mermaid-js/layout-tidy-tree
@mermaid-js/mermaid-zenuml
@mermaid-js/parser
@mermaid-js/tiny
commit: |
|
The latest updates on your projects. Learn more about Argos notifications ↗︎
|
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## develop #7865 +/- ##
===========================================
+ Coverage 77.79% 77.88% +0.08%
===========================================
Files 409 416 +7
Lines 30328 30567 +239
Branches 5175 5207 +32
===========================================
+ Hits 23595 23806 +211
- Misses 5410 5418 +8
- Partials 1323 1343 +20
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
|
Heads-up: following @aloisklink's review on #7842, Track 1 has switched from the opt-in-flag approach to an in-place migration sliced by rendering layer (shapes -> edges -> layout) - see the updated plan in #7849. This slice is paused for now. Its branch is preserved as an archive tag ( |
4c86941 to
faaaf20
Compare
Converts the legacy C4 db state (c4ShapeArray / boundaries / rels) into the unified renderer LayoutData format: elements become nodes (db variants use cylinder, queue variants use h-cyl), boundaries become isGroup clusters with parentId nesting, and rels become edges. UpdateElementStyle and UpdateRelStyle map onto cssStyles/style/labelStyle preserving legacy semantics. Default fills come from the existing c4 config color keys so the palette matches the legacy renderer. Kept in a separate file so the legacy c4Db keeps its exact shape. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds an opt-in renderer for C4 diagrams that goes through the unified rendering pipeline (dagre by default, other algorithms such as ELK via registerLayoutLoaders), replacing the legacy statement-order grid with a real layout algorithm. The legacy row-based renderer stays the default, so existing diagrams render byte-identical unless the flag is set. - c4Renderer-unified.ts: renders getData() output via render() - c4Diagram.ts: dispatches between legacy and unified renderer - styles.js: CSS for the unified path (nodes, dashed boundary clusters, edges, edge labels, title), theme-variable driven - config.schema.yaml: new c4.useUnifiedRenderer flag (default false) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Renders C4 Person and Person_Ext elements with the classic C4 notation (circular head over a rounded box body) instead of a plain rectangle. The shape is registered in the shared shape registry as c4-person so other diagrams can reuse it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Covers nested boundaries, UpdateElementStyle/UpdateRelStyle, db and queue shape variants, nested deployment nodes, and guards the rendered viewBox dimensions against layout blowups. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rowser) Adds four custom shape handlers for the unified C4 renderer, modeled on the existing c4Person shape: a tabbed folder, an open-top object-storage bucket, a server-side terminal box with a console glyph, and a browser window with a chrome bar. Registers them in the shapes registry. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replaces the type-only shape mapping with a resolver that honors an explicit $shape (via UpdateElementStyle) or $sprite keyword, then a recognised $tags token, before falling back to the element type. The default element box is now a rounded rectangle to match the Structurizr look. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Applies the diagram drop-shadow filter to C4 element shapes for the Structurizr look. The shadow is skipped for the hand-drawn look and for elements that opt out with $shadowing="false" (rendered as a c4-no-shadow class). Rounded corners come from the rounded default box and the new shape handlers. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Renders the element name in bold, then a muted [Stereotype] or [Stereotype: Technology] line (Software System, Container, Component, Person), then a smaller description, matching the c4model.com layout. Boundary type lines reuse the same muted styling. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Relationships are dashed with opaque rounded label backgrounds, and boundaries use a lighter dashed stroke with a start-anchored label, to match the c4model.com look. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
System_Boundary/Container_Boundary store an uppercase type (SYSTEM, CONTAINER); compare case-insensitively so the implicit boundary type is not shown as a redundant [SYSTEM] label. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds a cypress rendering case exercising the Structurizr shape variants (browser, terminal, bucket, folder) and documents the new shapes, styling, and the $shape/$sprite attributes. Includes a changeset. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Render elements as outlines (light fill, colored border and matching colored text) instead of saturated fills with white text, and drop the shadow, to match c4model.com. The palette color becomes the element's border+text identity, clamped dark enough to stay legible on the light fill. Relationship labels sit on a clean white background. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Person now has a circular head above a rounded body; the folder uses a clean rectangular tab; the terminal glyph and browser chrome dots take the element's identity color so they are visible on the light fill. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Draw the person's body first and the full head circle on top of it, so the circle reads as resting on the rectangle. Apply the configured c4ShapePadding (default 20) to every element so labels keep clear of the borders. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Size the person head to 60% of the body width (as on c4model.com) and round all C4 element corners more generously (12px), keeping the browser address-bar hint square. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Head radius 0.23x the body width, overlapping the body by 0.27x the head radius, with body corners rounded to 0.177x the width (set inline so it overrides the shared corner radius). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Draw two vertical arms inside the lower body (at +/-0.29x the width, spanning 0.45-0.97x the body height) in a lighter tint of the element color, matching the c4model.com person. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Render the person's arms as the text color at 40% opacity and move them to the lower body (mid-height to the bottom edge), matching the c4model.com person. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Render relationship labels smaller (0.85em, as on c4model.com) on an opaque background, and add rank spacing, so neighbouring relationship labels stay separate and legible instead of overlapping. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Use a linear edge curve for C4 relationships so the line passes through the layout's label point (placing the label on the line instead of beside it), and to match the straight relationships on c4model.com. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Labels were anchored on dagre's label-node position, which can sit beside the drawn line. Add an opt-in edge property centerLabelOnLine that makes positionEdgeLabel anchor on the line's true midpoint (calcLabelPosition), and set it on C4 relationships so the label centers on the line. Other diagrams are unaffected (the flag defaults off). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The previous centerLabelOnLine edge flag had no effect: dagre's buildLayoutGraph only keeps whitelisted edge attributes, so the custom property was stripped before reaching positionEdgeLabel. dagre's default labelpos 'r' is what offsets the label to the side of the edge. Set labelpos 'c' on C4 edges (a whitelisted attribute) so dagre places the label node on the edge and the label centers on the line. Reverts the ineffective flag, keeping the shared edge type and renderer untouched. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The shape handlers (c4-folder/bucket/terminal/browser) register new entries in shapeDefs, so the generated shapes table in the docs snapshot now lists them. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
faaaf20 to
45ee69d
Compare
|
Closing this PR. It was part of the original opt-in feature-slice approach for the C4 unified renderer. Following @aloisklink's review on #7842, that approach was superseded by an in-place migration sliced by rendering layer (shapes -> edges -> layout), tracked in #7849 (#7842 shapes, #7883 edges, layout PR to follow). This feature will be re-introduced on top of the migrated renderer once the layout slice lands. The branch is preserved as an archive tag ( |
Summary
Brings the unified-renderer C4 output in line with the official c4model.com / Structurizr look:
c4-personfigure (head + body + arms, matched to the c4model.com reference proportions), plusfolder,bucket,terminalandbrowsershape handlers, resolved from$shape/$sprite.labelpos: 'c').All behind
c4.useUnifiedRenderer; legacy renderer unchanged.Stacked on #7842 (opt-in unified renderer) - draft until #7842 merges; the diff carries #7842's commits until then. Tracked in #7849.
🤖 Generated with Claude Code