diff --git a/.changeset/class-default-unified-renderer.md b/.changeset/class-default-unified-renderer.md
new file mode 100644
index 00000000000..882824f8f27
--- /dev/null
+++ b/.changeset/class-default-unified-renderer.md
@@ -0,0 +1,12 @@
+---
+'mermaid': minor
+---
+
+feat: route `classDiagram` to the unified (v2) renderer by default
+
+`class.defaultRenderer` now defaults to `dagre-wrapper`, so plain `classDiagram`
+documents (without the `-v2` suffix) render through the unified renderer and the
+shared dagre layout/paint pipeline instead of the legacy class renderer. Set
+`class: { defaultRenderer: 'dagre-d3' }` in the config to restore the legacy
+renderer. Self-referential edges in class and ER diagrams now render as compact
+merged self-loops.
diff --git a/.fallowrc.json b/.fallowrc.json
index ecd6748273b..5649028a7c4 100644
--- a/.fallowrc.json
+++ b/.fallowrc.json
@@ -2,7 +2,11 @@
"$schema": "https://raw.githubusercontent.com/fallow-rs/fallow/main/schema.json",
"entry": [
"packages/mermaid/src/rendering-util/layout-algorithms/**/*.ts",
- "packages/mermaid/src/rendering-util/layout-algorithms/**/*.js"
+ "packages/mermaid/src/rendering-util/layout-algorithms/**/*.js",
+ "packages/mermaid/src/diagrams/block/**/*.ts",
+ "packages/mermaid/src/diagrams/block/**/*.js",
+ "packages/mermaid/src/rendering-util/rendering-elements/**/*.ts",
+ "packages/mermaid/src/rendering-util/rendering-elements/**/*.js"
],
"ignorePatterns": [
"packages/parser/**",
@@ -27,7 +31,39 @@
"scripts/**",
"packages/mermaid/scripts/**",
"packages/mermaid/src/dagre-wrapper/**",
- "packages/mermaid/src/diagrams/**",
+ "packages/mermaid/src/diagrams/architecture/**",
+ "packages/mermaid/src/diagrams/c4/**",
+ "packages/mermaid/src/diagrams/class/**",
+ "packages/mermaid/src/diagrams/common/**",
+ "packages/mermaid/src/diagrams/cynefin/**",
+ "packages/mermaid/src/diagrams/er/**",
+ "packages/mermaid/src/diagrams/error/**",
+ "packages/mermaid/src/diagrams/eventmodeling/**",
+ "packages/mermaid/src/diagrams/flowchart/**",
+ "packages/mermaid/src/diagrams/gantt/**",
+ "packages/mermaid/src/diagrams/git/**",
+ "packages/mermaid/src/diagrams/globalStyles.ts",
+ "packages/mermaid/src/diagrams/info/**",
+ "packages/mermaid/src/diagrams/ishikawa/**",
+ "packages/mermaid/src/diagrams/kanban/**",
+ "packages/mermaid/src/diagrams/mindmap/**",
+ "packages/mermaid/src/diagrams/packet/**",
+ "packages/mermaid/src/diagrams/pie/**",
+ "packages/mermaid/src/diagrams/quadrant-chart/**",
+ "packages/mermaid/src/diagrams/radar/**",
+ "packages/mermaid/src/diagrams/railroad/**",
+ "packages/mermaid/src/diagrams/requirement/**",
+ "packages/mermaid/src/diagrams/sankey/**",
+ "packages/mermaid/src/diagrams/sequence/**",
+ "packages/mermaid/src/diagrams/state/**",
+ "packages/mermaid/src/diagrams/swimlanes/**",
+ "packages/mermaid/src/diagrams/timeline/**",
+ "packages/mermaid/src/diagrams/treeView/**",
+ "packages/mermaid/src/diagrams/treemap/**",
+ "packages/mermaid/src/diagrams/user-journey/**",
+ "packages/mermaid/src/diagrams/venn/**",
+ "packages/mermaid/src/diagrams/wardley/**",
+ "packages/mermaid/src/diagrams/xychart/**",
"packages/mermaid/src/diagram-api/**",
"packages/mermaid/src/docs/**",
"packages/mermaid/src/schemas/**",
@@ -36,7 +72,6 @@
"packages/mermaid/src/types/**",
"packages/mermaid/src/utils/**",
"packages/mermaid/src/__mocks__/**",
- "packages/mermaid/src/rendering-util/rendering-elements/**",
".lintstagedrc.mjs",
"cypress.config.ts",
"eslint.config.js",
diff --git a/cypress/helpers/util.ts b/cypress/helpers/util.ts
index c02435c0b1d..9e95e935c7e 100644
--- a/cypress/helpers/util.ts
+++ b/cypress/helpers/util.ts
@@ -103,7 +103,7 @@ export const openURLAndVerifyRendering = (
const name: string = (options.name ?? cy.state('runnable').fullTitle()).replace(/\s+/g, '-');
cy.visit(url);
- cy.window().should('have.property', 'rendered', true);
+ cy.window({ timeout: 15000 }).should('have.property', 'rendered', true);
// Handle sandbox mode where SVG is inside an iframe
if (options.securityLevel === 'sandbox') {
diff --git a/cypress/integration/rendering/class/classDiagram-handDrawn-v3.spec.js b/cypress/integration/rendering/class/classDiagram-handDrawn-v3.spec.js
index d4009d518bb..f67fd219b36 100644
--- a/cypress/integration/rendering/class/classDiagram-handDrawn-v3.spec.js
+++ b/cypress/integration/rendering/class/classDiagram-handDrawn-v3.spec.js
@@ -1137,4 +1137,19 @@ class C13["With Città foreign language"]
{ class: { hierarchicalNamespaces: false } }
);
});
+
+ it('HD: should render a self-referential class diagram with multiplicity labels', () => {
+ imgSnapshotTest(
+ `
+ classDiagram
+ class SelfReferential{
+ +int id
+ +int self_referential_id
+ +SelfReferential referenced
+ }
+ SelfReferential "1" --> "0..1" SelfReferential : referenced
+ `,
+ { logLevel: 1, htmlLabels: true, look: 'handDrawn' }
+ );
+ });
});
diff --git a/cypress/platform/dev-diagrams/layout-tests/block-diagrams/test1.mmd b/cypress/platform/dev-diagrams/layout-tests/block-diagrams/test1.mmd
new file mode 100644
index 00000000000..6b49a3c1fb2
--- /dev/null
+++ b/cypress/platform/dev-diagrams/layout-tests/block-diagrams/test1.mmd
@@ -0,0 +1,4 @@
+block-beta
+ columns 5
+ PA["Paid proceeds (actual) $613"]:1 DEF["Deficit $5,155"]:4
+ CA["Cash back (actual) $128"]:1 SPO["Spoilage (35 unsold) $5,640"]:4
diff --git a/cypress/platform/dev-diagrams/layout-tests/block-diagrams/test2.mmd b/cypress/platform/dev-diagrams/layout-tests/block-diagrams/test2.mmd
new file mode 100644
index 00000000000..c1fd6d1ab78
--- /dev/null
+++ b/cypress/platform/dev-diagrams/layout-tests/block-diagrams/test2.mmd
@@ -0,0 +1,4 @@
+block
+ A>"rect_left_inv_arrow"]
+ B{"diamond"}
+ C{{"hexagon"}}
diff --git a/cypress/platform/dev-diagrams/layout-tests/block-diagrams/test3.mmd b/cypress/platform/dev-diagrams/layout-tests/block-diagrams/test3.mmd
new file mode 100644
index 00000000000..e763c580125
--- /dev/null
+++ b/cypress/platform/dev-diagrams/layout-tests/block-diagrams/test3.mmd
@@ -0,0 +1,6 @@
+block
+ A
+ B
+ classDef blue fill:#66f,stroke:#333,stroke-width:2px;
+ class A blue
+ style B fill:#f9F,stroke:#333,stroke-width:4px
diff --git a/cypress/platform/dev-diagrams/layout-tests/block-diagrams/test4.mmd b/cypress/platform/dev-diagrams/layout-tests/block-diagrams/test4.mmd
new file mode 100644
index 00000000000..617b07e00d1
--- /dev/null
+++ b/cypress/platform/dev-diagrams/layout-tests/block-diagrams/test4.mmd
@@ -0,0 +1,6 @@
+%% BL21
+block
+ A[/"lean right"/]
+ B[\"lean left"\]
+ C[/"trapezoid"\]
+ D[\"trapezoid alt"/]
diff --git a/cypress/platform/dev-diagrams/layout-tests/elk-edge-cases/4813-title-and-arrow-styling.mmd b/cypress/platform/dev-diagrams/layout-tests/elk-edge-cases/4813-title-and-arrow-styling.mmd
new file mode 100644
index 00000000000..b396d70ee10
--- /dev/null
+++ b/cypress/platform/dev-diagrams/layout-tests/elk-edge-cases/4813-title-and-arrow-styling.mmd
@@ -0,0 +1,6 @@
+---
+title: My title
+---
+flowchart LR
+ A-->B
+ A-->C
diff --git a/cypress/platform/dev-diagrams/layout-tests/elk-edge-cases/Render-stadium-shape.mmd b/cypress/platform/dev-diagrams/layout-tests/elk-edge-cases/Render-stadium-shape.mmd
new file mode 100644
index 00000000000..1ad9294470e
--- /dev/null
+++ b/cypress/platform/dev-diagrams/layout-tests/elk-edge-cases/Render-stadium-shape.mmd
@@ -0,0 +1,20 @@
+---
+config:
+ flowchart:
+ htmlLabels: false
+ fontFamily: 'courier'
+ elk:
+ nodePlacementAlignment: NONE
+---
+flowchart-elk TD
+ A([stadium shape test])
+ A -->|Get money| B([Go shopping])
+ B --> C([Let me think...
Do I want something for work,
something to spend every free second with,
or something to get around?])
+ C -->|One| D([Laptop])
+ C -->|Two| E([iPhone])
+ C -->|Three| F([Car
wroom wroom])
+ click A "index.html#link-clicked" "link test"
+ click B testClick "click test"
+ classDef someclass fill:#f96;
+ class A someclass;
+ class C someclass;
diff --git a/cypress/platform/dev-diagrams/layout-tests/elk-edge-cases/diamond-intersections.mmd b/cypress/platform/dev-diagrams/layout-tests/elk-edge-cases/diamond-intersections.mmd
new file mode 100644
index 00000000000..583c05843b4
--- /dev/null
+++ b/cypress/platform/dev-diagrams/layout-tests/elk-edge-cases/diamond-intersections.mmd
@@ -0,0 +1,38 @@
+---
+config:
+ layout: elk
+ elk:
+ nodePlacementAlignment: NONE
+---
+flowchart LR
+ subgraph s1["Untitled subgraph"]
+ n1["Evaluate"]
+ n2["Option 1"]
+ n3["Option 2"]
+ n4["fa:fa-car Option 3"]
+ end
+ subgraph s2["Untitled subgraph"]
+ n5["Evaluate"]
+ n6["Option 1"]
+ n7["Option 2"]
+ n8["fa:fa-car Option 3"]
+ end
+ A["Start"] -- Some text --> B("Continue")
+ B --> C{"Evaluate"}
+ C -- One --> D["Option 1"]
+ C -- Two --> E["Option 2"]
+ C -- Three --> F["fa:fa-car Option 3"]
+ n1 -- One --> n2
+ n1 -- Two --> n3
+ n1 -- Three --> n4
+ n5 -- One --> n6
+ n5 -- Two --> n7
+ n5 -- Three --> n8
+ n1@{ shape: diam}
+ n2@{ shape: rect}
+ n3@{ shape: rect}
+ n4@{ shape: rect}
+ n5@{ shape: diam}
+ n6@{ shape: rect}
+ n7@{ shape: rect}
+ n8@{ shape: rect}
diff --git a/cypress/platform/dev-diagrams/layout-tests/elk-edge-cases/full-class-diagram.mmd b/cypress/platform/dev-diagrams/layout-tests/elk-edge-cases/full-class-diagram.mmd
new file mode 100644
index 00000000000..b2a8a7206ac
--- /dev/null
+++ b/cypress/platform/dev-diagrams/layout-tests/elk-edge-cases/full-class-diagram.mmd
@@ -0,0 +1,32 @@
+---
+config:
+ elk:
+ nodePlacementAlignment: BALANCED
+---
+classDiagram
+ note "I love this diagram!\nDo you love it?"
+ Class01 <|-- AveryLongClass : Cool
+ <> Class01
+ Class03 "1" *-- "*" Class04
+ Class05 "1" o-- "many" Class06
+ Class07 "1" .. "*" Class08
+ Class09 "1" --> "*" C2 : Where am i?
+ Class09 "*" --* "*" C3
+ Class09 "1" --|> "1" Class07
+ Class12 <|.. Class08
+ Class11 ..>Class12
+ Class07 : equals()
+ Class07 : Object[] elementData
+ Class01 : size()
+ Class01 : int chimp
+ Class01 : int gorilla
+ Class01 : -int privateChimp
+ Class01 : +int publicGorilla
+ Class01 : #int protectedMarmoset
+ Class08 <--> C2: Cool label
+ class Class10 {
+ <>
+ int id
+ test()
+ }
+ note for Class10 "Cool class\nI said it's very cool class!"
diff --git a/cypress/platform/dev-diagrams/layout-tests/elk-edge-cases/non-rect-intersections.mmd b/cypress/platform/dev-diagrams/layout-tests/elk-edge-cases/non-rect-intersections.mmd
index bef0db45d14..c2c1d40afb6 100644
--- a/cypress/platform/dev-diagrams/layout-tests/elk-edge-cases/non-rect-intersections.mmd
+++ b/cypress/platform/dev-diagrams/layout-tests/elk-edge-cases/non-rect-intersections.mmd
@@ -1,4 +1,9 @@
-%% Validate ELK edge endpoints against non-rectangular node shapes.
+---
+config:
+ elk:
+ nodePlacementAlignment: BALANCED
+---
+
flowchart TD
Start([Start]) --> Split{Ready to Process?}
Split -->|yes| T1[Task A]
diff --git a/cypress/platform/dev-diagrams/layout-tests/elk-edge-cases/right-angles-not-curves.mmd b/cypress/platform/dev-diagrams/layout-tests/elk-edge-cases/right-angles-not-curves.mmd
new file mode 100644
index 00000000000..673a6d25e6d
--- /dev/null
+++ b/cypress/platform/dev-diagrams/layout-tests/elk-edge-cases/right-angles-not-curves.mmd
@@ -0,0 +1,23 @@
+---
+config:
+ elk:
+ nodePlacementAlignment: NONE
+---
+flowchart LR
+ subgraph G1
+ N00
+ N11
+ N12
+ N13
+ end
+ subgraph G2
+ N21
+ N22
+ end
+ N00 --- N01 & N02 & N03 & N04 & N05
+ N00 --- N11 & N12 & N13 & N22
+ N11 --- N22
+ N11 --- N22
+ N11 --- N22
+ N11 --- N22
+ N11 --- N22
diff --git a/cypress/platform/dev-diagrams/layout-tests/elk-edge-cases/should-render-edge-labels-correctly-when-flowchart-htmlLabels-is-false.mmd b/cypress/platform/dev-diagrams/layout-tests/elk-edge-cases/should-render-edge-labels-correctly-when-flowchart-htmlLabels-is-false.mmd
new file mode 100644
index 00000000000..9c532988a7f
--- /dev/null
+++ b/cypress/platform/dev-diagrams/layout-tests/elk-edge-cases/should-render-edge-labels-correctly-when-flowchart-htmlLabels-is-false.mmd
@@ -0,0 +1,35 @@
+---
+config:
+ flowchart:
+ htmlLabels: false
+ fontFamily: 'courier'
+---
+requirementDiagram
+ requirement test_req {
+ id: 1
+ text: the test text.
+ risk: high
+ verifymethod: test
+ }
+
+ functionalRequirement test_req2 {
+ id: 1.1
+ text: the second test text.
+ risk: low
+ verifymethod: inspection
+ }
+
+ element test_entity {
+ type: simulation
+ }
+
+ element test_entity2 {
+ type: word doc
+ docRef: reqs/test_entity
+ }
+
+ test_entity - satisfies -> test_req2
+ test_req - traces -> test_req2
+ test_req - contains -> test_req2
+ test_entity2 - verifies -> test_req
+ test_req <- copies - test_entity2
diff --git a/cypress/platform/dev-diagrams/layout-tests/elk-edge-cases/styled-edge-labels.mmd b/cypress/platform/dev-diagrams/layout-tests/elk-edge-cases/styled-edge-labels.mmd
new file mode 100644
index 00000000000..2fa0f0ea889
--- /dev/null
+++ b/cypress/platform/dev-diagrams/layout-tests/elk-edge-cases/styled-edge-labels.mmd
@@ -0,0 +1,15 @@
+flowchart TD
+ A[Christmas] ==> D
+ A[Christmas] -->|Get money| B(Go shopping)
+ A[Christmas] ==> C
+ subgraph T ["Test"]
+ A
+ B
+ C
+ end
+
+ classDef Test fill:#F84E68,stroke:#333,color:white;
+ class A,T Test
+ classDef TestSub fill:green;
+ class T TestSub
+ linkStyle 0,1 color:orange, stroke: orange;
diff --git a/cypress/platform/viewer.js b/cypress/platform/viewer.js
index c36d39b08d9..ef0e62d55f4 100644
--- a/cypress/platform/viewer.js
+++ b/cypress/platform/viewer.js
@@ -15,6 +15,13 @@ function markRendered() {
}
}
+function usesLegacyFontAwesomeSyntax(code) {
+ const legacyFontAwesomePattern = /fa[bklrs]?:fa-[\w-]+|::icon\(\s*fa\b/;
+ return Array.isArray(code)
+ ? code.some((diagramCode) => usesLegacyFontAwesomeSyntax(diagramCode))
+ : legacyFontAwesomePattern.test(code);
+}
+
function loadFontAwesomeCSS() {
const link = document.createElement('link');
link.rel = 'stylesheet';
@@ -34,14 +41,16 @@ function loadFontAwesomeCSS() {
* page.
*/
const contentLoaded = async function () {
- await loadFontAwesomeCSS();
- await Promise.all(Array.from(document.fonts, (font) => font.load()));
-
let pos = document.location.href.indexOf('?graph=');
if (pos > 0) {
pos = pos + 7;
const graphBase64 = document.location.href.substr(pos);
const graphObj = JSON.parse(b64ToUtf8(graphBase64));
+ if (usesLegacyFontAwesomeSyntax(graphObj.code)) {
+ await loadFontAwesomeCSS();
+ }
+ await Promise.all(Array.from(document.fonts, (font) => font.load()));
+
const darkThemes = ['dark', 'neo-dark', 'redux-dark', 'redux-dark-color'];
if (graphObj.mermaid && darkThemes.includes(graphObj.mermaid.theme)) {
document.body.style.background = '#3f3f3f';
diff --git a/docs/config/setup/defaultConfig/variables/configKeys.md b/docs/config/setup/defaultConfig/variables/configKeys.md
index 281c7c7df97..3582384af6a 100644
--- a/docs/config/setup/defaultConfig/variables/configKeys.md
+++ b/docs/config/setup/defaultConfig/variables/configKeys.md
@@ -12,4 +12,4 @@
> `const` **configKeys**: `Set`<`string`>
-Defined in: [packages/mermaid/src/defaultConfig.ts:336](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L336)
+Defined in: [packages/mermaid/src/defaultConfig.ts:340](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L340)
diff --git a/docs/config/setup/mermaid/functions/clearLayoutRenderState.md b/docs/config/setup/mermaid/functions/clearLayoutRenderState.md
index ce3c3278b65..420fe112b03 100644
--- a/docs/config/setup/mermaid/functions/clearLayoutRenderState.md
+++ b/docs/config/setup/mermaid/functions/clearLayoutRenderState.md
@@ -12,7 +12,7 @@
> **clearLayoutRenderState**(): `void`
-Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:164](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L164)
+Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:183](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L183)
## Returns
diff --git a/docs/config/setup/mermaid/functions/createCommonLayoutRenderer.md b/docs/config/setup/mermaid/functions/createCommonLayoutRenderer.md
index 78e3022cf00..da870c43e88 100644
--- a/docs/config/setup/mermaid/functions/createCommonLayoutRenderer.md
+++ b/docs/config/setup/mermaid/functions/createCommonLayoutRenderer.md
@@ -12,7 +12,7 @@
> **createCommonLayoutRenderer**<`CoreResult`, `PreparedLayout`, `MeasureResult`>(`__namedParameters`): (`data4Layout`, `svg`, `helpers?`, `options?`) => `Promise`<`void`>
-Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:87](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L87)
+Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:106](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L106)
## Type Parameters
diff --git a/docs/config/setup/mermaid/functions/defaultMeasureLayout.md b/docs/config/setup/mermaid/functions/defaultMeasureLayout.md
index f592ecdd7f4..83a4031cf3f 100644
--- a/docs/config/setup/mermaid/functions/defaultMeasureLayout.md
+++ b/docs/config/setup/mermaid/functions/defaultMeasureLayout.md
@@ -12,7 +12,7 @@
> **defaultMeasureLayout**(`data4Layout`, `__namedParameters`): `Promise`<{ `graph`: `Graph`; `groups`: { `clusters`: `D3Selection`<`SVGGElement`>; `edgeLabels`: `D3Selection`<`SVGGElement`>; `edgePaths`: `D3Selection`<`SVGGElement`>; `nodes`: `D3Selection`<`SVGGElement`>; `rootGroups`: `D3Selection`<`SVGGElement`>; }; `nodeElements`: `Map`<`string`, `D3Selection`<`SVGElement` | `SVGGElement`>>; }>
-Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:171](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L171)
+Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:190](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L190)
## Parameters
diff --git a/docs/config/setup/mermaid/functions/paintLayoutData.md b/docs/config/setup/mermaid/functions/paintLayoutData.md
index e701e30fa38..a5a528f2df2 100644
--- a/docs/config/setup/mermaid/functions/paintLayoutData.md
+++ b/docs/config/setup/mermaid/functions/paintLayoutData.md
@@ -10,9 +10,9 @@
# Function: paintLayoutData()
-> **paintLayoutData**(`data4Layout`, `__namedParameters`, `options`): `Promise`<`void`>
+> **paintLayoutData**(`data4Layout`, `context`, `options`): `Promise`<`void`>
-Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:178](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L178)
+Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:197](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L197)
## Parameters
@@ -20,7 +20,7 @@ Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.
[`LayoutData`](../interfaces/LayoutData.md)
-### \_\_namedParameters
+### context
[`CommonLayoutPaintContext`](../interfaces/CommonLayoutPaintContext.md)<`unknown`, { `graph`: `Graph`; `groups`: { `clusters`: `D3Selection`<`SVGGElement`>; `edgeLabels`: `D3Selection`<`SVGGElement`>; `edgePaths`: `D3Selection`<`SVGGElement`>; `nodes`: `D3Selection`<`SVGGElement`>; `rootGroups`: `D3Selection`<`SVGGElement`>; }; `nodeElements`: `Map`<`string`, `D3Selection`<`SVGElement` | `SVGGElement`>>; }>
diff --git a/docs/config/setup/mermaid/interfaces/CommonLayoutPaintContext.md b/docs/config/setup/mermaid/interfaces/CommonLayoutPaintContext.md
index 11d321050c4..bee69e5a24a 100644
--- a/docs/config/setup/mermaid/interfaces/CommonLayoutPaintContext.md
+++ b/docs/config/setup/mermaid/interfaces/CommonLayoutPaintContext.md
@@ -10,7 +10,7 @@
# Interface: CommonLayoutPaintContext\
-Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:45](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L45)
+Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:46](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L46)
## Extends
@@ -32,7 +32,7 @@ Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.
> **element**: `D3Selection`<`SVGElement`>
-Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:39](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L39)
+Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:40](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L40)
#### Inherited from
@@ -44,7 +44,7 @@ Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.
> `optional` **helpers**: `object`
-Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:40](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L40)
+Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:41](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L41)
#### common
@@ -492,7 +492,7 @@ The curve factory to use
> **measure**: `MeasureResult`
-Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:49](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L49)
+Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:50](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L50)
---
@@ -500,7 +500,7 @@ Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.
> `optional` **options**: [`RenderOptions`](RenderOptions.md)
-Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:41](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L41)
+Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:42](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L42)
#### Inherited from
@@ -512,7 +512,7 @@ Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.
> `optional` **preparedLayout**: `PreparedLayout`
-Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:42](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L42)
+Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:43](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L43)
#### Inherited from
diff --git a/docs/config/setup/mermaid/interfaces/CommonLayoutPaintOptions.md b/docs/config/setup/mermaid/interfaces/CommonLayoutPaintOptions.md
index 120b6d68fb7..7976917bf56 100644
--- a/docs/config/setup/mermaid/interfaces/CommonLayoutPaintOptions.md
+++ b/docs/config/setup/mermaid/interfaces/CommonLayoutPaintOptions.md
@@ -10,15 +10,93 @@
# Interface: CommonLayoutPaintOptions
-Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:52](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L52)
+Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:53](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L53)
## Properties
+### clusterDb?
+
+> `optional` **clusterDb**: `ClusterDb`
+
+Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:54](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L54)
+
+---
+
+### getEdgeNode()?
+
+> `optional` **getEdgeNode**: (`id`, `edge`, `context`) => `object` | `Node` | `undefined`
+
+Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:59](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L59)
+
+#### Parameters
+
+##### id
+
+`string` | `undefined`
+
+##### edge
+
+`Edge`
+
+##### context
+
+[`CommonLayoutPaintContext`](CommonLayoutPaintContext.md)<`unknown`, { `graph`: `Graph`; `groups`: { `clusters`: `D3Selection`<`SVGGElement`>; `edgeLabels`: `D3Selection`<`SVGGElement`>; `edgePaths`: `D3Selection`<`SVGGElement`>; `nodes`: `D3Selection`<`SVGGElement`>; `rootGroups`: `D3Selection`<`SVGGElement`>; }; `nodeElements`: `Map`<`string`, `D3Selection`<`SVGElement` | `SVGGElement`>>; }>
+
+#### Returns
+
+`object` | `Node` | `undefined`
+
+---
+
+### getNodes()?
+
+> `optional` **getNodes**: (`data4Layout`, `context`) => `Iterable`<`Node`>
+
+Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:55](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L55)
+
+#### Parameters
+
+##### data4Layout
+
+[`LayoutData`](LayoutData.md)
+
+##### context
+
+[`CommonLayoutPaintContext`](CommonLayoutPaintContext.md)<`unknown`, { `graph`: `Graph`; `groups`: { `clusters`: `D3Selection`<`SVGGElement`>; `edgeLabels`: `D3Selection`<`SVGGElement`>; `edgePaths`: `D3Selection`<`SVGGElement`>; `nodes`: `D3Selection`<`SVGGElement`>; `rootGroups`: `D3Selection`<`SVGGElement`>; }; `nodeElements`: `Map`<`string`, `D3Selection`<`SVGElement` | `SVGGElement`>>; }>
+
+#### Returns
+
+`Iterable`<`Node`>
+
+---
+
+### isCluster()?
+
+> `optional` **isCluster**: (`node`, `context`) => `boolean`
+
+Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:68](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L68)
+
+#### Parameters
+
+##### node
+
+`Node`
+
+##### context
+
+[`CommonLayoutPaintContext`](CommonLayoutPaintContext.md)<`unknown`, { `graph`: `Graph`; `groups`: { `clusters`: `D3Selection`<`SVGGElement`>; `edgeLabels`: `D3Selection`<`SVGGElement`>; `edgePaths`: `D3Selection`<`SVGGElement`>; `nodes`: `D3Selection`<`SVGGElement`>; `rootGroups`: `D3Selection`<`SVGGElement`>; }; `nodeElements`: `Map`<`string`, `D3Selection`<`SVGElement` | `SVGGElement`>>; }>
+
+#### Returns
+
+`boolean`
+
+---
+
### skipEdge()?
> `optional` **skipEdge**: (`edge`) => `boolean`
-Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:53](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L53)
+Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:72](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L72)
#### Parameters
@@ -36,4 +114,26 @@ Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.
> `optional` **skipIntersect**: `boolean` | (`edge`) => `boolean`
-Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:54](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L54)
+Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:73](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L73)
+
+---
+
+### skipNode()?
+
+> `optional` **skipNode**: (`node`, `context`) => `boolean`
+
+Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:64](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L64)
+
+#### Parameters
+
+##### node
+
+`Node`
+
+##### context
+
+[`CommonLayoutPaintContext`](CommonLayoutPaintContext.md)<`unknown`, { `graph`: `Graph`; `groups`: { `clusters`: `D3Selection`<`SVGGElement`>; `edgeLabels`: `D3Selection`<`SVGGElement`>; `edgePaths`: `D3Selection`<`SVGGElement`>; `nodes`: `D3Selection`<`SVGGElement`>; `rootGroups`: `D3Selection`<`SVGGElement`>; }; `nodeElements`: `Map`<`string`, `D3Selection`<`SVGElement` | `SVGGElement`>>; }>
+
+#### Returns
+
+`boolean`
diff --git a/docs/config/setup/mermaid/interfaces/CommonLayoutRenderContext.md b/docs/config/setup/mermaid/interfaces/CommonLayoutRenderContext.md
index 461901b7a73..3ef74298922 100644
--- a/docs/config/setup/mermaid/interfaces/CommonLayoutRenderContext.md
+++ b/docs/config/setup/mermaid/interfaces/CommonLayoutRenderContext.md
@@ -10,7 +10,7 @@
# Interface: CommonLayoutRenderContext\
-Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:38](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L38)
+Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:39](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L39)
## Extended by
@@ -28,7 +28,7 @@ Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.
> **element**: `D3Selection`<`SVGElement`>
-Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:39](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L39)
+Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:40](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L40)
---
@@ -36,7 +36,7 @@ Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.
> `optional` **helpers**: `object`
-Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:40](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L40)
+Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:41](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L41)
#### common
@@ -480,7 +480,7 @@ The curve factory to use
> `optional` **options**: [`RenderOptions`](RenderOptions.md)
-Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:41](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L41)
+Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:42](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L42)
---
@@ -488,4 +488,4 @@ Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.
> `optional` **preparedLayout**: `PreparedLayout`
-Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:42](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L42)
+Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:43](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L43)
diff --git a/docs/config/setup/mermaid/interfaces/CommonLayoutRendererDefinition.md b/docs/config/setup/mermaid/interfaces/CommonLayoutRendererDefinition.md
index eacdb1f930a..451c95b4310 100644
--- a/docs/config/setup/mermaid/interfaces/CommonLayoutRendererDefinition.md
+++ b/docs/config/setup/mermaid/interfaces/CommonLayoutRendererDefinition.md
@@ -10,7 +10,7 @@
# Interface: CommonLayoutRendererDefinition\
-Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:57](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L57)
+Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:76](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L76)
## Type Parameters
@@ -32,7 +32,7 @@ Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.
> `optional` **afterPaint**: (`data4Layout`, `context`, `coreResult`) => `void` | `Promise`<`void`>
-Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:79](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L79)
+Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:98](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L98)
#### Parameters
@@ -58,7 +58,7 @@ Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.
> `optional` **measureLayout**: (`data4Layout`, `context`) => `Promise`<`MeasureResult`>
-Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:66](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L66)
+Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:85](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L85)
#### Parameters
@@ -80,7 +80,7 @@ Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.
> `optional` **paintLayout**: (`data4Layout`, `context`, `coreResult`) => `void` | `Promise`<`void`>
-Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:74](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L74)
+Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:93](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L93)
#### Parameters
@@ -106,7 +106,7 @@ Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.
> `optional` **paintOptions**: [`CommonLayoutPaintOptions`](CommonLayoutPaintOptions.md)
-Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:84](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L84)
+Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:103](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L103)
---
@@ -114,7 +114,7 @@ Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.
> `optional` **prepareLayout**: (`data4Layout`, `context`) => `PreparedLayout` | `Promise`<`PreparedLayout`>
-Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:62](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L62)
+Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:81](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L81)
#### Parameters
@@ -136,7 +136,7 @@ Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.
> **runLayoutCore**: (`data4Layout`, `context`) => `CoreResult` | `Promise`<`CoreResult`>
-Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:70](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L70)
+Defined in: [packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts:89](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/layout-algorithms/common/index.ts#L89)
#### Parameters
diff --git a/packages/mermaid/src/config.spec.ts b/packages/mermaid/src/config.spec.ts
index 408cea9cc18..7a3b6bae186 100644
--- a/packages/mermaid/src/config.spec.ts
+++ b/packages/mermaid/src/config.spec.ts
@@ -63,6 +63,13 @@ describe('when working with site config', () => {
expect(config.elk?.nodePlacementAlignment).toBe('NONE');
});
+ it('should default class diagrams to dagre-wrapper without forcing class padding', () => {
+ const config = configApi.getConfig();
+
+ expect(config.class?.defaultRenderer).toBe('dagre-wrapper');
+ expect(config.class?.padding).toBeUndefined();
+ });
+
it('should retain railroad directives after sanitization', () => {
configApi.saveConfigFromInitialize({});
configApi.addDirective({
diff --git a/packages/mermaid/src/dagre-wrapper/GraphObjects.md b/packages/mermaid/src/dagre-wrapper/GraphObjects.md
deleted file mode 100644
index b90ce69312e..00000000000
--- a/packages/mermaid/src/dagre-wrapper/GraphObjects.md
+++ /dev/null
@@ -1,140 +0,0 @@
-# Cluster handling
-
-Dagre does not support edges between nodes and clusters or between clusters to other clusters. In order to remedy this shortcoming the dagre wrapper implements a few workarounds.
-
-In the diagram below there are two clusters and there are no edges to nodes outside the own cluster.
-
-```mermaid
-flowchart
- subgraph C1
- a --> b
- end
- subgraph C2
- c
- end
- C1 --> C2
-```
-
-In this case the dagre-wrapper will transform the graph to the graph below.
-
-```mermaid
-flowchart
- C1 --> C2
-```
-
-The new nodes C1 and C2 are a special type of nodes, clusterNodes. ClusterNodes have the nodes in the cluster including the cluster attached in a graph object.
-
-When rendering this diagram it is being rendered recursively. The diagram is rendered by the dagre-mermaid:render function which in turn will be used to render the node C1 and the node C2. The result of those renderings will be inserted as nodes in the "root" diagram. With this recursive approach it would be possible to have different layout direction for each cluster.
-
-```
-{ clusterNode: true, graph }
-```
-
-_Data for a clusterNode_
-
-When a cluster has edges to or from some of its nodes leading outside the cluster the approach of recursive rendering cannot be used as the layout of the graph needs to take responsibility for nodes outside of the cluster.
-
-```mermaid
-flowchart
- subgraph C1
- a
- end
- subgraph C2
- b
- end
- a --> C2
-```
-
-To handle this case a special type of edge is inserted. The edge to/from the cluster is replaced with an edge to/from a node in the cluster which is tagged with toCluster/fromCluster. When rendering this edge the intersection between the edge and the border of the cluster is calculated making the edge start/stop there. In practice this renders like an edge to/from the cluster.
-
-In the diagram above the root diagram would be rendered with C1 whereas C2 would be rendered recursively.
-
-Of these two approaches the top one renders better and is used when possible. When this is not possible, ie an edge is added crossing the border the non recursive approach is used.
-
-# Graph objects and their properties
-
-Explains the representation of various objects used to render the flow charts and what the properties mean. This is from the perspective of the dagre-wrapper.
-
-## node
-
-Sample object:
-
-```json
-{
- "shape": "rect",
- "labelText": "Test",
- "rx": 0,
- "ry": 0,
- "class": "default",
- "style": "",
- "id": "Test",
- "type": "group",
- "padding": 15
-}
-```
-
-This is set by the renderer of the diagram and insert the data that the wrapper needs for rendering.
-
-| property | description |
-| ---------- | ------------------------------------------------------------------------------------------------ |
-| labelStyle | Css styles for the label. User for instance for styling the labels for clusters |
-| shape | The shape of the node. |
-| labelText | The text on the label |
-| rx | The corner radius - maybe part of the shape instead? Used for rects. |
-| ry | The corner radius - maybe part of the shape instead? Used for rects. |
-| classes | Classes to be set for the shape. Not used |
-| style | Css styles for the actual shape |
-| id | id of the shape |
-| type | if set to group then this node indicates _a cluster_. |
-| padding | Padding. Passed from the render as this might differ between different diagrams. Maybe obsolete. |
-| data | Non-generic data specific to the shape. |
-
-# edge
-
-arrowType sets the type of arrows to use. The following arrow types are currently supported:
-
-arrow_cross
-double_arrow_cross
-arrow_point
-double_arrow_point
-arrow_circle
-double_arrow_circle
-
-Lets try to make these types semantic free so that diagram type semantics does not find its way into this more generic layer.
-
-Required edgeData for proper rendering:
-
-| property | description |
-| ---------- | -------------------------------------------------------------------- |
-| id | ID of the edge |
-| arrowHead | overlap between arrowHead and arrowType? |
-| arrowType | overlap between arrowHead and arrowType? |
-| style | |
-| labelStyle | |
-| label | overlap between label and labelText? |
-| labelPos | |
-| labelType | overlap between label and labelText? |
-| thickness | Sets the thickness of the edge. Can be \['normal', 'thick'\] |
-| pattern | Sets the pattern of the edge. Can be \['solid', 'dotted', 'dashed'\] |
-
-# Markers
-
-Define what markers that should be included in the diagram with the insert markers function. The function takes two arguments, first the element in which the markers should be included and a list of the markers that should be added.
-
-Ex:
-insertMarkers(el, \['point', 'circle'\])
-
-The example above adds the markers point and cross. This means that edges with the arrowTypes arrow_cross, double_arrow_cross, arrow_point and double_arrow_cross will get the corresponding markers but arrowType arrow_cross will have no impact.
-
-Current markers:
-
-- point - the standard arrow from flowcharts
-- circle - Arrows ending with circle
-- cross - arrows starting and ending with a cross
-
-// Todo - in case of common renderer
-
-# Common functions used by the renderer to be implemented by the Db
-
-getDirection
-getClasses
diff --git a/packages/mermaid/src/dagre-wrapper/blockArrowHelper.ts b/packages/mermaid/src/dagre-wrapper/blockArrowHelper.ts
deleted file mode 100644
index 57a28c23785..00000000000
--- a/packages/mermaid/src/dagre-wrapper/blockArrowHelper.ts
+++ /dev/null
@@ -1,247 +0,0 @@
-import type { Direction } from '../../src/diagrams/block/blockTypes.js';
-
-const expandAndDeduplicateDirections = (directions: Direction[]) => {
- const uniqueDirections = new Set();
-
- for (const direction of directions) {
- switch (direction) {
- case 'x':
- uniqueDirections.add('right');
- uniqueDirections.add('left');
- break;
- case 'y':
- uniqueDirections.add('up');
- uniqueDirections.add('down');
- break;
- default:
- uniqueDirections.add(direction);
- break;
- }
- }
-
- return uniqueDirections;
-};
-export const getArrowPoints = (
- duplicatedDirections: Direction[],
- bbox: { width: number; height: number },
- node: any,
- totalWidth?: number
-) => {
- // Expand and deduplicate the provided directions.
- // for instance: x, right => right, left
- const directions = expandAndDeduplicateDirections(duplicatedDirections);
-
- // Factor to divide height for some calculations.
- const f = 2;
-
- // Calculated height of the bounding box, accounting for node padding.
- const height = bbox.height + 2 * node.padding;
- // Midpoint calculation based on height.
- const midpoint = height / f;
- // Calculated width of the bounding box, accounting for additional width and node padding.
- // When totalWidth is provided
- const width = totalWidth ?? bbox.width + 2 * midpoint + node.padding;
- // Padding to use, half of the node padding.
- const padding = node.padding / 2;
-
- if (
- directions.has('right') &&
- directions.has('left') &&
- directions.has('up') &&
- directions.has('down')
- ) {
- // SQUARE
- return [
- // Bottom
- { x: 0, y: 0 },
- { x: midpoint, y: 0 },
- { x: width / 2, y: 2 * padding },
- { x: width - midpoint, y: 0 },
- { x: width, y: 0 },
-
- // Right
- { x: width, y: -height / 3 },
- { x: width + 2 * padding, y: -height / 2 },
- { x: width, y: (-2 * height) / 3 },
- { x: width, y: -height },
-
- // Top
- { x: width - midpoint, y: -height },
- { x: width / 2, y: -height - 2 * padding },
- { x: midpoint, y: -height },
-
- // Left
- { x: 0, y: -height },
- { x: 0, y: (-2 * height) / 3 },
- { x: -2 * padding, y: -height / 2 },
- { x: 0, y: -height / 3 },
- ];
- }
- if (directions.has('right') && directions.has('left') && directions.has('up')) {
- // RECTANGLE_VERTICAL (Top Open)
- return [
- { x: midpoint, y: 0 },
- { x: width - midpoint, y: 0 },
- { x: width, y: -height / 2 },
- { x: width - midpoint, y: -height },
- { x: midpoint, y: -height },
- { x: 0, y: -height / 2 },
- ];
- }
- if (directions.has('right') && directions.has('left') && directions.has('down')) {
- // RECTANGLE_VERTICAL (Bottom Open)
- return [
- { x: 0, y: 0 },
- { x: midpoint, y: -height },
- { x: width - midpoint, y: -height },
- { x: width, y: 0 },
- ];
- }
- if (directions.has('right') && directions.has('up') && directions.has('down')) {
- // RECTANGLE_HORIZONTAL (Right Open)
- return [
- { x: 0, y: 0 },
- { x: width, y: -midpoint },
- { x: width, y: -height + midpoint },
- { x: 0, y: -height },
- ];
- }
- if (directions.has('left') && directions.has('up') && directions.has('down')) {
- // RECTANGLE_HORIZONTAL (Left Open)
- return [
- { x: width, y: 0 },
- { x: 0, y: -midpoint },
- { x: 0, y: -height + midpoint },
- { x: width, y: -height },
- ];
- }
- if (directions.has('right') && directions.has('left')) {
- // HORIZONTAL_LINE
- return [
- { x: midpoint, y: 0 },
- { x: midpoint, y: -padding },
- { x: width - midpoint, y: -padding },
- { x: width - midpoint, y: 0 },
- { x: width, y: -height / 2 },
- { x: width - midpoint, y: -height },
- { x: width - midpoint, y: -height + padding },
- { x: midpoint, y: -height + padding },
- { x: midpoint, y: -height },
- { x: 0, y: -height / 2 },
- ];
- }
- if (directions.has('up') && directions.has('down')) {
- // VERTICAL_LINE
- return [
- // Bottom center
- { x: width / 2, y: 0 },
- // Left point of bottom arrow
- { x: 0, y: -padding },
- { x: midpoint, y: -padding },
- // Left top over vertical section
- { x: midpoint, y: -height + padding },
- { x: 0, y: -height + padding },
- // Top of arrow
- { x: width / 2, y: -height },
- { x: width, y: -height + padding },
- // Top of right vertical bar
- { x: width - midpoint, y: -height + padding },
- { x: width - midpoint, y: -padding },
- { x: width, y: -padding },
- ];
- }
- if (directions.has('right') && directions.has('up')) {
- // ANGLE_RT
- return [
- { x: 0, y: 0 },
- { x: width, y: -midpoint },
- { x: 0, y: -height },
- ];
- }
- if (directions.has('right') && directions.has('down')) {
- // ANGLE_RB
- return [
- { x: 0, y: 0 },
- { x: width, y: 0 },
- { x: 0, y: -height },
- ];
- }
- if (directions.has('left') && directions.has('up')) {
- // ANGLE_LT
- return [
- { x: width, y: 0 },
- { x: 0, y: -midpoint },
- { x: width, y: -height },
- ];
- }
- if (directions.has('left') && directions.has('down')) {
- // ANGLE_LB
- return [
- { x: width, y: 0 },
- { x: 0, y: 0 },
- { x: width, y: -height },
- ];
- }
- if (directions.has('right')) {
- // ARROW_RIGHT
- return [
- { x: midpoint, y: -padding },
- { x: midpoint, y: -padding },
- { x: width - midpoint, y: -padding },
- { x: width - midpoint, y: 0 },
- { x: width, y: -height / 2 },
- { x: width - midpoint, y: -height },
- { x: width - midpoint, y: -height + padding },
- // top left corner of arrow
- { x: midpoint, y: -height + padding },
- { x: midpoint, y: -height + padding },
- ];
- }
- if (directions.has('left')) {
- // ARROW_LEFT
- return [
- { x: midpoint, y: 0 },
- { x: midpoint, y: -padding },
- // Two points, the right corners
- { x: width - midpoint, y: -padding },
- { x: width - midpoint, y: -height + padding },
- { x: midpoint, y: -height + padding },
- { x: midpoint, y: -height },
- { x: 0, y: -height / 2 },
- ];
- }
- if (directions.has('up')) {
- // ARROW_TOP
- return [
- // Bottom center
- { x: midpoint, y: -padding },
- // Left top over vertical section
- { x: midpoint, y: -height + padding },
- { x: 0, y: -height + padding },
- // Top of arrow
- { x: width / 2, y: -height },
- { x: width, y: -height + padding },
- // Top of right vertical bar
- { x: width - midpoint, y: -height + padding },
- { x: width - midpoint, y: -padding },
- ];
- }
- if (directions.has('down')) {
- // ARROW_BOTTOM
- return [
- // Bottom center
- { x: width / 2, y: 0 },
- // Left point of bottom arrow
- { x: 0, y: -padding },
- { x: midpoint, y: -padding },
- // Left top over vertical section
- { x: midpoint, y: -height + padding },
- { x: width - midpoint, y: -height + padding },
- { x: width - midpoint, y: -padding },
- { x: width, y: -padding },
- ];
- }
-
- // POINT
- return [{ x: 0, y: 0 }];
-};
diff --git a/packages/mermaid/src/dagre-wrapper/clusters.js b/packages/mermaid/src/dagre-wrapper/clusters.js
deleted file mode 100644
index c7313e121c4..00000000000
--- a/packages/mermaid/src/dagre-wrapper/clusters.js
+++ /dev/null
@@ -1,256 +0,0 @@
-import intersectRect from './intersect/intersect-rect.js';
-import { log } from '../logger.js';
-import createLabel from './createLabel.js';
-import { createText } from '../rendering-util/createText.js';
-import { select } from 'd3';
-import { getConfig } from '../diagram-api/diagramAPI.js';
-import { getEffectiveHtmlLabels } from '../config.js';
-import { getSubGraphTitleMargins } from '../utils/subGraphTitleMargins.js';
-
-const rect = async (parent, node) => {
- log.info('Creating subgraph rect for ', node.id, node);
- const siteConfig = getConfig();
-
- // Add outer g element
- const shapeSvg = parent
- .insert('g')
- .attr('class', 'cluster' + (node.class ? ' ' + node.class : ''))
- .attr('id', node.id);
-
- // add the rect
- const rect = shapeSvg.insert('rect', ':first-child');
-
- const useHtmlLabels = getEffectiveHtmlLabels(siteConfig);
-
- // Create the label and insert it after the rect
- const label = shapeSvg.insert('g').attr('class', 'cluster-label');
-
- // TODO: the createText function returns a `Promise`, so I'm guessing it never runs?
- const text =
- node.labelType === 'markdown'
- ? createText(label, node.labelText, { style: node.labelStyle, useHtmlLabels }, siteConfig)
- : await createLabel(label, node.labelText, node.labelStyle, undefined, true);
-
- // Get the size of the label
- let bbox = text.getBBox();
-
- if (getEffectiveHtmlLabels(siteConfig)) {
- const div = text.children[0];
- const dv = select(text);
- bbox = div.getBoundingClientRect();
- dv.attr('width', bbox.width);
- dv.attr('height', bbox.height);
- }
-
- const padding = 0 * node.padding;
- const halfPadding = padding / 2;
-
- const width = node.width <= bbox.width + padding ? bbox.width + padding : node.width;
- if (node.width <= bbox.width + padding) {
- node.diff = (bbox.width - node.width) / 2 - node.padding / 2;
- } else {
- node.diff = -node.padding / 2;
- }
-
- log.trace('Data ', node, JSON.stringify(node));
- // center the rect around its coordinate
- rect
- .attr('style', node.style)
- .attr('rx', node.rx)
- .attr('ry', node.ry)
- .attr('x', node.x - width / 2)
- .attr('y', node.y - node.height / 2 - halfPadding)
- .attr('width', width)
- .attr('height', node.height + padding);
-
- const { subGraphTitleTopMargin } = getSubGraphTitleMargins(siteConfig);
- if (useHtmlLabels) {
- label.attr(
- 'transform',
- // This puts the label on top of the box instead of inside it
- `translate(${node.x - bbox.width / 2}, ${node.y - node.height / 2 + subGraphTitleTopMargin})`
- );
- } else {
- label.attr(
- 'transform',
- // This puts the label on top of the box instead of inside it
- `translate(${node.x}, ${node.y - node.height / 2 + subGraphTitleTopMargin})`
- );
- }
- // Center the label
-
- const rectBox = rect.node().getBBox();
- node.width = rectBox.width;
- node.height = rectBox.height;
-
- node.intersect = function (point) {
- return intersectRect(node, point);
- };
-
- return shapeSvg;
-};
-
-/**
- * Non visible cluster where the note is group with its
- *
- * @param {any} parent
- * @param {any} node
- * @returns {any} ShapeSvg
- */
-const noteGroup = (parent, node) => {
- // Add outer g element
- const shapeSvg = parent.insert('g').attr('class', 'note-cluster').attr('id', node.id);
-
- // add the rect
- const rect = shapeSvg.insert('rect', ':first-child');
-
- const padding = 0 * node.padding;
- const halfPadding = padding / 2;
-
- // center the rect around its coordinate
- rect
- .attr('rx', node.rx)
- .attr('ry', node.ry)
- .attr('x', node.x - node.width / 2 - halfPadding)
- .attr('y', node.y - node.height / 2 - halfPadding)
- .attr('width', node.width + padding)
- .attr('height', node.height + padding)
- .attr('fill', 'none');
-
- const rectBox = rect.node().getBBox();
- node.width = rectBox.width;
- node.height = rectBox.height;
-
- node.intersect = function (point) {
- return intersectRect(node, point);
- };
-
- return shapeSvg;
-};
-const roundedWithTitle = async (parent, node) => {
- const siteConfig = getConfig();
-
- // Add outer g element
- const shapeSvg = parent.insert('g').attr('class', node.classes).attr('id', node.id);
-
- // add the rect
- const rect = shapeSvg.insert('rect', ':first-child');
-
- // Create the label and insert it after the rect
- const label = shapeSvg.insert('g').attr('class', 'cluster-label');
- const innerRect = shapeSvg.append('rect');
-
- const text = await createLabel(label, node.labelText, node.labelStyle, undefined, true);
-
- // Get the size of the label
- let bbox = text.getBBox();
- if (getEffectiveHtmlLabels(siteConfig)) {
- const div = text.children[0];
- const dv = select(text);
- bbox = div.getBoundingClientRect();
- dv.attr('width', bbox.width);
- dv.attr('height', bbox.height);
- }
- bbox = text.getBBox();
- const padding = 0 * node.padding;
- const halfPadding = padding / 2;
-
- const width = node.width <= bbox.width + node.padding ? bbox.width + node.padding : node.width;
- if (node.width <= bbox.width + node.padding) {
- node.diff = (bbox.width + node.padding * 0 - node.width) / 2;
- } else {
- node.diff = -node.padding / 2;
- }
-
- // center the rect around its coordinate
- rect
- .attr('class', 'outer')
- .attr('x', node.x - width / 2 - halfPadding)
- .attr('y', node.y - node.height / 2 - halfPadding)
- .attr('width', width + padding)
- .attr('height', node.height + padding);
- innerRect
- .attr('class', 'inner')
- .attr('x', node.x - width / 2 - halfPadding)
- .attr('y', node.y - node.height / 2 - halfPadding + bbox.height - 1)
- .attr('width', width + padding)
- .attr('height', node.height + padding - bbox.height - 3);
-
- const { subGraphTitleTopMargin } = getSubGraphTitleMargins(siteConfig);
- // Center the label
- label.attr(
- 'transform',
- `translate(${node.x - bbox.width / 2}, ${
- node.y -
- node.height / 2 -
- node.padding / 3 +
- (getEffectiveHtmlLabels(siteConfig) ? 5 : 3) +
- subGraphTitleTopMargin
- })`
- );
-
- const rectBox = rect.node().getBBox();
- node.height = rectBox.height;
-
- node.intersect = function (point) {
- return intersectRect(node, point);
- };
-
- return shapeSvg;
-};
-
-const divider = (parent, node) => {
- // Add outer g element
- const shapeSvg = parent.insert('g').attr('class', node.classes).attr('id', node.id);
-
- // add the rect
- const rect = shapeSvg.insert('rect', ':first-child');
-
- const padding = 0 * node.padding;
- const halfPadding = padding / 2;
-
- // center the rect around its coordinate
- rect
- .attr('class', 'divider')
- .attr('x', node.x - node.width / 2 - halfPadding)
- .attr('y', node.y - node.height / 2)
- .attr('width', node.width + padding)
- .attr('height', node.height + padding);
-
- const rectBox = rect.node().getBBox();
- node.width = rectBox.width;
- node.height = rectBox.height;
- node.diff = -node.padding / 2;
- node.intersect = function (point) {
- return intersectRect(node, point);
- };
-
- return shapeSvg;
-};
-
-const shapes = { rect, roundedWithTitle, noteGroup, divider };
-
-let clusterElems = {};
-
-export const insertCluster = async (elem, node) => {
- log.trace('Inserting cluster');
- const shape = node.shape || 'rect';
- clusterElems[node.id] = await shapes[shape](elem, node);
-};
-export const getClusterTitleWidth = async (elem, node) => {
- const label = await createLabel(elem, node.labelText, node.labelStyle, undefined, true);
- const width = label.getBBox().width;
- elem.node().removeChild(label);
- return width;
-};
-
-export const clear = () => {
- clusterElems = {};
-};
-
-export const positionCluster = (node) => {
- log.info('Position cluster (' + node.id + ', ' + node.x + ', ' + node.y + ')');
- const el = clusterElems[node.id];
-
- el.attr('transform', 'translate(' + node.x + ', ' + node.y + ')');
-};
diff --git a/packages/mermaid/src/dagre-wrapper/createLabel.js b/packages/mermaid/src/dagre-wrapper/createLabel.js
deleted file mode 100644
index 24f726aceee..00000000000
--- a/packages/mermaid/src/dagre-wrapper/createLabel.js
+++ /dev/null
@@ -1,55 +0,0 @@
-import { getEffectiveHtmlLabels } from '../config.js';
-import { getConfig } from '../diagram-api/diagramAPI.js';
-import { createText } from '../rendering-util/createText.js';
-
-/**
- * @param {import('../types.js').D3Selection} element - The parent element to which the label will be appended.
- * @param {string | [string] | undefined} _vertexText - The text content of the label.
- * @param {string} style
- * @param {boolean} [isTitle] - If `true`, style this as a title label, else as a normal label.
- * @param {boolean} [isNode] - If `true`, style this as a node label, else as an edge label.
- * @deprecated svg-util/createText instead
- *
- * @example
- *
- * If `getEffectiveHtmlLabels(getConfig())` is `true`, you must reset the width
- * and height of the created label after creation, like this:
- *
- * ```js
- * const labelElement = await createLabel(parent, ... );
- * let slBox = labelElement.getBBox();
- * if (useHtmlLabels) {
- * const div = labelElement.children[0];
- * const dv = select(labelElement);
- * slBox = div.getBoundingClientRect();
- * dv.attr('width', slBox.width);
- * dv.attr('height', slBox.height);
- * }
- * parent.attr('transform', 'translate(' + -slBox.width / 2 + ', ' + -slBox.height / 2 + ')');
- * ```
- */
-const createLabel = async (element, _vertexText, style, isTitle = false, isNode = false) => {
- let vertexText = _vertexText || '';
- if (typeof vertexText === 'object') {
- vertexText = vertexText[0];
- }
-
- const config = getConfig();
- const useHtmlLabels = getEffectiveHtmlLabels(config);
-
- return await createText(
- element,
- vertexText,
- {
- style,
- isTitle,
- useHtmlLabels,
- markdown: false,
- isNode,
- width: Number.POSITIVE_INFINITY,
- },
- config
- );
-};
-
-export default createLabel;
diff --git a/packages/mermaid/src/dagre-wrapper/edgeMarker.spec.ts b/packages/mermaid/src/dagre-wrapper/edgeMarker.spec.ts
deleted file mode 100644
index 6fb43955269..00000000000
--- a/packages/mermaid/src/dagre-wrapper/edgeMarker.spec.ts
+++ /dev/null
@@ -1,80 +0,0 @@
-/* eslint-disable @typescript-eslint/unbound-method */
-import type { Mocked } from 'vitest';
-import type { SVG } from '../diagram-api/types.js';
-import { addEdgeMarkers } from './edgeMarker.js';
-
-describe('addEdgeMarker', () => {
- const svgPath = {
- attr: vitest.fn(),
- } as unknown as Mocked