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/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/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/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/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/.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-timings.yml b/.github/workflows/e2e-timings.yml index ef009fa2b..2bbfa8412 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@07cbaebb4bfc9c5d7db426ea5a5f585df29dd0a0 + uses: peter-evans/create-pull-request@cb4d3bfce175d44325c6b7697f81e0afe8a79bdf with: add-paths: | cypress/timings.json diff --git a/cypress/helpers/util.ts b/cypress/helpers/util.ts index 81b7036af..ab4bbef64 100644 --- a/cypress/helpers/util.ts +++ b/cypress/helpers/util.ts @@ -14,7 +14,7 @@ interface CodeObject { mermaid: CypressMermaidConfig; } -const utf8ToB64 = (str: string): string => { +export const utf8ToB64 = (str: string): string => { return Buffer.from(decodeURIComponent(encodeURIComponent(str))).toString('base64'); }; @@ -22,7 +22,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[], @@ -61,9 +61,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/block.spec.js b/cypress/integration/rendering/block.spec.js index f01d59375..27e23cd91 100644 --- a/cypress/integration/rendering/block.spec.js +++ b/cypress/integration/rendering/block.spec.js @@ -16,7 +16,7 @@ describe('Block diagram', () => { it('BL2: should handle columns statement in sub-blocks', () => { imgSnapshotTest( - `block-beta + `block id1["Hello"] block columns 3 @@ -32,7 +32,7 @@ describe('Block diagram', () => { it('BL3: should align block widths and handle columns statement in sub-blocks', () => { imgSnapshotTest( - `block-beta + `block block columns 1 id1 @@ -48,7 +48,7 @@ describe('Block diagram', () => { it('BL4: should align block widths and handle columns statements in deeper sub-blocks then 1 level', () => { imgSnapshotTest( - `block-beta + `block columns 1 block columns 1 @@ -68,7 +68,7 @@ describe('Block diagram', () => { it('BL5: should align block widths and handle columns statements in deeper sub-blocks then 1 level (alt)', () => { imgSnapshotTest( - `block-beta + `block columns 1 block id1 @@ -87,7 +87,7 @@ describe('Block diagram', () => { it('BL6: should handle block arrows and spece statements', () => { imgSnapshotTest( - `block-beta + `block columns 3 space:3 ida idb idc @@ -106,7 +106,7 @@ describe('Block diagram', () => { it('BL7: should handle different types of edges', () => { imgSnapshotTest( - `block-beta + `block columns 3 A space:5 A --o B @@ -119,7 +119,7 @@ describe('Block diagram', () => { it('BL8: should handle sub-blocks without columns statements', () => { imgSnapshotTest( - `block-beta + `block columns 2 C A B block @@ -133,7 +133,7 @@ describe('Block diagram', () => { it('BL9: should handle edges from blocks in sub blocks to other blocks', () => { imgSnapshotTest( - `block-beta + `block columns 3 B space block @@ -147,7 +147,7 @@ describe('Block diagram', () => { it('BL10: should handle edges from composite blocks', () => { imgSnapshotTest( - `block-beta + `block columns 3 B space block BL @@ -161,7 +161,7 @@ describe('Block diagram', () => { it('BL11: should handle edges to composite blocks', () => { imgSnapshotTest( - `block-beta + `block columns 3 B space block BL @@ -175,7 +175,7 @@ describe('Block diagram', () => { it('BL12: edges should handle labels', () => { imgSnapshotTest( - `block-beta + `block A space A -- "apa" --> E @@ -186,7 +186,7 @@ describe('Block diagram', () => { it('BL13: should handle block arrows in different directions', () => { imgSnapshotTest( - `block-beta + `block columns 3 space blockArrowId1<["down"]>(down) space blockArrowId2<["right"]>(right) blockArrowId3<["Sync"]>(x, y) blockArrowId4<["left"]>(left) @@ -199,7 +199,7 @@ describe('Block diagram', () => { it('BL14: should style statements and class statements', () => { imgSnapshotTest( - `block-beta + `block A B classDef blue fill:#66f,stroke:#333,stroke-width:2px; @@ -212,7 +212,7 @@ describe('Block diagram', () => { it('BL15: width alignment - D and E should share available space', () => { imgSnapshotTest( - `block-beta + `block block D E @@ -225,7 +225,7 @@ describe('Block diagram', () => { it('BL16: width alignment - C should be as wide as the composite block', () => { imgSnapshotTest( - `block-beta + `block block A("This is the text") B @@ -238,7 +238,7 @@ describe('Block diagram', () => { it('BL17: width alignment - blocks should be equal in width', () => { imgSnapshotTest( - `block-beta + `block A("This is the text") B C @@ -249,7 +249,7 @@ describe('Block diagram', () => { it('BL18: block types 1 - square, rounded and circle', () => { imgSnapshotTest( - `block-beta + `block A["square"] B("rounded") C(("circle")) @@ -260,7 +260,7 @@ describe('Block diagram', () => { it('BL19: block types 2 - odd, diamond and hexagon', () => { imgSnapshotTest( - `block-beta + `block A>"rect_left_inv_arrow"] B{"diamond"} C{{"hexagon"}} @@ -271,7 +271,7 @@ describe('Block diagram', () => { it('BL20: block types 3 - stadium', () => { imgSnapshotTest( - `block-beta + `block A(["stadium"]) `, {} @@ -280,7 +280,7 @@ describe('Block diagram', () => { it('BL21: block types 4 - lean right, lean left, trapezoid and inv trapezoid', () => { imgSnapshotTest( - `block-beta + `block A[/"lean right"/] B[\"lean left"\] C[/"trapezoid"\] @@ -292,7 +292,7 @@ describe('Block diagram', () => { it('BL22: block types 1 - square, rounded and circle', () => { imgSnapshotTest( - `block-beta + `block A["square"] B("rounded") C(("circle")) @@ -303,7 +303,7 @@ describe('Block diagram', () => { it('BL23: sizing - it should be possible to make a block wider', () => { imgSnapshotTest( - `block-beta + `block A("rounded"):2 B:2 C @@ -314,7 +314,7 @@ describe('Block diagram', () => { it('BL24: sizing - it should be possible to make a composite block wider', () => { imgSnapshotTest( - `block-beta + `block block:2 A end @@ -326,7 +326,7 @@ describe('Block diagram', () => { it('BL25: block in the middle with space on each side', () => { imgSnapshotTest( - `block-beta + `block columns 3 space middle["In the middle"] @@ -337,7 +337,7 @@ describe('Block diagram', () => { }); it('BL26: space and an edge', () => { imgSnapshotTest( - `block-beta + `block columns 5 A space B A --x B @@ -347,7 +347,7 @@ describe('Block diagram', () => { }); it('BL27: block sizes for regular blocks', () => { imgSnapshotTest( - `block-beta + `block columns 3 a["A wide one"] b:2 c:2 d `, @@ -356,7 +356,7 @@ describe('Block diagram', () => { }); it('BL28: composite block with a set width - f should use the available space', () => { imgSnapshotTest( - `block-beta + `block columns 3 a:3 block:e:3 @@ -370,7 +370,7 @@ describe('Block diagram', () => { it('BL29: composite block with a set width - f and g should split the available space', () => { imgSnapshotTest( - `block-beta + `block columns 3 a:3 block:e:3 @@ -393,6 +393,17 @@ describe('Block diagram', () => { overflow:3 short:1 also_overflow:2 +`, + {} + ); + }); + + it('BL31: edge without arrow syntax should render with no arrowheads', () => { + imgSnapshotTest( + `block-beta + a + b + a --- b `, {} ); diff --git a/cypress/integration/rendering/classDiagram.spec.js b/cypress/integration/rendering/classDiagram.spec.js index f66a2d6f3..bd2a96b34 100644 --- a/cypress/integration/rendering/classDiagram.spec.js +++ b/cypress/integration/rendering/classDiagram.spec.js @@ -512,4 +512,17 @@ describe('Class diagram', () => { ); }); }); + + it('should handle backticks for namespace and class names', () => { + imgSnapshotTest( + ` + classDiagram + namespace \`A::B\` { + class \`IPC::Sender\` + } + RenderProcessHost --|> \`IPC::Sender\` + `, + {} + ); + }); }); 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 d67e7a28c..5ef32c269 100644 --- a/cypress/integration/rendering/flowchart-v2.spec.js +++ b/cypress/integration/rendering/flowchart-v2.spec.js @@ -1113,6 +1113,37 @@ end ); }); }); + describe('Flowchart Node Shape Rendering', () => { + it('should render a stadium-shaped node', () => { + imgSnapshotTest( + `flowchart TB + A(["Start"]) --> n1["Untitled Node"] + A --> n2["Untitled Node"] + `, + {} + ); + }); + it('should render a diamond-shaped node using shape config', () => { + imgSnapshotTest( + `flowchart BT + n2["Untitled Node"] --> n1["Diamond"] + n1@{ shape: diam} + `, + {} + ); + }); + it('should render a rounded rectangle and a normal rectangle', () => { + imgSnapshotTest( + `flowchart BT + n2["Untitled Node"] --> n1["Rounded Rectangle"] + n3["Untitled Node"] --> n1 + n1@{ shape: rounded} + n3@{ shape: rect} + `, + {} + ); + }); + }); it('6617: Per Link Curve Styling using edge Ids', () => { imgSnapshotTest( @@ -1134,6 +1165,28 @@ 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 }); + }); + }); + it('V2 - 17: should apply class def colour to edge label', () => { imgSnapshotTest( ` graph LR diff --git a/cypress/integration/rendering/gantt.spec.js b/cypress/integration/rendering/gantt.spec.js index 2cc67918c..32dbcb4d9 100644 --- a/cypress/integration/rendering/gantt.spec.js +++ b/cypress/integration/rendering/gantt.spec.js @@ -565,6 +565,18 @@ describe('Gantt diagram', () => { ); }); + it('should render only the day when using dateFormat D', () => { + imgSnapshotTest( + ` + gantt + title Test + dateFormat D + A :a, 1, 1d + `, + {} + ); + }); + // TODO: fix it // // This test is skipped deliberately @@ -647,6 +659,49 @@ describe('Gantt diagram', () => { ); }); + it('should render a gantt diagram excluding a specific date in YYYY-MM-DD HH:mm:ss format', () => { + imgSnapshotTest( + ` + gantt + dateFormat YYYY-MM-DD HH:mm:ss + excludes 2025-07-07 + section Section + A task :a1, 2025-07-04 20:30:30, 2025-07-08 10:30:30 + Another task:after a1, 20h + `, + {} + ); + }); + + it('should render a gantt diagram excluding saturday and sunday in YYYY-MM-DD HH:mm:ss format', () => { + imgSnapshotTest( + ` + gantt + dateFormat YYYY-MM-DD HH:mm:ss + excludes weekends + weekend saturday + section Section + A task :a1, 2025-07-04 20:30:30, 2025-07-08 10:30:30 + Another task:after a1, 20h + `, + {} + ); + }); + it('should render a gantt diagram excluding friday and saturday in YYYY-MM-DD HH:mm:ss format', () => { + imgSnapshotTest( + ` + gantt + dateFormat YYYY-MM-DD HH:mm:ss + excludes weekends + weekend friday + section Section + A task :a1, 2025-07-04 20:30:30, 2025-07-08 10:30:30 + Another task:after a1, 20h + `, + {} + ); + }); + it("should render when there's a semicolon in the title", () => { imgSnapshotTest( ` diff --git a/cypress/integration/rendering/pie.spec.ts b/cypress/integration/rendering/pie.spec.ts index 171a83057..8f6ef7de3 100644 --- a/cypress/integration/rendering/pie.spec.ts +++ b/cypress/integration/rendering/pie.spec.ts @@ -82,4 +82,13 @@ describe('pie chart', () => { ` ); }); + it('should render pie slices only for non-zero values but shows all legends', () => { + imgSnapshotTest( + ` pie title Pets adopted by volunteers + "Dogs" : 386 + "Cats" : 85 + "Rats" : 1 + ` + ); + }); }); diff --git a/cypress/integration/rendering/sankey.spec.ts b/cypress/integration/rendering/sankey.spec.ts index ad0d75f18..b9940d998 100644 --- a/cypress/integration/rendering/sankey.spec.ts +++ b/cypress/integration/rendering/sankey.spec.ts @@ -15,7 +15,7 @@ describe('Sankey Diagram', () => { describe('when given a linkColor', function () { this.beforeAll(() => { cy.wrap( - `sankey-beta + `sankey a,b,10 ` ).as('graph'); @@ -62,7 +62,7 @@ describe('Sankey Diagram', () => { this.beforeAll(() => { cy.wrap( ` - sankey-beta + sankey a,b,8 b,c,8 diff --git a/cypress/integration/rendering/stateDiagram-v2.spec.js b/cypress/integration/rendering/stateDiagram-v2.spec.js index 83190dbc7..e5a0cedd0 100644 --- a/cypress/integration/rendering/stateDiagram-v2.spec.js +++ b/cypress/integration/rendering/stateDiagram-v2.spec.js @@ -602,6 +602,231 @@ State1 --> [*] -- 55 } +`, + {} + ); + }); + it('should render edge labels correctly', () => { + imgSnapshotTest( + `--- +title: On The Way To Something Something DarkSide +config: + look: default + theme: default +--- + +stateDiagram-v2 + + state State1_____________ + { + c0 + } + + state State2_____________ + { + c1 + } + + state State3_____________ + { + c7 + } + + state State4_____________ + { + c2 + } + + state State5_____________ + { + c3 + } + + state State6_____________ + { + c4 + } + + state State7_____________ + { + c5 + } + + state State8_____________ + { + c6 + } + + +[*] --> State1_____________ +State1_____________ --> State2_____________ : Transition1_____ +State2_____________ --> State4_____________ : Transition2_____ +State2_____________ --> State3_____________ : Transition3_____ +State3_____________ --> State2_____________ +State4_____________ --> State2_____________ : Transition5_____ +State4_____________ --> State5_____________ : Transition6_____ +State5_____________ --> State6_____________ : Transition7_____ +State6_____________ --> State4_____________ : Transition8_____ +State2_____________ --> State7_____________ : Transition4_____ +State4_____________ --> State7_____________ : Transition4_____ +State5_____________ --> State7_____________ : Transition4_____ +State6_____________ --> State7_____________ : Transition4_____ +State7_____________ --> State1_____________ : Transition9_____ +State5_____________ --> State8_____________ : Transition10____ +State8_____________ --> State5_____________ : Transition11____ +`, + {} + ); + }); + it('should render edge labels correctly with multiple transitions', () => { + imgSnapshotTest( + `--- +title: Multiple Transitions +config: + look: default + theme: default +--- + +stateDiagram-v2 + + state State1_____________ + { + c0 + } + + state State2_____________ + { + c1 + } + + state State3_____________ + { + c7 + } + + state State4_____________ + { + c2 + } + + state State5_____________ + { + c3 + } + + state State6_____________ + { + c4 + } + + state State7_____________ + { + c5 + } + + state State8_____________ + { + c6 + } + + state State9_____________ + { + c9 + } + +[*] --> State1_____________ +State1_____________ --> State2_____________ : Transition1_____ +State2_____________ --> State4_____________ : Transition2_____ +State2_____________ --> State3_____________ : Transition3_____ +State3_____________ --> State2_____________ +State4_____________ --> State2_____________ : Transition5_____ +State4_____________ --> State5_____________ : Transition6_____ +State5_____________ --> State6_____________ : Transition7_____ +State6_____________ --> State4_____________ : Transition8_____ +State2_____________ --> State7_____________ : Transition4_____ +State4_____________ --> State7_____________ : Transition4_____ +State5_____________ --> State7_____________ : Transition4_____ +State6_____________ --> State7_____________ : Transition4_____ +State7_____________ --> State1_____________ : Transition9_____ +State5_____________ --> State8_____________ : Transition10____ +State8_____________ --> State5_____________ : Transition11____ +State9_____________ --> State8_____________ : Transition12____ +`, + {} + ); + }); + + it('should render edge labels correctly with multiple states', () => { + imgSnapshotTest( + `--- +title: Multiple States +config: + look: default + theme: default +--- + +stateDiagram-v2 + + state State1_____________ + { + c0 + } + + state State2_____________ + { + c1 + } + + state State3_____________ + { + c7 + } + + state State4_____________ + { + c2 + } + + state State5_____________ + { + c3 + } + + state State6_____________ + { + c4 + } + + state State7_____________ + { + c5 + } + + state State8_____________ + { + c6 + } + + state State9_____________ + { + c9 + } + + state State10_____________ + { + c10 + } + +[*] --> State1_____________ +State1_____________ --> State2_____________ : Transition1_____ +State2_____________ --> State3_____________ : Transition2_____ +State3_____________ --> State4_____________ : Transition3_____ +State4_____________ --> State5_____________ : Transition4_____ +State5_____________ --> State6_____________ : Transition5_____ +State6_____________ --> State7_____________ : Transition6_____ +State7_____________ --> State8_____________ : Transition7_____ +State8_____________ --> State9_____________ : Transition8_____ +State9_____________ --> State10_____________ : Transition9_____ `, {} ); diff --git a/cypress/integration/rendering/xyChart.spec.js b/cypress/integration/rendering/xyChart.spec.js index a582355e8..d54086fa7 100644 --- a/cypress/integration/rendering/xyChart.spec.js +++ b/cypress/integration/rendering/xyChart.spec.js @@ -1,7 +1,7 @@ import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts'; describe('XY Chart', () => { - it('should render the simplest possible chart', () => { + it('should render the simplest possible xy-beta chart', () => { imgSnapshotTest( ` xychart-beta @@ -10,10 +10,19 @@ describe('XY Chart', () => { {} ); }); + it('should render the simplest possible xy chart', () => { + imgSnapshotTest( + ` + xychart + line [10, 30, 20] + `, + {} + ); + }); it('Should render a complete chart', () => { imgSnapshotTest( ` - xychart-beta + xychart title "Sales Revenue" x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] y-axis "Revenue (in $)" 4000 --> 11000 @@ -26,7 +35,7 @@ describe('XY Chart', () => { it('Should render a chart without title', () => { imgSnapshotTest( ` - xychart-beta + xychart x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] y-axis "Revenue (in $)" 4000 --> 11000 bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000] @@ -38,7 +47,7 @@ describe('XY Chart', () => { it('y-axis title not required', () => { imgSnapshotTest( ` - xychart-beta + xychart x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] y-axis 4000 --> 11000 bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000] @@ -50,7 +59,7 @@ describe('XY Chart', () => { it('Should render a chart without y-axis with different range', () => { imgSnapshotTest( ` - xychart-beta + xychart x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] bar [5000, 6000, 7500, 8200, 9500, 10500, 14000, 3200, 9200, 9900, 3400, 6000] line [2000, 7000, 6500, 9200, 9500, 7500, 11000, 10200, 3200, 8500, 7000, 8800] @@ -61,7 +70,7 @@ describe('XY Chart', () => { it('x axis title not required', () => { imgSnapshotTest( ` - xychart-beta + xychart x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] bar [5000, 6000, 7500, 8200, 9500, 10500, 14000, 3200, 9200, 9900, 3400, 6000] line [2000, 7000, 6500, 9200, 9500, 7500, 11000, 10200, 3200, 8500, 7000, 8800] @@ -72,7 +81,7 @@ describe('XY Chart', () => { it('Multiple plots can be rendered', () => { imgSnapshotTest( ` - xychart-beta + xychart line [23, 46, 77, 34] line [45, 32, 33, 12] bar [87, 54, 99, 85] @@ -86,7 +95,7 @@ describe('XY Chart', () => { it('Decimals and negative numbers are supported', () => { imgSnapshotTest( ` - xychart-beta + xychart y-axis -2.4 --> 3.5 line [+1.3, .6, 2.4, -.34] `, @@ -104,7 +113,7 @@ describe('XY Chart', () => { height: 20 plotReservedSpacePercent: 100 --- - xychart-beta + xychart line [5000, 9000, 7500, 6200, 9500, 5500, 11000, 8200, 9200, 9500, 7000, 8800] `, {} @@ -130,7 +139,7 @@ describe('XY Chart', () => { showTick: false showAxisLine: false --- - xychart-beta + xychart bar [5000, 9000, 7500, 6200, 9500, 5500, 11000, 8200, 9200, 9500, 7000, 8800] `, {} @@ -140,7 +149,7 @@ describe('XY Chart', () => { imgSnapshotTest( ` %%{init: {"xyChart": {"width": 1000, "height": 600, "titlePadding": 5, "titleFontSize": 10, "xAxis": {"labelFontSize": "20", "labelPadding": 10, "titleFontSize": 30, "titlePadding": 20, "tickLength": 10, "tickWidth": 5}, "yAxis": {"labelFontSize": "20", "labelPadding": 10, "titleFontSize": 30, "titlePadding": 20, "tickLength": 10, "tickWidth": 5}, "plotBorderWidth": 5, "chartOrientation": "horizontal", "plotReservedSpacePercent": 60 }}}%% - xychart-beta + xychart title "Sales Revenue" x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] y-axis "Revenue (in $)" 4000 --> 11000 @@ -181,7 +190,7 @@ describe('XY Chart', () => { plotReservedSpacePercent: 60 showDataLabel: true --- - xychart-beta + xychart title "Sales Revenue" x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] y-axis "Revenue (in $)" 4000 --> 11000 @@ -202,7 +211,7 @@ describe('XY Chart', () => { yAxis: showTitle: false --- - xychart-beta + xychart title "Sales Revenue" x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] y-axis "Revenue (in $)" 4000 --> 11000 @@ -223,7 +232,7 @@ describe('XY Chart', () => { yAxis: showLabel: false --- - xychart-beta + xychart title "Sales Revenue" x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] y-axis "Revenue (in $)" 4000 --> 11000 @@ -244,7 +253,7 @@ describe('XY Chart', () => { yAxis: showTick: false --- - xychart-beta + xychart title "Sales Revenue" x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] y-axis "Revenue (in $)" 4000 --> 11000 @@ -265,7 +274,7 @@ describe('XY Chart', () => { yAxis: showAxisLine: false --- - xychart-beta + xychart title "Sales Revenue" x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] y-axis "Revenue (in $)" 4000 --> 11000 @@ -294,7 +303,7 @@ describe('XY Chart', () => { xAxisLineColor: "#87ceeb" plotColorPalette: "#008000, #faba63" --- - xychart-beta + xychart title "Sales Revenue" x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] y-axis "Revenue (in $)" 4000 --> 11000 @@ -307,7 +316,7 @@ describe('XY Chart', () => { it('should use the correct distances between data points', () => { imgSnapshotTest( ` - xychart-beta + xychart x-axis 0 --> 2 line [0, 1, 0, 1] bar [1, 0, 1, 0] @@ -325,7 +334,7 @@ describe('XY Chart', () => { xyChart: showDataLabel: true --- - xychart-beta + xychart title "Sales Revenue" x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] y-axis "Revenue (in $)" 4000 --> 11000 @@ -344,7 +353,7 @@ describe('XY Chart', () => { showDataLabel: true chartOrientation: horizontal --- - xychart-beta + xychart title "Sales Revenue" x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] y-axis "Revenue (in $)" 4000 --> 11000 @@ -357,7 +366,7 @@ describe('XY Chart', () => { it('should render vertical bar chart without labels by default', () => { imgSnapshotTest( ` - xychart-beta + xychart title "Sales Revenue" x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] y-axis "Revenue (in $)" 4000 --> 11000 @@ -375,7 +384,7 @@ describe('XY Chart', () => { xyChart: chartOrientation: horizontal --- - xychart-beta + xychart title "Sales Revenue" x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] y-axis "Revenue (in $)" 4000 --> 11000 @@ -393,7 +402,7 @@ describe('XY Chart', () => { xyChart: showDataLabel: true --- - xychart-beta + xychart title "Multiple Bar Plots" x-axis Categories [A, B, C] y-axis "Values" 0 --> 100 @@ -412,7 +421,7 @@ describe('XY Chart', () => { showDataLabel: true chartOrientation: horizontal --- - xychart-beta + xychart title "Multiple Bar Plots" x-axis Categories [A, B, C] y-axis "Values" 0 --> 100 @@ -430,7 +439,7 @@ describe('XY Chart', () => { xyChart: showDataLabel: true --- - xychart-beta + xychart title "Single Bar Chart" x-axis Categories [A] y-axis "Value" 0 --> 100 @@ -449,7 +458,7 @@ describe('XY Chart', () => { showDataLabel: true chartOrientation: horizontal --- - xychart-beta + xychart title "Single Bar Chart" x-axis Categories [A] y-axis "Value" 0 --> 100 @@ -467,7 +476,7 @@ describe('XY Chart', () => { xyChart: showDataLabel: true --- - xychart-beta + xychart title "Decimal and Negative Values" x-axis Categories [A, B, C] y-axis -10 --> 10 @@ -486,7 +495,7 @@ describe('XY Chart', () => { showDataLabel: true chartOrientation: horizontal --- - xychart-beta + xychart title "Decimal and Negative Values" x-axis Categories [A, B, C] y-axis -10 --> 10 @@ -504,7 +513,7 @@ describe('XY Chart', () => { xyChart: showDataLabel: true --- - xychart-beta + xychart title "Sales Revenue" x-axis Months [jan,b,c] y-axis "Revenue (in $)" 4000 --> 12000 @@ -561,7 +570,7 @@ describe('XY Chart', () => { showDataLabel: true chartOrientation: horizontal --- - xychart-beta + xychart title "Sales Revenue" x-axis Months [jan,b,c] y-axis "Revenue (in $)" 4000 --> 12000 @@ -615,7 +624,7 @@ describe('XY Chart', () => { xyChart: showDataLabel: true --- - xychart-beta + xychart title "Sales Revenue" x-axis Months [jan,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s] y-axis "Revenue (in $)" 4000 --> 12000 @@ -672,7 +681,7 @@ describe('XY Chart', () => { showDataLabel: true chartOrientation: horizontal --- - xychart-beta + xychart title "Sales Revenue" x-axis Months [jan,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s] y-axis "Revenue (in $)" 4000 --> 12000 @@ -726,7 +735,7 @@ describe('XY Chart', () => { xyChart: showDataLabel: true --- - xychart-beta + xychart title "Sales Revenue" x-axis Months [jan] y-axis "Revenue (in $)" 3000 --> 12000 @@ -783,7 +792,7 @@ describe('XY Chart', () => { showDataLabel: true chartOrientation: horizontal --- - xychart-beta + xychart title "Sales Revenue" x-axis Months [jan] y-axis "Revenue (in $)" 3000 --> 12000 diff --git a/cypress/platform/darshan.html b/cypress/platform/darshan.html new file mode 100644 index 000000000..df5994d7d --- /dev/null +++ b/cypress/platform/darshan.html @@ -0,0 +1,35 @@ + + + + + + Mermaid Quick Test Page + + + + + +

Pie chart demos

+
+     pie title Default text position: Animal adoption
+        accTitle: simple pie char demo
+        accDescr: pie chart with 3 sections: dogs, cats, rats. Most are dogs.
+         "dogs" : -60.67
+        "rats" : 40.12
+    
+ +
+ + + diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html index ab7ded0c2..eb5528844 100644 --- a/cypress/platform/knsv2.html +++ b/cypress/platform/knsv2.html @@ -131,6 +131,22 @@
+---
+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"
     "Leaf 1.1": 12
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));
     
   
 
diff --git a/cypress/platform/viewer.js b/cypress/platform/viewer.js
index e120469fe..7ff95e163 100644
--- a/cypress/platform/viewer.js
+++ b/cypress/platform/viewer.js
@@ -182,7 +182,7 @@ const contentLoadedApi = async function () {
       for (let i = 0; i < numCodes; i++) {
         const { svg, bindFunctions } = await mermaid.render('newid' + i, graphObj.code[i], divs[i]);
         div.innerHTML = svg;
-        bindFunctions(div);
+        bindFunctions?.(div);
       }
     } else {
       const div = document.createElement('div');
@@ -194,7 +194,7 @@ const contentLoadedApi = async function () {
       const { svg, bindFunctions } = await mermaid.render('newid', graphObj.code, div);
       div.innerHTML = svg;
       console.log(div.innerHTML);
-      bindFunctions(div);
+      bindFunctions?.(div);
     }
   }
 };
diff --git a/cypress/timings.json b/cypress/timings.json
index 05263ad9f..86d5b5222 100644
--- a/cypress/timings.json
+++ b/cypress/timings.json
@@ -2,219 +2,219 @@
   "durations": [
     {
       "spec": "cypress/integration/other/configuration.spec.js",
-      "duration": 5672
+      "duration": 6297
     },
     {
       "spec": "cypress/integration/other/external-diagrams.spec.js",
-      "duration": 1990
+      "duration": 2187
     },
     {
       "spec": "cypress/integration/other/ghsa.spec.js",
-      "duration": 3186
+      "duration": 3509
     },
     {
       "spec": "cypress/integration/other/iife.spec.js",
-      "duration": 1948
+      "duration": 2218
     },
     {
       "spec": "cypress/integration/other/interaction.spec.js",
-      "duration": 11938
+      "duration": 12104
     },
     {
       "spec": "cypress/integration/other/rerender.spec.js",
-      "duration": 1932
+      "duration": 2151
     },
     {
       "spec": "cypress/integration/other/xss.spec.js",
-      "duration": 27237
+      "duration": 33064
     },
     {
       "spec": "cypress/integration/rendering/appli.spec.js",
-      "duration": 3170
+      "duration": 3488
     },
     {
       "spec": "cypress/integration/rendering/architecture.spec.ts",
-      "duration": 104
+      "duration": 106
     },
     {
       "spec": "cypress/integration/rendering/block.spec.js",
-      "duration": 17390
+      "duration": 18317
     },
     {
       "spec": "cypress/integration/rendering/c4.spec.js",
-      "duration": 5296
+      "duration": 5592
     },
     {
       "spec": "cypress/integration/rendering/classDiagram-elk-v3.spec.js",
-      "duration": 39004
+      "duration": 39358
     },
     {
       "spec": "cypress/integration/rendering/classDiagram-handDrawn-v3.spec.js",
-      "duration": 37653
+      "duration": 37160
     },
     {
       "spec": "cypress/integration/rendering/classDiagram-v2.spec.js",
-      "duration": 23278
+      "duration": 23660
     },
     {
       "spec": "cypress/integration/rendering/classDiagram-v3.spec.js",
-      "duration": 36645
+      "duration": 36866
     },
     {
       "spec": "cypress/integration/rendering/classDiagram.spec.js",
-      "duration": 15418
+      "duration": 17334
     },
     {
       "spec": "cypress/integration/rendering/conf-and-directives.spec.js",
-      "duration": 9684
+      "duration": 9871
     },
     {
       "spec": "cypress/integration/rendering/current.spec.js",
-      "duration": 2570
+      "duration": 2833
     },
     {
       "spec": "cypress/integration/rendering/erDiagram-unified.spec.js",
-      "duration": 84687
+      "duration": 85321
     },
     {
       "spec": "cypress/integration/rendering/erDiagram.spec.js",
-      "duration": 14819
+      "duration": 15673
     },
     {
       "spec": "cypress/integration/rendering/errorDiagram.spec.js",
-      "duration": 3371
+      "duration": 3724
     },
     {
       "spec": "cypress/integration/rendering/flowchart-elk.spec.js",
-      "duration": 39925
+      "duration": 41178
     },
     {
       "spec": "cypress/integration/rendering/flowchart-handDrawn.spec.js",
-      "duration": 34694
+      "duration": 29966
     },
     {
       "spec": "cypress/integration/rendering/flowchart-icon.spec.js",
-      "duration": 7137
+      "duration": 7689
     },
     {
       "spec": "cypress/integration/rendering/flowchart-shape-alias.spec.ts",
-      "duration": 24740
+      "duration": 24709
     },
     {
       "spec": "cypress/integration/rendering/flowchart-v2.spec.js",
-      "duration": 42077
+      "duration": 45565
     },
     {
       "spec": "cypress/integration/rendering/flowchart.spec.js",
-      "duration": 30642
+      "duration": 31144
     },
     {
       "spec": "cypress/integration/rendering/gantt.spec.js",
-      "duration": 18085
+      "duration": 20808
     },
     {
       "spec": "cypress/integration/rendering/gitGraph.spec.js",
-      "duration": 50107
+      "duration": 49985
     },
     {
       "spec": "cypress/integration/rendering/iconShape.spec.ts",
-      "duration": 276279
+      "duration": 273272
     },
     {
       "spec": "cypress/integration/rendering/imageShape.spec.ts",
-      "duration": 56505
+      "duration": 55880
     },
     {
       "spec": "cypress/integration/rendering/info.spec.ts",
-      "duration": 3036
+      "duration": 3271
     },
     {
       "spec": "cypress/integration/rendering/journey.spec.js",
-      "duration": 6889
+      "duration": 7293
     },
     {
       "spec": "cypress/integration/rendering/kanban.spec.ts",
-      "duration": 7353
+      "duration": 7861
     },
     {
       "spec": "cypress/integration/rendering/katex.spec.js",
-      "duration": 3580
+      "duration": 3922
     },
     {
       "spec": "cypress/integration/rendering/marker_unique_id.spec.js",
-      "duration": 2508
+      "duration": 2726
     },
     {
       "spec": "cypress/integration/rendering/mindmap.spec.ts",
-      "duration": 10939
+      "duration": 11670
     },
     {
       "spec": "cypress/integration/rendering/newShapes.spec.ts",
-      "duration": 149102
+      "duration": 146020
     },
     {
       "spec": "cypress/integration/rendering/oldShapes.spec.ts",
-      "duration": 113987
+      "duration": 114244
     },
     {
       "spec": "cypress/integration/rendering/packet.spec.ts",
-      "duration": 4060
+      "duration": 5036
     },
     {
       "spec": "cypress/integration/rendering/pie.spec.ts",
-      "duration": 5715
+      "duration": 6545
     },
     {
       "spec": "cypress/integration/rendering/quadrantChart.spec.js",
-      "duration": 8945
+      "duration": 9097
     },
     {
       "spec": "cypress/integration/rendering/radar.spec.js",
-      "duration": 5337
+      "duration": 5676
     },
     {
       "spec": "cypress/integration/rendering/requirement.spec.js",
-      "duration": 2643
+      "duration": 2795
     },
     {
       "spec": "cypress/integration/rendering/requirementDiagram-unified.spec.js",
-      "duration": 52072
+      "duration": 51660
     },
     {
       "spec": "cypress/integration/rendering/sankey.spec.ts",
-      "duration": 6692
+      "duration": 6957
     },
     {
       "spec": "cypress/integration/rendering/sequencediagram.spec.js",
-      "duration": 35721
+      "duration": 36026
     },
     {
       "spec": "cypress/integration/rendering/stateDiagram-v2.spec.js",
-      "duration": 26030
+      "duration": 29551
     },
     {
       "spec": "cypress/integration/rendering/stateDiagram.spec.js",
-      "duration": 16333
+      "duration": 17364
     },
     {
       "spec": "cypress/integration/rendering/theme.spec.js",
-      "duration": 29287
+      "duration": 30209
     },
     {
       "spec": "cypress/integration/rendering/timeline.spec.ts",
-      "duration": 8491
+      "duration": 8699
     },
     {
       "spec": "cypress/integration/rendering/treemap.spec.ts",
-      "duration": 12291
+      "duration": 12168
     },
     {
       "spec": "cypress/integration/rendering/xyChart.spec.js",
-      "duration": 20651
+      "duration": 21453
     },
     {
       "spec": "cypress/integration/rendering/zenuml.spec.js",
-      "duration": 3218
+      "duration": 3577
     }
   ]
 }
diff --git a/demos/block.html b/demos/block.html
index f0957b670..5296126e0 100644
--- a/demos/block.html
+++ b/demos/block.html
@@ -10,7 +10,7 @@
   
     

Block diagram demos

-block-beta
+block
 columns 1
   db(("DB"))
   blockArrowId6<["   "]>(down)
@@ -26,7 +26,7 @@ columns 1
   style B fill:#f9F,stroke:#333,stroke-width:4px
     
-block-beta
+block
     A1["square"]
     B1("rounded")
     C1(("circle"))
@@ -36,7 +36,7 @@ block-beta
     
-block-beta
+block
     A1(["stadium"])
     A2[["subroutine"]]
     B1[("cylinder")]
@@ -48,7 +48,7 @@ block-beta
     
-block-beta
+block
   block:e:4
     columns 2
       f
@@ -57,7 +57,7 @@ block-beta
 
     
-block-beta
+block
   block:e:4
     columns 2
       f
@@ -67,7 +67,7 @@ block-beta
 
     
-block-beta
+block
   columns 3
   a:3
   block:e:3
@@ -80,7 +80,7 @@ block-beta
 
     
-block-beta
+block
   columns 4
   a b c d
   block:e:4
@@ -97,19 +97,19 @@ flowchart LR
   X-- "a label" -->z
     
-block-beta
+block
 columns 5
    A space B
    A --x B
     
-block-beta
+block
 columns 3
   a["A wide one"] b:2 c:2 d
     
-block-beta
+block
 columns 3
   a b c
   e:3
@@ -117,7 +117,7 @@ columns 3
     
-block-beta
+block
 
   A1:3
   A2:1
diff --git a/demos/sankey.html b/demos/sankey.html
index 2439cb589..92e0f587d 100644
--- a/demos/sankey.html
+++ b/demos/sankey.html
@@ -20,12 +20,14 @@
           width: 800
           nodeAlignment: left
       ---
-      sankey-beta
-        Revenue,Expenses,10
-        Revenue,Profit,10
-        Expenses,Manufacturing,5
-        Expenses,Tax,3
-        Expenses,Research,2
+     sankey
+        a,b,8
+        b,c,8
+        c,d,8
+        d,e,8
+
+        x,c,4
+        c,y,4
     

Energy flow

@@ -40,7 +42,7 @@ linkColor: gradient nodeAlignment: justify --- - sankey-beta + sankey Agricultural 'waste',Bio-conversion,124.729 Bio-conversion,Liquid,0.597 diff --git a/demos/xychart.html b/demos/xychart.html index 25f8ec8ca..5706b15ea 100644 --- a/demos/xychart.html +++ b/demos/xychart.html @@ -16,7 +16,7 @@

XY Charts demos

-    xychart-beta
+    xychart
     title "Sales Revenue (in $)"
     x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
     y-axis "Revenue (in $)" 4000 --> 11000
@@ -26,7 +26,7 @@
     

XY Charts horizontal

-    xychart-beta horizontal
+    xychart horizontal
     title "Basic xychart"
     x-axis "this is x axis" [category1, "category 2", category3, category4]
     y-axis yaxisText 10 --> 150
@@ -36,7 +36,7 @@
     

XY Charts only lines and bar

-    xychart-beta
+    xychart
     line [23, 46, 77, 34]
     line [45, 32, 33, 12]
     line [87, 54, 99, 85]
@@ -48,13 +48,13 @@
     

XY Charts with +ve and -ve numbers

-    xychart-beta
+    xychart
     line [+1.3, .6, 2.4, -.34]
     

XY Charts Bar with multiple category

-    xychart-beta
+    xychart
     title "Basic xychart with many categories"
     x-axis "this is x axis" [category1, "category 2", category3, category4, category5, category6, category7]
     y-axis yaxisText 10 --> 150
@@ -63,7 +63,7 @@
 
     

XY Charts line with multiple category

-    xychart-beta
+    xychart
     title "Line chart with many category"
     x-axis "this is x axis" [category1, "category 2", category3, category4, category5, category6, category7]
     y-axis yaxisText 10 --> 150
@@ -72,7 +72,7 @@
 
     

XY Charts category with large text

-    xychart-beta
+    xychart
     title "Basic xychart with many categories with category overlap"
     x-axis "this is x axis" [category1, "Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint cillum sint consectetur cupidatat.", category3, category4, category5, category6, category7]
     y-axis yaxisText 10 --> 150
@@ -89,7 +89,7 @@ config:
     height: 20
     plotReservedSpacePercent: 100
 ---
-    xychart-beta
+    xychart
       line [5000, 9000, 7500, 6200, 9500, 5500, 11000, 8200, 9200, 9500, 7000, 8800]
     
@@ -103,7 +103,7 @@ config: height: 20 plotReservedSpacePercent: 100 --- - xychart-beta + xychart bar [5000, 9000, 7500, 6200, 9500, 5500, 11000, 8200, 9200, 9500, 7000, 8800]
@@ -136,7 +136,7 @@ config: chartOrientation: horizontal plotReservedSpacePercent: 60 --- - xychart-beta + xychart title "Sales Revenue" x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] y-axis "Revenue (in $)" 4000 --> 11000 @@ -162,7 +162,7 @@ config: xAxisLineColor: "#87ceeb" plotColorPalette: "#008000, #faba63" --- - xychart-beta + xychart title "Sales Revenue" x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] y-axis "Revenue (in $)" 4000 --> 11000 diff --git a/docs/config/setup/defaultConfig/variables/configKeys.md b/docs/config/setup/defaultConfig/variables/configKeys.md index 222111bd5..82b68d780 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:290](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L290) +Defined in: [packages/mermaid/src/defaultConfig.ts:292](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L292) diff --git a/docs/config/setup/mermaid/interfaces/MermaidConfig.md b/docs/config/setup/mermaid/interfaces/MermaidConfig.md index d08533713..f4c5b0b2b 100644 --- a/docs/config/setup/mermaid/interfaces/MermaidConfig.md +++ b/docs/config/setup/mermaid/interfaces/MermaidConfig.md @@ -18,7 +18,7 @@ Defined in: [packages/mermaid/src/config.type.ts:58](https://github.com/mermaid- > `optional` **altFontFamily**: `string` -Defined in: [packages/mermaid/src/config.type.ts:122](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L122) +Defined in: [packages/mermaid/src/config.type.ts:132](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L132) --- @@ -26,7 +26,7 @@ Defined in: [packages/mermaid/src/config.type.ts:122](https://github.com/mermaid > `optional` **architecture**: `ArchitectureDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:194](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L194) +Defined in: [packages/mermaid/src/config.type.ts:204](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L204) --- @@ -34,7 +34,7 @@ Defined in: [packages/mermaid/src/config.type.ts:194](https://github.com/mermaid > `optional` **arrowMarkerAbsolute**: `boolean` -Defined in: [packages/mermaid/src/config.type.ts:141](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L141) +Defined in: [packages/mermaid/src/config.type.ts:151](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L151) Controls whether or arrow markers in html code are absolute paths or anchors. This matters if you are using base tag settings. @@ -45,7 +45,7 @@ This matters if you are using base tag settings. > `optional` **block**: `BlockDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:201](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L201) +Defined in: [packages/mermaid/src/config.type.ts:211](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L211) --- @@ -53,7 +53,7 @@ Defined in: [packages/mermaid/src/config.type.ts:201](https://github.com/mermaid > `optional` **c4**: `C4DiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:198](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L198) +Defined in: [packages/mermaid/src/config.type.ts:208](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L208) --- @@ -61,7 +61,7 @@ Defined in: [packages/mermaid/src/config.type.ts:198](https://github.com/mermaid > `optional` **class**: `ClassDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:187](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L187) +Defined in: [packages/mermaid/src/config.type.ts:197](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L197) --- @@ -69,7 +69,7 @@ Defined in: [packages/mermaid/src/config.type.ts:187](https://github.com/mermaid > `optional` **darkMode**: `boolean` -Defined in: [packages/mermaid/src/config.type.ts:113](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L113) +Defined in: [packages/mermaid/src/config.type.ts:123](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L123) --- @@ -77,7 +77,7 @@ Defined in: [packages/mermaid/src/config.type.ts:113](https://github.com/mermaid > `optional` **deterministicIds**: `boolean` -Defined in: [packages/mermaid/src/config.type.ts:174](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L174) +Defined in: [packages/mermaid/src/config.type.ts:184](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L184) This option controls if the generated ids of nodes in the SVG are generated randomly or based on a seed. @@ -93,7 +93,7 @@ should not change unless content is changed. > `optional` **deterministicIDSeed**: `string` -Defined in: [packages/mermaid/src/config.type.ts:181](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L181) +Defined in: [packages/mermaid/src/config.type.ts:191](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L191) This option is the optional seed for deterministic ids. If set to `undefined` but deterministicIds is `true`, a simple number iterator is used. @@ -105,7 +105,7 @@ You can set this attribute to base the seed on a static string. > `optional` **dompurifyConfig**: `Config` -Defined in: [packages/mermaid/src/config.type.ts:203](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L203) +Defined in: [packages/mermaid/src/config.type.ts:213](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L213) --- @@ -115,12 +115,24 @@ Defined in: [packages/mermaid/src/config.type.ts:203](https://github.com/mermaid Defined in: [packages/mermaid/src/config.type.ts:91](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L91) +#### considerModelOrder? + +> `optional` **considerModelOrder**: `"NONE"` | `"NODES_AND_EDGES"` | `"PREFER_EDGES"` | `"PREFER_NODES"` + +Preserves the order of nodes and edges in the model file if this does not lead to additional edge crossings. Depending on the strategy this is not always possible since the node and edge order might be conflicting. + #### cycleBreakingStrategy? > `optional` **cycleBreakingStrategy**: `"GREEDY"` | `"DEPTH_FIRST"` | `"INTERACTIVE"` | `"MODEL_ORDER"` | `"GREEDY_MODEL_ORDER"` This strategy decides how to find cycles in the graph and deciding which edges need adjustment to break loops. +#### forceNodeModelOrder? + +> `optional` **forceNodeModelOrder**: `boolean` + +The node order given by the model does not change to produce a better layout. E.g. if node A is before node B in the model this is not changed during crossing minimization. This assumes that the node model order is already respected before crossing minimization. This can be achieved by setting considerModelOrder.strategy to NODES_AND_EDGES. + #### mergeEdges? > `optional` **mergeEdges**: `boolean` @@ -139,7 +151,7 @@ Elk specific option affecting how nodes are placed. > `optional` **er**: `ErDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:189](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L189) +Defined in: [packages/mermaid/src/config.type.ts:199](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L199) --- @@ -147,7 +159,7 @@ Defined in: [packages/mermaid/src/config.type.ts:189](https://github.com/mermaid > `optional` **flowchart**: `FlowchartDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:182](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L182) +Defined in: [packages/mermaid/src/config.type.ts:192](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L192) --- @@ -155,7 +167,7 @@ Defined in: [packages/mermaid/src/config.type.ts:182](https://github.com/mermaid > `optional` **fontFamily**: `string` -Defined in: [packages/mermaid/src/config.type.ts:121](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L121) +Defined in: [packages/mermaid/src/config.type.ts:131](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L131) Specifies the font to be used in the rendered diagrams. Can be any possible CSS `font-family`. @@ -167,7 +179,7 @@ See > `optional` **fontSize**: `number` -Defined in: [packages/mermaid/src/config.type.ts:205](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L205) +Defined in: [packages/mermaid/src/config.type.ts:215](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L215) --- @@ -175,7 +187,7 @@ Defined in: [packages/mermaid/src/config.type.ts:205](https://github.com/mermaid > `optional` **forceLegacyMathML**: `boolean` -Defined in: [packages/mermaid/src/config.type.ts:163](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L163) +Defined in: [packages/mermaid/src/config.type.ts:173](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L173) This option forces Mermaid to rely on KaTeX's own stylesheet for rendering MathML. Due to differences between OS fonts and browser's MathML implementation, this option is recommended if consistent rendering is important. @@ -187,7 +199,7 @@ If set to true, ignores legacyMathML. > `optional` **gantt**: `GanttDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:184](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L184) +Defined in: [packages/mermaid/src/config.type.ts:194](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L194) --- @@ -195,7 +207,7 @@ Defined in: [packages/mermaid/src/config.type.ts:184](https://github.com/mermaid > `optional` **gitGraph**: `GitGraphDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:197](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L197) +Defined in: [packages/mermaid/src/config.type.ts:207](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L207) --- @@ -213,7 +225,7 @@ Defines the seed to be used when using handDrawn look. This is important for the > `optional` **htmlLabels**: `boolean` -Defined in: [packages/mermaid/src/config.type.ts:114](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L114) +Defined in: [packages/mermaid/src/config.type.ts:124](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L124) --- @@ -221,7 +233,7 @@ Defined in: [packages/mermaid/src/config.type.ts:114](https://github.com/mermaid > `optional` **journey**: `JourneyDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:185](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L185) +Defined in: [packages/mermaid/src/config.type.ts:195](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L195) --- @@ -229,7 +241,7 @@ Defined in: [packages/mermaid/src/config.type.ts:185](https://github.com/mermaid > `optional` **kanban**: `KanbanDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:196](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L196) +Defined in: [packages/mermaid/src/config.type.ts:206](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L206) --- @@ -247,7 +259,7 @@ Defines which layout algorithm to use for rendering the diagram. > `optional` **legacyMathML**: `boolean` -Defined in: [packages/mermaid/src/config.type.ts:156](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L156) +Defined in: [packages/mermaid/src/config.type.ts:166](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L166) This option specifies if Mermaid can expect the dependent to include KaTeX stylesheets for browsers without their own MathML implementation. If this option is disabled and MathML is not supported, the math @@ -260,7 +272,7 @@ fall back to legacy rendering for KaTeX. > `optional` **logLevel**: `0` | `2` | `1` | `"trace"` | `"debug"` | `"info"` | `"warn"` | `"error"` | `"fatal"` | `3` | `4` | `5` -Defined in: [packages/mermaid/src/config.type.ts:127](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L127) +Defined in: [packages/mermaid/src/config.type.ts:137](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L137) This option decides the amount of logging to be used by mermaid. @@ -280,7 +292,7 @@ Defines which main look to use for the diagram. > `optional` **markdownAutoWrap**: `boolean` -Defined in: [packages/mermaid/src/config.type.ts:206](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L206) +Defined in: [packages/mermaid/src/config.type.ts:216](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L216) --- @@ -308,7 +320,7 @@ The maximum allowed size of the users text diagram > `optional` **mindmap**: `MindmapDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:195](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L195) +Defined in: [packages/mermaid/src/config.type.ts:205](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L205) --- @@ -316,7 +328,7 @@ Defined in: [packages/mermaid/src/config.type.ts:195](https://github.com/mermaid > `optional` **packet**: `PacketDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:200](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L200) +Defined in: [packages/mermaid/src/config.type.ts:210](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L210) --- @@ -324,7 +336,7 @@ Defined in: [packages/mermaid/src/config.type.ts:200](https://github.com/mermaid > `optional` **pie**: `PieDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:190](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L190) +Defined in: [packages/mermaid/src/config.type.ts:200](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L200) --- @@ -332,7 +344,7 @@ Defined in: [packages/mermaid/src/config.type.ts:190](https://github.com/mermaid > `optional` **quadrantChart**: `QuadrantChartConfig` -Defined in: [packages/mermaid/src/config.type.ts:191](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L191) +Defined in: [packages/mermaid/src/config.type.ts:201](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L201) --- @@ -340,7 +352,7 @@ Defined in: [packages/mermaid/src/config.type.ts:191](https://github.com/mermaid > `optional` **radar**: `RadarDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:202](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L202) +Defined in: [packages/mermaid/src/config.type.ts:212](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L212) --- @@ -348,7 +360,7 @@ Defined in: [packages/mermaid/src/config.type.ts:202](https://github.com/mermaid > `optional` **requirement**: `RequirementDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:193](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L193) +Defined in: [packages/mermaid/src/config.type.ts:203](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L203) --- @@ -356,7 +368,7 @@ Defined in: [packages/mermaid/src/config.type.ts:193](https://github.com/mermaid > `optional` **sankey**: `SankeyDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:199](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L199) +Defined in: [packages/mermaid/src/config.type.ts:209](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L209) --- @@ -364,7 +376,7 @@ Defined in: [packages/mermaid/src/config.type.ts:199](https://github.com/mermaid > `optional` **secure**: `string`\[] -Defined in: [packages/mermaid/src/config.type.ts:148](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L148) +Defined in: [packages/mermaid/src/config.type.ts:158](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L158) This option controls which `currentConfig` keys are considered secure and can only be changed via call to `mermaid.initialize`. @@ -376,7 +388,7 @@ This prevents malicious graph directives from overriding a site's default securi > `optional` **securityLevel**: `"strict"` | `"loose"` | `"antiscript"` | `"sandbox"` -Defined in: [packages/mermaid/src/config.type.ts:131](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L131) +Defined in: [packages/mermaid/src/config.type.ts:141](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L141) Level of trust for parsed diagram @@ -386,7 +398,7 @@ Level of trust for parsed diagram > `optional` **sequence**: `SequenceDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:183](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L183) +Defined in: [packages/mermaid/src/config.type.ts:193](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L193) --- @@ -394,7 +406,7 @@ Defined in: [packages/mermaid/src/config.type.ts:183](https://github.com/mermaid > `optional` **startOnLoad**: `boolean` -Defined in: [packages/mermaid/src/config.type.ts:135](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L135) +Defined in: [packages/mermaid/src/config.type.ts:145](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L145) Dictates whether mermaid starts on Page load @@ -404,7 +416,7 @@ Dictates whether mermaid starts on Page load > `optional` **state**: `StateDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:188](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L188) +Defined in: [packages/mermaid/src/config.type.ts:198](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L198) --- @@ -412,7 +424,7 @@ Defined in: [packages/mermaid/src/config.type.ts:188](https://github.com/mermaid > `optional` **suppressErrorRendering**: `boolean` -Defined in: [packages/mermaid/src/config.type.ts:212](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L212) +Defined in: [packages/mermaid/src/config.type.ts:222](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L222) Suppresses inserting 'Syntax error' diagram in the DOM. This is useful when you want to control how to handle syntax errors in your application. @@ -450,7 +462,7 @@ Defined in: [packages/mermaid/src/config.type.ts:65](https://github.com/mermaid- > `optional` **timeline**: `TimelineDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:186](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L186) +Defined in: [packages/mermaid/src/config.type.ts:196](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L196) --- @@ -458,7 +470,7 @@ Defined in: [packages/mermaid/src/config.type.ts:186](https://github.com/mermaid > `optional` **wrap**: `boolean` -Defined in: [packages/mermaid/src/config.type.ts:204](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L204) +Defined in: [packages/mermaid/src/config.type.ts:214](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L214) --- @@ -466,4 +478,4 @@ Defined in: [packages/mermaid/src/config.type.ts:204](https://github.com/mermaid > `optional` **xyChart**: `XYChartConfig` -Defined in: [packages/mermaid/src/config.type.ts:192](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L192) +Defined in: [packages/mermaid/src/config.type.ts:202](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L202) diff --git a/docs/ecosystem/integrations-community.md b/docs/ecosystem/integrations-community.md index e86abfd81..6bc16e3e2 100644 --- a/docs/ecosystem/integrations-community.md +++ b/docs/ecosystem/integrations-community.md @@ -73,7 +73,7 @@ To add an integration to this list, see the [Integrations - create page](./integ - [Obsidian](https://help.obsidian.md/Editing+and+formatting/Advanced+formatting+syntax#Diagram) ✅ - [Outline](https://docs.getoutline.com/s/guide/doc/diagrams-KQiKoT4wzK) ✅ - [Redmine](https://redmine.org) - - [Mermaid Macro](https://www.redmine.org/plugins/redmine_mermaid_macro) + - [Mermaid Macro](https://redmine.org/plugins/redmine_mermaid_macro) - [Markdown for mermaid plugin](https://github.com/jamieh-mongolian/markdown-for-mermaid-plugin) - [redmine-mermaid](https://github.com/styz/redmine_mermaid) - Visual Studio Code [Polyglot Interactive Notebooks](https://github.com/dotnet/interactive#net-interactive) @@ -117,7 +117,7 @@ Content Management Systems/Enterprise Content Management - [Grav CMS](https://getgrav.org/) - [Mermaid Diagrams Plugin](https://github.com/DanielFlaum/grav-plugin-mermaid-diagrams) - [GitLab Markdown Adapter](https://github.com/Goutte/grav-plugin-gitlab-markdown-adapter) -- [Tiki](https://tiki.org) +- [Tiki Wiki CMS Groupware](https://tiki.org) - [Tracker Entity Relationship Diagram](https://doc.tiki.org/Tracker-Entity-Relationship-Diagram) - [VitePress](https://vitepress.vuejs.org/) - [Plugin for Mermaid.js](https://emersonbottero.github.io/vitepress-plugin-mermaid/) diff --git a/docs/news/blog.md b/docs/news/blog.md index ff5f1b46b..eda497fdf 100644 --- a/docs/news/blog.md +++ b/docs/news/blog.md @@ -6,6 +6,66 @@ # Blog +## [Mermaid introduces the Visual Editor for Entity Relationship diagrams](https://docs.mermaidchart.com/blog/posts/mermaid-introduces-the-visual-editor-for-entity-relationship-diagrams) + +7/15/2025 • 7 mins + +Mermaid just introduced a Visual Editor for Entity Relationship diagrams, letting anyone map database structures through a simple point-and-click interface instead of code. This no-code ER builder now sits alongside Mermaid’s editors for flowcharts, sequence, and class diagrams, enabling teams to craft and share polished data models for apps, AI, and business processes. + +## [Mermaid supports Treemap Diagrams now!!!](https://docs.mermaidchart.com/blog/posts/mermaid-have-treemap-diagrams-now) + +7/3/2025 • 4 mins + +Mermaid has introduced Treemap diagrams, currently in beta, enhancing hierarchical data visualization. Treemap diagrams use nested rectangles to represent data relationships, focusing on size and proportions. They offer various applications, including budget visualization and market analysis. With simple syntax and customization options, users can effectively present complex data hierarchies. + +## [AI Diagram Generators and Data Visualization: Best Practices](https://docs.mermaidchart.com/blog/posts/ai-diagram-generators-and-data-visualization-best-practices) + +7/2/2025 • 6 mins + +AI diagram generators transform complex data into clear, interactive visuals – enabling faster analysis, better decisions, and stronger collaboration across teams. By combining automation with manual refinement, these tools empower anyone to communicate insights effectively, regardless of technical skill level. + +## [How to Choose the Best AI Diagram Generator for Your Needs (2025)](https://docs.mermaidchart.com/blog/posts/how-to-choose-the-best-ai-diagram-generator-for-your-needs-2025) + +6/26/2025 • 14 mins + +AI diagram generators are transforming how developers visualize and communicate complex systems, reducing hours of manual work into minutes. With tools like Mermaid AI, users benefit from both code-based and visual editing, enabling seamless collaboration and precision. Whether you’re diagramming workflows, software architecture, or data relationships, the right AI tool can significantly boost productivity and streamline communication. + +## [5 Time-Saving Tips for Using Mermaid’s AI Diagram Generator Effectively](https://docs.mermaidchart.com/blog/posts/5-time-saving-tips-for-using-mermaids-ai-diagram-generator-effectively) + +6/11/2025 • 10 mins + +See how developers can save time and boost productivity using Mermaid Chart’s AI diagram generator. Learn five practical tips that help turn plain language into powerful, professional diagrams. + +## [Enhancing Team Collaboration with AI-Powered Diagrams](https://docs.mermaidchart.com/blog/posts/enhancing-team-collaboration-with-ai-powered-diagrams) + +5/27/2025 • 6 mins + +Software teams move fast, but old-school diagramming tools can’t keep up. Mermaid Chart replaces static slides and whiteboards with real-time, AI-generated visuals that evolve with your code and ideas. Just describe a process in plain English, and watch it come to life. + +## [What is an AI Diagram Generator? Benefits and Use Cases](https://docs.mermaidchart.com/blog/posts/what-is-an-ai-diagram-generator-benefits-and-use-cases) + +5/22/2025 • 6 mins + +Discover how AI diagram generators like Mermaid Chart transform developer workflows. Instantly turn text into flowcharts, ERDs, and system diagrams, no manual drag-and-drop needed. Learn how it works, key benefits, and real-world use cases. + +## [How to Use Mermaid Chart as an AI Diagram Generator for Developers](https://docs.mermaidchart.com/blog/posts/how-to-use-mermaid-chart-as-an-ai-diagram-generator) + +5/21/2025 • 9 mins + +Would an AI diagram generator make your life easier? We think it would! + +## [Mermaid Chart VS Code Plugin: Create and Edit Mermaid.js Diagrams in Visual Studio Code](https://docs.mermaidchart.com/blog/posts/mermaid-chart-vs-code-plugin-create-and-edit-mermaid-js-diagrams-in-visual-studio-code) + +3/21/2025 • 5 mins + +The Mermaid Chart VS Code Plugin is a powerful developer diagramming tool that brings Mermaid.js diagramming directly into your Visual Studio Code environment. Whether you’re visualizing software architecture, documenting API flows, fixing bad documentation, or managing flowcharts and sequence diagrams, this plugin integrates seamlessly into your workflow. Key Features of the Mermaid Chart VS Code \[…] + +## [Mermaid Chart: The Evolution of Mermaid](https://docs.mermaidchart.com/blog/posts/mermaid-chart-the-evolution-of-mermaid) + +1/30/2025 • 3 mins + +Mermaid revolutionized diagramming with its simple, markdown-style syntax, empowering millions of developers worldwide. Now, Mermaid Chart takes it further with AI-powered visuals, a GUI for seamless editing, real-time collaboration, and advanced design tools. Experience the next generation of diagramming—faster, smarter, and built for modern teams. Try Mermaid Chart today! + ## [GUI for editing Mermaid Class Diagrams](https://docs.mermaidchart.com/blog/posts/gui-for-editing-mermaid-class-diagrams) 1/17/2025 • 5 mins diff --git a/docs/syntax/block.md b/docs/syntax/block.md index d711a2c92..5ca0db719 100644 --- a/docs/syntax/block.md +++ b/docs/syntax/block.md @@ -9,7 +9,7 @@ ## Introduction to Block Diagrams ```mermaid-example -block-beta +block columns 1 db(("DB")) blockArrowId6<["   "]>(down) @@ -26,7 +26,7 @@ columns 1 ``` ```mermaid -block-beta +block columns 1 db(("DB")) blockArrowId6<["   "]>(down) @@ -80,12 +80,12 @@ At its core, a block diagram consists of blocks representing different entities To create a simple block diagram with three blocks labeled 'a', 'b', and 'c', the syntax is as follows: ```mermaid-example -block-beta +block a b c ``` ```mermaid -block-beta +block a b c ``` @@ -101,13 +101,13 @@ While simple block diagrams are linear and straightforward, more complex systems In scenarios where you need to distribute blocks across multiple columns, you can specify the number of columns and arrange the blocks accordingly. Here's how to create a block diagram with three columns and four blocks, where the fourth block appears in a second row: ```mermaid-example -block-beta +block columns 3 a b c d ``` ```mermaid -block-beta +block columns 3 a b c d ``` @@ -130,13 +130,13 @@ In more complex diagrams, you may need blocks that span multiple columns to emph To create a block diagram where one block spans across two columns, you can specify the desired width for each block: ```mermaid-example -block-beta +block columns 3 a["A label"] b:2 c:2 d ``` ```mermaid -block-beta +block columns 3 a["A label"] b:2 c:2 d ``` @@ -153,7 +153,7 @@ Composite blocks, or blocks within blocks, are an advanced feature in Mermaid's Creating a composite block involves defining a parent block and then nesting other blocks within it. Here's how to define a composite block with nested elements: ```mermaid-example -block-beta +block block D end @@ -161,7 +161,7 @@ block-beta ``` ```mermaid -block-beta +block block D end @@ -180,7 +180,7 @@ Mermaid also allows for dynamic adjustment of column widths based on the content In diagrams with varying block sizes, Mermaid automatically adjusts the column widths to fit the largest block in each column. Here's an example: ```mermaid-example -block-beta +block columns 3 a:3 block:group1:2 @@ -195,7 +195,7 @@ block-beta ``` ```mermaid -block-beta +block columns 3 a:3 block:group1:2 @@ -215,7 +215,7 @@ This example demonstrates how Mermaid dynamically adjusts the width of the colum In scenarios where you need to stack blocks horizontally, you can use column width to accomplish the task. Blocks can be arranged vertically by putting them in a single column. Here is how you can create a block diagram in which 4 blocks are stacked on top of each other: ```mermaid-example -block-beta +block block columns 1 a["A label"] b c d @@ -223,7 +223,7 @@ block-beta ``` ```mermaid -block-beta +block block columns 1 a["A label"] b c d @@ -247,12 +247,12 @@ Mermaid supports a range of block shapes to suit different diagramming needs, fr To create a block with round edges, which can be used to represent a softer or more flexible component: ```mermaid-example -block-beta +block id1("This is the text in the box") ``` ```mermaid -block-beta +block id1("This is the text in the box") ``` @@ -261,12 +261,12 @@ block-beta A stadium-shaped block, resembling an elongated circle, can be used for components that are process-oriented: ```mermaid-example -block-beta +block id1(["This is the text in the box"]) ``` ```mermaid -block-beta +block id1(["This is the text in the box"]) ``` @@ -275,12 +275,12 @@ block-beta For representing subroutines or contained processes, a block with double vertical lines is useful: ```mermaid-example -block-beta +block id1[["This is the text in the box"]] ``` ```mermaid -block-beta +block id1[["This is the text in the box"]] ``` @@ -289,12 +289,12 @@ block-beta The cylindrical shape is ideal for representing databases or storage components: ```mermaid-example -block-beta +block id1[("Database")] ``` ```mermaid -block-beta +block id1[("Database")] ``` @@ -303,12 +303,12 @@ block-beta A circle can be used for centralized or pivotal components: ```mermaid-example -block-beta +block id1(("This is the text in the circle")) ``` ```mermaid -block-beta +block id1(("This is the text in the circle")) ``` @@ -319,36 +319,36 @@ For decision points, use a rhombus, and for unique or specialized processes, asy **Asymmetric** ```mermaid-example -block-beta +block id1>"This is the text in the box"] ``` ```mermaid -block-beta +block id1>"This is the text in the box"] ``` **Rhombus** ```mermaid-example -block-beta +block id1{"This is the text in the box"} ``` ```mermaid -block-beta +block id1{"This is the text in the box"} ``` **Hexagon** ```mermaid-example -block-beta +block id1{{"This is the text in the box"}} ``` ```mermaid -block-beta +block id1{{"This is the text in the box"}} ``` @@ -357,7 +357,7 @@ block-beta Parallelogram and trapezoid shapes are perfect for inputs/outputs and transitional processes: ```mermaid-example -block-beta +block id1[/"This is the text in the box"/] id2[\"This is the text in the box"\] A[/"Christmas"\] @@ -365,7 +365,7 @@ block-beta ``` ```mermaid -block-beta +block id1[/"This is the text in the box"/] id2[\"This is the text in the box"\] A[/"Christmas"\] @@ -377,12 +377,12 @@ block-beta For highlighting critical or high-priority components, a double circle can be effective: ```mermaid-example -block-beta +block id1((("This is the text in the circle"))) ``` ```mermaid -block-beta +block id1((("This is the text in the circle"))) ``` @@ -395,7 +395,7 @@ Mermaid also offers unique shapes like block arrows and space blocks for directi Block arrows can visually indicate direction or flow within a process: ```mermaid-example -block-beta +block blockArrowId<["Label"]>(right) blockArrowId2<["Label"]>(left) blockArrowId3<["Label"]>(up) @@ -406,7 +406,7 @@ block-beta ``` ```mermaid -block-beta +block blockArrowId<["Label"]>(right) blockArrowId2<["Label"]>(left) blockArrowId3<["Label"]>(up) @@ -421,14 +421,14 @@ block-beta Space blocks can be used to create intentional empty spaces in the diagram, which is useful for layout and readability: ```mermaid-example -block-beta +block columns 3 a space b c d e ``` ```mermaid -block-beta +block columns 3 a space b c d e @@ -437,12 +437,12 @@ block-beta or ```mermaid-example -block-beta +block ida space:3 idb idc ``` ```mermaid -block-beta +block ida space:3 idb idc ``` @@ -467,13 +467,13 @@ The most fundamental aspect of connecting blocks is the use of arrows or links. A simple link with an arrow can be created to show direction or flow from one block to another: ```mermaid-example -block-beta +block A space B A-->B ``` ```mermaid -block-beta +block A space B A-->B ``` @@ -490,13 +490,13 @@ Example - Text with Links To add text to a link, the syntax includes the text within the link definition: ```mermaid-example -block-beta +block A space:2 B A-- "X" -->B ``` ```mermaid -block-beta +block A space:2 B A-- "X" -->B ``` @@ -506,7 +506,7 @@ This example show how to add descriptive text to the links, enhancing the inform Example - Edges and Styles: ```mermaid-example -block-beta +block columns 1 db(("DB")) blockArrowId6<["   "]>(down) @@ -523,7 +523,7 @@ columns 1 ``` ```mermaid -block-beta +block columns 1 db(("DB")) blockArrowId6<["   "]>(down) @@ -552,7 +552,7 @@ Mermaid enables detailed styling of individual blocks, allowing you to apply var To apply custom styles to a block, you can use the `style` keyword followed by the block identifier and the desired CSS properties: ```mermaid-example -block-beta +block id1 space id2 id1("Start")-->id2("Stop") style id1 fill:#636,stroke:#333,stroke-width:4px @@ -560,7 +560,7 @@ block-beta ``` ```mermaid -block-beta +block id1 space id2 id1("Start")-->id2("Stop") style id1 fill:#636,stroke:#333,stroke-width:4px @@ -574,7 +574,7 @@ Mermaid enables applying styling to classes, which could make styling easier if #### Example - Styling a Single Class ```mermaid-example -block-beta +block A space B A-->B classDef blue fill:#6e6ce6,stroke:#333,stroke-width:4px; @@ -583,7 +583,7 @@ block-beta ``` ```mermaid -block-beta +block A space B A-->B classDef blue fill:#6e6ce6,stroke:#333,stroke-width:4px; @@ -608,7 +608,7 @@ Combining the elements of structure, linking, and styling, we can create compreh Illustrating a simple software system architecture with interconnected components: ```mermaid-example -block-beta +block columns 3 Frontend blockArrowId6<[" "]>(right) Backend space:2 down<[" "]>(down) @@ -621,7 +621,7 @@ block-beta ``` ```mermaid -block-beta +block columns 3 Frontend blockArrowId6<[" "]>(right) Backend space:2 down<[" "]>(down) @@ -640,7 +640,7 @@ This example shows a basic architecture with a frontend, backend, and database. Representing a business process flow with decision points and multiple stages: ```mermaid-example -block-beta +block columns 3 Start(("Start")) space:2 down<[" "]>(down) space:2 @@ -653,7 +653,7 @@ block-beta ``` ```mermaid -block-beta +block columns 3 Start(("Start")) space:2 down<[" "]>(down) space:2 @@ -682,7 +682,7 @@ Understanding and avoiding common syntax errors is key to a smooth experience wi A common mistake is incorrect linking syntax, which can lead to unexpected results or broken diagrams: ``` -block-beta +block A - B ``` @@ -690,13 +690,13 @@ block-beta Ensure that links between blocks are correctly specified with arrows (--> or ---) to define the direction and type of connection. Also remember that one of the fundamentals for block diagram is to give the author full control of where the boxes are positioned so in the example you need to add a space between the boxes: ```mermaid-example -block-beta +block A space B A --> B ``` ```mermaid -block-beta +block A space B A --> B ``` @@ -706,13 +706,13 @@ block-beta Applying styles in the wrong context or with incorrect syntax can lead to blocks not being styled as intended: ```mermaid-example - block-beta + block A style A fill#969; ``` ```mermaid - block-beta + block A style A fill#969; ``` @@ -721,14 +721,14 @@ Applying styles in the wrong context or with incorrect syntax can lead to blocks Correct the syntax by ensuring proper separation of style properties with commas and using the correct CSS property format: ```mermaid-example -block-beta +block A style A fill:#969,stroke:#333; ``` ```mermaid -block-beta +block A style A fill:#969,stroke:#333; diff --git a/docs/syntax/flowchart.md b/docs/syntax/flowchart.md index 5f827e52a..daaa29581 100644 --- a/docs/syntax/flowchart.md +++ b/docs/syntax/flowchart.md @@ -1816,7 +1816,7 @@ config: graph LR ``` -#### Edge level curve style using Edge IDs (v\+) +#### Edge level curve style using Edge IDs (v11.10.0+) You can assign IDs to [edges](#attaching-an-id-to-edges). After assigning an ID you can modify the line style by modifying the edge's `curve` property using the following syntax: diff --git a/docs/syntax/pie.md b/docs/syntax/pie.md index b8f452b66..fd5ec1db0 100644 --- a/docs/syntax/pie.md +++ b/docs/syntax/pie.md @@ -37,6 +37,11 @@ Drawing a pie chart is really simple in mermaid. - Followed by `:` colon as separator - Followed by `positive numeric value` (supported up to two decimal places) +**Note:** + +> Pie chart values must be **positive numbers greater than zero**. +> **Negative values are not allowed** and will result in an error. + \[pie] \[showData] (OPTIONAL) \[title] \[titlevalue] (OPTIONAL) "\[datakey1]" : \[dataValue1] diff --git a/docs/syntax/sankey.md b/docs/syntax/sankey.md index ccabc11c9..e981358b5 100644 --- a/docs/syntax/sankey.md +++ b/docs/syntax/sankey.md @@ -23,7 +23,7 @@ config: sankey: showValues: false --- -sankey-beta +sankey Agricultural 'waste',Bio-conversion,124.729 Bio-conversion,Liquid,0.597 @@ -101,7 +101,7 @@ config: sankey: showValues: false --- -sankey-beta +sankey Agricultural 'waste',Bio-conversion,124.729 Bio-conversion,Liquid,0.597 @@ -175,7 +175,7 @@ Wind,Electricity grid,289.366 ## Syntax -The idea behind syntax is that a user types `sankey-beta` keyword first, then pastes raw CSV below and get the result. +The idea behind syntax is that a user types `sankey` keyword first, then pastes raw CSV below and get the result. It implements CSV standard as [described here](https://www.ietf.org/rfc/rfc4180.txt) with subtle **differences**: @@ -187,7 +187,7 @@ It implements CSV standard as [described here](https://www.ietf.org/rfc/rfc4180. It is implied that 3 columns inside CSV should represent `source`, `target` and `value` accordingly: ```mermaid-example -sankey-beta +sankey %% source,target,value Electricity grid,Over generation / exports,104.453 @@ -196,7 +196,7 @@ Electricity grid,H2 conversion,27.14 ``` ```mermaid -sankey-beta +sankey %% source,target,value Electricity grid,Over generation / exports,104.453 @@ -209,7 +209,7 @@ Electricity grid,H2 conversion,27.14 CSV does not support empty lines without comma delimiters by default. But you can add them if needed: ```mermaid-example -sankey-beta +sankey Bio-conversion,Losses,26.862 @@ -219,7 +219,7 @@ Bio-conversion,Gas,81.144 ``` ```mermaid -sankey-beta +sankey Bio-conversion,Losses,26.862 @@ -233,14 +233,14 @@ Bio-conversion,Gas,81.144 If you need to have a comma, wrap it in double quotes: ```mermaid-example -sankey-beta +sankey Pumped heat,"Heating and cooling, homes",193.026 Pumped heat,"Heating and cooling, commercial",70.672 ``` ```mermaid -sankey-beta +sankey Pumped heat,"Heating and cooling, homes",193.026 Pumped heat,"Heating and cooling, commercial",70.672 @@ -251,14 +251,14 @@ Pumped heat,"Heating and cooling, commercial",70.672 If you need to have double quote, put a pair of them inside quoted string: ```mermaid-example -sankey-beta +sankey Pumped heat,"Heating and cooling, ""homes""",193.026 Pumped heat,"Heating and cooling, ""commercial""",70.672 ``` ```mermaid -sankey-beta +sankey Pumped heat,"Heating and cooling, ""homes""",193.026 Pumped heat,"Heating and cooling, ""commercial""",70.672 diff --git a/docs/syntax/xyChart.md b/docs/syntax/xyChart.md index dd64f742d..dec16a518 100644 --- a/docs/syntax/xyChart.md +++ b/docs/syntax/xyChart.md @@ -13,7 +13,7 @@ ## Example ```mermaid-example -xychart-beta +xychart title "Sales Revenue" x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] y-axis "Revenue (in $)" 4000 --> 11000 @@ -22,7 +22,7 @@ xychart-beta ``` ```mermaid -xychart-beta +xychart title "Sales Revenue" x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] y-axis "Revenue (in $)" 4000 --> 11000 @@ -40,7 +40,7 @@ xychart-beta The chart can be drawn horizontal or vertical, default value is vertical. ``` -xychart-beta horizontal +xychart horizontal ... ``` @@ -51,7 +51,7 @@ The title is a short description of the chart and it will always render on top o #### Example ``` -xychart-beta +xychart title "This is a simple example" ... ``` @@ -98,10 +98,10 @@ A bar chart offers the capability to graphically depict bars. #### Simplest example -The only two things required are the chart name (`xychart-beta`) and one data set. So you will be able to draw a chart with a simple config like +The only two things required are the chart name (`xychart`) and one data set. So you will be able to draw a chart with a simple config like ``` -xychart-beta +xychart line [+1.3, .6, 2.4, -.34] ``` @@ -176,7 +176,7 @@ config: xyChart: titleColor: "#ff0000" --- -xychart-beta +xychart title "Sales Revenue" x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] y-axis "Revenue (in $)" 4000 --> 11000 @@ -195,7 +195,7 @@ config: xyChart: titleColor: "#ff0000" --- -xychart-beta +xychart title "Sales Revenue" x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] y-axis "Revenue (in $)" 4000 --> 11000 diff --git a/packages/examples/package.json b/packages/examples/package.json index 26ae83e15..cd0fc0bd0 100644 --- a/packages/examples/package.json +++ b/packages/examples/package.json @@ -27,9 +27,6 @@ "devDependencies": { "mermaid": "workspace:*" }, - "peerDependencies": { - "mermaid": "workspace:~" - }, "publishConfig": { "access": "public" } diff --git a/packages/mermaid-layout-elk/CHANGELOG.md b/packages/mermaid-layout-elk/CHANGELOG.md index 96b5d2fae..ef40f04a0 100644 --- a/packages/mermaid-layout-elk/CHANGELOG.md +++ b/packages/mermaid-layout-elk/CHANGELOG.md @@ -1,5 +1,16 @@ # @mermaid-js/layout-elk +## 0.1.9 + +### Patch Changes + +- [#6857](https://github.com/mermaid-js/mermaid/pull/6857) [`b9ef683`](https://github.com/mermaid-js/mermaid/commit/b9ef683fb67b8959abc455d6cc5266c37ba435f6) Thanks [@knsv](https://github.com/knsv)! - feat: Exposing elk configuration forceNodeModelOrder and considerModelOrder to the mermaid configuration + +- [#6849](https://github.com/mermaid-js/mermaid/pull/6849) [`2260948`](https://github.com/mermaid-js/mermaid/commit/2260948b7bda08f00616c2ce678bed1da69eb96c) Thanks [@anderium](https://github.com/anderium)! - Make elk not force node model order, but strongly consider it instead + +- Updated dependencies [[`b9ef683`](https://github.com/mermaid-js/mermaid/commit/b9ef683fb67b8959abc455d6cc5266c37ba435f6), [`2c0931d`](https://github.com/mermaid-js/mermaid/commit/2c0931da46794b49d2523211e25f782900c34e94), [`33e08da`](https://github.com/mermaid-js/mermaid/commit/33e08daf175125295a06b1b80279437004a4e865), [`814b68b`](https://github.com/mermaid-js/mermaid/commit/814b68b4a94813f7c6b3d7fb4559532a7bab2652), [`fce7cab`](https://github.com/mermaid-js/mermaid/commit/fce7cabb71d68a20a66246fe23d066512126a412), [`fc07f0d`](https://github.com/mermaid-js/mermaid/commit/fc07f0d8abca49e4f887d7457b7b94fb07d1e3da), [`12e01bd`](https://github.com/mermaid-js/mermaid/commit/12e01bdb5cacf3569133979a5a4f1d8973e9aec1), [`01aaef3`](https://github.com/mermaid-js/mermaid/commit/01aaef39b4a1ec8bc5a0c6bfa3a20b712d67f4dc), [`daf8d8d`](https://github.com/mermaid-js/mermaid/commit/daf8d8d3befcd600618a629977b76463b38d0ad9), [`c36cd05`](https://github.com/mermaid-js/mermaid/commit/c36cd05c45ac3090181152b4dae41f8d7b569bd6), [`8bb29fc`](https://github.com/mermaid-js/mermaid/commit/8bb29fc879329ad109898e4025b4f4eba2ab0649), [`71b04f9`](https://github.com/mermaid-js/mermaid/commit/71b04f93b07f876df2b30656ef36036c1d0e4e4f), [`c99bce6`](https://github.com/mermaid-js/mermaid/commit/c99bce6bab4c7ce0b81b66d44f44853ce4aeb1c3), [`6cc1926`](https://github.com/mermaid-js/mermaid/commit/6cc192680a2531cab28f87a8061a53b786e010f3), [`9da6fb3`](https://github.com/mermaid-js/mermaid/commit/9da6fb39ae278401771943ac85d6d1b875f78cf1), [`e48b0ba`](https://github.com/mermaid-js/mermaid/commit/e48b0ba61dab7f95aa02da603b5b7d383b894932), [`4d62d59`](https://github.com/mermaid-js/mermaid/commit/4d62d5963238400270e9314c6e4d506f48147074), [`e9ce8cf`](https://github.com/mermaid-js/mermaid/commit/e9ce8cf4da9062d85098042044822100889bb0dd), [`9258b29`](https://github.com/mermaid-js/mermaid/commit/9258b2933bbe1ef41087345ffea3731673671c49), [`da90f67`](https://github.com/mermaid-js/mermaid/commit/da90f6760b6efb0da998bcb63b75eecc29e06c08), [`0133f1c`](https://github.com/mermaid-js/mermaid/commit/0133f1c0c5cff4fc4c8e0b99e9cf0b3d49dcbe71), [`895f9d4`](https://github.com/mermaid-js/mermaid/commit/895f9d43ff98ca05ebfba530789f677f31a011ff)]: + - mermaid@11.10.0 + ## 0.1.8 ### Patch Changes diff --git a/packages/mermaid-layout-elk/package.json b/packages/mermaid-layout-elk/package.json index 023958c1f..176c14b25 100644 --- a/packages/mermaid-layout-elk/package.json +++ b/packages/mermaid-layout-elk/package.json @@ -1,6 +1,6 @@ { "name": "@mermaid-js/layout-elk", - "version": "0.1.8", + "version": "0.1.9", "description": "ELK layout engine for mermaid", "module": "dist/mermaid-layout-elk.core.mjs", "types": "dist/layouts.d.ts", diff --git a/packages/mermaid-layout-elk/src/render.ts b/packages/mermaid-layout-elk/src/render.ts index 9f361bf7b..d1c44b67f 100644 --- a/packages/mermaid-layout-elk/src/render.ts +++ b/packages/mermaid-layout-elk/src/render.ts @@ -766,7 +766,10 @@ export const render = async ( id: 'root', layoutOptions: { 'elk.hierarchyHandling': 'INCLUDE_CHILDREN', - 'elk.layered.crossingMinimization.forceNodeModelOrder': true, + 'elk.layered.crossingMinimization.forceNodeModelOrder': + data4Layout.config.elk?.forceNodeModelOrder, + 'elk.layered.considerModelOrder.strategy': data4Layout.config.elk?.considerModelOrder, + 'elk.algorithm': algorithm, 'nodePlacement.strategy': data4Layout.config.elk?.nodePlacementStrategy, 'elk.layered.mergeEdges': data4Layout.config.elk?.mergeEdges, diff --git a/packages/mermaid-zenuml/CHANGELOG.md b/packages/mermaid-zenuml/CHANGELOG.md index 57e8795a4..a7fe35c78 100644 --- a/packages/mermaid-zenuml/CHANGELOG.md +++ b/packages/mermaid-zenuml/CHANGELOG.md @@ -1,5 +1,14 @@ # @mermaid-js/mermaid-zenuml +## 0.2.2 + +### Patch Changes + +- [#6798](https://github.com/mermaid-js/mermaid/pull/6798) [`3ffe961`](https://github.com/mermaid-js/mermaid/commit/3ffe9618aebc9ac96de6e3c826481f542f18c2a9) Thanks [@MrCoder](https://github.com/MrCoder)! - Fixed a critical bug that the ZenUML diagram is not rendered. + +- Updated dependencies [[`b9ef683`](https://github.com/mermaid-js/mermaid/commit/b9ef683fb67b8959abc455d6cc5266c37ba435f6), [`2c0931d`](https://github.com/mermaid-js/mermaid/commit/2c0931da46794b49d2523211e25f782900c34e94), [`33e08da`](https://github.com/mermaid-js/mermaid/commit/33e08daf175125295a06b1b80279437004a4e865), [`814b68b`](https://github.com/mermaid-js/mermaid/commit/814b68b4a94813f7c6b3d7fb4559532a7bab2652), [`fce7cab`](https://github.com/mermaid-js/mermaid/commit/fce7cabb71d68a20a66246fe23d066512126a412), [`fc07f0d`](https://github.com/mermaid-js/mermaid/commit/fc07f0d8abca49e4f887d7457b7b94fb07d1e3da), [`12e01bd`](https://github.com/mermaid-js/mermaid/commit/12e01bdb5cacf3569133979a5a4f1d8973e9aec1), [`01aaef3`](https://github.com/mermaid-js/mermaid/commit/01aaef39b4a1ec8bc5a0c6bfa3a20b712d67f4dc), [`daf8d8d`](https://github.com/mermaid-js/mermaid/commit/daf8d8d3befcd600618a629977b76463b38d0ad9), [`c36cd05`](https://github.com/mermaid-js/mermaid/commit/c36cd05c45ac3090181152b4dae41f8d7b569bd6), [`8bb29fc`](https://github.com/mermaid-js/mermaid/commit/8bb29fc879329ad109898e4025b4f4eba2ab0649), [`71b04f9`](https://github.com/mermaid-js/mermaid/commit/71b04f93b07f876df2b30656ef36036c1d0e4e4f), [`c99bce6`](https://github.com/mermaid-js/mermaid/commit/c99bce6bab4c7ce0b81b66d44f44853ce4aeb1c3), [`6cc1926`](https://github.com/mermaid-js/mermaid/commit/6cc192680a2531cab28f87a8061a53b786e010f3), [`9da6fb3`](https://github.com/mermaid-js/mermaid/commit/9da6fb39ae278401771943ac85d6d1b875f78cf1), [`e48b0ba`](https://github.com/mermaid-js/mermaid/commit/e48b0ba61dab7f95aa02da603b5b7d383b894932), [`4d62d59`](https://github.com/mermaid-js/mermaid/commit/4d62d5963238400270e9314c6e4d506f48147074), [`e9ce8cf`](https://github.com/mermaid-js/mermaid/commit/e9ce8cf4da9062d85098042044822100889bb0dd), [`9258b29`](https://github.com/mermaid-js/mermaid/commit/9258b2933bbe1ef41087345ffea3731673671c49), [`da90f67`](https://github.com/mermaid-js/mermaid/commit/da90f6760b6efb0da998bcb63b75eecc29e06c08), [`0133f1c`](https://github.com/mermaid-js/mermaid/commit/0133f1c0c5cff4fc4c8e0b99e9cf0b3d49dcbe71), [`895f9d4`](https://github.com/mermaid-js/mermaid/commit/895f9d43ff98ca05ebfba530789f677f31a011ff)]: + - mermaid@11.10.0 + ## 0.2.1 ### Patch Changes diff --git a/packages/mermaid-zenuml/package.json b/packages/mermaid-zenuml/package.json index ec7b9486d..cc9ce0d4a 100644 --- a/packages/mermaid-zenuml/package.json +++ b/packages/mermaid-zenuml/package.json @@ -1,6 +1,6 @@ { "name": "@mermaid-js/mermaid-zenuml", - "version": "0.2.1", + "version": "0.2.2", "description": "MermaidJS plugin for ZenUML integration", "module": "dist/mermaid-zenuml.core.mjs", "types": "dist/detector.d.ts", diff --git a/packages/mermaid/CHANGELOG.md b/packages/mermaid/CHANGELOG.md index 49756233a..df67f0cfd 100644 --- a/packages/mermaid/CHANGELOG.md +++ b/packages/mermaid/CHANGELOG.md @@ -1,5 +1,72 @@ # mermaid +## 11.10.0 + +### Minor Changes + +- [#6744](https://github.com/mermaid-js/mermaid/pull/6744) [`daf8d8d`](https://github.com/mermaid-js/mermaid/commit/daf8d8d3befcd600618a629977b76463b38d0ad9) Thanks [@SpecularAura](https://github.com/SpecularAura)! - feat: Added support for per link curve styling in flowchart diagram using edge ids + +### Patch Changes + +- [#6857](https://github.com/mermaid-js/mermaid/pull/6857) [`b9ef683`](https://github.com/mermaid-js/mermaid/commit/b9ef683fb67b8959abc455d6cc5266c37ba435f6) Thanks [@knsv](https://github.com/knsv)! - feat: Exposing elk configuration forceNodeModelOrder and considerModelOrder to the mermaid configuration + +- [#6653](https://github.com/mermaid-js/mermaid/pull/6653) [`2c0931d`](https://github.com/mermaid-js/mermaid/commit/2c0931da46794b49d2523211e25f782900c34e94) Thanks [@darshanr0107](https://github.com/darshanr0107)! - chore: Remove the "-beta" suffix from the XYChart, Block, Sankey diagrams to reflect their stable status + +- [#6683](https://github.com/mermaid-js/mermaid/pull/6683) [`33e08da`](https://github.com/mermaid-js/mermaid/commit/33e08daf175125295a06b1b80279437004a4e865) Thanks [@darshanr0107](https://github.com/darshanr0107)! - fix: Position the edge label in state diagram correctly relative to the edge + +- [#6693](https://github.com/mermaid-js/mermaid/pull/6693) [`814b68b`](https://github.com/mermaid-js/mermaid/commit/814b68b4a94813f7c6b3d7fb4559532a7bab2652) Thanks [@darshanr0107](https://github.com/darshanr0107)! - fix: Apply correct dateFormat in Gantt chart to show only day when specified + +- [#6734](https://github.com/mermaid-js/mermaid/pull/6734) [`fce7cab`](https://github.com/mermaid-js/mermaid/commit/fce7cabb71d68a20a66246fe23d066512126a412) Thanks [@darshanr0107](https://github.com/darshanr0107)! - fix: handle exclude dates properly in Gantt charts when using dateFormat: 'YYYY-MM-DD HH:mm:ss' + +- [#6733](https://github.com/mermaid-js/mermaid/pull/6733) [`fc07f0d`](https://github.com/mermaid-js/mermaid/commit/fc07f0d8abca49e4f887d7457b7b94fb07d1e3da) Thanks [@omkarht](https://github.com/omkarht)! - fix: fixed connection gaps in flowchart for roundedRect, stadium and diamond shape + +- [#6876](https://github.com/mermaid-js/mermaid/pull/6876) [`12e01bd`](https://github.com/mermaid-js/mermaid/commit/12e01bdb5cacf3569133979a5a4f1d8973e9aec1) Thanks [@sidharthv96](https://github.com/sidharthv96)! - fix: sanitize icon labels and icon SVGs + + Resolves CVE-2025-54880 reported by @fourcube + +- [#6801](https://github.com/mermaid-js/mermaid/pull/6801) [`01aaef3`](https://github.com/mermaid-js/mermaid/commit/01aaef39b4a1ec8bc5a0c6bfa3a20b712d67f4dc) Thanks [@sidharthv96](https://github.com/sidharthv96)! - fix: Update casing of ID in requirement diagram + +- [#6796](https://github.com/mermaid-js/mermaid/pull/6796) [`c36cd05`](https://github.com/mermaid-js/mermaid/commit/c36cd05c45ac3090181152b4dae41f8d7b569bd6) Thanks [@HashanCP](https://github.com/HashanCP)! - fix: Make flowchart elk detector regex match less greedy + +- [#6702](https://github.com/mermaid-js/mermaid/pull/6702) [`8bb29fc`](https://github.com/mermaid-js/mermaid/commit/8bb29fc879329ad109898e4025b4f4eba2ab0649) Thanks [@qraqras](https://github.com/qraqras)! - 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). + +- [#6717](https://github.com/mermaid-js/mermaid/pull/6717) [`71b04f9`](https://github.com/mermaid-js/mermaid/commit/71b04f93b07f876df2b30656ef36036c1d0e4e4f) Thanks [@darshanr0107](https://github.com/darshanr0107)! - 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. + +- [#6820](https://github.com/mermaid-js/mermaid/pull/6820) [`c99bce6`](https://github.com/mermaid-js/mermaid/commit/c99bce6bab4c7ce0b81b66d44f44853ce4aeb1c3) Thanks [@kriss-u](https://github.com/kriss-u)! - fix: Add escaped class literal name on namespace + +- [#6332](https://github.com/mermaid-js/mermaid/pull/6332) [`6cc1926`](https://github.com/mermaid-js/mermaid/commit/6cc192680a2531cab28f87a8061a53b786e010f3) Thanks [@ajuckel](https://github.com/ajuckel)! - fix: Allow equals sign in sequenceDiagram labels + +- [#6651](https://github.com/mermaid-js/mermaid/pull/6651) [`9da6fb3`](https://github.com/mermaid-js/mermaid/commit/9da6fb39ae278401771943ac85d6d1b875f78cf1) Thanks [@darshanr0107](https://github.com/darshanr0107)! - 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. + +- [#6803](https://github.com/mermaid-js/mermaid/pull/6803) [`e48b0ba`](https://github.com/mermaid-js/mermaid/commit/e48b0ba61dab7f95aa02da603b5b7d383b894932) Thanks [@omkarht](https://github.com/omkarht)! - chore: migrate to class-based ArchitectureDB implementation + +- [#6838](https://github.com/mermaid-js/mermaid/pull/6838) [`4d62d59`](https://github.com/mermaid-js/mermaid/commit/4d62d5963238400270e9314c6e4d506f48147074) Thanks [@saurabhg772244](https://github.com/saurabhg772244)! - fix: node border style for handdrawn shapes + +- [#6739](https://github.com/mermaid-js/mermaid/pull/6739) [`e9ce8cf`](https://github.com/mermaid-js/mermaid/commit/e9ce8cf4da9062d85098042044822100889bb0dd) Thanks [@kriss-u](https://github.com/kriss-u)! - fix: Update flowchart direction TD's behavior to be the same as TB + +- [#6833](https://github.com/mermaid-js/mermaid/pull/6833) [`9258b29`](https://github.com/mermaid-js/mermaid/commit/9258b2933bbe1ef41087345ffea3731673671c49) Thanks [@darshanr0107](https://github.com/darshanr0107)! - fix: correctly render non-directional lines for '---' in block diagrams + +- [#6855](https://github.com/mermaid-js/mermaid/pull/6855) [`da90f67`](https://github.com/mermaid-js/mermaid/commit/da90f6760b6efb0da998bcb63b75eecc29e06c08) Thanks [@sidharthv96](https://github.com/sidharthv96)! - fix: fallback to raw text instead of rendering _Unsupported markdown_ or empty blocks + + Instead of printing **Unsupported markdown: XXX**, or empty blocks when using a markdown feature + that Mermaid does not yet support when `htmlLabels: true`(default) or `htmlLabels: false`, + fallback to the raw markdown text. + +- [#6876](https://github.com/mermaid-js/mermaid/pull/6876) [`0133f1c`](https://github.com/mermaid-js/mermaid/commit/0133f1c0c5cff4fc4c8e0b99e9cf0b3d49dcbe71) Thanks [@sidharthv96](https://github.com/sidharthv96)! - fix: sanitize KATEX blocks + + Resolves CVE-2025-54881 reported by @fourcube + +- [#6804](https://github.com/mermaid-js/mermaid/pull/6804) [`895f9d4`](https://github.com/mermaid-js/mermaid/commit/895f9d43ff98ca05ebfba530789f677f31a011ff) Thanks [@omkarht](https://github.com/omkarht)! - chore: Update packet diagram to use new class-based database structure + ## 11.9.0 ### Minor Changes diff --git a/packages/mermaid/package.json b/packages/mermaid/package.json index 5a9669ff6..56446c34b 100644 --- a/packages/mermaid/package.json +++ b/packages/mermaid/package.json @@ -1,6 +1,6 @@ { "name": "mermaid", - "version": "11.9.0", + "version": "11.10.0", "description": "Markdown-ish syntax for generating flowcharts, mindmaps, sequence diagrams, class diagrams, gantt charts, git graphs and more.", "type": "module", "module": "./dist/mermaid.core.mjs", diff --git a/packages/mermaid/src/config.type.ts b/packages/mermaid/src/config.type.ts index 8cd451c16..70391f2e5 100644 --- a/packages/mermaid/src/config.type.ts +++ b/packages/mermaid/src/config.type.ts @@ -109,6 +109,16 @@ export interface MermaidConfig { | 'INTERACTIVE' | 'MODEL_ORDER' | 'GREEDY_MODEL_ORDER'; + /** + * The node order given by the model does not change to produce a better layout. E.g. if node A is before node B in the model this is not changed during crossing minimization. This assumes that the node model order is already respected before crossing minimization. This can be achieved by setting considerModelOrder.strategy to NODES_AND_EDGES. + * + */ + forceNodeModelOrder?: boolean; + /** + * Preserves the order of nodes and edges in the model file if this does not lead to additional edge crossings. Depending on the strategy this is not always possible since the node and edge order might be conflicting. + * + */ + considerModelOrder?: 'NONE' | 'NODES_AND_EDGES' | 'PREFER_EDGES' | 'PREFER_NODES'; }; darkMode?: boolean; htmlLabels?: boolean; diff --git a/packages/mermaid/src/dagre-wrapper/createLabel.js b/packages/mermaid/src/dagre-wrapper/createLabel.js index 467eed260..fdab9a34e 100644 --- a/packages/mermaid/src/dagre-wrapper/createLabel.js +++ b/packages/mermaid/src/dagre-wrapper/createLabel.js @@ -1,9 +1,9 @@ import { select } from 'd3'; -import { log } from '../logger.js'; import { getConfig } from '../diagram-api/diagramAPI.js'; -import { evaluate } from '../diagrams/common/common.js'; -import { decodeEntities } from '../utils.js'; +import { evaluate, sanitizeText } from '../diagrams/common/common.js'; +import { log } from '../logger.js'; import { replaceIconSubstring } from '../rendering-util/createText.js'; +import { decodeEntities } from '../utils.js'; /** * @param dom @@ -19,14 +19,14 @@ function applyStyle(dom, styleFn) { * @param {any} node * @returns {SVGForeignObjectElement} Node */ -function addHtmlLabel(node) { +function addHtmlLabel(node, config) { const fo = select(document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject')); const div = fo.append('xhtml:div'); const label = node.label; const labelClass = node.isNode ? 'nodeLabel' : 'edgeLabel'; const span = div.append('span'); - span.html(label); + span.html(sanitizeText(label, config)); applyStyle(span, node.labelStyle); span.attr('class', labelClass); @@ -49,7 +49,8 @@ const createLabel = async (_vertexText, style, isTitle, isNode) => { if (typeof vertexText === 'object') { vertexText = vertexText[0]; } - if (evaluate(getConfig().flowchart.htmlLabels)) { + const config = getConfig(); + if (evaluate(config.flowchart.htmlLabels)) { // TODO: addHtmlLabel accepts a labelStyle. Do we possibly have that? vertexText = vertexText.replace(/\\n|\n/g, '
'); log.debug('vertexText' + vertexText); @@ -59,7 +60,7 @@ const createLabel = async (_vertexText, style, isTitle, isNode) => { label, labelStyle: style.replace('fill:', 'color:'), }; - let vertexNode = addHtmlLabel(node); + let vertexNode = addHtmlLabel(node, config); // vertexNode.parentNode.removeChild(vertexNode); return vertexNode; } else { diff --git a/packages/mermaid/src/defaultConfig.ts b/packages/mermaid/src/defaultConfig.ts index 468f8e192..655bf3724 100644 --- a/packages/mermaid/src/defaultConfig.ts +++ b/packages/mermaid/src/defaultConfig.ts @@ -24,6 +24,8 @@ const config: RequiredDeep = { // mergeEdges is needed here to be considered mergeEdges: false, nodePlacementStrategy: 'BRANDES_KOEPF', + forceNodeModelOrder: false, + considerModelOrder: 'NODES_AND_EDGES', }, themeCSS: undefined, diff --git a/packages/mermaid/src/diagrams/architecture/svgDraw.ts b/packages/mermaid/src/diagrams/architecture/svgDraw.ts index f384defd8..6e470caa2 100644 --- a/packages/mermaid/src/diagrams/architecture/svgDraw.ts +++ b/packages/mermaid/src/diagrams/architecture/svgDraw.ts @@ -3,6 +3,7 @@ import { getConfig } from '../../diagram-api/diagramAPI.js'; import { createText } from '../../rendering-util/createText.js'; import { getIconSVG } from '../../rendering-util/icons.js'; import type { D3Element } from '../../types.js'; +import { sanitizeText } from '../common/common.js'; import type { ArchitectureDB } from './architectureDb.js'; import { architectureIcons } from './architectureIcons.js'; import { @@ -271,6 +272,7 @@ export const drawServices = async function ( elem: D3Element, services: ArchitectureService[] ): Promise { + const config = getConfig(); for (const service of services) { const serviceElem = elem.append('g'); const iconSize = db.getConfigField('iconSize'); @@ -285,7 +287,7 @@ export const drawServices = async function ( width: iconSize * 1.5, classes: 'architecture-service-label', }, - getConfig() + config ); textElem @@ -320,7 +322,7 @@ export const drawServices = async function ( .attr('class', 'node-icon-text') .attr('style', `height: ${iconSize}px;`) .append('div') - .html(service.iconText); + .html(sanitizeText(service.iconText, config)); const fontSize = parseInt( window diff --git a/packages/mermaid/src/diagrams/block/blockDB.ts b/packages/mermaid/src/diagrams/block/blockDB.ts index 39a8b47a0..b291be61e 100644 --- a/packages/mermaid/src/diagrams/block/blockDB.ts +++ b/packages/mermaid/src/diagrams/block/blockDB.ts @@ -238,13 +238,15 @@ export function edgeTypeStr2Type(typeStr: string): string { } export function edgeStrToEdgeData(typeStr: string): string { - switch (typeStr.trim()) { - case '--x': + switch (typeStr.replace(/^[\s-]+|[\s-]+$/g, '')) { + case 'x': return 'arrow_cross'; - case '--o': + case 'o': return 'arrow_circle'; - default: + case '>': return 'arrow_point'; + default: + return ''; } } diff --git a/packages/mermaid/src/diagrams/block/blockDetector.ts b/packages/mermaid/src/diagrams/block/blockDetector.ts index c4da643f0..6122221e8 100644 --- a/packages/mermaid/src/diagrams/block/blockDetector.ts +++ b/packages/mermaid/src/diagrams/block/blockDetector.ts @@ -3,7 +3,7 @@ import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-a const id = 'block'; const detector: DiagramDetector = (txt) => { - return /^\s*block-beta/.test(txt); + return /^\s*block(-beta)?/.test(txt); }; const loader = async () => { diff --git a/packages/mermaid/src/diagrams/block/parser/block.jison b/packages/mermaid/src/diagrams/block/parser/block.jison index 88bdf729e..3aa2759a6 100644 --- a/packages/mermaid/src/diagrams/block/parser/block.jison +++ b/packages/mermaid/src/diagrams/block/parser/block.jison @@ -36,10 +36,10 @@ CRLF \u000D\u000A %% -"block-beta" { return 'BLOCK_DIAGRAM_KEY'; } -"block"\s+ { yy.getLogger().debug('Found space-block'); return 'block';} -"block"\n+ { yy.getLogger().debug('Found nl-block'); return 'block';} -"block:" { yy.getLogger().debug('Found space-block'); return 'id-block';} +"block-beta" { yy.getLogger().debug('Found block-beta'); return 'BLOCK_DIAGRAM_KEY'; } +"block:" { yy.getLogger().debug('Found id-block'); return 'id-block'; } +"block" { yy.getLogger().debug('Found block'); return 'BLOCK_DIAGRAM_KEY'; } + // \s*\%\%.* { yy.getLogger().debug('Found comment',yytext); } [\s]+ { yy.getLogger().debug('.', yytext); /* skip all whitespace */ } [\n]+ {yy.getLogger().debug('_', yytext); /* skip all whitespace */ } @@ -240,7 +240,7 @@ columnsStatement blockStatement : id-block nodeStatement document end { yy.getLogger().debug('Rule: id-block statement : ', $2, $3); const id2 = yy.generateId(); $$ = { ...$2, type:'composite', children: $3 }; } - | block document end { yy.getLogger().debug('Rule: blockStatement : ', $1, $2, $3); const id = yy.generateId(); $$ = { id, type:'composite', label:'', children: $2 }; } + | BLOCK_DIAGRAM_KEY document end { yy.getLogger().debug('Rule: blockStatement : ', $1, $2, $3); const id = yy.generateId(); $$ = { id, type:'composite', label:'', children: $2 }; } ; node diff --git a/packages/mermaid/src/diagrams/block/parser/block.spec.ts b/packages/mermaid/src/diagrams/block/parser/block.spec.ts index 21da4e440..e6ad90a65 100644 --- a/packages/mermaid/src/diagrams/block/parser/block.spec.ts +++ b/packages/mermaid/src/diagrams/block/parser/block.spec.ts @@ -23,7 +23,7 @@ describe('Block diagram', function () { expect(blocks[0].label).toBe('id'); }); it('a node with a square shape and a label', () => { - const str = `block-beta + const str = `block id["A label"] `; @@ -35,7 +35,7 @@ describe('Block diagram', function () { expect(blocks[0].type).toBe('square'); }); it('a diagram with multiple nodes', () => { - const str = `block-beta + const str = `block id1 id2 `; @@ -51,7 +51,7 @@ describe('Block diagram', function () { expect(blocks[1].type).toBe('na'); }); it('a diagram with multiple nodes', () => { - const str = `block-beta + const str = `block id1 id2 id3 @@ -72,7 +72,7 @@ describe('Block diagram', function () { }); it('a node with a square shape and a label', () => { - const str = `block-beta + const str = `block id["A label"] id2`; @@ -87,7 +87,7 @@ describe('Block diagram', function () { expect(blocks[1].type).toBe('na'); }); it('a diagram with multiple nodes with edges abc123', () => { - const str = `block-beta + const str = `block id1["first"] --> id2["second"] `; @@ -101,7 +101,7 @@ describe('Block diagram', function () { expect(edges[0].arrowTypeEnd).toBe('arrow_point'); }); it('a diagram with multiple nodes with edges abc123', () => { - const str = `block-beta + const str = `block id1["first"] -- "a label" --> id2["second"] `; @@ -116,7 +116,7 @@ describe('Block diagram', function () { expect(edges[0].label).toBe('a label'); }); it('a diagram with column statements', () => { - const str = `block-beta + const str = `block columns 2 block1["Block 1"] `; @@ -127,7 +127,7 @@ describe('Block diagram', function () { expect(blocks.length).toBe(1); }); it('a diagram without column statements', () => { - const str = `block-beta + const str = `block block1["Block 1"] `; @@ -137,7 +137,7 @@ describe('Block diagram', function () { expect(blocks.length).toBe(1); }); it('a diagram with auto column statements', () => { - const str = `block-beta + const str = `block columns auto block1["Block 1"] `; @@ -149,7 +149,7 @@ describe('Block diagram', function () { }); it('blocks next to each other', () => { - const str = `block-beta + const str = `block columns 2 block1["Block 1"] block2["Block 2"] @@ -163,7 +163,7 @@ describe('Block diagram', function () { }); it('blocks on top of each other', () => { - const str = `block-beta + const str = `block columns 1 block1["Block 1"] block2["Block 2"] @@ -177,7 +177,7 @@ describe('Block diagram', function () { }); it('compound blocks 2', () => { - const str = `block-beta + const str = `block block aBlock["ABlock"] bBlock["BBlock"] @@ -205,7 +205,7 @@ describe('Block diagram', function () { expect(bBlock.type).toBe('square'); }); it('compound blocks of compound blocks', () => { - const str = `block-beta + const str = `block block aBlock["ABlock"] block @@ -240,7 +240,7 @@ describe('Block diagram', function () { expect(bBlock.type).toBe('square'); }); it('compound blocks with title', () => { - const str = `block-beta + const str = `block block:compoundBlock["Compound block"] columns 1 block2["Block 2"] @@ -265,7 +265,7 @@ describe('Block diagram', function () { expect(block2.type).toBe('square'); }); it('blocks mixed with compound blocks', () => { - const str = `block-beta + const str = `block columns 1 block1["Block 1"] @@ -292,7 +292,7 @@ describe('Block diagram', function () { }); it('Arrow blocks', () => { - const str = `block-beta + const str = `block columns 3 block1["Block 1"] blockArrow<["   "]>(right) @@ -316,7 +316,7 @@ describe('Block diagram', function () { expect(blockArrow.directions).toContain('right'); }); it('Arrow blocks with multiple points', () => { - const str = `block-beta + const str = `block columns 1 A blockArrow<["   "]>(up, down) @@ -339,7 +339,7 @@ describe('Block diagram', function () { expect(blockArrow.directions).not.toContain('right'); }); it('blocks with different widths', () => { - const str = `block-beta + const str = `block columns 3 one["One Slot"] two["Two slots"]:2 @@ -354,7 +354,7 @@ describe('Block diagram', function () { expect(two.widthInColumns).toBe(2); }); it('empty blocks', () => { - const str = `block-beta + const str = `block columns 3 space middle["In the middle"] @@ -373,7 +373,7 @@ describe('Block diagram', function () { expect(middle.label).toBe('In the middle'); }); it('classDef statements applied to a block', () => { - const str = `block-beta + const str = `block classDef black color:#ffffff, fill:#000000; mc["Memcache"] @@ -391,7 +391,7 @@ describe('Block diagram', function () { expect(black.styles[0]).toEqual('color:#ffffff'); }); it('style statements applied to a block', () => { - const str = `block-beta + const str = `block columns 1 B["A wide one in the middle"] style B fill:#f9F,stroke:#333,stroke-width:4px @@ -426,9 +426,9 @@ columns 1 describe('prototype properties', function () { function validateProperty(prop: string) { - expect(() => block.parse(`block-beta\n${prop}`)).not.toThrow(); + expect(() => block.parse(`block\n${prop}`)).not.toThrow(); expect(() => - block.parse(`block-beta\nA; classDef ${prop} color:#ffffff,fill:#000000; class A ${prop}`) + block.parse(`block\nA; classDef ${prop} color:#ffffff,fill:#000000; class A ${prop}`) ).not.toThrow(); } diff --git a/packages/mermaid/src/diagrams/class/parser/class.spec.js b/packages/mermaid/src/diagrams/class/parser/class.spec.js index fe0077a29..7d4922561 100644 --- a/packages/mermaid/src/diagrams/class/parser/class.spec.js +++ b/packages/mermaid/src/diagrams/class/parser/class.spec.js @@ -15,4 +15,12 @@ describe('class diagram', function () { expect(() => parser.parse(`classDiagram\nnamespace ${prop} {\n\tclass A\n}`)).not.toThrow(); }); }); + + describe('backtick escaping', function () { + it('should handle backtick-quoted namespace names', function () { + expect(() => + parser.parse(`classDiagram\nnamespace \`A::B\` {\n\tclass \`IPC::Sender\`\n}`) + ).not.toThrow(); + }); + }); }); diff --git a/packages/mermaid/src/diagrams/class/parser/classDiagram.jison b/packages/mermaid/src/diagrams/class/parser/classDiagram.jison index 83d9bd48e..0f971c8b9 100644 --- a/packages/mermaid/src/diagrams/class/parser/classDiagram.jison +++ b/packages/mermaid/src/diagrams/class/parser/classDiagram.jison @@ -242,6 +242,7 @@ classLabel namespaceName : alphaNumToken { $$=$1; } + | classLiteralName { $$=$1; } | alphaNumToken DOT namespaceName { $$=$1+'.'+$3; } | alphaNumToken namespaceName { $$=$1+$2; } ; diff --git a/packages/mermaid/src/diagrams/common/common.ts b/packages/mermaid/src/diagrams/common/common.ts index 00c9b8313..045a729f7 100644 --- a/packages/mermaid/src/diagrams/common/common.ts +++ b/packages/mermaid/src/diagrams/common/common.ts @@ -33,13 +33,13 @@ function setupDompurifyHooks() { const TEMPORARY_ATTRIBUTE = 'data-temp-href-target'; DOMPurify.addHook('beforeSanitizeAttributes', (node) => { - if (node instanceof Element && node.tagName === 'A' && node.hasAttribute('target')) { + if (node.tagName === 'A' && node.hasAttribute('target')) { node.setAttribute(TEMPORARY_ATTRIBUTE, node.getAttribute('target') ?? ''); } }); DOMPurify.addHook('afterSanitizeAttributes', (node) => { - if (node instanceof Element && node.tagName === 'A' && node.hasAttribute(TEMPORARY_ATTRIBUTE)) { + if (node.tagName === 'A' && node.hasAttribute(TEMPORARY_ATTRIBUTE)) { node.setAttribute('target', node.getAttribute(TEMPORARY_ATTRIBUTE) ?? ''); node.removeAttribute(TEMPORARY_ATTRIBUTE); if (node.getAttribute('target') === '_blank') { @@ -311,9 +311,8 @@ export const hasKatex = (text: string): boolean => (text.match(katexRegex)?.leng * @returns Object containing \{width, height\} */ export const calculateMathMLDimensions = async (text: string, config: MermaidConfig) => { - text = await renderKatex(text, config); const divElem = document.createElement('div'); - divElem.innerHTML = text; + divElem.innerHTML = await renderKatexSanitized(text, config); divElem.id = 'katex-temp'; divElem.style.visibility = 'hidden'; divElem.style.position = 'absolute'; @@ -325,14 +324,7 @@ export const calculateMathMLDimensions = async (text: string, config: MermaidCon return dim; }; -/** - * Attempts to render and return the KaTeX portion of a string with MathML - * - * @param text - The text to test - * @param config - Configuration for Mermaid - * @returns String containing MathML if KaTeX is supported, or an error message if it is not and stylesheets aren't present - */ -export const renderKatex = async (text: string, config: MermaidConfig): Promise => { +const renderKatexUnsanitized = async (text: string, config: MermaidConfig): Promise => { if (!hasKatex(text)) { return text; } @@ -373,6 +365,20 @@ export const renderKatex = async (text: string, config: MermaidConfig): Promise< ); }; +/** + * Attempts to render and return the KaTeX portion of a string with MathML + * + * @param text - The text to test + * @param config - Configuration for Mermaid + * @returns String containing MathML if KaTeX is supported, or an error message if it is not and stylesheets aren't present + */ +export const renderKatexSanitized = async ( + text: string, + config: MermaidConfig +): Promise => { + return sanitizeText(await renderKatexUnsanitized(text, config), config); +}; + export default { getRows, sanitizeText, diff --git a/packages/mermaid/src/diagrams/gantt/ganttDb.js b/packages/mermaid/src/diagrams/gantt/ganttDb.js index 3ae55fb25..b2b5b0566 100644 --- a/packages/mermaid/src/diagrams/gantt/ganttDb.js +++ b/packages/mermaid/src/diagrams/gantt/ganttDb.js @@ -167,7 +167,10 @@ export const getTasks = function () { }; export const isInvalidDate = function (date, dateFormat, excludes, includes) { - if (includes.includes(date.format(dateFormat.trim()))) { + const formattedDate = date.format(dateFormat.trim()); + const dateOnly = date.format('YYYY-MM-DD'); + + if (includes.includes(formattedDate) || includes.includes(dateOnly)) { return false; } if ( @@ -180,7 +183,7 @@ export const isInvalidDate = function (date, dateFormat, excludes, includes) { if (excludes.includes(date.format('dddd').toLowerCase())) { return true; } - return excludes.includes(date.format(dateFormat.trim())); + return excludes.includes(formattedDate) || excludes.includes(dateOnly); }; export const setWeekday = function (txt) { diff --git a/packages/mermaid/src/diagrams/gantt/ganttRenderer.js b/packages/mermaid/src/diagrams/gantt/ganttRenderer.js index f5c8c2e38..9f899a40f 100644 --- a/packages/mermaid/src/diagrams/gantt/ganttRenderer.js +++ b/packages/mermaid/src/diagrams/gantt/ganttRenderer.js @@ -581,17 +581,11 @@ export const draw = function (text, id, version, diagObj) { rectangles .append('rect') - .attr('id', function (d) { - return 'exclude-' + d.start.format('YYYY-MM-DD'); - }) - .attr('x', function (d) { - return timeScale(d.start) + theSidePad; - }) + .attr('id', (d) => 'exclude-' + d.start.format('YYYY-MM-DD')) + .attr('x', (d) => timeScale(d.start.startOf('day')) + theSidePad) .attr('y', conf.gridLineStartPadding) - .attr('width', function (d) { - const renderEnd = d.end.add(1, 'day'); - return timeScale(renderEnd) - timeScale(d.start); - }) + .attr('width', (d) => timeScale(d.end.endOf('day')) - timeScale(d.start.startOf('day'))) + .attr('height', h - theTopPad - conf.gridLineStartPadding) .attr('transform-origin', function (d, i) { return ( @@ -615,9 +609,20 @@ export const draw = function (text, id, version, diagObj) { * @param h */ function makeGrid(theSidePad, theTopPad, w, h) { + const dateFormat = diagObj.db.getDateFormat(); + const userAxisFormat = diagObj.db.getAxisFormat(); + let axisFormat; + if (userAxisFormat) { + axisFormat = userAxisFormat; + } else if (dateFormat === 'D') { + axisFormat = '%d'; + } else { + axisFormat = conf.axisFormat ?? '%Y-%m-%d'; + } + let bottomXAxis = axisBottom(timeScale) .tickSize(-h + theTopPad + conf.gridLineStartPadding) - .tickFormat(timeFormat(diagObj.db.getAxisFormat() || conf.axisFormat || '%Y-%m-%d')); + .tickFormat(timeFormat(axisFormat)); const reTickInterval = /^([1-9]\d*)(millisecond|second|minute|hour|day|week|month)$/; const resultTickInterval = reTickInterval.exec( @@ -669,7 +674,7 @@ export const draw = function (text, id, version, diagObj) { if (diagObj.db.topAxisEnabled() || conf.topAxis) { let topXAxis = axisTop(timeScale) .tickSize(-h + theTopPad + conf.gridLineStartPadding) - .tickFormat(timeFormat(diagObj.db.getAxisFormat() || conf.axisFormat || '%Y-%m-%d')); + .tickFormat(timeFormat(axisFormat)); if (resultTickInterval !== null) { const every = resultTickInterval[1]; diff --git a/packages/mermaid/src/diagrams/pie/pie.spec.ts b/packages/mermaid/src/diagrams/pie/pie.spec.ts index f00906cc5..60fff01e1 100644 --- a/packages/mermaid/src/diagrams/pie/pie.spec.ts +++ b/packages/mermaid/src/diagrams/pie/pie.spec.ts @@ -139,6 +139,32 @@ describe('pie', () => { }).rejects.toThrowError(); }); + it('should handle simple pie with zero slice value', async () => { + await parser.parse(`pie title Default text position: Animal adoption + accTitle: simple pie char demo + accDescr: pie chart with 3 sections: dogs, cats, rats. Most are dogs. + "dogs" : 0 + "rats" : 40.12 + `); + + const sections = db.getSections(); + expect(sections.get('dogs')).toBe(0); + expect(sections.get('rats')).toBe(40.12); + }); + + it('should handle simple pie with negative slice value', async () => { + await expect(async () => { + await parser.parse(`pie title Default text position: Animal adoption + accTitle: simple pie char demo + accDescr: pie chart with 3 sections: dogs, cats, rats. Most are dogs. + "dogs" : -60.67 + "rats" : 40.12 + `); + }).rejects.toThrowError( + '"dogs" has invalid value: -60.67. Negative values are not allowed in pie charts. All slice values must be >= 0.' + ); + }); + it('should handle unsafe properties', async () => { await expect( parser.parse(`pie title Unsafe props test diff --git a/packages/mermaid/src/diagrams/pie/pieDb.ts b/packages/mermaid/src/diagrams/pie/pieDb.ts index 64831495c..083ee97d5 100644 --- a/packages/mermaid/src/diagrams/pie/pieDb.ts +++ b/packages/mermaid/src/diagrams/pie/pieDb.ts @@ -34,6 +34,11 @@ const clear = (): void => { }; const addSection = ({ label, value }: D3Section): void => { + if (value < 0) { + throw new Error( + `"${label}" has invalid value: ${value}. Negative values are not allowed in pie charts. All slice values must be >= 0.` + ); + } if (!sections.has(label)) { sections.set(label, value); log.debug(`added new section: ${label}, with value: ${value}`); diff --git a/packages/mermaid/src/diagrams/pie/pieRenderer.ts b/packages/mermaid/src/diagrams/pie/pieRenderer.ts index a0cdce3df..5b87613ff 100644 --- a/packages/mermaid/src/diagrams/pie/pieRenderer.ts +++ b/packages/mermaid/src/diagrams/pie/pieRenderer.ts @@ -10,20 +10,14 @@ import { cleanAndMerge, parseFontSize } from '../../utils.js'; import type { D3Section, PieDB, Sections } from './pieTypes.js'; const createPieArcs = (sections: Sections): d3.PieArcDatum[] => { - // Compute the position of each group on the pie: + const sum = [...sections.values()].reduce((acc, val) => acc + val, 0); + const pieData: D3Section[] = [...sections.entries()] - .map((element: [string, number]): D3Section => { - return { - label: element[0], - value: element[1], - }; - }) - .sort((a: D3Section, b: D3Section): number => { - return b.value - a.value; - }); - const pie: d3.Pie = d3pie().value( - (d3Section: D3Section): number => d3Section.value - ); + .map(([label, value]) => ({ label, value })) + .filter((d) => (d.value / sum) * 100 >= 1) // Remove values < 1% + .sort((a, b) => b.value - a.value); + + const pie: d3.Pie = d3pie().value((d) => d.value); return pie(pieData); }; @@ -89,13 +83,21 @@ export const draw: DrawDefinition = (text, id, _version, diagObj) => { themeVariables.pie11, themeVariables.pie12, ]; + let sum = 0; + sections.forEach((section) => { + sum += section; + }); + + // Filter out arcs that would render as 0% + const filteredArcs = arcs.filter((datum) => ((datum.data.value / sum) * 100).toFixed(0) !== '0'); + // Set the color scale const color: d3.ScaleOrdinal = scaleOrdinal(myGeneratedColors); // Build the pie chart: each part of the pie is a path that we build using the arc function. group .selectAll('mySlices') - .data(arcs) + .data(filteredArcs) .enter() .append('path') .attr('d', arcGenerator) @@ -104,15 +106,11 @@ export const draw: DrawDefinition = (text, id, _version, diagObj) => { }) .attr('class', 'pieCircle'); - let sum = 0; - sections.forEach((section) => { - sum += section; - }); // Now add the percentage. // Use the centroid method to get the best coordinates. group .selectAll('mySlices') - .data(arcs) + .data(filteredArcs) .enter() .append('text') .text((datum: d3.PieArcDatum): string => { @@ -133,15 +131,20 @@ export const draw: DrawDefinition = (text, id, _version, diagObj) => { .attr('class', 'pieTitleText'); // Add the legends/annotations for each section + const allSectionData: D3Section[] = [...sections.entries()].map(([label, value]) => ({ + label, + value, + })); + const legend = group .selectAll('.legend') - .data(color.domain()) + .data(allSectionData) .enter() .append('g') .attr('class', 'legend') .attr('transform', (_datum, index: number): string => { const height = LEGEND_RECT_SIZE + LEGEND_SPACING; - const offset = (height * color.domain().length) / 2; + const offset = (height * allSectionData.length) / 2; const horizontal = 12 * LEGEND_RECT_SIZE; const vertical = index * height - offset; return 'translate(' + horizontal + ',' + vertical + ')'; @@ -151,20 +154,18 @@ export const draw: DrawDefinition = (text, id, _version, diagObj) => { .append('rect') .attr('width', LEGEND_RECT_SIZE) .attr('height', LEGEND_RECT_SIZE) - .style('fill', color) - .style('stroke', color); + .style('fill', (d) => color(d.label)) + .style('stroke', (d) => color(d.label)); legend - .data(arcs) .append('text') .attr('x', LEGEND_RECT_SIZE + LEGEND_SPACING) .attr('y', LEGEND_RECT_SIZE - LEGEND_SPACING) - .text((datum: d3.PieArcDatum): string => { - const { label, value } = datum.data; + .text((d) => { if (db.getShowData()) { - return `${label} [${value}]`; + return `${d.label} [${d.value}]`; } - return label; + return d.label; }); const longestTextWidth = Math.max( diff --git a/packages/mermaid/src/diagrams/sankey/parser/sankey.jison b/packages/mermaid/src/diagrams/sankey/parser/sankey.jison index 9d66b69a4..d531c438a 100644 --- a/packages/mermaid/src/diagrams/sankey/parser/sankey.jison +++ b/packages/mermaid/src/diagrams/sankey/parser/sankey.jison @@ -27,6 +27,7 @@ TEXTDATA [\u0020-\u0021\u0023-\u002B\u002D-\u007E] %% "sankey-beta" { this.pushState('csv'); return 'SANKEY'; } +"sankey" { this.pushState('csv'); return 'SANKEY'; } <> { return 'EOF' } // match end of file ({CRLF}|{LF}) { return 'NEWLINE' } {COMMA} { return 'COMMA' } diff --git a/packages/mermaid/src/diagrams/sankey/parser/sankey.spec.ts b/packages/mermaid/src/diagrams/sankey/parser/sankey.spec.ts index 007cda6f9..10fc86963 100644 --- a/packages/mermaid/src/diagrams/sankey/parser/sankey.spec.ts +++ b/packages/mermaid/src/diagrams/sankey/parser/sankey.spec.ts @@ -13,7 +13,7 @@ describe('Sankey diagram', function () { sankey.parser.yy.clear(); }); - it('parses csv', () => { + it('parses csv with sankey-beta syntax', () => { const csv = path.resolve(__dirname, './energy.csv'); const data = fs.readFileSync(csv, 'utf8'); const graphDefinition = prepareTextForParsing(cleanupComments('sankey-beta\n\n ' + data)); @@ -21,7 +21,15 @@ describe('Sankey diagram', function () { sankey.parser.parse(graphDefinition); }); - it('allows __proto__ as id', function () { + it('parses csv with sankey syntax', () => { + const csv = path.resolve(__dirname, './energy.csv'); + const data = fs.readFileSync(csv, 'utf8'); + const graphDefinition = prepareTextForParsing(cleanupComments('sankey\n\n ' + data)); + + sankey.parser.parse(graphDefinition); + }); + + it('allows __proto__ as id with sankey-beta syntax', function () { sankey.parser.parse( prepareTextForParsing(`sankey-beta __proto__,A,0.597 @@ -29,5 +37,14 @@ describe('Sankey diagram', function () { `) ); }); + + it('allows __proto__ as id with sankey syntax', function () { + sankey.parser.parse( + prepareTextForParsing(`sankey + __proto__,A,0.597 + A,__proto__,0.403 + `) + ); + }); }); }); diff --git a/packages/mermaid/src/diagrams/sankey/sankeyDetector.ts b/packages/mermaid/src/diagrams/sankey/sankeyDetector.ts index 73c4d1428..589bc9ade 100644 --- a/packages/mermaid/src/diagrams/sankey/sankeyDetector.ts +++ b/packages/mermaid/src/diagrams/sankey/sankeyDetector.ts @@ -3,7 +3,7 @@ import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-a const id = 'sankey'; const detector: DiagramDetector = (txt) => { - return /^\s*sankey-beta/.test(txt); + return /^\s*sankey(-beta)?/.test(txt); }; const loader = async () => { diff --git a/packages/mermaid/src/diagrams/sequence/parser/sequenceDiagram.jison b/packages/mermaid/src/diagrams/sequence/parser/sequenceDiagram.jison index d2e81df5f..2dcadc0bb 100644 --- a/packages/mermaid/src/diagrams/sequence/parser/sequenceDiagram.jison +++ b/packages/mermaid/src/diagrams/sequence/parser/sequenceDiagram.jison @@ -33,7 +33,7 @@ "actor" { this.begin('ID'); return 'participant_actor'; } "create" return 'create'; "destroy" { this.begin('ID'); return 'destroy'; } -[^\<->\->:\n,;]+?([\-]*[^\<->\->:\n,;]+?)*?(?=((?!\n)\s)+"as"(?!\n)\s|[#\n;]|$) { yytext = yytext.trim(); this.begin('ALIAS'); return 'ACTOR'; } +[^<\->\->:\n,;]+?([\-]*[^<\->\->:\n,;]+?)*?(?=((?!\n)\s)+"as"(?!\n)\s|[#\n;]|$) { yytext = yytext.trim(); this.begin('ALIAS'); return 'ACTOR'; } "as" { this.popState(); this.popState(); this.begin('LINE'); return 'AS'; } (?:) { this.popState(); this.popState(); return 'NEWLINE'; } "loop" { this.begin('LINE'); return 'loop'; } @@ -73,7 +73,7 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multili "off" return 'off'; "," return ','; ";" return 'NEWLINE'; -[^\+\<->\->:\n,;]+((?!(\-x|\-\-x|\-\)|\-\-\)))[\-]*[^\+\<->\->:\n,;]+)* { yytext = yytext.trim(); return 'ACTOR'; } +[^+<\->\->:\n,;]+((?!(\-x|\-\-x|\-\)|\-\-\)))[\-]*[^\+<\->\->:\n,;]+)* { yytext = yytext.trim(); return 'ACTOR'; } "->>" return 'SOLID_ARROW'; "<<->>" return 'BIDIRECTIONAL_SOLID_ARROW'; "-->>" return 'DOTTED_ARROW'; diff --git a/packages/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js b/packages/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js index c3b8c2b4a..97833be8f 100644 --- a/packages/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js +++ b/packages/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js @@ -350,6 +350,26 @@ Bob-->Alice-in-Wonderland:I am good thanks!`); expect(messages[1].from).toBe('Bob'); }); + it('should handle equals in participant names', async () => { + const diagram = await Diagram.fromText(` +sequenceDiagram +participant Alice=Wonderland +participant Bob +Alice=Wonderland->Bob:Hello Bob, how are - you? +Bob-->Alice=Wonderland:I am good thanks!`); + + const actors = diagram.db.getActors(); + expect([...actors.keys()]).toEqual(['Alice=Wonderland', 'Bob']); + expect(actors.get('Alice=Wonderland').description).toBe('Alice=Wonderland'); + expect(actors.get('Bob').description).toBe('Bob'); + + const messages = diagram.db.getMessages(); + + expect(messages.length).toBe(2); + expect(messages[0].from).toBe('Alice=Wonderland'); + expect(messages[1].from).toBe('Bob'); + }); + it('should alias participants', async () => { const diagram = await Diagram.fromText(` sequenceDiagram diff --git a/packages/mermaid/src/diagrams/sequence/svgDraw.js b/packages/mermaid/src/diagrams/sequence/svgDraw.js index 04ccd8a84..18fd2d034 100644 --- a/packages/mermaid/src/diagrams/sequence/svgDraw.js +++ b/packages/mermaid/src/diagrams/sequence/svgDraw.js @@ -1,8 +1,12 @@ -import common, { calculateMathMLDimensions, hasKatex, renderKatex } from '../common/common.js'; -import * as svgDrawCommon from '../common/svgDrawCommon.js'; -import { ZERO_WIDTH_SPACE, parseFontSize } from '../../utils.js'; import { sanitizeUrl } from '@braintree/sanitize-url'; import * as configApi from '../../config.js'; +import { ZERO_WIDTH_SPACE, parseFontSize } from '../../utils.js'; +import common, { + calculateMathMLDimensions, + hasKatex, + renderKatexSanitized, +} from '../common/common.js'; +import * as svgDrawCommon from '../common/svgDrawCommon.js'; export const ACTOR_TYPE_WIDTH = 18 * 2; const TOP_ACTOR_CLASS = 'actor-top'; @@ -87,13 +91,13 @@ const popupMenuToggle = function (popId) { export const drawKatex = async function (elem, textData, msgModel = null) { let textElem = elem.append('foreignObject'); - const lines = await renderKatex(textData.text, configApi.getConfig()); + const linesSanitized = await renderKatexSanitized(textData.text, configApi.getConfig()); const divElem = textElem .append('xhtml:div') .attr('style', 'width: fit-content;') .attr('xmlns', 'http://www.w3.org/1999/xhtml') - .html(lines); + .html(linesSanitized); const dim = divElem.node().getBoundingClientRect(); textElem.attr('height', Math.round(dim.height)).attr('width', Math.round(dim.width)); @@ -965,7 +969,7 @@ const _drawTextCandidateFunc = (function () { .append('div') .style('text-align', 'center') .style('vertical-align', 'middle') - .html(await renderKatex(content, configApi.getConfig())); + .html(await renderKatexSanitized(content, configApi.getConfig())); byTspan(content, s, x, y, width, height, textAttrs, conf); _setTextAttrs(text, textAttrs); diff --git a/packages/mermaid/src/diagrams/xychart/parser/xychart.jison b/packages/mermaid/src/diagrams/xychart/parser/xychart.jison index 987132d17..33575b946 100644 --- a/packages/mermaid/src/diagrams/xychart/parser/xychart.jison +++ b/packages/mermaid/src/diagrams/xychart/parser/xychart.jison @@ -30,6 +30,7 @@ [^\}]* { return "acc_descr_multiline_value"; } "xychart-beta" {return 'XYCHART';} +"xychart" {return 'XYCHART';} (?:"vertical"|"horizontal") {return 'CHART_ORIENTATION'} "x-axis" { this.pushState("axis_data"); return "X_AXIS"; } diff --git a/packages/mermaid/src/diagrams/xychart/parser/xychart.jison.spec.ts b/packages/mermaid/src/diagrams/xychart/parser/xychart.jison.spec.ts index d7de15f66..409972828 100644 --- a/packages/mermaid/src/diagrams/xychart/parser/xychart.jison.spec.ts +++ b/packages/mermaid/src/diagrams/xychart/parser/xychart.jison.spec.ts @@ -33,44 +33,44 @@ describe('Testing xychart jison file', () => { clearMocks(); }); - it('should throw error if xychart-beta text is not there', () => { - const str = 'xychart-beta-1'; + it('should throw error if xychart text is not there', () => { + const str = 'xychart-1'; expect(parserFnConstructor(str)).toThrow(); }); it('should not throw error if only xychart is there', () => { - const str = 'xychart-beta'; + const str = 'xychart'; expect(parserFnConstructor(str)).not.toThrow(); }); it('parse title of the chart within "', () => { - const str = 'xychart-beta \n title "This is a title"'; + const str = 'xychart \n title "This is a title"'; expect(parserFnConstructor(str)).not.toThrow(); expect(mockDB.setDiagramTitle).toHaveBeenCalledWith('This is a title'); }); it('parse title of the chart without "', () => { - const str = 'xychart-beta \n title oneLinertitle'; + const str = 'xychart \n title oneLinertitle'; expect(parserFnConstructor(str)).not.toThrow(); expect(mockDB.setDiagramTitle).toHaveBeenCalledWith('oneLinertitle'); }); it('parse chart orientation', () => { - const str = 'xychart-beta vertical'; + const str = 'xychart vertical'; expect(parserFnConstructor(str)).not.toThrow(); expect(mockDB.setOrientation).toHaveBeenCalledWith('vertical'); }); it('parse chart orientation with spaces', () => { - let str = 'xychart-beta horizontal '; + let str = 'xychart horizontal '; expect(parserFnConstructor(str)).not.toThrow(); expect(mockDB.setOrientation).toHaveBeenCalledWith('horizontal'); - str = 'xychart-beta abc'; + str = 'xychart abc'; expect(parserFnConstructor(str)).toThrow(); }); it('parse x-axis', () => { - const str = 'xychart-beta \nx-axis xAxisName\n'; + const str = 'xychart \nx-axis xAxisName\n'; expect(parserFnConstructor(str)).not.toThrow(); expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', @@ -79,7 +79,7 @@ describe('Testing xychart jison file', () => { }); it('parse x-axis with axis name without "', () => { - const str = 'xychart-beta \nx-axis xAxisName \n'; + const str = 'xychart \nx-axis xAxisName \n'; expect(parserFnConstructor(str)).not.toThrow(); expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', @@ -88,7 +88,7 @@ describe('Testing xychart jison file', () => { }); it('parse x-axis with axis name with "', () => { - const str = 'xychart-beta \n x-axis "xAxisName has space"\n'; + const str = 'xychart \n x-axis "xAxisName has space"\n'; expect(parserFnConstructor(str)).not.toThrow(); expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName has space', @@ -97,7 +97,7 @@ describe('Testing xychart jison file', () => { }); it('parse x-axis with axis name with " with spaces', () => { - const str = 'xychart-beta \n x-axis " xAxisName has space " \n'; + const str = 'xychart \n x-axis " xAxisName has space " \n'; expect(parserFnConstructor(str)).not.toThrow(); expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: ' xAxisName has space ', @@ -106,7 +106,7 @@ describe('Testing xychart jison file', () => { }); it('parse x-axis with axis name and range data', () => { - const str = 'xychart-beta \nx-axis xAxisName 45.5 --> 33 \n'; + const str = 'xychart \nx-axis xAxisName 45.5 --> 33 \n'; expect(parserFnConstructor(str)).not.toThrow(); expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', @@ -115,11 +115,11 @@ describe('Testing xychart jison file', () => { expect(mockDB.setXAxisRangeData).toHaveBeenCalledWith(45.5, 33); }); it('parse x-axis throw error for invalid range data', () => { - const str = 'xychart-beta \nx-axis xAxisName aaa --> 33 \n'; + const str = 'xychart \nx-axis xAxisName aaa --> 33 \n'; expect(parserFnConstructor(str)).toThrow(); }); it('parse x-axis with axis name and range data with only decimal part', () => { - const str = 'xychart-beta \nx-axis xAxisName 45.5 --> .34 \n'; + const str = 'xychart \nx-axis xAxisName 45.5 --> .34 \n'; expect(parserFnConstructor(str)).not.toThrow(); expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', @@ -129,7 +129,7 @@ describe('Testing xychart jison file', () => { }); it('parse x-axis without axis name and range data', () => { - const str = 'xychart-beta \nx-axis 45.5 --> 1.34 \n'; + const str = 'xychart \nx-axis 45.5 --> 1.34 \n'; expect(parserFnConstructor(str)).not.toThrow(); expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: '', @@ -139,7 +139,7 @@ describe('Testing xychart jison file', () => { }); it('parse x-axis with axis name and category data', () => { - const str = 'xychart-beta \nx-axis xAxisName [ "cat1" , cat2a ] \n '; + const str = 'xychart \nx-axis xAxisName [ "cat1" , cat2a ] \n '; expect(parserFnConstructor(str)).not.toThrow(); expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', @@ -155,7 +155,7 @@ describe('Testing xychart jison file', () => { }); it('parse x-axis without axis name and category data', () => { - const str = 'xychart-beta \nx-axis [ "cat1" , cat2a ] \n '; + const str = 'xychart \nx-axis [ "cat1" , cat2a ] \n '; expect(parserFnConstructor(str)).not.toThrow(); expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: '', @@ -171,14 +171,14 @@ describe('Testing xychart jison file', () => { }); it('parse x-axis throw error if unbalanced bracket', () => { - let str = 'xychart-beta \nx-axis xAxisName [ "cat1" [ cat2a ] \n '; + let str = 'xychart \nx-axis xAxisName [ "cat1" [ cat2a ] \n '; expect(parserFnConstructor(str)).toThrow(); - str = 'xychart-beta \nx-axis xAxisName [ "cat1" , cat2a ] ] \n '; + str = 'xychart \nx-axis xAxisName [ "cat1" , cat2a ] ] \n '; expect(parserFnConstructor(str)).toThrow(); }); it('parse x-axis complete variant 1', () => { - const str = `xychart-beta \n x-axis "this is x axis" [category1, "category 2", category3]\n`; + const str = `xychart \n x-axis "this is x axis" [category1, "category 2", category3]\n`; expect(parserFnConstructor(str)).not.toThrow(); expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'this is x axis', type: 'text' }); expect(mockDB.setXAxisBand).toHaveBeenCalledWith([ @@ -189,8 +189,7 @@ describe('Testing xychart jison file', () => { }); it('parse x-axis complete variant 2', () => { - const str = - 'xychart-beta \nx-axis xAxisName [ "cat1 with space" , cat2 , cat3] \n '; + const str = 'xychart \nx-axis xAxisName [ "cat1 with space" , cat2 , cat3] \n '; expect(parserFnConstructor(str)).not.toThrow(); expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' }); expect(mockDB.setXAxisBand).toHaveBeenCalledWith([ @@ -202,7 +201,7 @@ describe('Testing xychart jison file', () => { it('parse x-axis complete variant 3', () => { const str = - 'xychart-beta \nx-axis xAxisName [ "cat1 with space" , cat2 asdf , cat3] \n '; + 'xychart \nx-axis xAxisName [ "cat1 with space" , cat2 asdf , cat3] \n '; expect(parserFnConstructor(str)).not.toThrow(); expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' }); expect(mockDB.setXAxisBand).toHaveBeenCalledWith([ @@ -213,17 +212,17 @@ describe('Testing xychart jison file', () => { }); it('parse y-axis with axis name', () => { - const str = 'xychart-beta \ny-axis yAxisName\n'; + const str = 'xychart \ny-axis yAxisName\n'; expect(parserFnConstructor(str)).not.toThrow(); expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' }); }); it('parse y-axis with axis name with spaces', () => { - const str = 'xychart-beta \ny-axis yAxisName \n'; + const str = 'xychart \ny-axis yAxisName \n'; expect(parserFnConstructor(str)).not.toThrow(); expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' }); }); it('parse y-axis with axis name with "', () => { - const str = 'xychart-beta \n y-axis "yAxisName has space"\n'; + const str = 'xychart \n y-axis "yAxisName has space"\n'; expect(parserFnConstructor(str)).not.toThrow(); expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName has space', @@ -231,7 +230,7 @@ describe('Testing xychart jison file', () => { }); }); it('parse y-axis with axis name with " and spaces', () => { - const str = 'xychart-beta \n y-axis " yAxisName has space " \n'; + const str = 'xychart \n y-axis " yAxisName has space " \n'; expect(parserFnConstructor(str)).not.toThrow(); expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: ' yAxisName has space ', @@ -239,39 +238,39 @@ describe('Testing xychart jison file', () => { }); }); it('parse y-axis with axis name with range data', () => { - const str = 'xychart-beta \ny-axis yAxisName 45.5 --> 33 \n'; + const str = 'xychart \ny-axis yAxisName 45.5 --> 33 \n'; expect(parserFnConstructor(str)).not.toThrow(); expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' }); expect(mockDB.setYAxisRangeData).toHaveBeenCalledWith(45.5, 33); }); it('parse y-axis without axis name with range data', () => { - const str = 'xychart-beta \ny-axis 45.5 --> 33 \n'; + const str = 'xychart \ny-axis 45.5 --> 33 \n'; expect(parserFnConstructor(str)).not.toThrow(); expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: '', type: 'text' }); expect(mockDB.setYAxisRangeData).toHaveBeenCalledWith(45.5, 33); }); it('parse y-axis with axis name with range data with only decimal part', () => { - const str = 'xychart-beta \ny-axis yAxisName 45.5 --> .33 \n'; + const str = 'xychart \ny-axis yAxisName 45.5 --> .33 \n'; expect(parserFnConstructor(str)).not.toThrow(); expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' }); expect(mockDB.setYAxisRangeData).toHaveBeenCalledWith(45.5, 0.33); }); it('parse y-axis throw error for invalid number in range data', () => { - const str = 'xychart-beta \ny-axis yAxisName 45.5 --> abc \n'; + const str = 'xychart \ny-axis yAxisName 45.5 --> abc \n'; expect(parserFnConstructor(str)).toThrow(); }); it('parse y-axis throws error if range data is passed', () => { - const str = 'xychart-beta \ny-axis yAxisName [ 45.3, 33 ] \n'; + const str = 'xychart \ny-axis yAxisName [ 45.3, 33 ] \n'; expect(parserFnConstructor(str)).toThrow(); }); it('parse both axis at once', () => { - const str = 'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n'; + const str = 'xychart\nx-axis xAxisName\ny-axis yAxisName\n'; expect(parserFnConstructor(str)).not.toThrow(); expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' }); expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' }); }); it('parse line Data', () => { - const str = 'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line lineTitle [23, 45, 56.6]'; + const str = 'xychart\nx-axis xAxisName\ny-axis yAxisName\n line lineTitle [23, 45, 56.6]'; expect(parserFnConstructor(str)).not.toThrow(); expect(mockDB.setLineData).toHaveBeenCalledWith( { text: 'lineTitle', type: 'text' }, @@ -282,7 +281,7 @@ describe('Testing xychart jison file', () => { }); it('parse line Data with spaces and +,- symbols', () => { const str = - 'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ +23 , -45 , 56.6 ] '; + 'xychart\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ +23 , -45 , 56.6 ] '; expect(parserFnConstructor(str)).not.toThrow(); expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' }); expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' }); @@ -292,8 +291,7 @@ describe('Testing xychart jison file', () => { ); }); it('parse line Data without title', () => { - const str = - 'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line [ +23 , -45 , 56.6 , .33] '; + const str = 'xychart\nx-axis xAxisName\ny-axis yAxisName\n line [ +23 , -45 , 56.6 , .33] '; expect(parserFnConstructor(str)).not.toThrow(); expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' }); expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' }); @@ -304,34 +302,32 @@ describe('Testing xychart jison file', () => { }); it('parse line Data throws error unbalanced brackets', () => { let str = - 'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ +23 [ -45 , 56.6 ] '; + 'xychart\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ +23 [ -45 , 56.6 ] '; expect(parserFnConstructor(str)).toThrow(); str = - 'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ +23 , -45 ] 56.6 ] '; + 'xychart\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ +23 , -45 ] 56.6 ] '; expect(parserFnConstructor(str)).toThrow(); }); it('parse line Data throws error if data is not provided', () => { - const str = 'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" '; + const str = 'xychart\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" '; expect(parserFnConstructor(str)).toThrow(); }); it('parse line Data throws error if data is empty', () => { - const str = - 'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ ] '; + const str = 'xychart\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ ] '; expect(parserFnConstructor(str)).toThrow(); }); it('parse line Data throws error if , is not in proper', () => { const str = - 'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ +23 , , -45 , 56.6 ] '; + 'xychart\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ +23 , , -45 , 56.6 ] '; expect(parserFnConstructor(str)).toThrow(); }); it('parse line Data throws error if not number', () => { const str = - 'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ +23 , -4aa5 , 56.6 ] '; + 'xychart\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ +23 , -4aa5 , 56.6 ] '; expect(parserFnConstructor(str)).toThrow(); }); it('parse bar Data', () => { - const str = - 'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar barTitle [23, 45, 56.6, .22]'; + const str = 'xychart\nx-axis xAxisName\ny-axis yAxisName\n bar barTitle [23, 45, 56.6, .22]'; expect(parserFnConstructor(str)).not.toThrow(); expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' }); expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' }); @@ -342,7 +338,7 @@ describe('Testing xychart jison file', () => { }); it('parse bar Data spaces and +,- symbol', () => { const str = - 'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ +23 , -45 , 56.6 ] '; + 'xychart\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ +23 , -45 , 56.6 ] '; expect(parserFnConstructor(str)).not.toThrow(); expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' }); expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' }); @@ -352,8 +348,7 @@ describe('Testing xychart jison file', () => { ); }); it('parse bar Data without plot title', () => { - const str = - 'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar [ +23 , -45 , 56.6 ] '; + const str = 'xychart\nx-axis xAxisName\ny-axis yAxisName\n bar [ +23 , -45 , 56.6 ] '; expect(parserFnConstructor(str)).not.toThrow(); expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' }); expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' }); @@ -361,34 +356,34 @@ describe('Testing xychart jison file', () => { }); it('parse bar should throw for unbalanced brackets', () => { let str = - 'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ +23 [ -45 , 56.6 ] '; + 'xychart\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ +23 [ -45 , 56.6 ] '; expect(parserFnConstructor(str)).toThrow(); str = - 'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ +23 , -45 ] 56.6 ] '; + 'xychart\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ +23 , -45 ] 56.6 ] '; expect(parserFnConstructor(str)).toThrow(); }); it('parse bar should throw error if data is not provided', () => { - const str = 'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" '; + const str = 'xychart\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" '; expect(parserFnConstructor(str)).toThrow(); }); it('parse bar should throw error if data is empty', () => { const str = - 'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ ] '; + 'xychart\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ ] '; expect(parserFnConstructor(str)).toThrow(); }); it('parse bar should throw error if comma is not proper', () => { const str = - 'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ +23 , , -45 , 56.6 ] '; + 'xychart\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ +23 , , -45 , 56.6 ] '; expect(parserFnConstructor(str)).toThrow(); }); it('parse bar should throw error if number is not passed', () => { const str = - 'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ +23 , -4aa5 , 56.6 ] '; + 'xychart\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ +23 , -4aa5 , 56.6 ] '; expect(parserFnConstructor(str)).toThrow(); }); it('parse multiple bar and line variant 1', () => { const str = - 'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar barTitle1 [23, 45, 56.6] \n line lineTitle1 [11, 45.5, 67, 23] \n bar barTitle2 [13, 42, 56.89] \n line lineTitle2 [45, 99, 012]'; + 'xychart\nx-axis xAxisName\ny-axis yAxisName\n bar barTitle1 [23, 45, 56.6] \n line lineTitle1 [11, 45.5, 67, 23] \n bar barTitle2 [13, 42, 56.89] \n line lineTitle2 [45, 99, 012]'; expect(parserFnConstructor(str)).not.toThrow(); expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' }); expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' }); @@ -411,8 +406,8 @@ describe('Testing xychart jison file', () => { }); it('parse multiple bar and line variant 2', () => { const str = ` - xychart-beta horizontal - title Basic xychart + xychart horizontal + title "Basic xychart" x-axis "this is x axis" [category1, "category 2", category3] y-axis yaxisText 10 --> 150 bar barTitle1 [23, 45, 56.6] diff --git a/packages/mermaid/src/diagrams/xychart/xychartDetector.ts b/packages/mermaid/src/diagrams/xychart/xychartDetector.ts index 08be05b01..3a848cd7f 100644 --- a/packages/mermaid/src/diagrams/xychart/xychartDetector.ts +++ b/packages/mermaid/src/diagrams/xychart/xychartDetector.ts @@ -7,7 +7,7 @@ import type { const id = 'xychart'; const detector: DiagramDetector = (txt) => { - return /^\s*xychart-beta/.test(txt); + return /^\s*xychart(-beta)?/.test(txt); }; const loader: DiagramLoader = async () => { diff --git a/packages/mermaid/src/docs/.vitepress/components/EditorSelectionModal.vue b/packages/mermaid/src/docs/.vitepress/components/EditorSelectionModal.vue index e41a7096d..2334d446f 100644 --- a/packages/mermaid/src/docs/.vitepress/components/EditorSelectionModal.vue +++ b/packages/mermaid/src/docs/.vitepress/components/EditorSelectionModal.vue @@ -9,56 +9,136 @@ interface Feature { interface EditorColumn { title: string; description: string; - redirectUrl: string; + redBarText?: string; + redirectUrl?: string; + buttonText?: string; highlighted?: boolean; + proTrialUrl?: string; + proTrialButtonText?: string; features: Feature[]; + isButtonMargined?: boolean; } -const editorColumns: EditorColumn[] = [ - { - title: 'Playground', - description: 'Basic features, no login', - redirectUrl: - 'https://www.mermaidchart.com/play?utm_source=mermaid_js&utm_medium=editor_selection&utm_campaign=playground', - features: [ - { iconUrl: '/icons/public.svg', featureName: 'Diagram stored in URL' }, - { iconUrl: '/icons/terminal.svg', featureName: 'Code editor' }, - { iconUrl: '/icons/whiteboard.svg', featureName: 'Whiteboard' }, - ], - }, - { - title: 'Free', - description: 'Advanced features, free account', - redirectUrl: - 'https://www.mermaidchart.com/app/sign-up?utm_source=mermaid_js&utm_medium=editor_selection&utm_campaign=mermaid_chart&redirect=%2Fapp%2Fdiagrams%2Fnew', - highlighted: true, - features: [ - { iconUrl: '/icons/folder.svg', featureName: 'Storage' }, - { iconUrl: '/icons/terminal.svg', featureName: 'Code editor' }, - { iconUrl: '/icons/ai-diagram.svg', featureName: 'AI diagram generator' }, - { iconUrl: '/icons/whiteboard.svg', featureName: 'Whiteboard' }, - { iconUrl: '/icons/group.svg', featureName: 'Teams' }, - { iconUrl: '/icons/groups.svg', featureName: 'Multi-user editing' }, - { iconUrl: '/icons/ai-repair.svg', featureName: 'AI diagram repair' }, - { iconUrl: '/icons/version-history.svg', featureName: 'Version history' }, - { iconUrl: '/icons/comment.svg', featureName: 'Comments' }, - { iconUrl: '/icons/presentation.svg', featureName: 'Presentations' }, - { iconUrl: '/icons/plugins.svg', featureName: 'Advanced Plugins' }, - ], - }, - { - title: 'Open Source', - description: 'Code only, no login', - redirectUrl: 'https://mermaid.live/edit', - features: [ - { iconUrl: '/icons/public.svg', featureName: 'Diagram stored in URL' }, - { iconUrl: '/icons/terminal.svg', featureName: 'Code editor' }, - { iconUrl: '/icons/open-source.svg', featureName: 'Open source' }, - { iconUrl: '/icons/version-history.svg', featureName: 'Version history' }, - ], - }, +const mermaidChartFeatures: Feature[] = [ + { iconUrl: '/icons/folder.svg', featureName: 'Storage' }, + { iconUrl: '/icons/terminal.svg', featureName: 'Code editor' }, + { iconUrl: '/icons/ai-diagram.svg', featureName: 'AI diagram generator' }, + { iconUrl: '/icons/whiteboard.svg', featureName: 'Whiteboard' }, + { iconUrl: '/icons/group.svg', featureName: 'Teams' }, + { iconUrl: '/icons/groups.svg', featureName: 'Multi-user editing' }, + { iconUrl: '/icons/ai-repair.svg', featureName: 'AI diagram repair' }, + { iconUrl: '/icons/version-history.svg', featureName: 'Version history' }, + { iconUrl: '/icons/comment.svg', featureName: 'Comments' }, + { iconUrl: '/icons/presentation.svg', featureName: 'Presentations' }, + { iconUrl: '/icons/plugins.svg', featureName: 'Advanced plugins' }, ]; +const openSourceFeatures: Feature[] = [ + { iconUrl: '/icons/public.svg', featureName: 'Diagram stored in URL' }, + { iconUrl: '/icons/terminal.svg', featureName: 'Code editor' }, + { iconUrl: '/icons/open-source.svg', featureName: 'Open source' }, + { iconUrl: '/icons/version-history.svg', featureName: 'Version history' }, +]; + +const playgroundFeatures: Feature[] = [ + { iconUrl: '/icons/public.svg', featureName: 'Diagram stored in URL' }, + { iconUrl: '/icons/terminal.svg', featureName: 'Code editor' }, + { iconUrl: '/icons/whiteboard.svg', featureName: 'Whiteboard' }, +]; + +const editorColumnVariants: EditorColumn[][] = [ + [ + { + title: 'Playground', + description: 'Basic features, no login', + redirectUrl: + 'https://www.mermaidchart.com/app/sign-up?utm_source=mermaid_js&utm_medium=3_editor_selection_A&utm_campaign=start_playground', + buttonText: 'Start free', + features: playgroundFeatures, + }, + { + title: 'Free or Pro', + description: 'Advanced features, Free or Pro account', + proTrialUrl: + 'https://www.mermaidchart.com/app/sign-up?utm_source=mermaid_js&utm_medium=3_editor_selection_A&utm_campaign=start_free', + proTrialButtonText: 'Start free', + highlighted: true, + redBarText: 'Best for collaboration', + features: mermaidChartFeatures, + }, + { + title: 'Open Source', + description: 'Code only, no login', + redirectUrl: 'https://mermaid.live/edit', + buttonText: 'Start free', + features: openSourceFeatures, + }, + ], + [ + { + title: 'Mermaid Pro', + description: 'Unlock AI and real-time collaboration', + redirectUrl: + 'https://www.mermaidchart.com/app/sign-up?utm_source=mermaid_js&utm_medium=editor_selection_B&utm_campaign=start_free', + buttonText: 'Start Free', + highlighted: true, + redBarText: 'Recommended', + proTrialButtonText: 'Start Pro trial', + proTrialUrl: + 'https://www.mermaidchart.com/app/sign-up?utm_source=mermaid_js&utm_medium=editor_selection_B&utm_campaign=start_trial&redirect=%2Fapp%2Fuser%2Fbilling%2Fcheckout%3FisFromMermaid%3Dtrue', + features: mermaidChartFeatures, + }, + { + title: 'Open Source', + description: 'Code only, no login', + buttonText: 'Start free', + redirectUrl: 'https://mermaid.live/edit', + isButtonMargined: true, + features: openSourceFeatures, + }, + ], + [ + { + title: 'Mermaid Pro', + description: 'Unlock AI and real-time collaboration', + highlighted: true, + redBarText: 'Recommended', + proTrialButtonText: 'Start free trial', + proTrialUrl: + 'https://www.mermaidchart.com/app/sign-up?utm_source=mermaid_js&utm_medium=editor_selection_C&utm_campaign=start_trial&redirect=%2Fapp%2Fuser%2Fbilling%2Fcheckout%3FisFromMermaid%3Dtrue', + features: mermaidChartFeatures, + }, + { + title: 'Open Source', + description: 'Code only, no login', + buttonText: 'Start free', + redirectUrl: 'https://mermaid.live/edit', + features: openSourceFeatures, + }, + ], + [ + { + title: 'Mermaid Pro', + description: 'Unlock AI and real-time collaboration', + highlighted: true, + redBarText: 'Recommended', + proTrialButtonText: 'Start free', + proTrialUrl: + 'https://www.mermaidchart.com/app/sign-up?utm_source=mermaid_js&utm_medium=editor_selection_D&utm_campaign=start_free', + features: mermaidChartFeatures, + }, + { + title: 'Open Source', + description: 'Code only, no login', + redirectUrl: 'https://mermaid.live/edit', + buttonText: 'Start free', + features: openSourceFeatures, + }, + ], +]; + +const editorColumns = editorColumnVariants[Math.floor(Math.random() * editorColumnVariants.length)]; + const isVisible = ref(false); const handleMouseDown = (e: MouseEvent) => { @@ -84,44 +164,53 @@ onUnmounted(() => {