diff --git a/.build/common.ts b/.build/common.ts
index efd0e3a85..2497d443f 100644
--- a/.build/common.ts
+++ b/.build/common.ts
@@ -33,6 +33,11 @@ export const packageOptions = {
packageName: 'mermaid-layout-elk',
file: 'layouts.ts',
},
+ 'mermaid-layout-tidy-tree': {
+ name: 'mermaid-layout-tidy-tree',
+ packageName: 'mermaid-layout-tidy-tree',
+ file: 'index.ts',
+ },
examples: {
name: 'mermaid-examples',
packageName: 'examples',
diff --git a/.changeset/beige-peas-shave.md b/.changeset/beige-peas-shave.md
deleted file mode 100644
index c405f3dcc..000000000
--- a/.changeset/beige-peas-shave.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@mermaid-js/mermaid-zenuml': patch
----
-
-Fixed a critical bug that the ZenUML diagram is not rendered.
diff --git a/.changeset/chatty-lemons-stick.md b/.changeset/chatty-lemons-stick.md
deleted file mode 100644
index 733e374ef..000000000
--- a/.changeset/chatty-lemons-stick.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'mermaid': patch
----
-
-chore: Remove the "-beta" suffix from the XYChart, Block, Sankey diagrams to reflect their stable status
diff --git a/.changeset/clean-wolves-turn.md b/.changeset/clean-wolves-turn.md
new file mode 100644
index 000000000..7a44c1c16
--- /dev/null
+++ b/.changeset/clean-wolves-turn.md
@@ -0,0 +1,5 @@
+---
+'mermaid': patch
+---
+
+fix: Render newlines as spaces in class diagrams
diff --git a/.changeset/cold-sites-accept.md b/.changeset/cold-sites-accept.md
deleted file mode 100644
index cba7ae414..000000000
--- a/.changeset/cold-sites-accept.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'mermaid': patch
----
-
-fix: Position the edge label in state diagram correctly relative to the edge
diff --git a/.changeset/crazy-loops-matter.md b/.changeset/crazy-loops-matter.md
new file mode 100644
index 000000000..e6377a9e5
--- /dev/null
+++ b/.changeset/crazy-loops-matter.md
@@ -0,0 +1,5 @@
+---
+'mermaid': patch
+---
+
+fix: Handle arrows correctly when auto number is enabled
diff --git a/.changeset/empty-clouds-cry.md b/.changeset/empty-clouds-cry.md
deleted file mode 100644
index c513542f1..000000000
--- a/.changeset/empty-clouds-cry.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'mermaid': patch
----
-
-fix: Apply correct dateFormat in Gantt chart to show only day when specified
diff --git a/.changeset/fuzzy-pears-cough.md b/.changeset/fuzzy-pears-cough.md
deleted file mode 100644
index 6ed777506..000000000
--- a/.changeset/fuzzy-pears-cough.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'mermaid': patch
----
-
-fix: handle exclude dates properly in Gantt charts when using dateFormat: 'YYYY-MM-DD HH:mm:ss'
diff --git a/.changeset/gold-spiders-join.md b/.changeset/gold-spiders-join.md
deleted file mode 100644
index 56bccc244..000000000
--- a/.changeset/gold-spiders-join.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'mermaid': patch
----
-
-fix: fixed connection gaps in flowchart for roundedRect, stadium and diamond shape
diff --git a/.changeset/hungry-baths-glow.md b/.changeset/hungry-baths-glow.md
new file mode 100644
index 000000000..b3084bcab
--- /dev/null
+++ b/.changeset/hungry-baths-glow.md
@@ -0,0 +1,5 @@
+---
+'mermaid': minor
+---
+
+feat: Added support for new participant types (`actor`, `boundary`, `control`, `entity`, `database`, `collections`, `queue`) in `sequenceDiagram`.
diff --git a/.changeset/hungry-guests-drive.md b/.changeset/hungry-guests-drive.md
new file mode 100644
index 000000000..1b0e0a07b
--- /dev/null
+++ b/.changeset/hungry-guests-drive.md
@@ -0,0 +1,7 @@
+---
+'mermaid': minor
+'@mermaid-js/layout-tidy-tree': minor
+'@mermaid-js/layout-elk': minor
+---
+
+feat: Update mindmap rendering to support multiple layouts, improved edge intersections, and new shapes
diff --git a/.changeset/large-mirrors-cheer.md b/.changeset/large-mirrors-cheer.md
deleted file mode 100644
index 4e3903039..000000000
--- a/.changeset/large-mirrors-cheer.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'mermaid': patch
----
-
-fix: Update casing of ID in requirement diagram
diff --git a/.changeset/lemon-masks-unite.md b/.changeset/lemon-masks-unite.md
deleted file mode 100644
index 306ff1cce..000000000
--- a/.changeset/lemon-masks-unite.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'mermaid': minor
----
-
-feat: Added support for per link curve styling in flowchart diagram using edge ids
diff --git a/.changeset/light-flowers-judge.md b/.changeset/light-flowers-judge.md
deleted file mode 100644
index 6378a9b0a..000000000
--- a/.changeset/light-flowers-judge.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'mermaid': patch
----
-
-fix: Make flowchart elk detector regex match less greedy
diff --git a/.changeset/lovely-queens-own.md b/.changeset/lovely-queens-own.md
deleted file mode 100644
index edc8dda2d..000000000
--- a/.changeset/lovely-queens-own.md
+++ /dev/null
@@ -1,8 +0,0 @@
----
-'mermaid': patch
----
-
-fix(block): overflowing blocks no longer affect later lines
-
-This may change the layout of block diagrams that have overflowing lines
-(i.e. block diagrams that use up more columns that the `columns` specifier).
diff --git a/.changeset/ninety-roses-turn.md b/.changeset/ninety-roses-turn.md
deleted file mode 100644
index a69a6e7a0..000000000
--- a/.changeset/ninety-roses-turn.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-'mermaid': patch
----
-
-fix: log warning for blocks exceeding column width
-
-This update adds a validation check that logs a warning message when a block's width exceeds the defined column layout.
diff --git a/.changeset/rare-women-fly.md b/.changeset/rare-women-fly.md
deleted file mode 100644
index 46d08dd10..000000000
--- a/.changeset/rare-women-fly.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'mermaid': patch
----
-
-fix: Add escaped class literal name on namespace
diff --git a/.changeset/seven-papayas-film.md b/.changeset/seven-papayas-film.md
deleted file mode 100644
index 109743117..000000000
--- a/.changeset/seven-papayas-film.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-'mermaid': patch
----
-
-Add validation for negative values in pie charts:
-
-Prevents crashes during parsing by validating values post-parsing.
-
-Provides clearer, user-friendly error messages for invalid negative inputs.
diff --git a/.changeset/silver-eyes-build.md b/.changeset/silver-eyes-build.md
deleted file mode 100644
index 76f0a0125..000000000
--- a/.changeset/silver-eyes-build.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'mermaid': patch
----
-
-chore: migrate to class-based ArchitectureDB implementation
diff --git a/.changeset/six-planets-rescue.md b/.changeset/six-planets-rescue.md
deleted file mode 100644
index 8b04a69ed..000000000
--- a/.changeset/six-planets-rescue.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'mermaid': patch
----
-
-fix: node border style for handdrawn shapes
diff --git a/.changeset/smart-humans-cover.md b/.changeset/smart-humans-cover.md
deleted file mode 100644
index 4408e0a9c..000000000
--- a/.changeset/smart-humans-cover.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'mermaid': patch
----
-
-fix: Update flowchart direction TD's behavior to be the same as TB
diff --git a/.changeset/strong-dryers-pay.md b/.changeset/strong-dryers-pay.md
deleted file mode 100644
index 495cde202..000000000
--- a/.changeset/strong-dryers-pay.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'mermaid': patch
----
-
-fix: correctly render non-directional lines for '---' in block diagrams
diff --git a/.changeset/vast-buses-see.md b/.changeset/vast-buses-see.md
deleted file mode 100644
index fc2a0e6c6..000000000
--- a/.changeset/vast-buses-see.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'mermaid': patch
----
-
-chore: Update packet diagram to use new class-based database structure
diff --git a/.cspell/contributors.txt b/.cspell/contributors.txt
index 80f4df22a..a95f8654e 100644
--- a/.cspell/contributors.txt
+++ b/.cspell/contributors.txt
@@ -2,6 +2,7 @@
Ashish Jain
cpettitt
Dong Cai
+fourcube
knsv
Knut Sveidqvist
Nikolay Rozhkov
diff --git a/.cspell/mermaid-terms.txt b/.cspell/mermaid-terms.txt
index b0cfa0a1d..6900c15b0 100644
--- a/.cspell/mermaid-terms.txt
+++ b/.cspell/mermaid-terms.txt
@@ -5,6 +5,7 @@ bmatrix
braintree
catmull
compositTitleSize
+cose
curv
doublecircle
elems
diff --git a/.cspell/misc-terms.txt b/.cspell/misc-terms.txt
index 1820e3c86..2906a02fa 100644
--- a/.cspell/misc-terms.txt
+++ b/.cspell/misc-terms.txt
@@ -1,4 +1,5 @@
BRANDES
+Buzan
circo
handDrawn
KOEPF
diff --git a/.github/lychee.toml b/.github/lychee.toml
index fbe7a71a2..06b3aa707 100644
--- a/.github/lychee.toml
+++ b/.github/lychee.toml
@@ -59,6 +59,7 @@ exclude = [
"https://huehive.co",
"https://foswiki.org",
"https://www.gnu.org",
+"https://redmine.org",
"https://mermaid-preview.com"
]
diff --git a/.github/workflows/e2e-applitools.yml b/.github/workflows/e2e-applitools.yml
index dd97b49e1..6aaa91eb8 100644
--- a/.github/workflows/e2e-applitools.yml
+++ b/.github/workflows/e2e-applitools.yml
@@ -23,9 +23,6 @@ env:
jobs:
e2e-applitools:
runs-on: ubuntu-latest
- container:
- image: cypress/browsers:node-20.11.0-chrome-121.0.6167.85-1-ff-120.0-edge-121.0.2277.83-1
- options: --user 1001
steps:
- if: ${{ ! env.USE_APPLI }}
name: Warn if not using Applitools
diff --git a/.github/workflows/e2e-timings.yml b/.github/workflows/e2e-timings.yml
index f4c28acad..21dbda293 100644
--- a/.github/workflows/e2e-timings.yml
+++ b/.github/workflows/e2e-timings.yml
@@ -58,7 +58,7 @@ jobs:
echo "EOF" >> $GITHUB_OUTPUT
- name: Commit and create pull request
- uses: peter-evans/create-pull-request@1310d7dab503600742045e6fd4b84dda64352858
+ uses: peter-evans/create-pull-request@18e469570b1cf0dfc11d60ec121099f8ff3e617a
with:
add-paths: |
cypress/timings.json
diff --git a/.github/workflows/validate-lockfile.yml b/.github/workflows/validate-lockfile.yml
index 6eb0a63ca..59a6df96d 100644
--- a/.github/workflows/validate-lockfile.yml
+++ b/.github/workflows/validate-lockfile.yml
@@ -35,7 +35,7 @@ jobs:
# 2) No unwanted vitepress paths
if grep -qF 'packages/mermaid/src/vitepress' pnpm-lock.yaml; then
- issues+=("• Disallowed path 'packages/mermaid/src/vitepress' present. Run `rm -rf packages/mermaid/src/vitepress && pnpm install` to regenerate.")
+ issues+=("• Disallowed path 'packages/mermaid/src/vitepress' present. Run \`rm -rf packages/mermaid/src/vitepress && pnpm install\` to regenerate.")
fi
# 3) Lockfile only changes when package.json changes
diff --git a/.gitignore b/.gitignore
index 7448f2a81..7eb55d5cb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@ node_modules/
coverage/
.idea/
.pnpm-store/
+.instructions/
dist
v8-compile-cache-0
diff --git a/cypress/helpers/util.ts b/cypress/helpers/util.ts
index 79be26dd9..cf0e9a87d 100644
--- a/cypress/helpers/util.ts
+++ b/cypress/helpers/util.ts
@@ -15,7 +15,7 @@ interface CodeObject {
mermaid: CypressMermaidConfig;
}
-const utf8ToB64 = (str: string): string => {
+export const utf8ToB64 = (str: string): string => {
return Buffer.from(decodeURIComponent(encodeURIComponent(str))).toString('base64');
};
@@ -23,7 +23,7 @@ const batchId: string =
'mermaid-batch-' +
(Cypress.env('useAppli')
? Date.now().toString()
- : Cypress.env('CYPRESS_COMMIT') || Date.now().toString());
+ : (Cypress.env('CYPRESS_COMMIT') ?? Date.now().toString()));
export const mermaidUrl = (
graphStr: string | string[],
@@ -62,9 +62,7 @@ export const imgSnapshotTest = (
sequence: {
...(_options.sequence ?? {}),
actorFontFamily: 'courier',
- noteFontFamily: _options.sequence?.noteFontFamily
- ? _options.sequence.noteFontFamily
- : 'courier',
+ noteFontFamily: _options.sequence?.noteFontFamily ?? 'courier',
messageFontFamily: 'courier',
},
};
diff --git a/cypress/integration/other/xss.spec.js b/cypress/integration/other/xss.spec.js
index 1e51d2f23..35a493850 100644
--- a/cypress/integration/other/xss.spec.js
+++ b/cypress/integration/other/xss.spec.js
@@ -1,4 +1,4 @@
-import { mermaidUrl } from '../../helpers/util.ts';
+import { imgSnapshotTest, mermaidUrl, utf8ToB64 } from '../../helpers/util.ts';
describe('XSS', () => {
it('should handle xss in tags', () => {
const str =
@@ -141,4 +141,37 @@ describe('XSS', () => {
cy.wait(1000);
cy.get('#the-malware').should('not.exist');
});
+
+ it('should sanitize icon labels in architecture diagrams', () => {
+ const str = JSON.stringify({
+ code: `architecture-beta
+ group api(cloud)[API]
+ service db "" [Database] in api`,
+ });
+ imgSnapshotTest(utf8ToB64(str), {}, true);
+ cy.wait(1000);
+ cy.get('#the-malware').should('not.exist');
+ });
+
+ it('should sanitize katex blocks', () => {
+ const str = JSON.stringify({
+ code: `sequenceDiagram
+ participant A as Alice
$$\\text{Alice}$$
+ A->>John: Hello John, how are you?`,
+ });
+ imgSnapshotTest(utf8ToB64(str), {}, true);
+ cy.wait(1000);
+ cy.get('#the-malware').should('not.exist');
+ });
+
+ it('should sanitize labels', () => {
+ const str = JSON.stringify({
+ code: `erDiagram
+ "
" ||--|| ENTITY2 : "
"
+ `,
+ });
+ imgSnapshotTest(utf8ToB64(str), {}, true);
+ cy.wait(1000);
+ cy.get('#the-malware').should('not.exist');
+ });
});
diff --git a/cypress/integration/rendering/classDiagram.spec.js b/cypress/integration/rendering/classDiagram.spec.js
index bd2a96b34..6cea402f8 100644
--- a/cypress/integration/rendering/classDiagram.spec.js
+++ b/cypress/integration/rendering/classDiagram.spec.js
@@ -524,5 +524,18 @@ describe('Class diagram', () => {
`,
{}
);
+ it('should handle an empty class body with empty braces', () => {
+ imgSnapshotTest(
+ ` classDiagram
+ class FooBase~T~ {}
+ class Bar {
+ +Zip
+ +Zap()
+ }
+ FooBase <|-- Ba
+ `,
+ { flowchart: { defaultRenderer: 'elk' } }
+ );
+ });
});
});
diff --git a/cypress/integration/rendering/flowchart-elk.spec.js b/cypress/integration/rendering/flowchart-elk.spec.js
index 27af2c40c..312e1d5b4 100644
--- a/cypress/integration/rendering/flowchart-elk.spec.js
+++ b/cypress/integration/rendering/flowchart-elk.spec.js
@@ -1053,6 +1053,21 @@ flowchart LR
});
});
});
+
+ it('6647-elk: should keep node order when using elk layout unless it would add crossings', () => {
+ imgSnapshotTest(
+ `---
+config:
+ layout: elk
+---
+ flowchart TB
+ a --> a1 & a2 & a3 & a4
+ b --> b1 & b2
+ b2 --> b3
+ b1 --> b4
+ `
+ );
+ });
});
describe('Title and arrow styling #4813', () => {
diff --git a/cypress/integration/rendering/flowchart-v2.spec.js b/cypress/integration/rendering/flowchart-v2.spec.js
index 69ff10b00..8c6cde57a 100644
--- a/cypress/integration/rendering/flowchart-v2.spec.js
+++ b/cypress/integration/rendering/flowchart-v2.spec.js
@@ -1118,7 +1118,7 @@ end
imgSnapshotTest(
`flowchart TB
A(["Start"]) --> n1["Untitled Node"]
- A --> n2["Untitled Node"]
+ A --> n2["Untitled Node"]
`,
{}
);
@@ -1127,7 +1127,7 @@ end
imgSnapshotTest(
`flowchart BT
n2["Untitled Node"] --> n1["Diamond"]
- n1@{ shape: diam}
+ n1@{ shape: diam}
`,
{}
);
@@ -1138,7 +1138,7 @@ end
n2["Untitled Node"] --> n1["Rounded Rectangle"]
n3["Untitled Node"] --> n1
n1@{ shape: rounded}
- n3@{ shape: rect}
+ n3@{ shape: rect}
`,
{}
);
@@ -1164,4 +1164,26 @@ end
`
);
});
+
+ describe('when rendering unsuported markdown', () => {
+ const graph = `flowchart TB
+ mermaid{"What is\nyourmermaid version?"} --> v10["<11"] --"\`<**1**1\`"--> fine["No bug"]
+ mermaid --> v11[">= v11"] -- ">= v11" --> broken["Affected by https://github.com/mermaid-js/mermaid/issues/5824"]
+ subgraph subgraph1["\`How to fix **fix**\`"]
+ broken --> B["B"]
+ end
+ githost["Github, Gitlab, BitBucket, etc."]
+ githost2["\`Github, Gitlab, BitBucket, etc.\`"]
+ a["1."]
+ b["- x"]
+ `;
+
+ it('should render raw strings', () => {
+ imgSnapshotTest(graph);
+ });
+
+ it('should render raw strings with htmlLabels: false', () => {
+ imgSnapshotTest(graph, { htmlLabels: false });
+ });
+ });
});
diff --git a/cypress/integration/rendering/mindmap-tidy-tree.spec.js b/cypress/integration/rendering/mindmap-tidy-tree.spec.js
new file mode 100644
index 000000000..e111c281a
--- /dev/null
+++ b/cypress/integration/rendering/mindmap-tidy-tree.spec.js
@@ -0,0 +1,79 @@
+import { imgSnapshotTest } from '../../helpers/util.ts';
+
+describe('Mindmap Tidy Tree', () => {
+ it('1-tidy-tree: should render a simple mindmap without children', () => {
+ imgSnapshotTest(
+ ` ---
+ config:
+ layout: tidy-tree
+ ---
+ mindmap
+ root((mindmap))
+ A
+ B
+ `
+ );
+ });
+ it('2-tidy-tree: should render a simple mindmap', () => {
+ imgSnapshotTest(
+ ` ---
+ config:
+ layout: tidy-tree
+ ---
+ mindmap
+ root((mindmap is a long thing))
+ A
+ B
+ C
+ D
+ `
+ );
+ });
+ it('3-tidy-tree: should render a mindmap with different shapes', () => {
+ imgSnapshotTest(
+ ` ---
+ config:
+ layout: tidy-tree
+ ---
+ mindmap
+ root((mindmap))
+ Origins
+ Long history
+ ::icon(fa fa-book)
+ Popularisation
+ British popular psychology author Tony Buzan
+ Research
+ On effectiveness<br/>and features
+ On Automatic creation
+ Uses
+ Creative techniques
+ Strategic planning
+ Argument mapping
+ Tools
+ id)I am a cloud(
+ id))I am a bang((
+ Tools
+ `
+ );
+ });
+ it('4-tidy-tree: should render a mindmap with children', () => {
+ imgSnapshotTest(
+ ` ---
+ config:
+ layout: tidy-tree
+ ---
+ mindmap
+ ((This is a mindmap))
+ child1
+ grandchild 1
+ grandchild 2
+ child2
+ grandchild 3
+ grandchild 4
+ child3
+ grandchild 5
+ grandchild 6
+ `
+ );
+ });
+});
diff --git a/cypress/integration/rendering/mindmap.spec.ts b/cypress/integration/rendering/mindmap.spec.ts
index d76e58c56..e0409ed46 100644
--- a/cypress/integration/rendering/mindmap.spec.ts
+++ b/cypress/integration/rendering/mindmap.spec.ts
@@ -159,12 +159,10 @@ root
});
it('square shape', () => {
imgSnapshotTest(
- `
-mindmap
+ `mindmap
root[
The root
- ]
- `,
+ ]`,
{},
undefined,
shouldHaveRoot
@@ -172,12 +170,10 @@ mindmap
});
it('rounded rect shape', () => {
imgSnapshotTest(
- `
-mindmap
+ `mindmap
root((
The root
- ))
- `,
+ ))`,
{},
undefined,
shouldHaveRoot
@@ -185,12 +181,10 @@ mindmap
});
it('circle shape', () => {
imgSnapshotTest(
- `
-mindmap
+ `mindmap
root(
The root
- )
- `,
+ )`,
{},
undefined,
shouldHaveRoot
@@ -198,10 +192,8 @@ mindmap
});
it('default shape', () => {
imgSnapshotTest(
- `
-mindmap
- The root
- `,
+ `mindmap
+ The root`,
{},
undefined,
shouldHaveRoot
@@ -209,12 +201,10 @@ mindmap
});
it('adding children', () => {
imgSnapshotTest(
- `
-mindmap
+ `mindmap
The root
child1
- child2
- `,
+ child2`,
{},
undefined,
shouldHaveRoot
@@ -222,13 +212,11 @@ mindmap
});
it('adding grand children', () => {
imgSnapshotTest(
- `
-mindmap
+ `mindmap
The root
child1
child2
- child3
- `,
+ child3`,
{},
undefined,
shouldHaveRoot
@@ -240,25 +228,21 @@ mindmap
`mindmap
id1[\`**Start** with
a second line 😎\`]
- id2[\`The dog in **the** hog... a *very long text* about it
-Word!\`]
-`
+ id2[\`The dog in **the** hog... a *very long text* about it Word!\`]`
);
});
});
describe('Include char sequence "graph" in text (#6795)', () => {
it('has a label with char sequence "graph"', () => {
imgSnapshotTest(
- `
- mindmap
+ ` mindmap
root
Photograph
Waterfall
Landscape
Geography
Mountains
- Rocks
- `,
+ Rocks`,
{ flowchart: { defaultRenderer: 'elk' } }
);
});
diff --git a/cypress/integration/rendering/sequencediagram-v2.spec.js b/cypress/integration/rendering/sequencediagram-v2.spec.js
new file mode 100644
index 000000000..f1c2aafbd
--- /dev/null
+++ b/cypress/integration/rendering/sequencediagram-v2.spec.js
@@ -0,0 +1,659 @@
+import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
+
+const looks = ['classic'];
+const participantTypes = [
+ { type: 'participant', display: 'participant' },
+ { type: 'actor', display: 'actor' },
+ { type: 'boundary', display: 'boundary' },
+ { type: 'control', display: 'control' },
+ { type: 'entity', display: 'entity' },
+ { type: 'database', display: 'database' },
+ { type: 'collections', display: 'collections' },
+ { type: 'queue', display: 'queue' },
+];
+
+const restrictedTypes = ['boundary', 'control', 'entity', 'database', 'collections', 'queue'];
+
+const interactionTypes = ['->>', '-->>', '->', '-->', '-x', '--x', '->>+', '-->>+'];
+
+const notePositions = ['left of', 'right of', 'over'];
+
+function getParticipantLine(name, type, alias) {
+ if (restrictedTypes.includes(type)) {
+ return ` participant ${name}@{ "type" : "${type}" }\n`;
+ } else if (alias) {
+ return ` participant ${name}@{ "type" : "${type}" } \n`;
+ } else {
+ return ` participant ${name}@{ "type" : "${type}" }\n`;
+ }
+}
+
+looks.forEach((look) => {
+ describe(`Sequence Diagram Tests - ${look} look`, () => {
+ it('should render all participant types', () => {
+ let diagramCode = `sequenceDiagram\n`;
+ participantTypes.forEach((pt, index) => {
+ const name = `${pt.display}${index}`;
+ diagramCode += getParticipantLine(name, pt.type);
+ });
+ for (let i = 0; i < participantTypes.length - 1; i++) {
+ diagramCode += ` ${participantTypes[i].display}${i} ->> ${participantTypes[i + 1].display}${i + 1}: Message ${i}\n`;
+ }
+ imgSnapshotTest(diagramCode, { look, sequence: { diagramMarginX: 50, diagramMarginY: 10 } });
+ });
+
+ it('should render all interaction types', () => {
+ let diagramCode = `sequenceDiagram\n`;
+ diagramCode += getParticipantLine('A', 'actor');
+ diagramCode += getParticipantLine('B', 'boundary');
+ interactionTypes.forEach((interaction, index) => {
+ diagramCode += ` A ${interaction} B: ${interaction} message ${index}\n`;
+ });
+ imgSnapshotTest(diagramCode, { look });
+ });
+
+ it('should render participant creation and destruction', () => {
+ let diagramCode = `sequenceDiagram\n`;
+ participantTypes.forEach((pt, index) => {
+ const name = `${pt.display}${index}`;
+ diagramCode += getParticipantLine('A', pt.type);
+ diagramCode += getParticipantLine('B', pt.type);
+ diagramCode += ` create participant ${name}@{ "type" : "${pt.type}" }\n`;
+ diagramCode += ` A ->> ${name}: Hello ${pt.display}\n`;
+ if (index % 2 === 0) {
+ diagramCode += ` destroy ${name}\n`;
+ }
+ });
+ imgSnapshotTest(diagramCode, { look });
+ });
+
+ it('should render notes in all positions', () => {
+ let diagramCode = `sequenceDiagram\n`;
+ diagramCode += getParticipantLine('A', 'actor');
+ diagramCode += getParticipantLine('B', 'boundary');
+ notePositions.forEach((position, index) => {
+ diagramCode += ` Note ${position} A: Note ${position} ${index}\n`;
+ });
+ diagramCode += ` A ->> B: Message with notes\n`;
+ imgSnapshotTest(diagramCode, { look });
+ });
+
+ it('should render parallel interactions', () => {
+ let diagramCode = `sequenceDiagram\n`;
+ participantTypes.slice(0, 4).forEach((pt, index) => {
+ diagramCode += getParticipantLine(`${pt.display}${index}`, pt.type);
+ });
+ diagramCode += ` par Parallel actions\n`;
+ for (let i = 0; i < 3; i += 2) {
+ diagramCode += ` ${participantTypes[i].display}${i} ->> ${participantTypes[i + 1].display}${i + 1}: Message ${i}\n`;
+ if (i < participantTypes.length - 2) {
+ diagramCode += ` and\n`;
+ }
+ }
+ diagramCode += ` end\n`;
+ imgSnapshotTest(diagramCode, { look });
+ });
+
+ it('should render alternative flows', () => {
+ let diagramCode = `sequenceDiagram\n`;
+ diagramCode += getParticipantLine('A', 'actor');
+ diagramCode += getParticipantLine('B', 'boundary');
+ diagramCode += ` alt Successful case\n`;
+ diagramCode += ` A ->> B: Request\n`;
+ diagramCode += ` B -->> A: Success\n`;
+ diagramCode += ` else Failure case\n`;
+ diagramCode += ` A ->> B: Request\n`;
+ diagramCode += ` B --x A: Failure\n`;
+ diagramCode += ` end\n`;
+ imgSnapshotTest(diagramCode, { look });
+ });
+
+ it('should render loops', () => {
+ let diagramCode = `sequenceDiagram\n`;
+ participantTypes.slice(0, 3).forEach((pt, index) => {
+ diagramCode += getParticipantLine(`${pt.display}${index}`, pt.type);
+ });
+ diagramCode += ` loop For each participant\n`;
+ for (let i = 0; i < 3; i++) {
+ diagramCode += ` ${participantTypes[0].display}0 ->> ${participantTypes[1].display}1: Message ${i}\n`;
+ }
+ diagramCode += ` end\n`;
+ imgSnapshotTest(diagramCode, { look });
+ });
+
+ it('should render boxes around groups', () => {
+ let diagramCode = `sequenceDiagram\n`;
+ diagramCode += ` box Group 1\n`;
+ participantTypes.slice(0, 3).forEach((pt, index) => {
+ diagramCode += ` ${getParticipantLine(`${pt.display}${index}`, pt.type)}`;
+ });
+ diagramCode += ` end\n`;
+ diagramCode += ` box rgb(200,220,255) Group 2\n`;
+ participantTypes.slice(3, 6).forEach((pt, index) => {
+ diagramCode += ` ${getParticipantLine(`${pt.display}${index}`, pt.type)}`;
+ });
+ diagramCode += ` end\n`;
+ diagramCode += ` ${participantTypes[0].display}0 ->> ${participantTypes[3].display}0: Cross-group message\n`;
+ imgSnapshotTest(diagramCode, { look });
+ });
+
+ it('should render with different font settings', () => {
+ let diagramCode = `sequenceDiagram\n`;
+ participantTypes.slice(0, 3).forEach((pt, index) => {
+ diagramCode += getParticipantLine(`${pt.display}${index}`, pt.type);
+ });
+ diagramCode += ` ${participantTypes[0].display}0 ->> ${participantTypes[1].display}1: Regular message\n`;
+ diagramCode += ` Note right of ${participantTypes[1].display}1: Regular note\n`;
+ imgSnapshotTest(diagramCode, {
+ look,
+ sequence: {
+ actorFontFamily: 'courier',
+ actorFontSize: 14,
+ messageFontFamily: 'Arial',
+ messageFontSize: 12,
+ noteFontFamily: 'times',
+ noteFontSize: 16,
+ noteAlign: 'left',
+ },
+ });
+ });
+ });
+});
+
+// Additional tests for specific combinations
+describe('Sequence Diagram Special Cases', () => {
+ it('should render complex sequence with all features', () => {
+ const diagramCode = `
+ sequenceDiagram
+ box rgb(200,220,255) Authentication
+ actor User
+ participant LoginUI@{ "type": "boundary" }
+ participant AuthService@{ "type": "control" }
+ participant UserDB@{ "type": "database" }
+ end
+
+ box rgb(200,255,220) Order Processing
+ participant Order@{ "type": "entity" }
+ participant OrderQueue@{ "type": "queue" }
+ participant AuditLogs@{ "type": "collections" }
+ end
+
+ User ->> LoginUI: Enter credentials
+ LoginUI ->> AuthService: Validate
+ AuthService ->> UserDB: Query user
+ UserDB -->> AuthService: User data
+ alt Valid credentials
+ AuthService -->> LoginUI: Success
+ LoginUI -->> User: Welcome
+
+ par Place order
+ User ->> Order: New order
+ Order ->> OrderQueue: Process
+ and
+ Order ->> AuditLogs: Record
+ end
+
+ loop Until confirmed
+ OrderQueue ->> Order: Update status
+ Order -->> User: Notification
+ end
+ else Invalid credentials
+ AuthService --x LoginUI: Failure
+ LoginUI --x User: Retry
+ end
+ `;
+ imgSnapshotTest(diagramCode, {});
+ });
+
+ it('should render with wrapped messages and notes', () => {
+ const diagramCode = `
+ sequenceDiagram
+ participant A
+ participant B
+
+ A ->> B: This is a very long message that should wrap properly in the diagram rendering
+ Note over A,B: This is a very long note that should also wrap properly when rendered in the diagram
+
+ par Wrapped parallel
+ A ->> B: Parallel message 1
with explicit line break
+ and
+ B ->> A: Parallel message 2
with explicit line break
+ end
+
+ loop Wrapped loop
+ Note right of B: This is a long note
in a loop
+ A ->> B: Message in loop
+ end
+ `;
+ imgSnapshotTest(diagramCode, { sequence: { wrap: true } });
+ });
+ describe('Sequence Diagram Rendering with Different Participant Types', () => {
+ it('should render a sequence diagram with various participant types', () => {
+ imgSnapshotTest(
+ `
+ sequenceDiagram
+ participant User@{ "type": "actor" }
+ participant AuthService@{ "type": "control" }
+ participant UI@{ "type": "boundary" }
+ participant OrderController@{ "type": "control" }
+ participant Product@{ "type": "entity" }
+ participant MongoDB@{ "type": "database" }
+ participant Products@{ "type": "collections" }
+ participant OrderQueue@{ "type": "queue" }
+ User ->> UI: Login request
+ UI ->> AuthService: Validate credentials
+ AuthService -->> UI: Authentication token
+ UI ->> OrderController: Place order
+ OrderController ->> Product: Check availability
+ Product -->> OrderController: Available
+ OrderController ->> MongoDB: Save order
+ MongoDB -->> OrderController: Order saved
+ OrderController ->> OrderQueue: Process payment
+ OrderQueue -->> User: Order confirmation
+ `
+ );
+ });
+
+ it('should render participant creation and destruction with different types', () => {
+ imgSnapshotTest(`
+ sequenceDiagram
+ participant Alice@{ "type" : "boundary" }
+ Alice->>Bob: Hello Bob, how are you ?
+ Bob->>Alice: Fine, thank you. And you?
+ create participant Carl@{ "type" : "control" }
+ Alice->>Carl: Hi Carl!
+ create actor D as Donald
+ Carl->>D: Hi!
+ destroy Carl
+ Alice-xCarl: We are too many
+ destroy Bob
+ Bob->>Alice: I agree
+ `);
+ });
+
+ it('should handle complex interactions between different participant types', () => {
+ imgSnapshotTest(
+ `
+ sequenceDiagram
+ box rgb(200,220,255) Authentication
+ participant User@{ "type": "actor" }
+ participant LoginUI@{ "type": "boundary" }
+ participant AuthService@{ "type": "control" }
+ participant UserDB@{ "type": "database" }
+ end
+
+ box rgb(200,255,220) Order Processing
+ participant Order@{ "type": "entity" }
+ participant OrderQueue@{ "type": "queue" }
+ participant AuditLogs@{ "type": "collections" }
+ end
+
+ User ->> LoginUI: Enter credentials
+ LoginUI ->> AuthService: Validate
+ AuthService ->> UserDB: Query user
+ UserDB -->> AuthService: User data
+
+ alt Valid credentials
+ AuthService -->> LoginUI: Success
+ LoginUI -->> User: Welcome
+
+ par Place order
+ User ->> Order: New order
+ Order ->> OrderQueue: Process
+ and
+ Order ->> AuditLogs: Record
+ end
+
+ loop Until confirmed
+ OrderQueue ->> Order: Update status
+ Order -->> User: Notification
+ end
+ else Invalid credentials
+ AuthService --x LoginUI: Failure
+ LoginUI --x User: Retry
+ end
+ `,
+ { sequence: { useMaxWidth: false } }
+ );
+ });
+
+ it('should render parallel processes with different participant types', () => {
+ imgSnapshotTest(
+ `
+ sequenceDiagram
+ participant Customer@{ "type": "actor" }
+ participant Frontend@{ "type": "participant" }
+ participant PaymentService@{ "type": "boundary" }
+ participant InventoryManager@{ "type": "control" }
+ participant Order@{ "type": "entity" }
+ participant OrdersDB@{ "type": "database" }
+ participant NotificationQueue@{ "type": "queue" }
+
+ Customer ->> Frontend: Place order
+ Frontend ->> Order: Create order
+ par Parallel Processing
+ Order ->> PaymentService: Process payment
+ and
+ Order ->> InventoryManager: Reserve items
+ end
+ PaymentService -->> Order: Payment confirmed
+ InventoryManager -->> Order: Items reserved
+ Order ->> OrdersDB: Save finalized order
+ OrdersDB -->> Order: Order saved
+ Order ->> NotificationQueue: Send confirmation
+ NotificationQueue -->> Customer: Order confirmation
+ `
+ );
+ });
+ });
+ it('should render different participant types with notes and loops', () => {
+ imgSnapshotTest(
+ `
+ sequenceDiagram
+ actor Admin
+ participant Dashboard
+ participant AuthService@{ "type" : "boundary" }
+ participant UserManager@{ "type" : "control" }
+ participant UserProfile@{ "type" : "entity" }
+ participant UserDB@{ "type" : "database" }
+ participant Logs@{ "type" : "database" }
+
+ Admin ->> Dashboard: Open user management
+ loop Authentication check
+ Dashboard ->> AuthService: Verify admin rights
+ AuthService ->> Dashboard: Access granted
+ end
+ Dashboard ->> UserManager: List users
+ UserManager ->> UserDB: Query users
+ UserDB ->> UserManager: Return user data
+ Note right of UserDB: Encrypted data
requires decryption
+ UserManager ->> UserProfile: Format profiles
+ UserProfile ->> UserManager: Formatted data
+ UserManager ->> Dashboard: Display users
+ Dashboard ->> Logs: Record access
+ Logs ->> Admin: Audit trail
+ `
+ );
+ });
+
+ it('should render different participant types with alternative flows', () => {
+ imgSnapshotTest(
+ `
+ sequenceDiagram
+ actor Client
+ participant MobileApp
+ participant CloudService@{ "type" : "boundary" }
+ participant DataProcessor@{ "type" : "control" }
+ participant Transaction@{ "type" : "entity" }
+ participant TransactionsDB@{ "type" : "database" }
+ participant EventBus@{ "type" : "queue" }
+
+ Client ->> MobileApp: Initiate transaction
+ MobileApp ->> CloudService: Authenticate
+ alt Authentication successful
+ CloudService -->> MobileApp: Auth token
+ MobileApp ->> DataProcessor: Process data
+ DataProcessor ->> Transaction: Create transaction
+ Transaction ->> TransactionsDB: Save record
+ TransactionsDB -->> Transaction: Confirmation
+ Transaction ->> EventBus: Publish event
+ EventBus -->> Client: Notification
+ else Authentication failed
+ CloudService -->> MobileApp: Error
+ MobileApp -->> Client: Show error
+ end
+ `
+ );
+ });
+
+ it('should render different participant types with wrapping text', () => {
+ imgSnapshotTest(
+ `
+ sequenceDiagram
+ participant B@{ "type" : "boundary" }
+ participant C@{ "type" : "control" }
+ participant E@{ "type" : "entity" }
+ participant DB@{ "type" : "database" }
+ participant COL@{ "type" : "collections" }
+ participant Q@{ "type" : "queue" }
+
+ FE ->> B: Another long message
with explicit
line breaks
+ B -->> FE: Response message that is also quite long and needs to wrap
+ FE ->> C: Process data
+ C ->> E: Validate
+ E -->> C: Validation result
+ C ->> DB: Save
+ DB -->> C: Save result
+ C ->> COL: Log
+ COL -->> Q: Forward
+ Q -->> LongNameUser: Final response with confirmation of all actions taken
+ `,
+ { sequence: { wrap: true } }
+ );
+ });
+
+ describe('Sequence Diagram - New Participant Types with Long Notes and Messages', () => {
+ it('should render long notes left of boundary', () => {
+ imgSnapshotTest(
+ `
+ sequenceDiagram
+ participant Alice@{ "type" : "boundary" }
+ actor Bob
+ Alice->>Bob: Hola
+ Note left of Alice: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
+ Bob->>Alice: I'm short though
+ `,
+ {}
+ );
+ });
+
+ it('should render wrapped long notes left of control', () => {
+ imgSnapshotTest(
+ `
+ sequenceDiagram
+ participant Alice@{ "type" : "control" }
+ actor Bob
+ Alice->>Bob: Hola
+ Note left of Alice:wrap: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
+ Bob->>Alice: I'm short though
+ `,
+ {}
+ );
+ });
+
+ it('should render long notes right of entity', () => {
+ imgSnapshotTest(
+ `
+ sequenceDiagram
+ participant Alice@{ "type" : "entity" }
+ actor Bob
+ Alice->>Bob: Hola
+ Note right of Alice: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
+ Bob->>Alice: I'm short though
+ `,
+ {}
+ );
+ });
+
+ it('should render wrapped long notes right of database', () => {
+ imgSnapshotTest(
+ `
+ sequenceDiagram
+ participant Alice@{ "type" : "database" }
+ actor Bob
+ Alice->>Bob: Hola
+ Note right of Alice:wrap: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
+ Bob->>Alice: I'm short though
+ `,
+ {}
+ );
+ });
+
+ it('should render long notes over collections', () => {
+ imgSnapshotTest(
+ `
+ sequenceDiagram
+ participant Alice@{ "type" : "collections" }
+ actor Bob
+ Alice->>Bob: Hola
+ Note over Alice: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
+ Bob->>Alice: I'm short though
+ `,
+ {}
+ );
+ });
+
+ it('should render wrapped long notes over queue', () => {
+ imgSnapshotTest(
+ `
+ sequenceDiagram
+ participant Alice@{ "type" : "queue" }
+ actor Bob
+ Alice->>Bob: Hola
+ Note over Alice:wrap: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
+ Bob->>Alice: I'm short though
+ `,
+ {}
+ );
+ });
+
+ it('should render notes over actor and boundary', () => {
+ imgSnapshotTest(
+ `
+ sequenceDiagram
+ actor Alice
+ participant Charlie@{ "type" : "boundary" }
+ note over Alice: Some note
+ note over Charlie: Other note
+ `,
+ {}
+ );
+ });
+
+ it('should render long messages from database to collections', () => {
+ imgSnapshotTest(
+ `
+ sequenceDiagram
+ participant Alice@{ "type" : "database" }
+ participant Bob@{ "type" : "collections" }
+ Alice->>Bob: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
+ Bob->>Alice: I'm short though
+ `,
+ {}
+ );
+ });
+
+ it('should render wrapped long messages from control to entity', () => {
+ imgSnapshotTest(
+ `
+ sequenceDiagram
+ participant Alice@{ "type" : "control" }
+ participant Bob@{ "type" : "entity" }
+ Alice->>Bob:wrap: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
+ Bob->>Alice: I'm short though
+ `,
+ {}
+ );
+ });
+
+ it('should render long messages from queue to boundary', () => {
+ imgSnapshotTest(
+ `
+ sequenceDiagram
+ participant Alice@{ "type" : "queue" }
+ participant Bob@{ "type" : "boundary" }
+ Alice->>Bob: I'm short
+ Bob->>Alice: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
+ `,
+ {}
+ );
+ });
+
+ it('should render wrapped long messages from actor to database', () => {
+ imgSnapshotTest(
+ `
+ sequenceDiagram
+ actor Alice
+ participant Bob@{ "type" : "database" }
+ Alice->>Bob: I'm short
+ Bob->>Alice:wrap: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
+ `,
+ {}
+ );
+ });
+ });
+
+ describe('svg size', () => {
+ it('should render a sequence diagram when useMaxWidth is true (default)', () => {
+ renderGraph(
+ `
+ sequenceDiagram
+ actor Alice
+ participant Bob@{ "type" : "boundary" }
+ participant John@{ "type" : "control" }
+ Alice ->> Bob: Hello Bob, how are you?
+ Bob-->>John: How about you John?
+ Bob--x Alice: I am good thanks!
+ Bob-x John: I am good thanks!
+ Note right of John: Bob thinks a long
long time, so long
that the text does
not fit on a row.
+ Bob-->Alice: Checking with John...
+ alt either this
+ Alice->>John: Yes
+ else or this
+ Alice->>John: No
+ else or this will happen
+ Alice->John: Maybe
+ end
+ par this happens in parallel
+ Alice -->> Bob: Parallel message 1
+ and
+ Alice -->> John: Parallel message 2
+ end
+ `,
+ { sequence: { useMaxWidth: true } }
+ );
+ cy.get('svg').should((svg) => {
+ expect(svg).to.have.attr('width', '100%');
+ const style = svg.attr('style');
+ expect(style).to.match(/^max-width: [\d.]+px;$/);
+ const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
+ expect(maxWidthValue).to.be.within(820 * 0.95, 820 * 1.05);
+ });
+ });
+
+ it('should render a sequence diagram when useMaxWidth is false', () => {
+ renderGraph(
+ `
+ sequenceDiagram
+ actor Alice
+ participant Bob@{ "type" : "boundary" }
+ participant John@{ "type" : "control" }
+ Alice ->> Bob: Hello Bob, how are you?
+ Bob-->>John: How about you John?
+ Bob--x Alice: I am good thanks!
+ Bob-x John: I am good thanks!
+ Note right of John: Bob thinks a long
long time, so long
that the text does
not fit on a row.
+ Bob-->Alice: Checking with John...
+ alt either this
+ Alice->>John: Yes
+ else or this
+ Alice->>John: No
+ else or this will happen
+ Alice->John: Maybe
+ end
+ par this happens in parallel
+ Alice -->> Bob: Parallel message 1
+ and
+ Alice -->> John: Parallel message 2
+ end
+ `,
+ { sequence: { useMaxWidth: false } }
+ );
+ cy.get('svg').should((svg) => {
+ const width = parseFloat(svg.attr('width'));
+ expect(width).to.be.within(820 * 0.95, 820 * 1.05);
+ expect(svg).to.not.have.attr('style');
+ });
+ });
+ });
+});
diff --git a/cypress/integration/rendering/sequencediagram.spec.js b/cypress/integration/rendering/sequencediagram.spec.js
index f18e99abf..6709b557c 100644
--- a/cypress/integration/rendering/sequencediagram.spec.js
+++ b/cypress/integration/rendering/sequencediagram.spec.js
@@ -893,6 +893,17 @@ describe('Sequence diagram', () => {
}
);
});
+
+ it('should handle bidirectional arrows with autonumber', () => {
+ imgSnapshotTest(`
+ sequenceDiagram
+ autonumber
+ participant A
+ participant B
+ A<<->>B: This is a bidirectional message
+ A->B: This is a normal message`);
+ });
+
it('should support actor links and properties when not mirrored EXPERIMENTAL: USE WITH CAUTION', () => {
//Be aware that the syntax for "properties" is likely to be changed.
imgSnapshotTest(
diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html
index ab7ded0c2..fc33a58b4 100644
--- a/cypress/platform/knsv2.html
+++ b/cypress/platform/knsv2.html
@@ -130,6 +130,92 @@
+ --- + config: + layout: tidy-tree + --- + mindmap + root((mindmap)) + Origins + Long history + ::icon(fa fa-book) + Popularisation + British popular psychology author Tony Buzan + Research + On effectiveness+
and features + On Automatic creation + Uses + Creative techniques + Strategic planning + Argument mapping + Tools + Pen and paper + Mermaid + +
+ --- + config: + layout: tidy-tree + --- + mindmap + root((mindmap is a long thing)) + A + B + C + D ++
+ --- + config: + layout: tidy-tree + --- + mindmap + root((mindmap)) + A + B ++
+ --- + config: + layout: tidy-tree + --- + mindmap + root((mindmap)) + A + a + apa[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on] + apa2[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on] + b + c + d + B + apa3[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on] + D + apa5[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on] + apa4[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on] + ++ +
+--- +config: + layout: elk + elk: + mergeEdges: false + forceNodeModelOrder: false + considerModelOrder: NONE + +--- + flowchart TB + a --> a1 & a2 & a3 & a4 + b --> b1 & b2 + b2 --> b3 + b1 --> b4
treemap "Section 1" @@ -175,8 +261,145 @@ treemap "Item B2": 25
+ --- + config: + layout: tidy-tree + --- + mindmap + root((mindmap)) + a + apa[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on] + apa2[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on] + b + apa3[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on] + apa4[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on] + + ++
+ --- + config: + layout: tidy-tree + --- + flowchart TB + A --> n0["1"] + A --> n1["2"] + A --> n2["3"] + A --> n3["4"] --> Q & R & S & T ++
+ --- + config: + layout: elk + --- + flowchart TB + A --> n0["1"] + A --> n1["2"] + A --> n2["3"] + A --> n3["4"] --> Q & R & S & T ++
+ --- + config: + layout: dagre + --- + mindmap + root((mindmap is a long thing)) + Origins + Long history + ::icon(fa fa-book) + Popularisation + British popular psychology author Tony Buzan + Research + On effectiveness<br/>and features + On Automatic creation + Uses + Creative techniques + Strategic planning + Argument mapping + Tools + Pen and paper + Mermaid ++
+ --- + config: + layout: cose-bilkent + --- + mindmap + root((mindmap)) + Origins + Long history + ::icon(fa fa-book) + Popularisation + British popular psychology author Tony Buzan + Research + On effectiveness<br/>and features + On Automatic creation + Uses + Creative techniques + Strategic planning + Argument mapping + Tools + Pen and paper + Mermaid ++
+ --- + config: + layout: elk + --- + mindmap + root((mindmap)) + Origins + Long history + ::icon(fa fa-book) + Popularisation + British popular psychology author Tony Buzan + Research + On effectiveness<br/>and features + On Automatic creation + Uses + Creative techniques + Strategic planning + Argument mapping + Tools + Pen and paper + Mermaid ++
+ --- + config: + layout: cose-bilkent + --- flowchart LR - AB["apa@apa@"] --> B(("`apa@apa`")) + root{mindmap} --- Origins --- Europe + Origins --> Asia + root --- Background --- Rich + Background --- Poor + subgraph apa + Background + Poor + end + + + + ++
+ --- + config: + layout: elk + --- + flowchart LR + root{mindmap} --- Origins --- Europe + Origins --> Asia + root --- Background --- Rich + Background --- Poor + + + +
flowchart @@ -258,6 +481,44 @@ config:
--- +config: + layout: elk +--- + flowchart LR + a + subgraph s0["APA"] + subgraph s8["APA"] + subgraph s1["APA"] + D{"X"} + E[Q] + end + subgraph s3["BAPA"] + F[Q] + I + end + D --> I + D --> I + D --> I + + I{"X"} + end + end ++
+--- +config: + layout: elk +--- + flowchart LR + a + D{"Use the editor"} + + D -- Mermaid js --> I{"fa:fa-code Text"} + D-->I + D-->I ++
+--- config: layout: elk --- diff --git a/cypress/platform/mindmap-layouts.html b/cypress/platform/mindmap-layouts.html new file mode 100644 index 000000000..0aef65d42 --- /dev/null +++ b/cypress/platform/mindmap-layouts.html @@ -0,0 +1,376 @@ + + + + + +Mermaid Quick Test Page + + + + + ++ --- + config: + layout: tidy-tree + --- + mindmap + root((mindmap)) + A + B +++ --- + config: + layout: dagre + --- + mindmap + root((mindmap)) + A + B +++ --- + config: + layout: elk + --- + mindmap + root((mindmap)) + A + B +++ --- + config: + layout: cose-bilkent + --- + mindmap + root((mindmap)) + A + B +++ --- + config: + layout: tidy-tree + --- + mindmap + root((mindmap is a long thing)) + A + B + C + D +++ --- + config: + layout: dagre + --- + mindmap + root((mindmap is a long thing)) + A + B + C + D +++ --- + config: + layout: elk + --- + mindmap + root((mindmap is a long thing)) + A + B + C + D +++ --- + config: + layout: cose-bilkent + --- + mindmap + root((mindmap is a long thing)) + A + B + C + D ++ ++ --- + config: + layout: tidy-tree + --- + mindmap + root((mindmap)) + Origins + Long history + ::icon(fa fa-book) + Popularisation + British popular psychology author Tony Buzan + Research + On effectiveness<br/>and features + On Automatic creation + Uses + Creative techniques + Strategic planning + Argument mapping + Tools + id)I am a cloud( + id))I am a bang(( + Tools +++ --- + config: + layout: dagre + --- + mindmap + root((mindmap)) + Origins + Long history + ::icon(fa fa-book) + Popularisation + British popular psychology author Tony Buzan + Research + On effectiveness<br/>and features + On Automatic creation + Uses + Creative techniques + Strategic planning + Argument mapping + Tools + id)I am a cloud( + id))I am a bang(( + Tools +++ --- + config: + layout: elk + --- + mindmap + root((mindmap)) + Origins + Long history + ::icon(fa fa-book) + Popularisation + British popular psychology author Tony Buzan + Research + On effectiveness<br/>and features + On Automatic creation + Uses + Creative techniques + Strategic planning + Argument mapping + Tools + id)I am a cloud( + id))I am a bang(( + Tools +++ --- + config: + layout: cose-bilkent + --- + mindmap + root((mindmap)) + Origins + Long history + ::icon(fa fa-book) + Popularisation + British popular psychology author Tony Buzan + Research + On effectiveness<br/>and features + On Automatic creation + Uses + Creative techniques + Strategic planning + Argument mapping + Tools + id)I am a cloud( + id))I am a bang(( + Tools +++ --- + config: + layout: tidy-tree + --- + mindmap + root((mindmap)) + A + a + apa[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on] + apa2[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on] + b + c + d + B + apa3[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on] + D + apa5[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on] + apa4[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on] + +++ --- + config: + layout: dagre + --- + mindmap + root((mindmap)) + A + a + apa[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on] + apa2[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on] + b + c + d + B + apa3[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on] + D + apa5[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on] + apa4[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on] + +++ --- + config: + layout: elk + --- + mindmap + root((mindmap)) + A + a + apa[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on] + apa2[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on] + b + c + d + B + apa3[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on] + D + apa5[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on] + apa4[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on] + +++ --- + config: + layout: cose-bilkent + --- + mindmap + root((mindmap)) + A + a + apa[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on] + apa2[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on] + b + c + d + B + apa3[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on] + D + apa5[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on] + apa4[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on] + ++ ++ --- + config: + layout: tidy-tree + --- + mindmap + ((This is a mindmap)) + child1 + grandchild 1 + grandchild 2 + child2 + grandchild 3 + grandchild 4 + child3 + grandchild 5 + grandchild 6 + ++ ++ --- + config: + layout: dagre + --- + mindmap + ((This is a mindmap)) + child1 + grandchild 1 + grandchild 2 + child2 + grandchild 3 + grandchild 4 + child3 + grandchild 5 + grandchild 6 + ++ ++ --- + config: + layout: elk + --- + mindmap + ((This is a mindmap)) + child1 + grandchild 1 + grandchild 2 + child2 + grandchild 3 + grandchild 4 + child3 + grandchild 5 + grandchild 6 + ++ ++ --- + config: + layout: cose-bilkent + --- + mindmap + ((This is a mindmap)) + child1 + grandchild 1 + grandchild 2 + child2 + grandchild 3 + grandchild 4 + child3 + grandchild 5 + grandchild 6 + ++ +
+ + + diff --git a/cypress/platform/sidv.html b/cypress/platform/sidv.html index b0a1699da..1651b0737 100644 --- a/cypress/platform/sidv.html +++ b/cypress/platform/sidv.html @@ -41,10 +41,6 @@ graph TB const { svg } = await mermaid.render('d22', value); console.log(svg); el.innerHTML = svg; - // mermaid.test1('first_slow', 1200).then((r) => console.info(r)); - // mermaid.test1('second_fast', 200).then((r) => console.info(r)); - // mermaid.test1('third_fast', 200).then((r) => console.info(r)); - // mermaid.test1('forth_slow', 1200).then((r) => console.info(r));