Compare commits

..

158 Commits

Author SHA1 Message Date
autofix-ci[bot]
23fd1c59e6 [autofix.ci] apply automated fixes 2025-08-25 01:07:37 +00:00
renovate[bot]
ee5969bc1e fix(deps): update all patch dependencies 2025-08-25 01:02:12 +00:00
Shubham P
29886b8dd4 Merge pull request #6886 from mermaid-js/6721/Bidirectional-arrows--render-incorrectly-with-autonumber-in-sequence-diagrams
6721: Correct rendering of bidirectional arrows with auto number
2025-08-21 15:57:22 +00:00
darshanr0107
e0b45c2d2b chore: added changeset
on-behalf-of: @Mermaid-Chart <hello@mermaidchart.com>
2025-08-21 19:15:30 +05:30
darshanr0107
d4c76968e9 fix: correct rendering of bidirectional arrows with autonumber
on-behalf-of: @Mermaid-Chart <hello@mermaidchart.com>
2025-08-21 19:09:39 +05:30
Sidharth Vinod
7171237b96 Merge pull request #6865 from mermaid-js/renovate/peter-evans-create-pull-request-digest
chore(deps): update peter-evans/create-pull-request digest to cb4d3bf
2025-08-20 00:07:42 +05:30
Shubham P
066883f4cd Merge branch 'develop' into renovate/peter-evans-create-pull-request-digest 2025-08-19 19:01:50 +05:30
Sidharth Vinod
96778f7789 Merge pull request #6880 from mermaid-js/changeset-release/master
Version Packages
2025-08-19 13:33:48 +05:30
github-actions[bot]
d4c058bd56 Version Packages 2025-08-19 08:02:22 +00:00
Sidharth Vinod
b638a0a9c1 temp: Remove peerDeps from examples 2025-08-19 13:29:58 +05:30
Sidharth Vinod
fd9aa36c77 chore: Update peerDependencies for examples 2025-08-19 13:22:32 +05:30
Sidharth Vinod
46a9f1b31e temp: Disable cspell check as it's blocking release 2025-08-19 13:11:21 +05:30
Sidharth Vinod
83c6224cc0 Merge pull request #6878 from mermaid-js/develop
Pre Release
2025-08-19 13:06:56 +05:30
Sidharth Vinod
d8161b1923 fix: move fourcube to contributor 2025-08-19 13:05:44 +05:30
Sidharth Vinod
8223141af9 chore: add fourcube to cspell 2025-08-19 13:04:47 +05:30
Sidharth Vinod
99f98a6876 Merge pull request #6877 from mermaid-js/update-timings
Update E2E Timings
2025-08-19 13:01:41 +05:30
github-actions[bot]
ef28f548df chore: update E2E timings 2025-08-19 04:12:32 +00:00
Sidharth Vinod
e448c53b53 Merge pull request #6876 from mermaid-js/develop
Pre Release
2025-08-18 19:47:51 +05:30
Sidharth Vinod
cad144734d chore: ignore redmine.org in linkchecker 2025-08-18 17:55:32 +05:30
Sidharth Vinod
5e57f22e23 Merge pull request #6875 from mermaid-js/sidv/fixDev
chore: just something to let autofix run
2025-08-18 17:43:25 +05:30
Sidharth Vinod
fc2c32603d fix: Config handling
Co-authored-by: Saurabh Gore <saurabh@mermaidchart.com>
2025-08-18 17:26:01 +05:30
autofix-ci[bot]
8c7da5af56 [autofix.ci] apply automated fixes 2025-08-18 11:52:01 +00:00
Sidharth Vinod
4b89af3aca chore: just something to let autofix run 2025-08-18 17:16:32 +05:30
autofix-ci[bot]
c534d3d364 [autofix.ci] apply automated fixes 2025-08-18 11:46:12 +00:00
renovate[bot]
4db72f5357 chore(deps): update peter-evans/create-pull-request digest to cb4d3bf 2025-08-18 11:31:20 +00:00
Sidharth Vinod
2aa8330279 Merge commit from fork
fix: Sanitize icons and icon labels
2025-08-18 17:00:40 +05:30
Sidharth Vinod
803e2e14be Merge remote-tracking branch 'upstream/develop' into advisory-fix-1
* upstream/develop: (68 commits)
  fix: sanitize addHtmlLabel in createLabel
  docs(integrations): update Tiki to Tiki Wiki CMS Groupware community in list cms/ecm to avoid confusion
  updated lock file
  #6856 Exposing elk configuration forceNodeModelOrder and considerModelOrder to the mermaid configuration
  chore: Modify changeset
  Update .changeset/strong-laws-confess.md
  fix: fallback to raw text instead of rendering empty boxes when `htmlLabels: false`
  chore: Modify changeset
  [autofix.ci] apply automated fixes
  test: Add E2E test for unsupported markdown
  Create strong-laws-confess.md
  fix: Remove data loss when unsupported markdown is encountered
  Apply suggestion from @sidharthv96
  Add changeset and integration test
  chore: update E2E timings
  Make elk not force model order, but strongly consider it instead
  chore(deps): update peter-evans/create-pull-request digest to 1310d7d
  added changeset
  Fix border style for hand drawn shapes
  test: Verify label is sanitized
  ...
2025-08-18 16:59:44 +05:30
Sidharth Vinod
685516a85e Merge commit from fork
fix: Sanitize KATEX blocks
2025-08-18 16:57:11 +05:30
Sidharth Vinod
880f7454a3 fix: sanitize addHtmlLabel in createLabel
Co-authored-by: Chris Grieger <chris@scolp.de>
2025-08-18 16:53:20 +05:30
Sidharth Vinod
1f46c9e9bb Merge pull request #6861 from Baraka24/docs/6339_update-tiki-in-integrations-community-list
docs(integrations): update Tiki to Tiki Wiki CMS Groupware community in list cms/ecm to avoid confusion
2025-08-16 18:46:37 +00:00
Baraka Kinywa
ec7099dc27 docs(integrations): update Tiki to Tiki Wiki CMS Groupware community in list cms/ecm to avoid confusion 2025-08-16 10:20:05 +02:00
Sidharth Vinod
e6ee145edf Merge pull request #6857 from mermaid-js/elk-exposing-considerModelOrder-to-config
Exposing elk configuration forceNodeModelOrder and considerMode…
2025-08-14 11:18:58 +00:00
Knut Sveidqvist
5cc264feb7 updated lock file 2025-08-14 13:05:40 +02:00
Alois Klink
690cc73259 Merge pull request #6855 from mermaid-js/sidv/showRawData
fix: fallback to raw text instead of rendering *Unsupported markdown*
2025-08-14 11:01:58 +00:00
Knut Sveidqvist
b9ef683fb6 #6856 Exposing elk configuration forceNodeModelOrder and considerModelOrder to the mermaid configuration 2025-08-14 12:56:20 +02:00
Sidharth Vinod
6a6289f2aa chore: Modify changeset 2025-08-14 16:18:45 +05:30
Sidharth Vinod
accb4c6369 Update .changeset/strong-laws-confess.md
Co-authored-by: Alois Klink <alois@aloisklink.com>
2025-08-14 03:47:30 -07:00
Sidharth Vinod
52be254ad3 fix: fallback to raw text instead of rendering empty boxes when htmlLabels: false 2025-08-14 16:17:04 +05:30
Sidharth Vinod
9c071a9064 chore: Modify changeset
Co-authored-by: Alois Klink <alois@mermaidchart.com>
2025-08-14 15:47:29 +05:30
Knut Sveidqvist
91d7229f1b Merge pull request #6849 from anderium/bug/6647_fix-crossing-regression-while-keeping-preferred-node-order
Make elk not force node model order, but strongly consider it instead
2025-08-14 10:17:25 +00:00
autofix-ci[bot]
60feec465b [autofix.ci] apply automated fixes 2025-08-14 09:26:22 +00:00
Sidharth Vinod
d1ae687d1e Merge branch 'sidv/showRawData' of https://github.com/mermaid-js/mermaid into sidv/showRawData
* 'sidv/showRawData' of https://github.com/mermaid-js/mermaid:
  Create strong-laws-confess.md
2025-08-14 14:48:46 +05:30
Sidharth Vinod
7af6723ac0 test: Add E2E test for unsupported markdown 2025-08-14 14:48:37 +05:30
Sidharth Vinod
da90f6760b Create strong-laws-confess.md 2025-08-14 02:16:38 -07:00
Sidharth Vinod
d74013c642 fix: Remove data loss when unsupported markdown is encountered 2025-08-14 13:05:44 +05:30
Sidharth Vinod
ce996346f8 Merge pull request #6821 from kriss-u/chore/4119_cspell_issue_eslint
chore: run cspell on lint staged for markdown files
2025-08-14 11:46:13 +05:30
Sidharth Vinod
29edfa7f56 Apply suggestion from @sidharthv96 2025-08-13 10:03:26 -07:00
Sidharth Vinod
14a4ab81c9 Merge pull request #6850 from mermaid-js/update-timings
Update E2E Timings
2025-08-13 22:15:22 +05:30
Sidharth Vinod
13d72262d9 Merge pull request #6847 from mermaid-js/rajat-ht/feat-editor-selection-ab-test
Feat: Add editor selection A/B test
2025-08-13 21:55:18 +05:30
rajat-ht
62dee0bad4 chore: update UI for variant A 2025-08-13 21:51:21 +05:30
rajat-ht
9e81e1146a chore: spell check 2025-08-13 19:34:48 +05:30
anderium
2260948b7b Add changeset and integration test 2025-08-13 14:39:09 +02:00
rajat-ht
186429ae32 chore: Update UI design 2025-08-13 16:28:18 +05:30
github-actions[bot]
657a9ef785 chore: update E2E timings 2025-08-13 04:15:39 +00:00
anderium
4f24489d81 Make elk not force model order, but strongly consider it instead
This improves the ordering in models with crossings that can be resolved by reordering nodes. It keeps the node order to still avoid #6647 which cause this regression to be introduced.

[See this example on the ELK Editor.](https://rtsys.informatik.uni-kiel.de/elklive/elkgraph.html?compressedContent=IYGw5g9gTglgLgCwLYC4AEJgE8CmUcAmAUAPQloDGUEAzjTAHZgCyjMSMAXsHDBAwDoAZtAo4AchAI5mUnCADyUaVHRwoAVxxEK-eitnTFyvAJrqeOMFnTiFAEQCiAZQD6AQXH3Xj+wHEXIlJyABUEGBo0CLQAI2ACNAB3BBwGNA16JjQRKDFJaUN5JRU1TRwBIIY5NAYABjQAbwxgGPk0ACJa9rQAXyIq6Rr3RubWkA7gbr6BnBqARhHMMY65qf7qhgAmRZa29s21mZqADR3l9uPDjYAhM72Yq8GGa+GmpfuBVd71p+vbt9243aMQEB2+R2epwB5wAWmsiIQwLM6mgALQAPiGaARBCRNXqGPmQURyIWhK2xNxyOG5OulLxzzRmOe7hxDNutLpbORLyZNWux25-I5zMFQq2fIYYuCaGuGjgaEQ0RoCAgGhACVaaAA1jgAA4KxCzGjAJDlGUASQV+GgKkicAgaAAzAAaNAAFjdczd2xgQkoehgBjkxhUZgscCsNjQdnEjjQAAppEJgOq4ABKSrVABu9Whe1zj1m2YW+aBJaLaGz2zLHWrlezTru5adDfdzbr7vhJKrBMxJaFub51cHfarTtHw-dRCAA)
2025-08-13 01:47:25 +02:00
rajat-ht
2a514fa69e Feat: Add editor selection A/B test 2025-08-12 18:18:03 +05:30
Sidharth Vinod
bf3ca9d1ef Merge pull request #6332 from ajuckel/ajuckel/issue-6171-equals-in-sequence-labels
fix: Allow equals sign in sequenceDiagram labels
2025-08-11 14:36:42 +00:00
Shubham P
e53c17a012 Merge pull request #6841 from mermaid-js/renovate/peter-evans-create-pull-request-digest
chore(deps): update peter-evans/create-pull-request digest to 1310d7d
2025-08-11 07:24:30 +00:00
renovate[bot]
bb2d6973ba chore(deps): update peter-evans/create-pull-request digest to 1310d7d 2025-08-11 02:12:30 +00:00
Sidharth Vinod
aeaf626bb5 fix: Sanitize check in unit test 2025-08-08 18:59:47 +05:30
Sidharth Vinod
9322771b5c Merge pull request #6839 from aloisklink/refactor/remove-unnecessary-check-in-DOMPurify-hooks
refactor: remove unnecessary `Element` check since DOMPurify 3.2.2
2025-08-08 13:09:49 +00:00
Sidharth Vinod
2fe3063bf5 Merge pull request #6838 from saurabhg772244/saurabh/fix-node-border-style-for-hand-drawn-shapes
Saurabh/fix-node-border-style-for-hand-drawn-shapes
2025-08-08 13:02:38 +00:00
Shubham P
4e55a45b1b Merge branch 'develop' into saurabh/fix-node-border-style-for-hand-drawn-shapes 2025-08-08 16:57:55 +05:30
Knut Sveidqvist
3d319824a6 Merge pull request #6683 from mermaid-js/6576-state-diagram-label-position
6576: State diagram edge label position
2025-08-08 10:26:18 +00:00
Knut Sveidqvist
aa5d443a46 Merge pull request #6693 from mermaid-js/6649-gantt-chart-dateformat
6649: gantt chart date format issue
2025-08-08 10:09:59 +00:00
Knut Sveidqvist
356da0b4d7 Merge branch 'develop' into 6576-state-diagram-label-position 2025-08-08 12:01:34 +02:00
Knut Sveidqvist
22530a8bdf Merge pull request #6653 from mermaid-js/4459-remove-beta-suffix
#4459: Remove beta suffix
2025-08-08 09:55:06 +00:00
Knut Sveidqvist
e6574ef40c Merge pull request #6651 from mermaid-js/6584-piechart-zero-negative-values
6584: prevent pie chart crash on zero or negative values
2025-08-08 09:52:16 +00:00
Knut Sveidqvist
c4eb526162 Merge pull request #6734 from mermaid-js/6730-gantt-excludes-datetime-format
6730: Fix excluded dates ignored in YYYY-MM-DD HH:mm:ss date format in gantt diagram
2025-08-08 09:33:56 +00:00
saurabhg772244
4d62d59632 added changeset 2025-08-08 14:19:03 +05:30
saurabhg772244
5af489d8dd Fix border style for hand drawn shapes 2025-08-08 14:17:09 +05:30
Sidharth Vinod
096fbe933e test: Verify label is sanitized
Co-authored-by: Chris Grieger <chris@scolp.de>
2025-08-08 12:55:18 +05:30
Sidharth Vinod
e539909e87 fix: Label in addHtmlSpan 2025-08-08 12:54:26 +05:30
Knut Sveidqvist
074701e316 Merge pull request #6833 from mermaid-js/6611-block-diagram-arrow-direction
6611: Block diagram shows incorrect arrow direction
2025-08-08 07:24:02 +00:00
Sidharth Vinod
cfc76ef1cb fix: sanitize HTML for spans 2025-08-07 22:49:39 +05:30
Sidharth Vinod
4b31361506 Merge pull request #6733 from mermaid-js/fix-connection-gaps-in-flowchart-shapes
Fix: Connection gaps in flowchart shapes
2025-08-07 14:36:34 +00:00
Sidharth Vinod
20a18971ea chore: Add CVE ID 2025-08-07 13:39:01 +05:30
Sidharth Vinod
e1e36dfcb3 chore: Add CVE ID 2025-08-07 13:37:54 +05:30
darshanr0107
165ffefad5 chore: remove unnecessary test case
on-behalf-of: @Mermaid-Chart <hello@mermaidchart.com>
2025-08-07 12:09:49 +05:30
darshanr0107
9258b2933b add changeset
on-behalf-of: @Mermaid-Chart <hello@mermaidchart.com>
2025-08-06 20:05:35 +05:30
darshanr0107
f5445b266e fix: incorrect arrow direction in block direction
on-behalf-of: @Mermaid-Chart <hello@mermaidchart.com>
2025-08-06 20:01:28 +05:30
Alois Klink
7a1530d911 refactor: remove unnecessary Element check
[DOMPurify v3.2.2][1] narrowed down the types of these hooks so that
these are known to have the `Element` type, which means checking the
type of these at runtime is unnecessary.

[1]: https://github.com/cure53/DOMPurify/releases/tag/3.2.2

See: fe3cffbb67
See: 4cdfd1ffef
2025-08-06 22:30:09 +08:00
Sidharth Vinod
e32e80ea7f chore: Add @fourcube in changeset 2025-08-05 10:17:21 -07:00
Sidharth Vinod
3256807d25 chore: Add @fourcube in changeset 2025-08-05 22:44:58 +05:30
Sidharth Vinod
0133f1c0c5 docs: Add changeset 2025-08-05 22:42:13 +05:30
Sidharth Vinod
12e01bdb5c docs: Add changeset 2025-08-05 22:41:10 +05:30
Sidharth Vinod
a776b4f0ab Merge branch 'advisory-fix-1' of https://github.com/mermaid-js/mermaid-ghsa-7rqq-prvp-x9jh into advisory-fix-1
* 'advisory-fix-1' of https://github.com/mermaid-js/mermaid-ghsa-7rqq-prvp-x9jh:
  fix: Sanitize Katex
2025-08-05 22:37:06 +05:30
Sidharth Vinod
8d79bc9b19 test: check katex sanitization 2025-08-05 22:36:28 +05:30
Sidharth Vinod
ecf7ab4355 fix: Sanitize getIconSVG 2025-08-05 22:33:05 +05:30
Sidharth Vinod
c61a431e2d fix: Sanitize iconText 2025-08-05 22:32:38 +05:30
Sidharth Vinod
526b35c602 test: Architecture XSS 2025-08-05 22:30:45 +05:30
Sidharth Vinod
8090580c67 test: Handle missing bindFunctions 2025-08-05 22:27:21 +05:30
Sidharth Vinod
9d685178d2 fix: Sanitize Katex 2025-08-05 20:44:03 +05:30
omkarht
b451c66d7c chore: added test case for updated shapes
on-behalf-of: @Mermaid-Chart <hello@mermaidchart.com>
2025-08-05 19:43:34 +05:30
omkarht
1dd11705d9 fix: updated changeset
on-behalf-of: @Mermaid-Chart <hello@mermaidchart.com>
2025-08-05 17:40:18 +05:30
Krishna Upadhyay
17142ef8d7 chore: run cspell on lint staged for markdown files [skip ci] 2025-08-04 20:53:19 -05:00
omkarht
29de40478f Merge branch 'develop' into fix-connection-gaps-in-flowchart-shapes 2025-08-04 17:06:03 +05:30
Sidharth Vinod
bcd3e33243 Merge pull request #6776 from mermaid-js/update-blog
DOCS: update blog page
2025-07-18 13:52:59 +05:30
Steph
b2754bc553 update blog page 2025-07-17 14:44:38 -07:00
Sidharth Vinod
b65a73f432 Merge pull request #6697 from mermaid-js/rajat-ht/feat-add-start-pro-trial
feat: Add start pro trial button.
2025-07-17 11:57:18 +05:30
darshanr0107
a14cd0e2a1 fix: update test case
on-behalf-of: @Mermaid-Chart <hello@mermaidchart.com>
2025-07-16 18:47:45 +05:30
darshanr0107
0823e08a54 Merge branch 'develop' into 6584-piechart-zero-negative-values 2025-07-16 18:05:06 +05:30
darshanr0107
5cafe241d0 Merge branch 'develop' into 6649-gantt-chart-dateformat 2025-07-16 17:29:52 +05:30
darshanr0107
c847817a54 Merge branch 'develop' into 6730-gantt-excludes-datetime-format 2025-07-16 17:29:37 +05:30
darshanr0107
3ab0961bdc fix: PR comment and updated test case
on-behalf-of: @Mermaid-Chart <hello@mermaidchart.com>
2025-07-16 17:27:08 +05:30
omkarht
0892870b5d Merge branch 'develop' into fix-connection-gaps-in-flowchart-shapes 2025-07-16 14:55:22 +05:30
omkarht
500f90a105 Merge branch 'fix-connection-gaps-in-flowchart-shapes' of https://github.com/mermaid-js/mermaid into fix-connection-gaps-in-flowchart-shapes 2025-07-16 14:54:09 +05:30
omkarht
14983158a2 fix: updated hexagon shape
on-behalf-of: @Mermaid-Chart hello@mermaidchart.com
2025-07-16 14:52:53 +05:30
darshanr0107
3fea9e8759 fix: update changeset
on-behalf-of: @Mermaid-Chart <hello@mermaidchart.com>
2025-07-16 13:40:40 +05:30
darshanr0107
e5ea2ed0b1 Merge branch 'develop' of https://github.com/mermaid-js/mermaid into 4459-remove-beta-suffix 2025-07-16 13:38:28 +05:30
darshanr0107
34e7f9704b fix: update changeset
on-behalf-of: @Mermaid-Chart <hello@mermaidchart.com>
2025-07-16 13:20:47 +05:30
darshanr0107
1176d30668 fix: update changeset
on-behalf-of: @Mermaid-Chart <hello@mermaidchart.com>
2025-07-16 12:38:35 +05:30
Sidharth Vinod
6728852b7a Merge branch 'develop' into fix-connection-gaps-in-flowchart-shapes 2025-07-15 20:37:20 +05:30
Sidharth Vinod
15e7c890ed Merge branch 'develop' into 6576-state-diagram-label-position 2025-07-15 20:21:40 +05:30
omkarht
0451e343ef Merge branch 'develop' into fix-connection-gaps-in-flowchart-shapes 2025-07-14 16:53:02 +05:30
omkarht
a2dbc8e4b3 updated hexagon shape 2025-07-14 16:51:34 +05:30
darshanr0107
aea16eaf7e Merge branch 'develop' into 6584-piechart-zero-negative-values 2025-07-10 16:36:41 +05:30
darshanr0107
bb7cd70034 Merge branch 'develop' into 6730-gantt-excludes-datetime-format 2025-07-10 16:35:54 +05:30
darshanr0107
35a92efcdc resolve PR comments 2025-07-10 15:49:53 +05:30
darshanr0107
fce7cabb71 add changeset 2025-07-09 20:24:36 +05:30
darshanr0107
38e6dc497a Merge branch 'develop' into 6730-gantt-excludes-datetime-format 2025-07-09 20:06:07 +05:30
darshanr0107
5f0c53c8a7 fix excluded dates ignored in YYYY-MM-DD HH:mm:ss date format 2025-07-09 20:02:18 +05:30
omkarht
f9da4433ff Merge branch 'develop' into fix-connection-gaps-in-flowchart-shapes 2025-07-09 19:07:25 +05:30
omkarht
fc07f0d8ab added changeset 2025-07-09 19:06:57 +05:30
omkarht
ce7a487dfc Fix: Fixed Connection gaps in flowchart shapes 2025-07-09 18:37:52 +05:30
darshanr0107
8c0d12027d Merge branch 'develop' into 6584-piechart-zero-negative-values 2025-07-09 12:22:59 +05:30
rajat-ht
ea72740d1f Merge branch 'master' of https://github.com/mermaid-js/mermaid into rajat-ht/feat-add-start-pro-trial 2025-07-07 17:08:17 +05:30
rajat-ht
427dc38857 chore: revert 'Open Editor' link in header 2025-07-03 19:21:24 +05:30
rajat-ht
ec21042c53 chore: minor UI updates and added search params to URL 2025-07-03 19:00:33 +05:30
rajat-ht
4a86b68e01 chore: update UI as per suggestion 2025-07-02 18:51:06 +05:30
darshanr0107
1414380181 Merge branch 'develop' into 6584-piechart-zero-negative-values 2025-07-01 12:34:50 +05:30
darshanr0107
6686ee9253 Merge branch 'develop' into 4459-remove-beta-suffix 2025-07-01 12:34:33 +05:30
darshanr0107
7f109c7b94 Merge branch 'develop' into 6576-state-diagram-label-position 2025-07-01 11:15:46 +05:30
darshanr0107
b9c3375be3 Merge branch '6576-state-diagram-label-position' of https://github.com/mermaid-js/mermaid into 6576-state-diagram-label-position 2025-06-30 20:20:48 +05:30
darshanr0107
4254bdd473 added test cases for edge label positions 2025-06-30 20:15:32 +05:30
darshanr0107
4012cbf013 Update changeset
Co-authored-by: Sidharth Vinod <github@sidharth.dev>
2025-06-30 18:32:31 +05:30
rajat-ht
8693be56ee feat: Add start pro trial button. 2025-06-27 17:26:54 +05:30
darshanr0107
814b68b4a9 added changeset 2025-06-27 15:16:20 +05:30
darshanr0107
bfa0eefa32 fix gantt chart date format issue 2025-06-27 15:01:45 +05:30
darshanr0107
579c22cf5d refactor code 2025-06-24 17:08:42 +05:30
darshanr0107
33e08daf17 added changeset 2025-06-24 15:10:36 +05:30
darshanr0107
24257de8a6 fix state diagram edge label position 2025-06-24 14:50:20 +05:30
darshanr0107
42ac1848dd Merge branch 'develop' into 6584-piechart-zero-negative-values 2025-06-23 19:52:23 +05:30
darshanr0107
3920ad442d resolved PR comments 2025-06-23 15:08:11 +05:30
darshanr0107
53d27b771d Merge branch 'develop' into 4459-remove-beta-suffix 2025-06-17 15:57:40 +05:30
darshanr0107
2c0931da46 added changeset 2025-06-17 15:53:25 +05:30
darshanr0107
8224a81ab6 fix xychart test cases 2025-06-17 13:52:04 +05:30
darshanr0107
98442294ed resolved PR comments 2025-06-17 13:44:12 +05:30
darshanr0107
a3d164fde8 remove beta suffix for block diagram 2025-06-17 12:43:26 +05:30
darshanr0107
9dc987b28b remove beta support for sankey diagram 2025-06-17 12:12:40 +05:30
darshanr0107
72c0d9df26 added test case for preventing zero% values from rendering 2025-06-16 19:38:58 +05:30
darshanr0107
cfbce54638 prevent zero% slices from rendering in pie chart 2025-06-16 19:11:29 +05:30
darshanr0107
6979aa1013 Fix failing test cases and update error messages for negative and zero inputs 2025-06-16 14:53:09 +05:30
darshanr0107
ea60525988 remove beta suffix from xyChart 2025-06-13 19:33:43 +05:30
darshanr0107
9da6fb39ae added changeset 2025-06-12 19:18:36 +05:30
darshanr0107
83b9a17277 fix: prevent pie chart crash on zero or negative values 2025-06-12 18:13:11 +05:30
Anthony Juckel
6cc192680a Added changeset 2025-03-03 15:10:37 -06:00
Anthony Juckel
3dd6107e76 fix: Allow equals sign in sequenceDiagram labels 2025-03-03 15:08:34 -06:00
145 changed files with 4054 additions and 2645 deletions

View File

@@ -1,5 +0,0 @@
---
'@mermaid-js/mermaid-zenuml': patch
---
Fixed a critical bug that the ZenUML diagram is not rendered.

View File

@@ -0,0 +1,5 @@
---
'mermaid': patch
---
fix: Handle arrows correctly when auto number is enabled

View File

@@ -1,5 +0,0 @@
---
'mermaid': patch
---
fix: Update casing of ID in requirement diagram

View File

@@ -1,5 +0,0 @@
---
'mermaid': minor
---
feat: Added support for per link curve styling in flowchart diagram using edge ids

View File

@@ -1,5 +0,0 @@
---
'mermaid': patch
---
fix: Make flowchart elk detector regex match less greedy

View File

@@ -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).

View File

@@ -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.

View File

@@ -1,5 +0,0 @@
---
'mermaid': patch
---
fix: Add escaped class literal name on namespace

View File

@@ -1,5 +0,0 @@
---
'mermaid': patch
---
chore: migrate to class-based ArchitectureDB implementation

View File

@@ -1,5 +0,0 @@
---
'mermaid': patch
---
fix: Update flowchart direction TD's behavior to be the same as TB

View File

@@ -1,5 +0,0 @@
---
'mermaid': patch
---
chore: Update packet diagram to use new class-based database structure

View File

@@ -143,7 +143,6 @@ typeof
typestr typestr
unshift unshift
urlsafe urlsafe
usecase
verifymethod verifymethod
VERIFYMTHD VERIFYMTHD
WARN_DOCSDIR_DOESNT_MATCH WARN_DOCSDIR_DOESNT_MATCH

View File

@@ -2,6 +2,7 @@
Ashish Jain Ashish Jain
cpettitt cpettitt
Dong Cai Dong Cai
fourcube
knsv knsv
Knut Sveidqvist Knut Sveidqvist
Nikolay Rozhkov Nikolay Rozhkov

1
.github/lychee.toml vendored
View File

@@ -59,6 +59,7 @@ exclude = [
"https://huehive.co", "https://huehive.co",
"https://foswiki.org", "https://foswiki.org",
"https://www.gnu.org", "https://www.gnu.org",
"https://redmine.org",
"https://mermaid-preview.com" "https://mermaid-preview.com"
] ]

View File

@@ -36,7 +36,7 @@ jobs:
# Initializes the CodeQL tools for scanning. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10 uses: github/codeql-action/init@5378192d256ef1302a6980fffe5ca04426d43091 # v3.28.21
with: with:
config-file: ./.github/codeql/codeql-config.yml config-file: ./.github/codeql/codeql-config.yml
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
@@ -48,7 +48,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below) # If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild - name: Autobuild
uses: github/codeql-action/autobuild@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10 uses: github/codeql-action/autobuild@5378192d256ef1302a6980fffe5ca04426d43091 # v3.28.21
# Command-line programs to run using the OS shell. # Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
@@ -62,4 +62,4 @@ jobs:
# make release # make release
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10 uses: github/codeql-action/analyze@5378192d256ef1302a6980fffe5ca04426d43091 # v3.28.21

View File

@@ -56,7 +56,7 @@ jobs:
args: -X POST "$APPLITOOLS_SERVER_URL/api/externals/github/push?apiKey=$APPLITOOLS_API_KEY&CommitSha=$GITHUB_SHA&BranchName=${APPLITOOLS_BRANCH}$&ParentBranchName=$APPLITOOLS_PARENT_BRANCH" args: -X POST "$APPLITOOLS_SERVER_URL/api/externals/github/push?apiKey=$APPLITOOLS_API_KEY&CommitSha=$GITHUB_SHA&BranchName=${APPLITOOLS_BRANCH}$&ParentBranchName=$APPLITOOLS_PARENT_BRANCH"
- name: Cypress run - name: Cypress run
uses: cypress-io/github-action@18a6541367f4580a515371905f499a27a44e8dbe # v6.7.12 uses: cypress-io/github-action@108b8684ae52e735ff7891524cbffbcd4be5b19f # v6.7.16
id: cypress id: cypress
with: with:
start: pnpm run dev start: pnpm run dev

View File

@@ -27,12 +27,12 @@ jobs:
with: with:
node-version-file: '.node-version' node-version-file: '.node-version'
- name: Install dependencies - name: Install dependencies
uses: cypress-io/github-action@18a6541367f4580a515371905f499a27a44e8dbe # v6.7.12 uses: cypress-io/github-action@108b8684ae52e735ff7891524cbffbcd4be5b19f # v6.7.16
with: with:
runTests: false runTests: false
- name: Cypress run - name: Cypress run
uses: cypress-io/github-action@18a6541367f4580a515371905f499a27a44e8dbe # v6.7.12 uses: cypress-io/github-action@108b8684ae52e735ff7891524cbffbcd4be5b19f # v6.7.16
id: cypress id: cypress
with: with:
install: false install: false
@@ -58,7 +58,7 @@ jobs:
echo "EOF" >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT
- name: Commit and create pull request - name: Commit and create pull request
uses: peter-evans/create-pull-request@07cbaebb4bfc9c5d7db426ea5a5f585df29dd0a0 uses: peter-evans/create-pull-request@cb4d3bfce175d44325c6b7697f81e0afe8a79bdf
with: with:
add-paths: | add-paths: |
cypress/timings.json cypress/timings.json

View File

@@ -45,7 +45,7 @@ jobs:
node-version-file: '.node-version' node-version-file: '.node-version'
- name: Cache snapshots - name: Cache snapshots
id: cache-snapshot id: cache-snapshot
uses: actions/cache@0c907a75c2c80ebcb7f088228285e798b750cf8f # v4.2.1 uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
with: with:
path: ./cypress/snapshots path: ./cypress/snapshots
key: ${{ runner.os }}-snapshots-${{ env.targetHash }} key: ${{ runner.os }}-snapshots-${{ env.targetHash }}
@@ -59,7 +59,7 @@ jobs:
- name: Install dependencies - name: Install dependencies
if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' }} if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' }}
uses: cypress-io/github-action@18a6541367f4580a515371905f499a27a44e8dbe # v6.7.12 uses: cypress-io/github-action@108b8684ae52e735ff7891524cbffbcd4be5b19f # v6.7.16
with: with:
# just perform install # just perform install
runTests: false runTests: false
@@ -95,13 +95,13 @@ jobs:
# These cached snapshots are downloaded, providing the reference snapshots. # These cached snapshots are downloaded, providing the reference snapshots.
- name: Cache snapshots - name: Cache snapshots
id: cache-snapshot id: cache-snapshot
uses: actions/cache/restore@0c907a75c2c80ebcb7f088228285e798b750cf8f # v4.2.1 uses: actions/cache/restore@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
with: with:
path: ./cypress/snapshots path: ./cypress/snapshots
key: ${{ runner.os }}-snapshots-${{ env.targetHash }} key: ${{ runner.os }}-snapshots-${{ env.targetHash }}
- name: Install dependencies - name: Install dependencies
uses: cypress-io/github-action@18a6541367f4580a515371905f499a27a44e8dbe # v6.7.12 uses: cypress-io/github-action@108b8684ae52e735ff7891524cbffbcd4be5b19f # v6.7.16
with: with:
runTests: false runTests: false
@@ -117,7 +117,7 @@ jobs:
# Install NPM dependencies, cache them correctly # Install NPM dependencies, cache them correctly
# and run all Cypress tests # and run all Cypress tests
- name: Cypress run - name: Cypress run
uses: cypress-io/github-action@18a6541367f4580a515371905f499a27a44e8dbe # v6.7.12 uses: cypress-io/github-action@108b8684ae52e735ff7891524cbffbcd4be5b19f # v6.7.16
id: cypress id: cypress
with: with:
install: false install: false

View File

@@ -32,7 +32,7 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Restore lychee cache - name: Restore lychee cache
uses: actions/cache@0c907a75c2c80ebcb7f088228285e798b750cf8f # v4.2.1 uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
with: with:
path: .lycheecache path: .lycheecache
key: cache-lychee-${{ github.sha }} key: cache-lychee-${{ github.sha }}

View File

@@ -36,7 +36,7 @@ jobs:
- name: Create Release Pull Request or Publish to npm - name: Create Release Pull Request or Publish to npm
id: changesets id: changesets
uses: changesets/action@c8bada60c408975afd1a20b3db81d6eee6789308 # v1.4.9 uses: changesets/action@06245a4e0a36c064a573d4150030f5ec548e4fcc # v1.4.10
with: with:
version: pnpm changeset:version version: pnpm changeset:version
publish: pnpm changeset:publish publish: pnpm changeset:publish

View File

@@ -20,18 +20,18 @@ jobs:
with: with:
persist-credentials: false persist-credentials: false
- name: Run analysis - name: Run analysis
uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1 uses: ossf/scorecard-action@05b42c624433fc40578a4040d5cf5e36ddca8cde # v2.4.2
with: with:
results_file: results.sarif results_file: results.sarif
results_format: sarif results_format: sarif
publish_results: true publish_results: true
- name: Upload artifact - name: Upload artifact
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1 uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with: with:
name: SARIF file name: SARIF file
path: results.sarif path: results.sarif
retention-days: 5 retention-days: 5
- name: Upload to code-scanning - name: Upload to code-scanning
uses: github/codeql-action/upload-sarif@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10 uses: github/codeql-action/upload-sarif@5378192d256ef1302a6980fffe5ca04426d43091 # v3.28.21
with: with:
sarif_file: results.sarif sarif_file: results.sarif

View File

@@ -19,7 +19,7 @@ jobs:
message: 'chore: update browsers list' message: 'chore: update browsers list'
push: false push: false
- name: Create Pull Request - name: Create Pull Request
uses: peter-evans/create-pull-request@67ccf781d68cd99b580ae25a5c18a1cc84ffff1f # v7.0.6 uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
with: with:
branch: update-browserslist branch: update-browserslist
title: Update Browserslist title: Update Browserslist

View File

@@ -14,7 +14,7 @@ interface CodeObject {
mermaid: CypressMermaidConfig; mermaid: CypressMermaidConfig;
} }
const utf8ToB64 = (str: string): string => { export const utf8ToB64 = (str: string): string => {
return Buffer.from(decodeURIComponent(encodeURIComponent(str))).toString('base64'); return Buffer.from(decodeURIComponent(encodeURIComponent(str))).toString('base64');
}; };
@@ -22,7 +22,7 @@ const batchId: string =
'mermaid-batch-' + 'mermaid-batch-' +
(Cypress.env('useAppli') (Cypress.env('useAppli')
? Date.now().toString() ? Date.now().toString()
: Cypress.env('CYPRESS_COMMIT') || Date.now().toString()); : (Cypress.env('CYPRESS_COMMIT') ?? Date.now().toString()));
export const mermaidUrl = ( export const mermaidUrl = (
graphStr: string | string[], graphStr: string | string[],
@@ -61,9 +61,7 @@ export const imgSnapshotTest = (
sequence: { sequence: {
...(_options.sequence ?? {}), ...(_options.sequence ?? {}),
actorFontFamily: 'courier', actorFontFamily: 'courier',
noteFontFamily: _options.sequence?.noteFontFamily noteFontFamily: _options.sequence?.noteFontFamily ?? 'courier',
? _options.sequence.noteFontFamily
: 'courier',
messageFontFamily: 'courier', messageFontFamily: 'courier',
}, },
}; };

View File

@@ -1,4 +1,4 @@
import { mermaidUrl } from '../../helpers/util.ts'; import { imgSnapshotTest, mermaidUrl, utf8ToB64 } from '../../helpers/util.ts';
describe('XSS', () => { describe('XSS', () => {
it('should handle xss in tags', () => { it('should handle xss in tags', () => {
const str = const str =
@@ -141,4 +141,37 @@ describe('XSS', () => {
cy.wait(1000); cy.wait(1000);
cy.get('#the-malware').should('not.exist'); 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 "<img src=x onerror=\\"xssAttack()\\">" [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<img src="x" onerror="xssAttack()">$$\\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
"<img src=x onerror=xssAttack()>" ||--|| ENTITY2 : "<img src=x onerror=xssAttack()>"
`,
});
imgSnapshotTest(utf8ToB64(str), {}, true);
cy.wait(1000);
cy.get('#the-malware').should('not.exist');
});
}); });

View File

@@ -16,7 +16,7 @@ describe('Block diagram', () => {
it('BL2: should handle columns statement in sub-blocks', () => { it('BL2: should handle columns statement in sub-blocks', () => {
imgSnapshotTest( imgSnapshotTest(
`block-beta `block
id1["Hello"] id1["Hello"]
block block
columns 3 columns 3
@@ -32,7 +32,7 @@ describe('Block diagram', () => {
it('BL3: should align block widths and handle columns statement in sub-blocks', () => { it('BL3: should align block widths and handle columns statement in sub-blocks', () => {
imgSnapshotTest( imgSnapshotTest(
`block-beta `block
block block
columns 1 columns 1
id1 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', () => { it('BL4: should align block widths and handle columns statements in deeper sub-blocks then 1 level', () => {
imgSnapshotTest( imgSnapshotTest(
`block-beta `block
columns 1 columns 1
block block
columns 1 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)', () => { it('BL5: should align block widths and handle columns statements in deeper sub-blocks then 1 level (alt)', () => {
imgSnapshotTest( imgSnapshotTest(
`block-beta `block
columns 1 columns 1
block block
id1 id1
@@ -87,7 +87,7 @@ describe('Block diagram', () => {
it('BL6: should handle block arrows and spece statements', () => { it('BL6: should handle block arrows and spece statements', () => {
imgSnapshotTest( imgSnapshotTest(
`block-beta `block
columns 3 columns 3
space:3 space:3
ida idb idc ida idb idc
@@ -106,7 +106,7 @@ describe('Block diagram', () => {
it('BL7: should handle different types of edges', () => { it('BL7: should handle different types of edges', () => {
imgSnapshotTest( imgSnapshotTest(
`block-beta `block
columns 3 columns 3
A space:5 A space:5
A --o B A --o B
@@ -119,7 +119,7 @@ describe('Block diagram', () => {
it('BL8: should handle sub-blocks without columns statements', () => { it('BL8: should handle sub-blocks without columns statements', () => {
imgSnapshotTest( imgSnapshotTest(
`block-beta `block
columns 2 columns 2
C A B C A B
block block
@@ -133,7 +133,7 @@ describe('Block diagram', () => {
it('BL9: should handle edges from blocks in sub blocks to other blocks', () => { it('BL9: should handle edges from blocks in sub blocks to other blocks', () => {
imgSnapshotTest( imgSnapshotTest(
`block-beta `block
columns 3 columns 3
B space B space
block block
@@ -147,7 +147,7 @@ describe('Block diagram', () => {
it('BL10: should handle edges from composite blocks', () => { it('BL10: should handle edges from composite blocks', () => {
imgSnapshotTest( imgSnapshotTest(
`block-beta `block
columns 3 columns 3
B space B space
block BL block BL
@@ -161,7 +161,7 @@ describe('Block diagram', () => {
it('BL11: should handle edges to composite blocks', () => { it('BL11: should handle edges to composite blocks', () => {
imgSnapshotTest( imgSnapshotTest(
`block-beta `block
columns 3 columns 3
B space B space
block BL block BL
@@ -175,7 +175,7 @@ describe('Block diagram', () => {
it('BL12: edges should handle labels', () => { it('BL12: edges should handle labels', () => {
imgSnapshotTest( imgSnapshotTest(
`block-beta `block
A A
space space
A -- "apa" --> E A -- "apa" --> E
@@ -186,7 +186,7 @@ describe('Block diagram', () => {
it('BL13: should handle block arrows in different directions', () => { it('BL13: should handle block arrows in different directions', () => {
imgSnapshotTest( imgSnapshotTest(
`block-beta `block
columns 3 columns 3
space blockArrowId1<["down"]>(down) space space blockArrowId1<["down"]>(down) space
blockArrowId2<["right"]>(right) blockArrowId3<["Sync"]>(x, y) blockArrowId4<["left"]>(left) 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', () => { it('BL14: should style statements and class statements', () => {
imgSnapshotTest( imgSnapshotTest(
`block-beta `block
A A
B B
classDef blue fill:#66f,stroke:#333,stroke-width:2px; 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', () => { it('BL15: width alignment - D and E should share available space', () => {
imgSnapshotTest( imgSnapshotTest(
`block-beta `block
block block
D D
E E
@@ -225,7 +225,7 @@ describe('Block diagram', () => {
it('BL16: width alignment - C should be as wide as the composite block', () => { it('BL16: width alignment - C should be as wide as the composite block', () => {
imgSnapshotTest( imgSnapshotTest(
`block-beta `block
block block
A("This is the text") A("This is the text")
B B
@@ -238,7 +238,7 @@ describe('Block diagram', () => {
it('BL17: width alignment - blocks should be equal in width', () => { it('BL17: width alignment - blocks should be equal in width', () => {
imgSnapshotTest( imgSnapshotTest(
`block-beta `block
A("This is the text") A("This is the text")
B B
C C
@@ -249,7 +249,7 @@ describe('Block diagram', () => {
it('BL18: block types 1 - square, rounded and circle', () => { it('BL18: block types 1 - square, rounded and circle', () => {
imgSnapshotTest( imgSnapshotTest(
`block-beta `block
A["square"] A["square"]
B("rounded") B("rounded")
C(("circle")) C(("circle"))
@@ -260,7 +260,7 @@ describe('Block diagram', () => {
it('BL19: block types 2 - odd, diamond and hexagon', () => { it('BL19: block types 2 - odd, diamond and hexagon', () => {
imgSnapshotTest( imgSnapshotTest(
`block-beta `block
A>"rect_left_inv_arrow"] A>"rect_left_inv_arrow"]
B{"diamond"} B{"diamond"}
C{{"hexagon"}} C{{"hexagon"}}
@@ -271,7 +271,7 @@ describe('Block diagram', () => {
it('BL20: block types 3 - stadium', () => { it('BL20: block types 3 - stadium', () => {
imgSnapshotTest( imgSnapshotTest(
`block-beta `block
A(["stadium"]) A(["stadium"])
`, `,
{} {}
@@ -280,7 +280,7 @@ describe('Block diagram', () => {
it('BL21: block types 4 - lean right, lean left, trapezoid and inv trapezoid', () => { it('BL21: block types 4 - lean right, lean left, trapezoid and inv trapezoid', () => {
imgSnapshotTest( imgSnapshotTest(
`block-beta `block
A[/"lean right"/] A[/"lean right"/]
B[\"lean left"\] B[\"lean left"\]
C[/"trapezoid"\] C[/"trapezoid"\]
@@ -292,7 +292,7 @@ describe('Block diagram', () => {
it('BL22: block types 1 - square, rounded and circle', () => { it('BL22: block types 1 - square, rounded and circle', () => {
imgSnapshotTest( imgSnapshotTest(
`block-beta `block
A["square"] A["square"]
B("rounded") B("rounded")
C(("circle")) C(("circle"))
@@ -303,7 +303,7 @@ describe('Block diagram', () => {
it('BL23: sizing - it should be possible to make a block wider', () => { it('BL23: sizing - it should be possible to make a block wider', () => {
imgSnapshotTest( imgSnapshotTest(
`block-beta `block
A("rounded"):2 A("rounded"):2
B:2 B:2
C C
@@ -314,7 +314,7 @@ describe('Block diagram', () => {
it('BL24: sizing - it should be possible to make a composite block wider', () => { it('BL24: sizing - it should be possible to make a composite block wider', () => {
imgSnapshotTest( imgSnapshotTest(
`block-beta `block
block:2 block:2
A A
end end
@@ -326,7 +326,7 @@ describe('Block diagram', () => {
it('BL25: block in the middle with space on each side', () => { it('BL25: block in the middle with space on each side', () => {
imgSnapshotTest( imgSnapshotTest(
`block-beta `block
columns 3 columns 3
space space
middle["In the middle"] middle["In the middle"]
@@ -337,7 +337,7 @@ describe('Block diagram', () => {
}); });
it('BL26: space and an edge', () => { it('BL26: space and an edge', () => {
imgSnapshotTest( imgSnapshotTest(
`block-beta `block
columns 5 columns 5
A space B A space B
A --x B A --x B
@@ -347,7 +347,7 @@ describe('Block diagram', () => {
}); });
it('BL27: block sizes for regular blocks', () => { it('BL27: block sizes for regular blocks', () => {
imgSnapshotTest( imgSnapshotTest(
`block-beta `block
columns 3 columns 3
a["A wide one"] b:2 c:2 d 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', () => { it('BL28: composite block with a set width - f should use the available space', () => {
imgSnapshotTest( imgSnapshotTest(
`block-beta `block
columns 3 columns 3
a:3 a:3
block:e: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', () => { it('BL29: composite block with a set width - f and g should split the available space', () => {
imgSnapshotTest( imgSnapshotTest(
`block-beta `block
columns 3 columns 3
a:3 a:3
block:e:3 block:e:3
@@ -393,6 +393,17 @@ describe('Block diagram', () => {
overflow:3 overflow:3
short:1 short:1
also_overflow:2 also_overflow:2
`,
{}
);
});
it('BL31: edge without arrow syntax should render with no arrowheads', () => {
imgSnapshotTest(
`block-beta
a
b
a --- b
`, `,
{} {}
); );

View File

@@ -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', () => { describe('Title and arrow styling #4813', () => {

View File

@@ -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', () => { it('6617: Per Link Curve Styling using edge Ids', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -1133,4 +1164,26 @@ end
` `
); );
}); });
describe('when rendering unsuported markdown', () => {
const graph = `flowchart TB
mermaid{"What is\nyourmermaid version?"} --> v10["<11"] --"\`<**1**1\`"--> fine["No bug"]
mermaid --> v11[">= v11"] -- ">= v11" --> broken["Affected by https://github.com/mermaid-js/mermaid/issues/5824"]
subgraph subgraph1["\`How to fix **fix**\`"]
broken --> B["B"]
end
githost["Github, Gitlab, BitBucket, etc."]
githost2["\`Github, Gitlab, BitBucket, etc.\`"]
a["1."]
b["- x"]
`;
it('should render raw strings', () => {
imgSnapshotTest(graph);
});
it('should render raw strings with htmlLabels: false', () => {
imgSnapshotTest(graph, { htmlLabels: false });
});
});
}); });

View File

@@ -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 // TODO: fix it
// //
// This test is skipped deliberately // 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", () => { it("should render when there's a semicolon in the title", () => {
imgSnapshotTest( imgSnapshotTest(
` `

View File

@@ -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
`
);
});
}); });

View File

@@ -15,7 +15,7 @@ describe('Sankey Diagram', () => {
describe('when given a linkColor', function () { describe('when given a linkColor', function () {
this.beforeAll(() => { this.beforeAll(() => {
cy.wrap( cy.wrap(
`sankey-beta `sankey
a,b,10 a,b,10
` `
).as('graph'); ).as('graph');
@@ -62,7 +62,7 @@ describe('Sankey Diagram', () => {
this.beforeAll(() => { this.beforeAll(() => {
cy.wrap( cy.wrap(
` `
sankey-beta sankey
a,b,8 a,b,8
b,c,8 b,c,8

View File

@@ -893,6 +893,17 @@ describe('Sequence diagram', () => {
} }
); );
}); });
it('should handle bidirectional arrows with autonumber', () => {
imgSnapshotTest(`
sequenceDiagram
autonumber
participant A
participant B
A<<->>B: This is a bidirectional message
A->B: This is a normal message`);
});
it('should support actor links and properties when not mirrored EXPERIMENTAL: USE WITH CAUTION', () => { it('should support actor links and properties when not mirrored EXPERIMENTAL: USE WITH CAUTION', () => {
//Be aware that the syntax for "properties" is likely to be changed. //Be aware that the syntax for "properties" is likely to be changed.
imgSnapshotTest( imgSnapshotTest(

View File

@@ -602,6 +602,231 @@ State1 --> [*]
-- --
55 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_____
`, `,
{} {}
); );

View File

@@ -1,7 +1,7 @@
import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts'; import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
describe('XY Chart', () => { describe('XY Chart', () => {
it('should render the simplest possible chart', () => { it('should render the simplest possible xy-beta chart', () => {
imgSnapshotTest( imgSnapshotTest(
` `
xychart-beta 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', () => { it('Should render a complete chart', () => {
imgSnapshotTest( imgSnapshotTest(
` `
xychart-beta xychart
title "Sales Revenue" title "Sales Revenue"
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
y-axis "Revenue (in $)" 4000 --> 11000 y-axis "Revenue (in $)" 4000 --> 11000
@@ -26,7 +35,7 @@ describe('XY Chart', () => {
it('Should render a chart without title', () => { it('Should render a chart without title', () => {
imgSnapshotTest( imgSnapshotTest(
` `
xychart-beta xychart
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
y-axis "Revenue (in $)" 4000 --> 11000 y-axis "Revenue (in $)" 4000 --> 11000
bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000] 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', () => { it('y-axis title not required', () => {
imgSnapshotTest( imgSnapshotTest(
` `
xychart-beta xychart
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
y-axis 4000 --> 11000 y-axis 4000 --> 11000
bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000] 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', () => { it('Should render a chart without y-axis with different range', () => {
imgSnapshotTest( imgSnapshotTest(
` `
xychart-beta xychart
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] 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] 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] 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', () => { it('x axis title not required', () => {
imgSnapshotTest( imgSnapshotTest(
` `
xychart-beta xychart
x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] 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] 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] 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', () => { it('Multiple plots can be rendered', () => {
imgSnapshotTest( imgSnapshotTest(
` `
xychart-beta xychart
line [23, 46, 77, 34] line [23, 46, 77, 34]
line [45, 32, 33, 12] line [45, 32, 33, 12]
bar [87, 54, 99, 85] bar [87, 54, 99, 85]
@@ -86,7 +95,7 @@ describe('XY Chart', () => {
it('Decimals and negative numbers are supported', () => { it('Decimals and negative numbers are supported', () => {
imgSnapshotTest( imgSnapshotTest(
` `
xychart-beta xychart
y-axis -2.4 --> 3.5 y-axis -2.4 --> 3.5
line [+1.3, .6, 2.4, -.34] line [+1.3, .6, 2.4, -.34]
`, `,
@@ -104,7 +113,7 @@ describe('XY Chart', () => {
height: 20 height: 20
plotReservedSpacePercent: 100 plotReservedSpacePercent: 100
--- ---
xychart-beta xychart
line [5000, 9000, 7500, 6200, 9500, 5500, 11000, 8200, 9200, 9500, 7000, 8800] line [5000, 9000, 7500, 6200, 9500, 5500, 11000, 8200, 9200, 9500, 7000, 8800]
`, `,
{} {}
@@ -130,7 +139,7 @@ describe('XY Chart', () => {
showTick: false showTick: false
showAxisLine: false showAxisLine: false
--- ---
xychart-beta xychart
bar [5000, 9000, 7500, 6200, 9500, 5500, 11000, 8200, 9200, 9500, 7000, 8800] bar [5000, 9000, 7500, 6200, 9500, 5500, 11000, 8200, 9200, 9500, 7000, 8800]
`, `,
{} {}
@@ -140,7 +149,7 @@ describe('XY Chart', () => {
imgSnapshotTest( 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 }}}%% %%{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" title "Sales Revenue"
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
y-axis "Revenue (in $)" 4000 --> 11000 y-axis "Revenue (in $)" 4000 --> 11000
@@ -181,7 +190,7 @@ describe('XY Chart', () => {
plotReservedSpacePercent: 60 plotReservedSpacePercent: 60
showDataLabel: true showDataLabel: true
--- ---
xychart-beta xychart
title "Sales Revenue" title "Sales Revenue"
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
y-axis "Revenue (in $)" 4000 --> 11000 y-axis "Revenue (in $)" 4000 --> 11000
@@ -202,7 +211,7 @@ describe('XY Chart', () => {
yAxis: yAxis:
showTitle: false showTitle: false
--- ---
xychart-beta xychart
title "Sales Revenue" title "Sales Revenue"
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
y-axis "Revenue (in $)" 4000 --> 11000 y-axis "Revenue (in $)" 4000 --> 11000
@@ -223,7 +232,7 @@ describe('XY Chart', () => {
yAxis: yAxis:
showLabel: false showLabel: false
--- ---
xychart-beta xychart
title "Sales Revenue" title "Sales Revenue"
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
y-axis "Revenue (in $)" 4000 --> 11000 y-axis "Revenue (in $)" 4000 --> 11000
@@ -244,7 +253,7 @@ describe('XY Chart', () => {
yAxis: yAxis:
showTick: false showTick: false
--- ---
xychart-beta xychart
title "Sales Revenue" title "Sales Revenue"
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
y-axis "Revenue (in $)" 4000 --> 11000 y-axis "Revenue (in $)" 4000 --> 11000
@@ -265,7 +274,7 @@ describe('XY Chart', () => {
yAxis: yAxis:
showAxisLine: false showAxisLine: false
--- ---
xychart-beta xychart
title "Sales Revenue" title "Sales Revenue"
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
y-axis "Revenue (in $)" 4000 --> 11000 y-axis "Revenue (in $)" 4000 --> 11000
@@ -294,7 +303,7 @@ describe('XY Chart', () => {
xAxisLineColor: "#87ceeb" xAxisLineColor: "#87ceeb"
plotColorPalette: "#008000, #faba63" plotColorPalette: "#008000, #faba63"
--- ---
xychart-beta xychart
title "Sales Revenue" title "Sales Revenue"
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
y-axis "Revenue (in $)" 4000 --> 11000 y-axis "Revenue (in $)" 4000 --> 11000
@@ -307,7 +316,7 @@ describe('XY Chart', () => {
it('should use the correct distances between data points', () => { it('should use the correct distances between data points', () => {
imgSnapshotTest( imgSnapshotTest(
` `
xychart-beta xychart
x-axis 0 --> 2 x-axis 0 --> 2
line [0, 1, 0, 1] line [0, 1, 0, 1]
bar [1, 0, 1, 0] bar [1, 0, 1, 0]
@@ -325,7 +334,7 @@ describe('XY Chart', () => {
xyChart: xyChart:
showDataLabel: true showDataLabel: true
--- ---
xychart-beta xychart
title "Sales Revenue" title "Sales Revenue"
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
y-axis "Revenue (in $)" 4000 --> 11000 y-axis "Revenue (in $)" 4000 --> 11000
@@ -344,7 +353,7 @@ describe('XY Chart', () => {
showDataLabel: true showDataLabel: true
chartOrientation: horizontal chartOrientation: horizontal
--- ---
xychart-beta xychart
title "Sales Revenue" title "Sales Revenue"
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
y-axis "Revenue (in $)" 4000 --> 11000 y-axis "Revenue (in $)" 4000 --> 11000
@@ -357,7 +366,7 @@ describe('XY Chart', () => {
it('should render vertical bar chart without labels by default', () => { it('should render vertical bar chart without labels by default', () => {
imgSnapshotTest( imgSnapshotTest(
` `
xychart-beta xychart
title "Sales Revenue" title "Sales Revenue"
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
y-axis "Revenue (in $)" 4000 --> 11000 y-axis "Revenue (in $)" 4000 --> 11000
@@ -375,7 +384,7 @@ describe('XY Chart', () => {
xyChart: xyChart:
chartOrientation: horizontal chartOrientation: horizontal
--- ---
xychart-beta xychart
title "Sales Revenue" title "Sales Revenue"
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
y-axis "Revenue (in $)" 4000 --> 11000 y-axis "Revenue (in $)" 4000 --> 11000
@@ -393,7 +402,7 @@ describe('XY Chart', () => {
xyChart: xyChart:
showDataLabel: true showDataLabel: true
--- ---
xychart-beta xychart
title "Multiple Bar Plots" title "Multiple Bar Plots"
x-axis Categories [A, B, C] x-axis Categories [A, B, C]
y-axis "Values" 0 --> 100 y-axis "Values" 0 --> 100
@@ -412,7 +421,7 @@ describe('XY Chart', () => {
showDataLabel: true showDataLabel: true
chartOrientation: horizontal chartOrientation: horizontal
--- ---
xychart-beta xychart
title "Multiple Bar Plots" title "Multiple Bar Plots"
x-axis Categories [A, B, C] x-axis Categories [A, B, C]
y-axis "Values" 0 --> 100 y-axis "Values" 0 --> 100
@@ -430,7 +439,7 @@ describe('XY Chart', () => {
xyChart: xyChart:
showDataLabel: true showDataLabel: true
--- ---
xychart-beta xychart
title "Single Bar Chart" title "Single Bar Chart"
x-axis Categories [A] x-axis Categories [A]
y-axis "Value" 0 --> 100 y-axis "Value" 0 --> 100
@@ -449,7 +458,7 @@ describe('XY Chart', () => {
showDataLabel: true showDataLabel: true
chartOrientation: horizontal chartOrientation: horizontal
--- ---
xychart-beta xychart
title "Single Bar Chart" title "Single Bar Chart"
x-axis Categories [A] x-axis Categories [A]
y-axis "Value" 0 --> 100 y-axis "Value" 0 --> 100
@@ -467,7 +476,7 @@ describe('XY Chart', () => {
xyChart: xyChart:
showDataLabel: true showDataLabel: true
--- ---
xychart-beta xychart
title "Decimal and Negative Values" title "Decimal and Negative Values"
x-axis Categories [A, B, C] x-axis Categories [A, B, C]
y-axis -10 --> 10 y-axis -10 --> 10
@@ -486,7 +495,7 @@ describe('XY Chart', () => {
showDataLabel: true showDataLabel: true
chartOrientation: horizontal chartOrientation: horizontal
--- ---
xychart-beta xychart
title "Decimal and Negative Values" title "Decimal and Negative Values"
x-axis Categories [A, B, C] x-axis Categories [A, B, C]
y-axis -10 --> 10 y-axis -10 --> 10
@@ -504,7 +513,7 @@ describe('XY Chart', () => {
xyChart: xyChart:
showDataLabel: true showDataLabel: true
--- ---
xychart-beta xychart
title "Sales Revenue" title "Sales Revenue"
x-axis Months [jan,b,c] x-axis Months [jan,b,c]
y-axis "Revenue (in $)" 4000 --> 12000 y-axis "Revenue (in $)" 4000 --> 12000
@@ -561,7 +570,7 @@ describe('XY Chart', () => {
showDataLabel: true showDataLabel: true
chartOrientation: horizontal chartOrientation: horizontal
--- ---
xychart-beta xychart
title "Sales Revenue" title "Sales Revenue"
x-axis Months [jan,b,c] x-axis Months [jan,b,c]
y-axis "Revenue (in $)" 4000 --> 12000 y-axis "Revenue (in $)" 4000 --> 12000
@@ -615,7 +624,7 @@ describe('XY Chart', () => {
xyChart: xyChart:
showDataLabel: true showDataLabel: true
--- ---
xychart-beta xychart
title "Sales Revenue" 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] 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 y-axis "Revenue (in $)" 4000 --> 12000
@@ -672,7 +681,7 @@ describe('XY Chart', () => {
showDataLabel: true showDataLabel: true
chartOrientation: horizontal chartOrientation: horizontal
--- ---
xychart-beta xychart
title "Sales Revenue" 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] 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 y-axis "Revenue (in $)" 4000 --> 12000
@@ -726,7 +735,7 @@ describe('XY Chart', () => {
xyChart: xyChart:
showDataLabel: true showDataLabel: true
--- ---
xychart-beta xychart
title "Sales Revenue" title "Sales Revenue"
x-axis Months [jan] x-axis Months [jan]
y-axis "Revenue (in $)" 3000 --> 12000 y-axis "Revenue (in $)" 3000 --> 12000
@@ -783,7 +792,7 @@ describe('XY Chart', () => {
showDataLabel: true showDataLabel: true
chartOrientation: horizontal chartOrientation: horizontal
--- ---
xychart-beta xychart
title "Sales Revenue" title "Sales Revenue"
x-axis Months [jan] x-axis Months [jan]
y-axis "Revenue (in $)" 3000 --> 12000 y-axis "Revenue (in $)" 3000 --> 12000

View File

@@ -0,0 +1,35 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Mermaid Quick Test Page</title>
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=" />
<style>
div.mermaid {
font-family: 'Courier New', Courier, monospace !important;
}
</style>
</head>
<body>
<h1>Pie chart demos</h1>
<pre class="mermaid">
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
</pre>
<hr />
<script type="module">
import mermaid from '/mermaid.esm.mjs';
mermaid.initialize({
theme: 'forest',
logLevel: 3,
securityLevel: 'loose',
});
</script>
</body>
</html>

View File

@@ -131,6 +131,22 @@
<body> <body>
<pre id="diagram4" class="mermaid"> <pre id="diagram4" class="mermaid">
---
config:
layout: elk
elk:
mergeEdges: false
forceNodeModelOrder: false
considerModelOrder: NONE
---
flowchart TB
a --> a1 & a2 & a3 & a4
b --> b1 & b2
b2 --> b3
b1 --> b4</pre
>
<pre id="diagram4" class="mermaid">
treemap treemap
"Section 1" "Section 1"
"Leaf 1.1": 12 "Leaf 1.1": 12

View File

@@ -41,10 +41,6 @@ graph TB
const { svg } = await mermaid.render('d22', value); const { svg } = await mermaid.render('d22', value);
console.log(svg); console.log(svg);
el.innerHTML = 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));
</script> </script>
</body> </body>
</html> </html>

View File

@@ -182,7 +182,7 @@ const contentLoadedApi = async function () {
for (let i = 0; i < numCodes; i++) { for (let i = 0; i < numCodes; i++) {
const { svg, bindFunctions } = await mermaid.render('newid' + i, graphObj.code[i], divs[i]); const { svg, bindFunctions } = await mermaid.render('newid' + i, graphObj.code[i], divs[i]);
div.innerHTML = svg; div.innerHTML = svg;
bindFunctions(div); bindFunctions?.(div);
} }
} else { } else {
const div = document.createElement('div'); const div = document.createElement('div');
@@ -194,7 +194,7 @@ const contentLoadedApi = async function () {
const { svg, bindFunctions } = await mermaid.render('newid', graphObj.code, div); const { svg, bindFunctions } = await mermaid.render('newid', graphObj.code, div);
div.innerHTML = svg; div.innerHTML = svg;
console.log(div.innerHTML); console.log(div.innerHTML);
bindFunctions(div); bindFunctions?.(div);
} }
} }
}; };

View File

@@ -2,219 +2,219 @@
"durations": [ "durations": [
{ {
"spec": "cypress/integration/other/configuration.spec.js", "spec": "cypress/integration/other/configuration.spec.js",
"duration": 5672 "duration": 6297
}, },
{ {
"spec": "cypress/integration/other/external-diagrams.spec.js", "spec": "cypress/integration/other/external-diagrams.spec.js",
"duration": 1990 "duration": 2187
}, },
{ {
"spec": "cypress/integration/other/ghsa.spec.js", "spec": "cypress/integration/other/ghsa.spec.js",
"duration": 3186 "duration": 3509
}, },
{ {
"spec": "cypress/integration/other/iife.spec.js", "spec": "cypress/integration/other/iife.spec.js",
"duration": 1948 "duration": 2218
}, },
{ {
"spec": "cypress/integration/other/interaction.spec.js", "spec": "cypress/integration/other/interaction.spec.js",
"duration": 11938 "duration": 12104
}, },
{ {
"spec": "cypress/integration/other/rerender.spec.js", "spec": "cypress/integration/other/rerender.spec.js",
"duration": 1932 "duration": 2151
}, },
{ {
"spec": "cypress/integration/other/xss.spec.js", "spec": "cypress/integration/other/xss.spec.js",
"duration": 27237 "duration": 33064
}, },
{ {
"spec": "cypress/integration/rendering/appli.spec.js", "spec": "cypress/integration/rendering/appli.spec.js",
"duration": 3170 "duration": 3488
}, },
{ {
"spec": "cypress/integration/rendering/architecture.spec.ts", "spec": "cypress/integration/rendering/architecture.spec.ts",
"duration": 104 "duration": 106
}, },
{ {
"spec": "cypress/integration/rendering/block.spec.js", "spec": "cypress/integration/rendering/block.spec.js",
"duration": 17390 "duration": 18317
}, },
{ {
"spec": "cypress/integration/rendering/c4.spec.js", "spec": "cypress/integration/rendering/c4.spec.js",
"duration": 5296 "duration": 5592
}, },
{ {
"spec": "cypress/integration/rendering/classDiagram-elk-v3.spec.js", "spec": "cypress/integration/rendering/classDiagram-elk-v3.spec.js",
"duration": 39004 "duration": 39358
}, },
{ {
"spec": "cypress/integration/rendering/classDiagram-handDrawn-v3.spec.js", "spec": "cypress/integration/rendering/classDiagram-handDrawn-v3.spec.js",
"duration": 37653 "duration": 37160
}, },
{ {
"spec": "cypress/integration/rendering/classDiagram-v2.spec.js", "spec": "cypress/integration/rendering/classDiagram-v2.spec.js",
"duration": 23278 "duration": 23660
}, },
{ {
"spec": "cypress/integration/rendering/classDiagram-v3.spec.js", "spec": "cypress/integration/rendering/classDiagram-v3.spec.js",
"duration": 36645 "duration": 36866
}, },
{ {
"spec": "cypress/integration/rendering/classDiagram.spec.js", "spec": "cypress/integration/rendering/classDiagram.spec.js",
"duration": 15418 "duration": 17334
}, },
{ {
"spec": "cypress/integration/rendering/conf-and-directives.spec.js", "spec": "cypress/integration/rendering/conf-and-directives.spec.js",
"duration": 9684 "duration": 9871
}, },
{ {
"spec": "cypress/integration/rendering/current.spec.js", "spec": "cypress/integration/rendering/current.spec.js",
"duration": 2570 "duration": 2833
}, },
{ {
"spec": "cypress/integration/rendering/erDiagram-unified.spec.js", "spec": "cypress/integration/rendering/erDiagram-unified.spec.js",
"duration": 84687 "duration": 85321
}, },
{ {
"spec": "cypress/integration/rendering/erDiagram.spec.js", "spec": "cypress/integration/rendering/erDiagram.spec.js",
"duration": 14819 "duration": 15673
}, },
{ {
"spec": "cypress/integration/rendering/errorDiagram.spec.js", "spec": "cypress/integration/rendering/errorDiagram.spec.js",
"duration": 3371 "duration": 3724
}, },
{ {
"spec": "cypress/integration/rendering/flowchart-elk.spec.js", "spec": "cypress/integration/rendering/flowchart-elk.spec.js",
"duration": 39925 "duration": 41178
}, },
{ {
"spec": "cypress/integration/rendering/flowchart-handDrawn.spec.js", "spec": "cypress/integration/rendering/flowchart-handDrawn.spec.js",
"duration": 34694 "duration": 29966
}, },
{ {
"spec": "cypress/integration/rendering/flowchart-icon.spec.js", "spec": "cypress/integration/rendering/flowchart-icon.spec.js",
"duration": 7137 "duration": 7689
}, },
{ {
"spec": "cypress/integration/rendering/flowchart-shape-alias.spec.ts", "spec": "cypress/integration/rendering/flowchart-shape-alias.spec.ts",
"duration": 24740 "duration": 24709
}, },
{ {
"spec": "cypress/integration/rendering/flowchart-v2.spec.js", "spec": "cypress/integration/rendering/flowchart-v2.spec.js",
"duration": 42077 "duration": 45565
}, },
{ {
"spec": "cypress/integration/rendering/flowchart.spec.js", "spec": "cypress/integration/rendering/flowchart.spec.js",
"duration": 30642 "duration": 31144
}, },
{ {
"spec": "cypress/integration/rendering/gantt.spec.js", "spec": "cypress/integration/rendering/gantt.spec.js",
"duration": 18085 "duration": 20808
}, },
{ {
"spec": "cypress/integration/rendering/gitGraph.spec.js", "spec": "cypress/integration/rendering/gitGraph.spec.js",
"duration": 50107 "duration": 49985
}, },
{ {
"spec": "cypress/integration/rendering/iconShape.spec.ts", "spec": "cypress/integration/rendering/iconShape.spec.ts",
"duration": 276279 "duration": 273272
}, },
{ {
"spec": "cypress/integration/rendering/imageShape.spec.ts", "spec": "cypress/integration/rendering/imageShape.spec.ts",
"duration": 56505 "duration": 55880
}, },
{ {
"spec": "cypress/integration/rendering/info.spec.ts", "spec": "cypress/integration/rendering/info.spec.ts",
"duration": 3036 "duration": 3271
}, },
{ {
"spec": "cypress/integration/rendering/journey.spec.js", "spec": "cypress/integration/rendering/journey.spec.js",
"duration": 6889 "duration": 7293
}, },
{ {
"spec": "cypress/integration/rendering/kanban.spec.ts", "spec": "cypress/integration/rendering/kanban.spec.ts",
"duration": 7353 "duration": 7861
}, },
{ {
"spec": "cypress/integration/rendering/katex.spec.js", "spec": "cypress/integration/rendering/katex.spec.js",
"duration": 3580 "duration": 3922
}, },
{ {
"spec": "cypress/integration/rendering/marker_unique_id.spec.js", "spec": "cypress/integration/rendering/marker_unique_id.spec.js",
"duration": 2508 "duration": 2726
}, },
{ {
"spec": "cypress/integration/rendering/mindmap.spec.ts", "spec": "cypress/integration/rendering/mindmap.spec.ts",
"duration": 10939 "duration": 11670
}, },
{ {
"spec": "cypress/integration/rendering/newShapes.spec.ts", "spec": "cypress/integration/rendering/newShapes.spec.ts",
"duration": 149102 "duration": 146020
}, },
{ {
"spec": "cypress/integration/rendering/oldShapes.spec.ts", "spec": "cypress/integration/rendering/oldShapes.spec.ts",
"duration": 113987 "duration": 114244
}, },
{ {
"spec": "cypress/integration/rendering/packet.spec.ts", "spec": "cypress/integration/rendering/packet.spec.ts",
"duration": 4060 "duration": 5036
}, },
{ {
"spec": "cypress/integration/rendering/pie.spec.ts", "spec": "cypress/integration/rendering/pie.spec.ts",
"duration": 5715 "duration": 6545
}, },
{ {
"spec": "cypress/integration/rendering/quadrantChart.spec.js", "spec": "cypress/integration/rendering/quadrantChart.spec.js",
"duration": 8945 "duration": 9097
}, },
{ {
"spec": "cypress/integration/rendering/radar.spec.js", "spec": "cypress/integration/rendering/radar.spec.js",
"duration": 5337 "duration": 5676
}, },
{ {
"spec": "cypress/integration/rendering/requirement.spec.js", "spec": "cypress/integration/rendering/requirement.spec.js",
"duration": 2643 "duration": 2795
}, },
{ {
"spec": "cypress/integration/rendering/requirementDiagram-unified.spec.js", "spec": "cypress/integration/rendering/requirementDiagram-unified.spec.js",
"duration": 52072 "duration": 51660
}, },
{ {
"spec": "cypress/integration/rendering/sankey.spec.ts", "spec": "cypress/integration/rendering/sankey.spec.ts",
"duration": 6692 "duration": 6957
}, },
{ {
"spec": "cypress/integration/rendering/sequencediagram.spec.js", "spec": "cypress/integration/rendering/sequencediagram.spec.js",
"duration": 35721 "duration": 36026
}, },
{ {
"spec": "cypress/integration/rendering/stateDiagram-v2.spec.js", "spec": "cypress/integration/rendering/stateDiagram-v2.spec.js",
"duration": 26030 "duration": 29551
}, },
{ {
"spec": "cypress/integration/rendering/stateDiagram.spec.js", "spec": "cypress/integration/rendering/stateDiagram.spec.js",
"duration": 16333 "duration": 17364
}, },
{ {
"spec": "cypress/integration/rendering/theme.spec.js", "spec": "cypress/integration/rendering/theme.spec.js",
"duration": 29287 "duration": 30209
}, },
{ {
"spec": "cypress/integration/rendering/timeline.spec.ts", "spec": "cypress/integration/rendering/timeline.spec.ts",
"duration": 8491 "duration": 8699
}, },
{ {
"spec": "cypress/integration/rendering/treemap.spec.ts", "spec": "cypress/integration/rendering/treemap.spec.ts",
"duration": 12291 "duration": 12168
}, },
{ {
"spec": "cypress/integration/rendering/xyChart.spec.js", "spec": "cypress/integration/rendering/xyChart.spec.js",
"duration": 20651 "duration": 21453
}, },
{ {
"spec": "cypress/integration/rendering/zenuml.spec.js", "spec": "cypress/integration/rendering/zenuml.spec.js",
"duration": 3218 "duration": 3577
} }
] ]
} }

View File

@@ -10,7 +10,7 @@
<body> <body>
<h1>Block diagram demos</h1> <h1>Block diagram demos</h1>
<pre id="diagram" class="mermaid"> <pre id="diagram" class="mermaid">
block-beta block
columns 1 columns 1
db(("DB")) db(("DB"))
blockArrowId6<["&nbsp;&nbsp;&nbsp;"]>(down) blockArrowId6<["&nbsp;&nbsp;&nbsp;"]>(down)
@@ -26,7 +26,7 @@ columns 1
style B fill:#f9F,stroke:#333,stroke-width:4px style B fill:#f9F,stroke:#333,stroke-width:4px
</pre> </pre>
<pre id="diagram" class="mermaid"> <pre id="diagram" class="mermaid">
block-beta block
A1["square"] A1["square"]
B1("rounded") B1("rounded")
C1(("circle")) C1(("circle"))
@@ -36,7 +36,7 @@ block-beta
</pre> </pre>
<pre id="diagram" class="mermaid"> <pre id="diagram" class="mermaid">
block-beta block
A1(["stadium"]) A1(["stadium"])
A2[["subroutine"]] A2[["subroutine"]]
B1[("cylinder")] B1[("cylinder")]
@@ -48,7 +48,7 @@ block-beta
</pre> </pre>
<pre id="diagram" class="mermaid"> <pre id="diagram" class="mermaid">
block-beta block
block:e:4 block:e:4
columns 2 columns 2
f f
@@ -57,7 +57,7 @@ block-beta
</pre> </pre>
<pre id="diagram" class="mermaid"> <pre id="diagram" class="mermaid">
block-beta block
block:e:4 block:e:4
columns 2 columns 2
f f
@@ -67,7 +67,7 @@ block-beta
</pre> </pre>
<pre id="diagram" class="mermaid"> <pre id="diagram" class="mermaid">
block-beta block
columns 3 columns 3
a:3 a:3
block:e:3 block:e:3
@@ -80,7 +80,7 @@ block-beta
</pre> </pre>
<pre id="diagram" class="mermaid"> <pre id="diagram" class="mermaid">
block-beta block
columns 4 columns 4
a b c d a b c d
block:e:4 block:e:4
@@ -97,19 +97,19 @@ flowchart LR
X-- "a label" -->z X-- "a label" -->z
</pre> </pre>
<pre id="diagram" class="mermaid"> <pre id="diagram" class="mermaid">
block-beta block
columns 5 columns 5
A space B A space B
A --x B A --x B
</pre> </pre>
<pre id="diagram" class="mermaid"> <pre id="diagram" class="mermaid">
block-beta block
columns 3 columns 3
a["A wide one"] b:2 c:2 d a["A wide one"] b:2 c:2 d
</pre> </pre>
<pre id="diagram" class="mermaid"> <pre id="diagram" class="mermaid">
block-beta block
columns 3 columns 3
a b c a b c
e:3 e:3
@@ -117,7 +117,7 @@ columns 3
</pre> </pre>
<pre id="diagram" class="mermaid"> <pre id="diagram" class="mermaid">
block-beta block
A1:3 A1:3
A2:1 A2:1

View File

@@ -11,7 +11,7 @@
rel="stylesheet" rel="stylesheet"
/> />
<link <link
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css"
rel="stylesheet" rel="stylesheet"
/> />
<link <link

View File

@@ -20,12 +20,14 @@
width: 800 width: 800
nodeAlignment: left nodeAlignment: left
--- ---
sankey-beta sankey
Revenue,Expenses,10 a,b,8
Revenue,Profit,10 b,c,8
Expenses,Manufacturing,5 c,d,8
Expenses,Tax,3 d,e,8
Expenses,Research,2
x,c,4
c,y,4
</pre> </pre>
<h2>Energy flow</h2> <h2>Energy flow</h2>
@@ -40,7 +42,7 @@
linkColor: gradient linkColor: gradient
nodeAlignment: justify nodeAlignment: justify
--- ---
sankey-beta sankey
Agricultural 'waste',Bio-conversion,124.729 Agricultural 'waste',Bio-conversion,124.729
Bio-conversion,Liquid,0.597 Bio-conversion,Liquid,0.597

View File

@@ -16,7 +16,7 @@
<body> <body>
<h1>XY Charts demos</h1> <h1>XY Charts demos</h1>
<pre class="mermaid"> <pre class="mermaid">
xychart-beta xychart
title "Sales Revenue (in $)" title "Sales Revenue (in $)"
x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
y-axis "Revenue (in $)" 4000 --> 11000 y-axis "Revenue (in $)" 4000 --> 11000
@@ -26,7 +26,7 @@
<hr /> <hr />
<h1>XY Charts horizontal</h1> <h1>XY Charts horizontal</h1>
<pre class="mermaid"> <pre class="mermaid">
xychart-beta horizontal xychart horizontal
title "Basic xychart" title "Basic xychart"
x-axis "this is x axis" [category1, "category 2", category3, category4] x-axis "this is x axis" [category1, "category 2", category3, category4]
y-axis yaxisText 10 --> 150 y-axis yaxisText 10 --> 150
@@ -36,7 +36,7 @@
<hr /> <hr />
<h1>XY Charts only lines and bar</h1> <h1>XY Charts only lines and bar</h1>
<pre class="mermaid"> <pre class="mermaid">
xychart-beta xychart
line [23, 46, 77, 34] line [23, 46, 77, 34]
line [45, 32, 33, 12] line [45, 32, 33, 12]
line [87, 54, 99, 85] line [87, 54, 99, 85]
@@ -48,13 +48,13 @@
<hr /> <hr />
<h1>XY Charts with +ve and -ve numbers</h1> <h1>XY Charts with +ve and -ve numbers</h1>
<pre class="mermaid"> <pre class="mermaid">
xychart-beta xychart
line [+1.3, .6, 2.4, -.34] line [+1.3, .6, 2.4, -.34]
</pre> </pre>
<h1>XY Charts Bar with multiple category</h1> <h1>XY Charts Bar with multiple category</h1>
<pre class="mermaid"> <pre class="mermaid">
xychart-beta xychart
title "Basic xychart with many categories" title "Basic xychart with many categories"
x-axis "this is x axis" [category1, "category 2", category3, category4, category5, category6, category7] x-axis "this is x axis" [category1, "category 2", category3, category4, category5, category6, category7]
y-axis yaxisText 10 --> 150 y-axis yaxisText 10 --> 150
@@ -63,7 +63,7 @@
<h1>XY Charts line with multiple category</h1> <h1>XY Charts line with multiple category</h1>
<pre class="mermaid"> <pre class="mermaid">
xychart-beta xychart
title "Line chart with many category" title "Line chart with many category"
x-axis "this is x axis" [category1, "category 2", category3, category4, category5, category6, category7] x-axis "this is x axis" [category1, "category 2", category3, category4, category5, category6, category7]
y-axis yaxisText 10 --> 150 y-axis yaxisText 10 --> 150
@@ -72,7 +72,7 @@
<h1>XY Charts category with large text</h1> <h1>XY Charts category with large text</h1>
<pre class="mermaid"> <pre class="mermaid">
xychart-beta xychart
title "Basic xychart with many categories with category overlap" 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] 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 y-axis yaxisText 10 --> 150
@@ -89,7 +89,7 @@ config:
height: 20 height: 20
plotReservedSpacePercent: 100 plotReservedSpacePercent: 100
--- ---
xychart-beta xychart
line [5000, 9000, 7500, 6200, 9500, 5500, 11000, 8200, 9200, 9500, 7000, 8800] line [5000, 9000, 7500, 6200, 9500, 5500, 11000, 8200, 9200, 9500, 7000, 8800]
</pre> </pre>
@@ -103,7 +103,7 @@ config:
height: 20 height: 20
plotReservedSpacePercent: 100 plotReservedSpacePercent: 100
--- ---
xychart-beta xychart
bar [5000, 9000, 7500, 6200, 9500, 5500, 11000, 8200, 9200, 9500, 7000, 8800] bar [5000, 9000, 7500, 6200, 9500, 5500, 11000, 8200, 9200, 9500, 7000, 8800]
</pre> </pre>
@@ -136,7 +136,7 @@ config:
chartOrientation: horizontal chartOrientation: horizontal
plotReservedSpacePercent: 60 plotReservedSpacePercent: 60
--- ---
xychart-beta xychart
title "Sales Revenue" title "Sales Revenue"
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
y-axis "Revenue (in $)" 4000 --> 11000 y-axis "Revenue (in $)" 4000 --> 11000
@@ -162,7 +162,7 @@ config:
xAxisLineColor: "#87ceeb" xAxisLineColor: "#87ceeb"
plotColorPalette: "#008000, #faba63" plotColorPalette: "#008000, #faba63"
--- ---
xychart-beta xychart
title "Sales Revenue" title "Sales Revenue"
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
y-axis "Revenue (in $)" 4000 --> 11000 y-axis "Revenue (in $)" 4000 --> 11000

View File

@@ -29,7 +29,8 @@ In GitHub, you first [**fork a mermaid repository**](https://github.com/mermaid-
Then you **clone** a copy to your local development machine (e.g. where you code) to make a copy with all the files to work with. Then you **clone** a copy to your local development machine (e.g. where you code) to make a copy with all the files to work with.
> **💡 Tip** > [Here is a GitHub document that gives an overview of the process](https://docs.github.com/en/get-started/quickstart/fork-a-repo). > **💡 Tip**
> [Here is a GitHub document that gives an overview of the process](https://docs.github.com/en/get-started/quickstart/fork-a-repo).
```bash ```bash
git clone git@github.com/your-fork/mermaid git clone git@github.com/your-fork/mermaid

View File

@@ -33,7 +33,8 @@ mindmap
## Join the Development ## Join the Development
> **💡 Tip** > **Check out our** [**detailed contribution guide**](./contributing.md). > **💡 Tip**
> **Check out our** [**detailed contribution guide**](./contributing.md).
Where to start: Where to start:
@@ -47,7 +48,8 @@ Where to start:
## A Question Or a Suggestion? ## A Question Or a Suggestion?
> **💡 Tip** > **Have a look at** [**how to open an issue**](./questions-and-suggestions.md). > **💡 Tip**
> **Have a look at** [**how to open an issue**](./questions-and-suggestions.md).
If you have faced a vulnerability [report it to us](./security.md). If you have faced a vulnerability [report it to us](./security.md).

View File

@@ -22,7 +22,6 @@ While directives allow you to change most of the default configuration settings,
Mermaid basically supports two types of configuration options to be overridden by directives. Mermaid basically supports two types of configuration options to be overridden by directives.
1. _General/Top Level configurations_ : These are the configurations that are available and applied to all the diagram. **Some of the most important top-level** configurations are: 1. _General/Top Level configurations_ : These are the configurations that are available and applied to all the diagram. **Some of the most important top-level** configurations are:
- theme - theme
- fontFamily - fontFamily
- logLevel - logLevel

View File

@@ -12,4 +12,4 @@
> `const` **configKeys**: `Set`<`string`> > `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)

View File

@@ -88,13 +88,103 @@ Defined in: node_modules/.pnpm/typescript\@5.7.3/node_modules/typescript/lib/lib
--- ---
### prepareStackTrace()? ### stackTraceLimit
> `static` `optional` **prepareStackTrace**: (`err`, `stackTraces`) => `any` > `static` **stackTraceLimit**: `number`
Defined in: node_modules/.pnpm/@types+node\@22.13.5/node_modules/@types/node/globals.d.ts:143 Defined in: node_modules/.pnpm/@types+node\@22.17.2/node_modules/@types/node/globals.d.ts:161
Optional override for formatting stack traces The `Error.stackTraceLimit` property specifies the number of stack frames
collected by a stack trace (whether generated by `new Error().stack` or
`Error.captureStackTrace(obj)`).
The default value is `10` but may be set to any valid JavaScript number. Changes
will affect any stack trace captured _after_ the value has been changed.
If set to a non-number value, or set to a negative number, stack traces will
not capture any frames.
#### Inherited from
`Error.stackTraceLimit`
## Methods
### captureStackTrace()
> `static` **captureStackTrace**(`targetObject`, `constructorOpt`?): `void`
Defined in: node_modules/.pnpm/@types+node\@22.17.2/node_modules/@types/node/globals.d.ts:145
Creates a `.stack` property on `targetObject`, which when accessed returns
a string representing the location in the code at which
`Error.captureStackTrace()` was called.
```js
const myObject = {};
Error.captureStackTrace(myObject);
myObject.stack; // Similar to `new Error().stack`
```
The first line of the trace will be prefixed with
`${myObject.name}: ${myObject.message}`.
The optional `constructorOpt` argument accepts a function. If given, all frames
above `constructorOpt`, including `constructorOpt`, will be omitted from the
generated stack trace.
The `constructorOpt` argument is useful for hiding implementation
details of error generation from the user. For instance:
```js
function a() {
b();
}
function b() {
c();
}
function c() {
// Create an error without stack trace to avoid calculating the stack trace twice.
const { stackTraceLimit } = Error;
Error.stackTraceLimit = 0;
const error = new Error();
Error.stackTraceLimit = stackTraceLimit;
// Capture the stack trace above function b
Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace
throw error;
}
a();
```
#### Parameters
##### targetObject
`object`
##### constructorOpt?
`Function`
#### Returns
`void`
#### Inherited from
`Error.captureStackTrace`
---
### prepareStackTrace()
> `static` **prepareStackTrace**(`err`, `stackTraces`): `any`
Defined in: node_modules/.pnpm/@types+node\@22.17.2/node_modules/@types/node/globals.d.ts:149
#### Parameters #### Parameters
@@ -117,43 +207,3 @@ Optional override for formatting stack traces
#### Inherited from #### Inherited from
`Error.prepareStackTrace` `Error.prepareStackTrace`
---
### stackTraceLimit
> `static` **stackTraceLimit**: `number`
Defined in: node_modules/.pnpm/@types+node\@22.13.5/node_modules/@types/node/globals.d.ts:145
#### Inherited from
`Error.stackTraceLimit`
## Methods
### captureStackTrace()
> `static` **captureStackTrace**(`targetObject`, `constructorOpt`?): `void`
Defined in: node_modules/.pnpm/@types+node\@22.13.5/node_modules/@types/node/globals.d.ts:136
Create .stack property on a target object
#### Parameters
##### targetObject
`object`
##### constructorOpt?
`Function`
#### Returns
`void`
#### Inherited from
`Error.captureStackTrace`

View File

@@ -18,7 +18,7 @@ Defined in: [packages/mermaid/src/config.type.ts:58](https://github.com/mermaid-
> `optional` **altFontFamily**: `string` > `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` > `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` > `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. Controls whether or arrow markers in html code are absolute paths or anchors.
This matters if you are using base tag settings. 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` > `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` > `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` > `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` > `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` > `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 This option controls if the generated ids of nodes in the SVG are
generated randomly or based on a seed. generated randomly or based on a seed.
@@ -93,7 +93,7 @@ should not change unless content is changed.
> `optional` **deterministicIDSeed**: `string` > `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. This option is the optional seed for deterministic ids.
If set to `undefined` but deterministicIds is `true`, a simple number iterator is used. 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` > `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) 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? #### cycleBreakingStrategy?
> `optional` **cycleBreakingStrategy**: `"GREEDY"` | `"DEPTH_FIRST"` | `"INTERACTIVE"` | `"MODEL_ORDER"` | `"GREEDY_MODEL_ORDER"` > `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. 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? #### mergeEdges?
> `optional` **mergeEdges**: `boolean` > `optional` **mergeEdges**: `boolean`
@@ -139,7 +151,7 @@ Elk specific option affecting how nodes are placed.
> `optional` **er**: `ErDiagramConfig` > `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` > `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` > `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. Specifies the font to be used in the rendered diagrams.
Can be any possible CSS `font-family`. Can be any possible CSS `font-family`.
@@ -167,7 +179,7 @@ See <https://developer.mozilla.org/en-US/docs/Web/CSS/font-family>
> `optional` **fontSize**: `number` > `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` > `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 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. 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` > `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` > `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` > `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` > `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` > `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` > `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 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 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` > `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. 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` > `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` > `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` > `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` > `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` > `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` > `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` > `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` > `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`\[] > `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 This option controls which `currentConfig` keys are considered secure and
can only be changed via call to `mermaid.initialize`. 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"` > `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 Level of trust for parsed diagram
@@ -386,7 +398,7 @@ Level of trust for parsed diagram
> `optional` **sequence**: `SequenceDiagramConfig` > `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` > `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 Dictates whether mermaid starts on Page load
@@ -404,7 +416,7 @@ Dictates whether mermaid starts on Page load
> `optional` **state**: `StateDiagramConfig` > `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` > `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. Suppresses inserting 'Syntax error' diagram in the DOM.
This is useful when you want to control how to handle syntax errors in your application. 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` > `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` > `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` > `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)

View File

@@ -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) ✅ - [Obsidian](https://help.obsidian.md/Editing+and+formatting/Advanced+formatting+syntax#Diagram) ✅
- [Outline](https://docs.getoutline.com/s/guide/doc/diagrams-KQiKoT4wzK) ✅ - [Outline](https://docs.getoutline.com/s/guide/doc/diagrams-KQiKoT4wzK) ✅
- [Redmine](https://redmine.org) - [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) - [Markdown for mermaid plugin](https://github.com/jamieh-mongolian/markdown-for-mermaid-plugin)
- [redmine-mermaid](https://github.com/styz/redmine_mermaid) - [redmine-mermaid](https://github.com/styz/redmine_mermaid)
- Visual Studio Code [Polyglot Interactive Notebooks](https://github.com/dotnet/interactive#net-interactive) - 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/) - [Grav CMS](https://getgrav.org/)
- [Mermaid Diagrams Plugin](https://github.com/DanielFlaum/grav-plugin-mermaid-diagrams) - [Mermaid Diagrams Plugin](https://github.com/DanielFlaum/grav-plugin-mermaid-diagrams)
- [GitLab Markdown Adapter](https://github.com/Goutte/grav-plugin-gitlab-markdown-adapter) - [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) - [Tracker Entity Relationship Diagram](https://doc.tiki.org/Tracker-Entity-Relationship-Diagram)
- [VitePress](https://vitepress.vuejs.org/) - [VitePress](https://vitepress.vuejs.org/)
- [Plugin for Mermaid.js](https://emersonbottero.github.io/vitepress-plugin-mermaid/) - [Plugin for Mermaid.js](https://emersonbottero.github.io/vitepress-plugin-mermaid/)

View File

@@ -29,7 +29,6 @@ Try the Ultimate AI, Mermaid, and Visual Diagramming Suite by creating an accoun
- **Plugins** - A plugin system for extending the functionality of Mermaid. - **Plugins** - A plugin system for extending the functionality of Mermaid.
Official Mermaid Chart plugins: Official Mermaid Chart plugins:
- [Mermaid Chart GPT](https://chatgpt.com/g/g-684cc36f30208191b21383b88650a45d-mermaid-chart-diagrams-and-charts) - [Mermaid Chart GPT](https://chatgpt.com/g/g-684cc36f30208191b21383b88650a45d-mermaid-chart-diagrams-and-charts)
- [Confluence](https://marketplace.atlassian.com/apps/1234056/mermaid-chart-for-confluence?hosting=cloud&tab=overview) - [Confluence](https://marketplace.atlassian.com/apps/1234056/mermaid-chart-for-confluence?hosting=cloud&tab=overview)
- [Jira](https://marketplace.atlassian.com/apps/1234810/mermaid-chart-for-jira?tab=overview&hosting=cloud) - [Jira](https://marketplace.atlassian.com/apps/1234810/mermaid-chart-for-jira?tab=overview&hosting=cloud)

View File

@@ -35,13 +35,11 @@ The Mermaid Chart team is excited to introduce a new Visual Editor for Flowchart
Learn more: Learn more:
- Visual Editor For Flowcharts - Visual Editor For Flowcharts
- [Blog post](https://www.mermaidchart.com/blog/posts/mermaid-chart-releases-new-visual-editor-for-flowcharts) - [Blog post](https://www.mermaidchart.com/blog/posts/mermaid-chart-releases-new-visual-editor-for-flowcharts)
- [Demo video](https://www.youtube.com/watch?v=5aja0gijoO0) - [Demo video](https://www.youtube.com/watch?v=5aja0gijoO0)
- Visual Editor For Sequence diagrams - Visual Editor For Sequence diagrams
- [Blog post](https://www.mermaidchart.com/blog/posts/mermaid-chart-unveils-visual-editor-for-sequence-diagrams) - [Blog post](https://www.mermaidchart.com/blog/posts/mermaid-chart-unveils-visual-editor-for-sequence-diagrams)
- [Demo video](https://youtu.be/imc2u5_N6Dc) - [Demo video](https://youtu.be/imc2u5_N6Dc)

View File

@@ -6,6 +6,66 @@
# Blog # 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 Mermaids 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 youre diagramming workflows, software architecture, or data relationships, the right AI tool can significantly boost productivity and streamline communication.
## [5 Time-Saving Tips for Using Mermaids 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 Charts 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 cant 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 youre 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) ## [GUI for editing Mermaid Class Diagrams](https://docs.mermaidchart.com/blog/posts/gui-for-editing-mermaid-class-diagrams)
1/17/2025 • 5 mins 1/17/2025 • 5 mins

View File

@@ -9,7 +9,7 @@
## Introduction to Block Diagrams ## Introduction to Block Diagrams
```mermaid-example ```mermaid-example
block-beta block
columns 1 columns 1
db(("DB")) db(("DB"))
blockArrowId6<["&nbsp;&nbsp;&nbsp;"]>(down) blockArrowId6<["&nbsp;&nbsp;&nbsp;"]>(down)
@@ -26,7 +26,7 @@ columns 1
``` ```
```mermaid ```mermaid
block-beta block
columns 1 columns 1
db(("DB")) db(("DB"))
blockArrowId6<["&nbsp;&nbsp;&nbsp;"]>(down) blockArrowId6<["&nbsp;&nbsp;&nbsp;"]>(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: To create a simple block diagram with three blocks labeled 'a', 'b', and 'c', the syntax is as follows:
```mermaid-example ```mermaid-example
block-beta block
a b c a b c
``` ```
```mermaid ```mermaid
block-beta block
a b c 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: 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 ```mermaid-example
block-beta block
columns 3 columns 3
a b c d a b c d
``` ```
```mermaid ```mermaid
block-beta block
columns 3 columns 3
a b c d 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: To create a block diagram where one block spans across two columns, you can specify the desired width for each block:
```mermaid-example ```mermaid-example
block-beta block
columns 3 columns 3
a["A label"] b:2 c:2 d a["A label"] b:2 c:2 d
``` ```
```mermaid ```mermaid
block-beta block
columns 3 columns 3
a["A label"] b:2 c:2 d 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: 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 ```mermaid-example
block-beta block
block block
D D
end end
@@ -161,7 +161,7 @@ block-beta
``` ```
```mermaid ```mermaid
block-beta block
block block
D D
end 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: 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 ```mermaid-example
block-beta block
columns 3 columns 3
a:3 a:3
block:group1:2 block:group1:2
@@ -195,7 +195,7 @@ block-beta
``` ```
```mermaid ```mermaid
block-beta block
columns 3 columns 3
a:3 a:3
block:group1:2 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: 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 ```mermaid-example
block-beta block
block block
columns 1 columns 1
a["A label"] b c d a["A label"] b c d
@@ -223,7 +223,7 @@ block-beta
``` ```
```mermaid ```mermaid
block-beta block
block block
columns 1 columns 1
a["A label"] b c d 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: To create a block with round edges, which can be used to represent a softer or more flexible component:
```mermaid-example ```mermaid-example
block-beta block
id1("This is the text in the box") id1("This is the text in the box")
``` ```
```mermaid ```mermaid
block-beta block
id1("This is the text in the box") 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: A stadium-shaped block, resembling an elongated circle, can be used for components that are process-oriented:
```mermaid-example ```mermaid-example
block-beta block
id1(["This is the text in the box"]) id1(["This is the text in the box"])
``` ```
```mermaid ```mermaid
block-beta block
id1(["This is the text in the box"]) 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: For representing subroutines or contained processes, a block with double vertical lines is useful:
```mermaid-example ```mermaid-example
block-beta block
id1[["This is the text in the box"]] id1[["This is the text in the box"]]
``` ```
```mermaid ```mermaid
block-beta block
id1[["This is the text in the box"]] 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: The cylindrical shape is ideal for representing databases or storage components:
```mermaid-example ```mermaid-example
block-beta block
id1[("Database")] id1[("Database")]
``` ```
```mermaid ```mermaid
block-beta block
id1[("Database")] id1[("Database")]
``` ```
@@ -303,12 +303,12 @@ block-beta
A circle can be used for centralized or pivotal components: A circle can be used for centralized or pivotal components:
```mermaid-example ```mermaid-example
block-beta block
id1(("This is the text in the circle")) id1(("This is the text in the circle"))
``` ```
```mermaid ```mermaid
block-beta block
id1(("This is the text in the circle")) 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** **Asymmetric**
```mermaid-example ```mermaid-example
block-beta block
id1>"This is the text in the box"] id1>"This is the text in the box"]
``` ```
```mermaid ```mermaid
block-beta block
id1>"This is the text in the box"] id1>"This is the text in the box"]
``` ```
**Rhombus** **Rhombus**
```mermaid-example ```mermaid-example
block-beta block
id1{"This is the text in the box"} id1{"This is the text in the box"}
``` ```
```mermaid ```mermaid
block-beta block
id1{"This is the text in the box"} id1{"This is the text in the box"}
``` ```
**Hexagon** **Hexagon**
```mermaid-example ```mermaid-example
block-beta block
id1{{"This is the text in the box"}} id1{{"This is the text in the box"}}
``` ```
```mermaid ```mermaid
block-beta block
id1{{"This is the text in the box"}} 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: Parallelogram and trapezoid shapes are perfect for inputs/outputs and transitional processes:
```mermaid-example ```mermaid-example
block-beta block
id1[/"This is the text in the box"/] id1[/"This is the text in the box"/]
id2[\"This is the text in the box"\] id2[\"This is the text in the box"\]
A[/"Christmas"\] A[/"Christmas"\]
@@ -365,7 +365,7 @@ block-beta
``` ```
```mermaid ```mermaid
block-beta block
id1[/"This is the text in the box"/] id1[/"This is the text in the box"/]
id2[\"This is the text in the box"\] id2[\"This is the text in the box"\]
A[/"Christmas"\] A[/"Christmas"\]
@@ -377,12 +377,12 @@ block-beta
For highlighting critical or high-priority components, a double circle can be effective: For highlighting critical or high-priority components, a double circle can be effective:
```mermaid-example ```mermaid-example
block-beta block
id1((("This is the text in the circle"))) id1((("This is the text in the circle")))
``` ```
```mermaid ```mermaid
block-beta block
id1((("This is the text in the circle"))) 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: Block arrows can visually indicate direction or flow within a process:
```mermaid-example ```mermaid-example
block-beta block
blockArrowId<["Label"]>(right) blockArrowId<["Label"]>(right)
blockArrowId2<["Label"]>(left) blockArrowId2<["Label"]>(left)
blockArrowId3<["Label"]>(up) blockArrowId3<["Label"]>(up)
@@ -406,7 +406,7 @@ block-beta
``` ```
```mermaid ```mermaid
block-beta block
blockArrowId<["Label"]>(right) blockArrowId<["Label"]>(right)
blockArrowId2<["Label"]>(left) blockArrowId2<["Label"]>(left)
blockArrowId3<["Label"]>(up) 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: Space blocks can be used to create intentional empty spaces in the diagram, which is useful for layout and readability:
```mermaid-example ```mermaid-example
block-beta block
columns 3 columns 3
a space b a space b
c d e c d e
``` ```
```mermaid ```mermaid
block-beta block
columns 3 columns 3
a space b a space b
c d e c d e
@@ -437,12 +437,12 @@ block-beta
or or
```mermaid-example ```mermaid-example
block-beta block
ida space:3 idb idc ida space:3 idb idc
``` ```
```mermaid ```mermaid
block-beta block
ida space:3 idb idc 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: A simple link with an arrow can be created to show direction or flow from one block to another:
```mermaid-example ```mermaid-example
block-beta block
A space B A space B
A-->B A-->B
``` ```
```mermaid ```mermaid
block-beta block
A space B A space B
A-->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: To add text to a link, the syntax includes the text within the link definition:
```mermaid-example ```mermaid-example
block-beta block
A space:2 B A space:2 B
A-- "X" -->B A-- "X" -->B
``` ```
```mermaid ```mermaid
block-beta block
A space:2 B A space:2 B
A-- "X" -->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: Example - Edges and Styles:
```mermaid-example ```mermaid-example
block-beta block
columns 1 columns 1
db(("DB")) db(("DB"))
blockArrowId6<["&nbsp;&nbsp;&nbsp;"]>(down) blockArrowId6<["&nbsp;&nbsp;&nbsp;"]>(down)
@@ -523,7 +523,7 @@ columns 1
``` ```
```mermaid ```mermaid
block-beta block
columns 1 columns 1
db(("DB")) db(("DB"))
blockArrowId6<["&nbsp;&nbsp;&nbsp;"]>(down) blockArrowId6<["&nbsp;&nbsp;&nbsp;"]>(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: 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 ```mermaid-example
block-beta block
id1 space id2 id1 space id2
id1("Start")-->id2("Stop") id1("Start")-->id2("Stop")
style id1 fill:#636,stroke:#333,stroke-width:4px style id1 fill:#636,stroke:#333,stroke-width:4px
@@ -560,7 +560,7 @@ block-beta
``` ```
```mermaid ```mermaid
block-beta block
id1 space id2 id1 space id2
id1("Start")-->id2("Stop") id1("Start")-->id2("Stop")
style id1 fill:#636,stroke:#333,stroke-width:4px 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 #### Example - Styling a Single Class
```mermaid-example ```mermaid-example
block-beta block
A space B A space B
A-->B A-->B
classDef blue fill:#6e6ce6,stroke:#333,stroke-width:4px; classDef blue fill:#6e6ce6,stroke:#333,stroke-width:4px;
@@ -583,7 +583,7 @@ block-beta
``` ```
```mermaid ```mermaid
block-beta block
A space B A space B
A-->B A-->B
classDef blue fill:#6e6ce6,stroke:#333,stroke-width:4px; 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: Illustrating a simple software system architecture with interconnected components:
```mermaid-example ```mermaid-example
block-beta block
columns 3 columns 3
Frontend blockArrowId6<[" "]>(right) Backend Frontend blockArrowId6<[" "]>(right) Backend
space:2 down<[" "]>(down) space:2 down<[" "]>(down)
@@ -621,7 +621,7 @@ block-beta
``` ```
```mermaid ```mermaid
block-beta block
columns 3 columns 3
Frontend blockArrowId6<[" "]>(right) Backend Frontend blockArrowId6<[" "]>(right) Backend
space:2 down<[" "]>(down) 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: Representing a business process flow with decision points and multiple stages:
```mermaid-example ```mermaid-example
block-beta block
columns 3 columns 3
Start(("Start")) space:2 Start(("Start")) space:2
down<[" "]>(down) space:2 down<[" "]>(down) space:2
@@ -653,7 +653,7 @@ block-beta
``` ```
```mermaid ```mermaid
block-beta block
columns 3 columns 3
Start(("Start")) space:2 Start(("Start")) space:2
down<[" "]>(down) 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: A common mistake is incorrect linking syntax, which can lead to unexpected results or broken diagrams:
``` ```
block-beta block
A - B 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: 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 ```mermaid-example
block-beta block
A space B A space B
A --> B A --> B
``` ```
```mermaid ```mermaid
block-beta block
A space B A space B
A --> 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: Applying styles in the wrong context or with incorrect syntax can lead to blocks not being styled as intended:
```mermaid-example ```mermaid-example
block-beta block
A A
style A fill#969; style A fill#969;
``` ```
```mermaid ```mermaid
block-beta block
A A
style A fill#969; 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: Correct the syntax by ensuring proper separation of style properties with commas and using the correct CSS property format:
```mermaid-example ```mermaid-example
block-beta block
A A
style A fill:#969,stroke:#333; style A fill:#969,stroke:#333;
``` ```
```mermaid ```mermaid
block-beta block
A A
style A fill:#969,stroke:#333; style A fill:#969,stroke:#333;

View File

@@ -139,7 +139,6 @@ The following unfinished features are not supported in the short term.
- [ ] Legend - [ ] Legend
- [x] System Context - [x] System Context
- [x] Person(alias, label, ?descr, ?sprite, ?tags, $link) - [x] Person(alias, label, ?descr, ?sprite, ?tags, $link)
- [x] Person_Ext - [x] Person_Ext
- [x] System(alias, label, ?descr, ?sprite, ?tags, $link) - [x] System(alias, label, ?descr, ?sprite, ?tags, $link)
@@ -153,7 +152,6 @@ The following unfinished features are not supported in the short term.
- [x] System_Boundary - [x] System_Boundary
- [x] Container diagram - [x] Container diagram
- [x] Container(alias, label, ?techn, ?descr, ?sprite, ?tags, $link) - [x] Container(alias, label, ?techn, ?descr, ?sprite, ?tags, $link)
- [x] ContainerDb - [x] ContainerDb
- [x] ContainerQueue - [x] ContainerQueue
@@ -163,7 +161,6 @@ The following unfinished features are not supported in the short term.
- [x] Container_Boundary(alias, label, ?tags, $link) - [x] Container_Boundary(alias, label, ?tags, $link)
- [x] Component diagram - [x] Component diagram
- [x] Component(alias, label, ?techn, ?descr, ?sprite, ?tags, $link) - [x] Component(alias, label, ?techn, ?descr, ?sprite, ?tags, $link)
- [x] ComponentDb - [x] ComponentDb
- [x] ComponentQueue - [x] ComponentQueue
@@ -172,18 +169,15 @@ The following unfinished features are not supported in the short term.
- [x] ComponentQueue_Ext - [x] ComponentQueue_Ext
- [x] Dynamic diagram - [x] Dynamic diagram
- [x] RelIndex(index, from, to, label, ?tags, $link) - [x] RelIndex(index, from, to, label, ?tags, $link)
- [x] Deployment diagram - [x] Deployment diagram
- [x] Deployment_Node(alias, label, ?type, ?descr, ?sprite, ?tags, $link) - [x] Deployment_Node(alias, label, ?type, ?descr, ?sprite, ?tags, $link)
- [x] Node(alias, label, ?type, ?descr, ?sprite, ?tags, $link): short name of Deployment_Node() - [x] Node(alias, label, ?type, ?descr, ?sprite, ?tags, $link): short name of Deployment_Node()
- [x] Node_L(alias, label, ?type, ?descr, ?sprite, ?tags, $link): left aligned Node() - [x] Node_L(alias, label, ?type, ?descr, ?sprite, ?tags, $link): left aligned Node()
- [x] Node_R(alias, label, ?type, ?descr, ?sprite, ?tags, $link): right aligned Node() - [x] Node_R(alias, label, ?type, ?descr, ?sprite, ?tags, $link): right aligned Node()
- [x] Relationship Types - [x] Relationship Types
- [x] Rel(from, to, label, ?techn, ?descr, ?sprite, ?tags, $link) - [x] Rel(from, to, label, ?techn, ?descr, ?sprite, ?tags, $link)
- [x] BiRel (bidirectional relationship) - [x] BiRel (bidirectional relationship)
- [x] Rel_U, Rel_Up - [x] Rel_U, Rel_Up

View File

@@ -1816,7 +1816,7 @@ config:
graph LR graph LR
``` ```
#### Edge level curve style using Edge IDs (v\<MERMAID_RELEASE_VERSION>+) #### 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: 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:

View File

@@ -360,7 +360,8 @@ gantt
weekday monday weekday monday
``` ```
> **Warning** > `millisecond` and `second` support was added in v10.3.0 > **Warning**
> `millisecond` and `second` support was added in v10.3.0
## Output in compact mode ## Output in compact mode

View File

@@ -37,6 +37,11 @@ Drawing a pie chart is really simple in mermaid.
- Followed by `:` colon as separator - Followed by `:` colon as separator
- Followed by `positive numeric value` (supported up to two decimal places) - 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) \[pie] \[showData] (OPTIONAL)
\[title] \[titlevalue] (OPTIONAL) \[title] \[titlevalue] (OPTIONAL)
"\[datakey1]" : \[dataValue1] "\[datakey1]" : \[dataValue1]

View File

@@ -23,7 +23,7 @@ config:
sankey: sankey:
showValues: false showValues: false
--- ---
sankey-beta sankey
Agricultural 'waste',Bio-conversion,124.729 Agricultural 'waste',Bio-conversion,124.729
Bio-conversion,Liquid,0.597 Bio-conversion,Liquid,0.597
@@ -101,7 +101,7 @@ config:
sankey: sankey:
showValues: false showValues: false
--- ---
sankey-beta sankey
Agricultural 'waste',Bio-conversion,124.729 Agricultural 'waste',Bio-conversion,124.729
Bio-conversion,Liquid,0.597 Bio-conversion,Liquid,0.597
@@ -175,7 +175,7 @@ Wind,Electricity grid,289.366
## Syntax ## 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**: 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: It is implied that 3 columns inside CSV should represent `source`, `target` and `value` accordingly:
```mermaid-example ```mermaid-example
sankey-beta sankey
%% source,target,value %% source,target,value
Electricity grid,Over generation / exports,104.453 Electricity grid,Over generation / exports,104.453
@@ -196,7 +196,7 @@ Electricity grid,H2 conversion,27.14
``` ```
```mermaid ```mermaid
sankey-beta sankey
%% source,target,value %% source,target,value
Electricity grid,Over generation / exports,104.453 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: CSV does not support empty lines without comma delimiters by default. But you can add them if needed:
```mermaid-example ```mermaid-example
sankey-beta sankey
Bio-conversion,Losses,26.862 Bio-conversion,Losses,26.862
@@ -219,7 +219,7 @@ Bio-conversion,Gas,81.144
``` ```
```mermaid ```mermaid
sankey-beta sankey
Bio-conversion,Losses,26.862 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: If you need to have a comma, wrap it in double quotes:
```mermaid-example ```mermaid-example
sankey-beta sankey
Pumped heat,"Heating and cooling, homes",193.026 Pumped heat,"Heating and cooling, homes",193.026
Pumped heat,"Heating and cooling, commercial",70.672 Pumped heat,"Heating and cooling, commercial",70.672
``` ```
```mermaid ```mermaid
sankey-beta sankey
Pumped heat,"Heating and cooling, homes",193.026 Pumped heat,"Heating and cooling, homes",193.026
Pumped heat,"Heating and cooling, commercial",70.672 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: If you need to have double quote, put a pair of them inside quoted string:
```mermaid-example ```mermaid-example
sankey-beta sankey
Pumped heat,"Heating and cooling, ""homes""",193.026 Pumped heat,"Heating and cooling, ""homes""",193.026
Pumped heat,"Heating and cooling, ""commercial""",70.672 Pumped heat,"Heating and cooling, ""commercial""",70.672
``` ```
```mermaid ```mermaid
sankey-beta sankey
Pumped heat,"Heating and cooling, ""homes""",193.026 Pumped heat,"Heating and cooling, ""homes""",193.026
Pumped heat,"Heating and cooling, ""commercial""",70.672 Pumped heat,"Heating and cooling, ""commercial""",70.672

View File

@@ -13,7 +13,7 @@
## Example ## Example
```mermaid-example ```mermaid-example
xychart-beta xychart
title "Sales Revenue" title "Sales Revenue"
x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
y-axis "Revenue (in $)" 4000 --> 11000 y-axis "Revenue (in $)" 4000 --> 11000
@@ -22,7 +22,7 @@ xychart-beta
``` ```
```mermaid ```mermaid
xychart-beta xychart
title "Sales Revenue" title "Sales Revenue"
x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
y-axis "Revenue (in $)" 4000 --> 11000 y-axis "Revenue (in $)" 4000 --> 11000
@@ -40,7 +40,7 @@ xychart-beta
The chart can be drawn horizontal or vertical, default value is vertical. 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 #### Example
``` ```
xychart-beta xychart
title "This is a simple example" title "This is a simple example"
... ...
``` ```
@@ -98,10 +98,10 @@ A bar chart offers the capability to graphically depict bars.
#### Simplest example #### 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] line [+1.3, .6, 2.4, -.34]
``` ```
@@ -176,7 +176,7 @@ config:
xyChart: xyChart:
titleColor: "#ff0000" titleColor: "#ff0000"
--- ---
xychart-beta xychart
title "Sales Revenue" title "Sales Revenue"
x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
y-axis "Revenue (in $)" 4000 --> 11000 y-axis "Revenue (in $)" 4000 --> 11000
@@ -195,7 +195,7 @@ config:
xyChart: xyChart:
titleColor: "#ff0000" titleColor: "#ff0000"
--- ---
xychart-beta xychart
title "Sales Revenue" title "Sales Revenue"
x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
y-axis "Revenue (in $)" 4000 --> 11000 y-axis "Revenue (in $)" 4000 --> 11000

View File

@@ -64,35 +64,35 @@
}, },
"devDependencies": { "devDependencies": {
"@applitools/eyes-cypress": "^3.44.9", "@applitools/eyes-cypress": "^3.44.9",
"@argos-ci/cypress": "^5.0.2", "@argos-ci/cypress": "^5.0.7",
"@changesets/changelog-github": "^0.5.1", "@changesets/changelog-github": "^0.5.1",
"@changesets/cli": "^2.27.12", "@changesets/cli": "^2.27.12",
"@cspell/eslint-plugin": "^8.19.4", "@cspell/eslint-plugin": "^8.19.4",
"@cypress/code-coverage": "^3.12.49", "@cypress/code-coverage": "^3.12.49",
"@eslint/js": "^9.26.0", "@eslint/js": "^9.26.0",
"@rollup/plugin-typescript": "^12.1.2", "@rollup/plugin-typescript": "^12.1.4",
"@types/cors": "^2.8.17", "@types/cors": "^2.8.19",
"@types/express": "^5.0.0", "@types/express": "^5.0.3",
"@types/js-yaml": "^4.0.9", "@types/js-yaml": "^4.0.9",
"@types/jsdom": "^21.1.7", "@types/jsdom": "^21.1.7",
"@types/lodash": "^4.17.15", "@types/lodash": "^4.17.20",
"@types/mdast": "^4.0.4", "@types/mdast": "^4.0.4",
"@types/node": "^22.13.5", "@types/node": "^22.13.17",
"@types/rollup-plugin-visualizer": "^5.0.3", "@types/rollup-plugin-visualizer": "^5.0.3",
"@vitest/coverage-v8": "^3.0.6", "@vitest/coverage-v8": "^3.0.9",
"@vitest/spy": "^3.0.6", "@vitest/spy": "^3.0.9",
"@vitest/ui": "^3.0.6", "@vitest/ui": "^3.0.9",
"ajv": "^8.17.1", "ajv": "^8.17.1",
"chokidar": "3.6.0", "chokidar": "3.6.0",
"concurrently": "^9.1.2", "concurrently": "^9.1.2",
"cors": "^2.8.5", "cors": "^2.8.5",
"cpy-cli": "^5.0.0", "cpy-cli": "^5.0.0",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"cspell": "^9.1.3", "cspell": "^9.1.5",
"cypress": "^14.5.1", "cypress": "^14.5.4",
"cypress-image-snapshot": "^4.0.1", "cypress-image-snapshot": "^4.0.1",
"cypress-split": "^1.24.14", "cypress-split": "^1.24.21",
"esbuild": "^0.25.0", "esbuild": "^0.25.9",
"eslint": "^9.26.0", "eslint": "^9.26.0",
"eslint-config-prettier": "^10.1.8", "eslint-config-prettier": "^10.1.8",
"eslint-plugin-cypress": "^4.3.0", "eslint-plugin-cypress": "^4.3.0",
@@ -107,29 +107,29 @@
"eslint-plugin-unicorn": "^59.0.1", "eslint-plugin-unicorn": "^59.0.1",
"express": "^5.1.0", "express": "^5.1.0",
"globals": "^16.0.0", "globals": "^16.0.0",
"globby": "^14.0.2", "globby": "^14.1.0",
"husky": "^9.1.7", "husky": "^9.1.7",
"jest": "^30.0.4", "jest": "^30.0.5",
"jison": "^0.4.18", "jison": "^0.4.18",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
"jsdom": "^26.1.0", "jsdom": "^26.1.0",
"langium-cli": "3.3.0", "langium-cli": "3.3.0",
"lint-staged": "^16.1.2", "lint-staged": "^16.1.5",
"markdown-table": "^3.0.4", "markdown-table": "^3.0.4",
"nyc": "^17.1.0", "nyc": "^17.1.0",
"path-browserify": "^1.0.1", "path-browserify": "^1.0.1",
"prettier": "^3.5.2", "prettier": "^3.5.3",
"prettier-plugin-jsdoc": "^1.3.2", "prettier-plugin-jsdoc": "^1.3.3",
"rimraf": "^6.0.1", "rimraf": "^6.0.1",
"rollup-plugin-visualizer": "^6.0.3", "rollup-plugin-visualizer": "^6.0.3",
"start-server-and-test": "^2.0.10", "start-server-and-test": "^2.0.13",
"tslib": "^2.8.1", "tslib": "^2.8.1",
"tsx": "^4.7.3", "tsx": "^4.7.3",
"typescript": "~5.7.3", "typescript": "~5.7.3",
"typescript-eslint": "^8.38.0", "typescript-eslint": "^8.38.0",
"vite": "^7.0.3", "vite": "^7.0.6",
"vite-plugin-istanbul": "^7.0.0", "vite-plugin-istanbul": "^7.0.0",
"vitest": "^3.0.6" "vitest": "^3.0.9"
}, },
"nyc": { "nyc": {
"report-dir": "coverage/cypress" "report-dir": "coverage/cypress"

View File

@@ -27,9 +27,6 @@
"devDependencies": { "devDependencies": {
"mermaid": "workspace:*" "mermaid": "workspace:*"
}, },
"peerDependencies": {
"mermaid": "workspace:~"
},
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"
} }

View File

@@ -37,7 +37,7 @@
] ]
}, },
"dependencies": { "dependencies": {
"@braintree/sanitize-url": "^7.0.4", "@braintree/sanitize-url": "^7.1.1",
"d3": "^7.9.0", "d3": "^7.9.0",
"khroma": "^2.1.0" "khroma": "^2.1.0"
}, },

View File

@@ -1,5 +1,16 @@
# @mermaid-js/layout-elk # @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 ## 0.1.8
### Patch Changes ### Patch Changes

View File

@@ -1,6 +1,6 @@
{ {
"name": "@mermaid-js/layout-elk", "name": "@mermaid-js/layout-elk",
"version": "0.1.8", "version": "0.1.9",
"description": "ELK layout engine for mermaid", "description": "ELK layout engine for mermaid",
"module": "dist/mermaid-layout-elk.core.mjs", "module": "dist/mermaid-layout-elk.core.mjs",
"types": "dist/layouts.d.ts", "types": "dist/layouts.d.ts",

View File

@@ -766,7 +766,10 @@ export const render = async (
id: 'root', id: 'root',
layoutOptions: { layoutOptions: {
'elk.hierarchyHandling': 'INCLUDE_CHILDREN', '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, 'elk.algorithm': algorithm,
'nodePlacement.strategy': data4Layout.config.elk?.nodePlacementStrategy, 'nodePlacement.strategy': data4Layout.config.elk?.nodePlacementStrategy,
'elk.layered.mergeEdges': data4Layout.config.elk?.mergeEdges, 'elk.layered.mergeEdges': data4Layout.config.elk?.mergeEdges,

View File

@@ -1,5 +1,14 @@
# @mermaid-js/mermaid-zenuml # @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 ## 0.2.1
### Patch Changes ### Patch Changes

View File

@@ -1,6 +1,6 @@
{ {
"name": "@mermaid-js/mermaid-zenuml", "name": "@mermaid-js/mermaid-zenuml",
"version": "0.2.1", "version": "0.2.2",
"description": "MermaidJS plugin for ZenUML integration", "description": "MermaidJS plugin for ZenUML integration",
"module": "dist/mermaid-zenuml.core.mjs", "module": "dist/mermaid-zenuml.core.mjs",
"types": "dist/detector.d.ts", "types": "dist/detector.d.ts",

View File

@@ -1,5 +1,72 @@
# mermaid # 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 ## 11.9.0
### Minor Changes ### Minor Changes
@@ -87,7 +154,6 @@
### Minor Changes ### Minor Changes
- [#6408](https://github.com/mermaid-js/mermaid/pull/6408) [`ad65313`](https://github.com/mermaid-js/mermaid/commit/ad653138e16765d095613a6e5de86dc5e52ac8f0) Thanks [@ashishjain0512](https://github.com/ashishjain0512)! - fix: restore curve type configuration functionality for flowcharts. This fixes the issue where curve type settings were not being applied when configured through any of the following methods: - [#6408](https://github.com/mermaid-js/mermaid/pull/6408) [`ad65313`](https://github.com/mermaid-js/mermaid/commit/ad653138e16765d095613a6e5de86dc5e52ac8f0) Thanks [@ashishjain0512](https://github.com/ashishjain0512)! - fix: restore curve type configuration functionality for flowcharts. This fixes the issue where curve type settings were not being applied when configured through any of the following methods:
- Config - Config
- Init directive (%%{ init: { 'flowchart': { 'curve': '...' } } }%%) - Init directive (%%{ init: { 'flowchart': { 'curve': '...' } } }%%)
- LinkStyle command (linkStyle default interpolate ...) - LinkStyle command (linkStyle default interpolate ...)
@@ -106,14 +172,12 @@
### Minor Changes ### Minor Changes
- [#6187](https://github.com/mermaid-js/mermaid/pull/6187) [`7809b5a`](https://github.com/mermaid-js/mermaid/commit/7809b5a93fae127f45727071f5ff14325222c518) Thanks [@ashishjain0512](https://github.com/ashishjain0512)! - Flowchart new syntax for node metadata bugs - [#6187](https://github.com/mermaid-js/mermaid/pull/6187) [`7809b5a`](https://github.com/mermaid-js/mermaid/commit/7809b5a93fae127f45727071f5ff14325222c518) Thanks [@ashishjain0512](https://github.com/ashishjain0512)! - Flowchart new syntax for node metadata bugs
- Incorrect label mapping for nodes when using `&` - Incorrect label mapping for nodes when using `&`
- Syntax error when `}` with trailing spaces before new line - Syntax error when `}` with trailing spaces before new line
- [#6136](https://github.com/mermaid-js/mermaid/pull/6136) [`ec0d9c3`](https://github.com/mermaid-js/mermaid/commit/ec0d9c389aa6018043187654044c1e0b5aa4f600) Thanks [@knsv](https://github.com/knsv)! - Adding support for animation of flowchart edges - [#6136](https://github.com/mermaid-js/mermaid/pull/6136) [`ec0d9c3`](https://github.com/mermaid-js/mermaid/commit/ec0d9c389aa6018043187654044c1e0b5aa4f600) Thanks [@knsv](https://github.com/knsv)! - Adding support for animation of flowchart edges
- [#6373](https://github.com/mermaid-js/mermaid/pull/6373) [`05bdf0e`](https://github.com/mermaid-js/mermaid/commit/05bdf0e20e2629fe77513218fbd4e28e65f75882) Thanks [@ashishjain0512](https://github.com/ashishjain0512)! - Upgrade Requirement and ER diagram to use the common renderer flow - [#6373](https://github.com/mermaid-js/mermaid/pull/6373) [`05bdf0e`](https://github.com/mermaid-js/mermaid/commit/05bdf0e20e2629fe77513218fbd4e28e65f75882) Thanks [@ashishjain0512](https://github.com/ashishjain0512)! - Upgrade Requirement and ER diagram to use the common renderer flow
- Added support for directions - Added support for directions
- Added support for hand drawn look - Added support for hand drawn look
@@ -162,7 +226,6 @@
- [#5999](https://github.com/mermaid-js/mermaid/pull/5999) [`742ad7c`](https://github.com/mermaid-js/mermaid/commit/742ad7c130964df1fb5544e909d9556081285f68) Thanks [@knsv](https://github.com/knsv)! - Adding Kanban board, a new diagram type - [#5999](https://github.com/mermaid-js/mermaid/pull/5999) [`742ad7c`](https://github.com/mermaid-js/mermaid/commit/742ad7c130964df1fb5544e909d9556081285f68) Thanks [@knsv](https://github.com/knsv)! - Adding Kanban board, a new diagram type
- [#5880](https://github.com/mermaid-js/mermaid/pull/5880) [`bdf145f`](https://github.com/mermaid-js/mermaid/commit/bdf145ffe362462176d9c1e68d5f3ff5c9d962b0) Thanks [@yari-dewalt](https://github.com/yari-dewalt)! - Class diagram changes: - [#5880](https://github.com/mermaid-js/mermaid/pull/5880) [`bdf145f`](https://github.com/mermaid-js/mermaid/commit/bdf145ffe362462176d9c1e68d5f3ff5c9d962b0) Thanks [@yari-dewalt](https://github.com/yari-dewalt)! - Class diagram changes:
- Updates the class diagram to the new unified way of rendering. - Updates the class diagram to the new unified way of rendering.
- Includes a new "classBox" shape to be used in diagrams - Includes a new "classBox" shape to be used in diagrams
- Other updates such as: - Other updates such as:

View File

@@ -1,6 +1,6 @@
{ {
"name": "mermaid", "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.", "description": "Markdown-ish syntax for generating flowcharts, mindmaps, sequence diagrams, class diagrams, gantt charts, git graphs and more.",
"type": "module", "type": "module",
"module": "./dist/mermaid.core.mjs", "module": "./dist/mermaid.core.mjs",
@@ -67,8 +67,8 @@
] ]
}, },
"dependencies": { "dependencies": {
"@braintree/sanitize-url": "^7.0.4", "@braintree/sanitize-url": "^7.1.1",
"@iconify/utils": "^2.1.33", "@iconify/utils": "^2.3.0",
"@mermaid-js/parser": "workspace:^", "@mermaid-js/parser": "workspace:^",
"@types/d3": "^7.4.3", "@types/d3": "^7.4.3",
"cytoscape": "^3.29.3", "cytoscape": "^3.29.3",
@@ -89,7 +89,7 @@
"uuid": "^11.1.0" "uuid": "^11.1.0"
}, },
"devDependencies": { "devDependencies": {
"@adobe/jsonschema2md": "^8.0.2", "@adobe/jsonschema2md": "^8.0.5",
"@iconify/types": "^2.0.0", "@iconify/types": "^2.0.0",
"@types/cytoscape": "^3.21.9", "@types/cytoscape": "^3.21.9",
"@types/cytoscape-fcose": "^2.2.4", "@types/cytoscape-fcose": "^2.2.4",
@@ -105,30 +105,30 @@
"@types/stylis": "^4.2.7", "@types/stylis": "^4.2.7",
"@types/uuid": "^10.0.0", "@types/uuid": "^10.0.0",
"ajv": "^8.17.1", "ajv": "^8.17.1",
"canvas": "^3.1.0", "canvas": "^3.1.2",
"chokidar": "3.6.0", "chokidar": "3.6.0",
"concurrently": "^9.1.2", "concurrently": "^9.1.2",
"csstree-validator": "^4.0.1", "csstree-validator": "^4.0.1",
"globby": "^14.0.2", "globby": "^14.1.0",
"jison": "^0.4.18", "jison": "^0.4.18",
"js-base64": "^3.7.7", "js-base64": "^3.7.8",
"jsdom": "^26.1.0", "jsdom": "^26.1.0",
"json-schema-to-typescript": "^15.0.4", "json-schema-to-typescript": "^15.0.4",
"micromatch": "^4.0.8", "micromatch": "^4.0.8",
"path-browserify": "^1.0.1", "path-browserify": "^1.0.1",
"prettier": "^3.5.2", "prettier": "^3.5.3",
"remark": "^15.0.1", "remark": "^15.0.1",
"remark-frontmatter": "^5.0.0", "remark-frontmatter": "^5.0.0",
"remark-gfm": "^4.0.1", "remark-gfm": "^4.0.1",
"rimraf": "^6.0.1", "rimraf": "^6.0.1",
"start-server-and-test": "^2.0.10", "start-server-and-test": "^2.0.13",
"type-fest": "^4.35.0", "type-fest": "^4.35.0",
"typedoc": "^0.27.8", "typedoc": "^0.27.9",
"typedoc-plugin-markdown": "^4.4.2", "typedoc-plugin-markdown": "^4.4.2",
"typescript": "~5.7.3", "typescript": "~5.7.3",
"unist-util-flatmap": "^1.0.0", "unist-util-flatmap": "^1.0.0",
"unist-util-visit": "^5.0.0", "unist-util-visit": "^5.0.0",
"vitepress": "^1.0.2", "vitepress": "^1.6.4",
"vitepress-plugin-search": "1.0.4-alpha.22" "vitepress-plugin-search": "1.0.4-alpha.22"
}, },
"files": [ "files": [

View File

@@ -109,6 +109,16 @@ export interface MermaidConfig {
| 'INTERACTIVE' | 'INTERACTIVE'
| 'MODEL_ORDER' | 'MODEL_ORDER'
| 'GREEDY_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; darkMode?: boolean;
htmlLabels?: boolean; htmlLabels?: boolean;

View File

@@ -1,9 +1,9 @@
import { select } from 'd3'; import { select } from 'd3';
import { log } from '../logger.js';
import { getConfig } from '../diagram-api/diagramAPI.js'; import { getConfig } from '../diagram-api/diagramAPI.js';
import { evaluate } from '../diagrams/common/common.js'; import { evaluate, sanitizeText } from '../diagrams/common/common.js';
import { decodeEntities } from '../utils.js'; import { log } from '../logger.js';
import { replaceIconSubstring } from '../rendering-util/createText.js'; import { replaceIconSubstring } from '../rendering-util/createText.js';
import { decodeEntities } from '../utils.js';
/** /**
* @param dom * @param dom
@@ -19,14 +19,14 @@ function applyStyle(dom, styleFn) {
* @param {any} node * @param {any} node
* @returns {SVGForeignObjectElement} Node * @returns {SVGForeignObjectElement} Node
*/ */
function addHtmlLabel(node) { function addHtmlLabel(node, config) {
const fo = select(document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject')); const fo = select(document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject'));
const div = fo.append('xhtml:div'); const div = fo.append('xhtml:div');
const label = node.label; const label = node.label;
const labelClass = node.isNode ? 'nodeLabel' : 'edgeLabel'; const labelClass = node.isNode ? 'nodeLabel' : 'edgeLabel';
const span = div.append('span'); const span = div.append('span');
span.html(label); span.html(sanitizeText(label, config));
applyStyle(span, node.labelStyle); applyStyle(span, node.labelStyle);
span.attr('class', labelClass); span.attr('class', labelClass);
@@ -49,7 +49,8 @@ const createLabel = async (_vertexText, style, isTitle, isNode) => {
if (typeof vertexText === 'object') { if (typeof vertexText === 'object') {
vertexText = vertexText[0]; 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? // TODO: addHtmlLabel accepts a labelStyle. Do we possibly have that?
vertexText = vertexText.replace(/\\n|\n/g, '<br />'); vertexText = vertexText.replace(/\\n|\n/g, '<br />');
log.debug('vertexText' + vertexText); log.debug('vertexText' + vertexText);
@@ -59,7 +60,7 @@ const createLabel = async (_vertexText, style, isTitle, isNode) => {
label, label,
labelStyle: style.replace('fill:', 'color:'), labelStyle: style.replace('fill:', 'color:'),
}; };
let vertexNode = addHtmlLabel(node); let vertexNode = addHtmlLabel(node, config);
// vertexNode.parentNode.removeChild(vertexNode); // vertexNode.parentNode.removeChild(vertexNode);
return vertexNode; return vertexNode;
} else { } else {

View File

@@ -24,6 +24,8 @@ const config: RequiredDeep<MermaidConfig> = {
// mergeEdges is needed here to be considered // mergeEdges is needed here to be considered
mergeEdges: false, mergeEdges: false,
nodePlacementStrategy: 'BRANDES_KOEPF', nodePlacementStrategy: 'BRANDES_KOEPF',
forceNodeModelOrder: false,
considerModelOrder: 'NODES_AND_EDGES',
}, },
themeCSS: undefined, themeCSS: undefined,

View File

@@ -28,7 +28,6 @@ import architecture from '../diagrams/architecture/architectureDetector.js';
import { registerLazyLoadedDiagrams } from './detectType.js'; import { registerLazyLoadedDiagrams } from './detectType.js';
import { registerDiagram } from './diagramAPI.js'; import { registerDiagram } from './diagramAPI.js';
import { treemap } from '../diagrams/treemap/detector.js'; import { treemap } from '../diagrams/treemap/detector.js';
import { usecase } from '../diagrams/usecase/detector.js';
import '../type.d.ts'; import '../type.d.ts';
let hasLoadedDiagrams = false; let hasLoadedDiagrams = false;
@@ -102,7 +101,6 @@ export const addDiagrams = () => {
xychart, xychart,
block, block,
radar, radar,
treemap, treemap
usecase
); );
}; };

View File

@@ -3,6 +3,7 @@ import { getConfig } from '../../diagram-api/diagramAPI.js';
import { createText } from '../../rendering-util/createText.js'; import { createText } from '../../rendering-util/createText.js';
import { getIconSVG } from '../../rendering-util/icons.js'; import { getIconSVG } from '../../rendering-util/icons.js';
import type { D3Element } from '../../types.js'; import type { D3Element } from '../../types.js';
import { sanitizeText } from '../common/common.js';
import type { ArchitectureDB } from './architectureDb.js'; import type { ArchitectureDB } from './architectureDb.js';
import { architectureIcons } from './architectureIcons.js'; import { architectureIcons } from './architectureIcons.js';
import { import {
@@ -271,6 +272,7 @@ export const drawServices = async function (
elem: D3Element, elem: D3Element,
services: ArchitectureService[] services: ArchitectureService[]
): Promise<number> { ): Promise<number> {
const config = getConfig();
for (const service of services) { for (const service of services) {
const serviceElem = elem.append('g'); const serviceElem = elem.append('g');
const iconSize = db.getConfigField('iconSize'); const iconSize = db.getConfigField('iconSize');
@@ -285,7 +287,7 @@ export const drawServices = async function (
width: iconSize * 1.5, width: iconSize * 1.5,
classes: 'architecture-service-label', classes: 'architecture-service-label',
}, },
getConfig() config
); );
textElem textElem
@@ -320,7 +322,7 @@ export const drawServices = async function (
.attr('class', 'node-icon-text') .attr('class', 'node-icon-text')
.attr('style', `height: ${iconSize}px;`) .attr('style', `height: ${iconSize}px;`)
.append('div') .append('div')
.html(service.iconText); .html(sanitizeText(service.iconText, config));
const fontSize = const fontSize =
parseInt( parseInt(
window window

View File

@@ -238,13 +238,15 @@ export function edgeTypeStr2Type(typeStr: string): string {
} }
export function edgeStrToEdgeData(typeStr: string): string { export function edgeStrToEdgeData(typeStr: string): string {
switch (typeStr.trim()) { switch (typeStr.replace(/^[\s-]+|[\s-]+$/g, '')) {
case '--x': case 'x':
return 'arrow_cross'; return 'arrow_cross';
case '--o': case 'o':
return 'arrow_circle'; return 'arrow_circle';
default: case '>':
return 'arrow_point'; return 'arrow_point';
default:
return '';
} }
} }

View File

@@ -3,7 +3,7 @@ import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-a
const id = 'block'; const id = 'block';
const detector: DiagramDetector = (txt) => { const detector: DiagramDetector = (txt) => {
return /^\s*block-beta/.test(txt); return /^\s*block(-beta)?/.test(txt);
}; };
const loader = async () => { const loader = async () => {

View File

@@ -36,10 +36,10 @@ CRLF \u000D\u000A
%% %%
"block-beta" { return 'BLOCK_DIAGRAM_KEY'; } "block-beta" { yy.getLogger().debug('Found block-beta'); return 'BLOCK_DIAGRAM_KEY'; }
"block"\s+ { yy.getLogger().debug('Found space-block'); return 'block';} "block:" { yy.getLogger().debug('Found id-block'); return 'id-block'; }
"block"\n+ { yy.getLogger().debug('Found nl-block'); return 'block';} "block" { yy.getLogger().debug('Found block'); return 'BLOCK_DIAGRAM_KEY'; }
"block:" { yy.getLogger().debug('Found space-block'); return 'id-block';}
// \s*\%\%.* { yy.getLogger().debug('Found comment',yytext); } // \s*\%\%.* { yy.getLogger().debug('Found comment',yytext); }
[\s]+ { yy.getLogger().debug('.', yytext); /* skip all whitespace */ } [\s]+ { yy.getLogger().debug('.', yytext); /* skip all whitespace */ }
[\n]+ {yy.getLogger().debug('_', yytext); /* skip all whitespace */ } [\n]+ {yy.getLogger().debug('_', yytext); /* skip all whitespace */ }
@@ -240,7 +240,7 @@ columnsStatement
blockStatement blockStatement
: id-block nodeStatement document end { yy.getLogger().debug('Rule: id-block statement : ', $2, $3); const id2 = yy.generateId(); $$ = { ...$2, type:'composite', children: $3 }; } : 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 node

View File

@@ -23,7 +23,7 @@ describe('Block diagram', function () {
expect(blocks[0].label).toBe('id'); expect(blocks[0].label).toBe('id');
}); });
it('a node with a square shape and a label', () => { it('a node with a square shape and a label', () => {
const str = `block-beta const str = `block
id["A label"] id["A label"]
`; `;
@@ -35,7 +35,7 @@ describe('Block diagram', function () {
expect(blocks[0].type).toBe('square'); expect(blocks[0].type).toBe('square');
}); });
it('a diagram with multiple nodes', () => { it('a diagram with multiple nodes', () => {
const str = `block-beta const str = `block
id1 id1
id2 id2
`; `;
@@ -51,7 +51,7 @@ describe('Block diagram', function () {
expect(blocks[1].type).toBe('na'); expect(blocks[1].type).toBe('na');
}); });
it('a diagram with multiple nodes', () => { it('a diagram with multiple nodes', () => {
const str = `block-beta const str = `block
id1 id1
id2 id2
id3 id3
@@ -72,7 +72,7 @@ describe('Block diagram', function () {
}); });
it('a node with a square shape and a label', () => { it('a node with a square shape and a label', () => {
const str = `block-beta const str = `block
id["A label"] id["A label"]
id2`; id2`;
@@ -87,7 +87,7 @@ describe('Block diagram', function () {
expect(blocks[1].type).toBe('na'); expect(blocks[1].type).toBe('na');
}); });
it('a diagram with multiple nodes with edges abc123', () => { it('a diagram with multiple nodes with edges abc123', () => {
const str = `block-beta const str = `block
id1["first"] --> id2["second"] id1["first"] --> id2["second"]
`; `;
@@ -101,7 +101,7 @@ describe('Block diagram', function () {
expect(edges[0].arrowTypeEnd).toBe('arrow_point'); expect(edges[0].arrowTypeEnd).toBe('arrow_point');
}); });
it('a diagram with multiple nodes with edges abc123', () => { it('a diagram with multiple nodes with edges abc123', () => {
const str = `block-beta const str = `block
id1["first"] -- "a label" --> id2["second"] id1["first"] -- "a label" --> id2["second"]
`; `;
@@ -116,7 +116,7 @@ describe('Block diagram', function () {
expect(edges[0].label).toBe('a label'); expect(edges[0].label).toBe('a label');
}); });
it('a diagram with column statements', () => { it('a diagram with column statements', () => {
const str = `block-beta const str = `block
columns 2 columns 2
block1["Block 1"] block1["Block 1"]
`; `;
@@ -127,7 +127,7 @@ describe('Block diagram', function () {
expect(blocks.length).toBe(1); expect(blocks.length).toBe(1);
}); });
it('a diagram without column statements', () => { it('a diagram without column statements', () => {
const str = `block-beta const str = `block
block1["Block 1"] block1["Block 1"]
`; `;
@@ -137,7 +137,7 @@ describe('Block diagram', function () {
expect(blocks.length).toBe(1); expect(blocks.length).toBe(1);
}); });
it('a diagram with auto column statements', () => { it('a diagram with auto column statements', () => {
const str = `block-beta const str = `block
columns auto columns auto
block1["Block 1"] block1["Block 1"]
`; `;
@@ -149,7 +149,7 @@ describe('Block diagram', function () {
}); });
it('blocks next to each other', () => { it('blocks next to each other', () => {
const str = `block-beta const str = `block
columns 2 columns 2
block1["Block 1"] block1["Block 1"]
block2["Block 2"] block2["Block 2"]
@@ -163,7 +163,7 @@ describe('Block diagram', function () {
}); });
it('blocks on top of each other', () => { it('blocks on top of each other', () => {
const str = `block-beta const str = `block
columns 1 columns 1
block1["Block 1"] block1["Block 1"]
block2["Block 2"] block2["Block 2"]
@@ -177,7 +177,7 @@ describe('Block diagram', function () {
}); });
it('compound blocks 2', () => { it('compound blocks 2', () => {
const str = `block-beta const str = `block
block block
aBlock["ABlock"] aBlock["ABlock"]
bBlock["BBlock"] bBlock["BBlock"]
@@ -205,7 +205,7 @@ describe('Block diagram', function () {
expect(bBlock.type).toBe('square'); expect(bBlock.type).toBe('square');
}); });
it('compound blocks of compound blocks', () => { it('compound blocks of compound blocks', () => {
const str = `block-beta const str = `block
block block
aBlock["ABlock"] aBlock["ABlock"]
block block
@@ -240,7 +240,7 @@ describe('Block diagram', function () {
expect(bBlock.type).toBe('square'); expect(bBlock.type).toBe('square');
}); });
it('compound blocks with title', () => { it('compound blocks with title', () => {
const str = `block-beta const str = `block
block:compoundBlock["Compound block"] block:compoundBlock["Compound block"]
columns 1 columns 1
block2["Block 2"] block2["Block 2"]
@@ -265,7 +265,7 @@ describe('Block diagram', function () {
expect(block2.type).toBe('square'); expect(block2.type).toBe('square');
}); });
it('blocks mixed with compound blocks', () => { it('blocks mixed with compound blocks', () => {
const str = `block-beta const str = `block
columns 1 columns 1
block1["Block 1"] block1["Block 1"]
@@ -292,7 +292,7 @@ describe('Block diagram', function () {
}); });
it('Arrow blocks', () => { it('Arrow blocks', () => {
const str = `block-beta const str = `block
columns 3 columns 3
block1["Block 1"] block1["Block 1"]
blockArrow<["&nbsp;&nbsp;&nbsp;"]>(right) blockArrow<["&nbsp;&nbsp;&nbsp;"]>(right)
@@ -316,7 +316,7 @@ describe('Block diagram', function () {
expect(blockArrow.directions).toContain('right'); expect(blockArrow.directions).toContain('right');
}); });
it('Arrow blocks with multiple points', () => { it('Arrow blocks with multiple points', () => {
const str = `block-beta const str = `block
columns 1 columns 1
A A
blockArrow<["&nbsp;&nbsp;&nbsp;"]>(up, down) blockArrow<["&nbsp;&nbsp;&nbsp;"]>(up, down)
@@ -339,7 +339,7 @@ describe('Block diagram', function () {
expect(blockArrow.directions).not.toContain('right'); expect(blockArrow.directions).not.toContain('right');
}); });
it('blocks with different widths', () => { it('blocks with different widths', () => {
const str = `block-beta const str = `block
columns 3 columns 3
one["One Slot"] one["One Slot"]
two["Two slots"]:2 two["Two slots"]:2
@@ -354,7 +354,7 @@ describe('Block diagram', function () {
expect(two.widthInColumns).toBe(2); expect(two.widthInColumns).toBe(2);
}); });
it('empty blocks', () => { it('empty blocks', () => {
const str = `block-beta const str = `block
columns 3 columns 3
space space
middle["In the middle"] middle["In the middle"]
@@ -373,7 +373,7 @@ describe('Block diagram', function () {
expect(middle.label).toBe('In the middle'); expect(middle.label).toBe('In the middle');
}); });
it('classDef statements applied to a block', () => { it('classDef statements applied to a block', () => {
const str = `block-beta const str = `block
classDef black color:#ffffff, fill:#000000; classDef black color:#ffffff, fill:#000000;
mc["Memcache"] mc["Memcache"]
@@ -391,7 +391,7 @@ describe('Block diagram', function () {
expect(black.styles[0]).toEqual('color:#ffffff'); expect(black.styles[0]).toEqual('color:#ffffff');
}); });
it('style statements applied to a block', () => { it('style statements applied to a block', () => {
const str = `block-beta const str = `block
columns 1 columns 1
B["A wide one in the middle"] B["A wide one in the middle"]
style B fill:#f9F,stroke:#333,stroke-width:4px style B fill:#f9F,stroke:#333,stroke-width:4px
@@ -426,9 +426,9 @@ columns 1
describe('prototype properties', function () { describe('prototype properties', function () {
function validateProperty(prop: string) { function validateProperty(prop: string) {
expect(() => block.parse(`block-beta\n${prop}`)).not.toThrow(); expect(() => block.parse(`block\n${prop}`)).not.toThrow();
expect(() => 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(); ).not.toThrow();
} }

View File

@@ -33,13 +33,13 @@ function setupDompurifyHooks() {
const TEMPORARY_ATTRIBUTE = 'data-temp-href-target'; const TEMPORARY_ATTRIBUTE = 'data-temp-href-target';
DOMPurify.addHook('beforeSanitizeAttributes', (node) => { 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') ?? ''); node.setAttribute(TEMPORARY_ATTRIBUTE, node.getAttribute('target') ?? '');
} }
}); });
DOMPurify.addHook('afterSanitizeAttributes', (node) => { 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.setAttribute('target', node.getAttribute(TEMPORARY_ATTRIBUTE) ?? '');
node.removeAttribute(TEMPORARY_ATTRIBUTE); node.removeAttribute(TEMPORARY_ATTRIBUTE);
if (node.getAttribute('target') === '_blank') { if (node.getAttribute('target') === '_blank') {
@@ -311,9 +311,8 @@ export const hasKatex = (text: string): boolean => (text.match(katexRegex)?.leng
* @returns Object containing \{width, height\} * @returns Object containing \{width, height\}
*/ */
export const calculateMathMLDimensions = async (text: string, config: MermaidConfig) => { export const calculateMathMLDimensions = async (text: string, config: MermaidConfig) => {
text = await renderKatex(text, config);
const divElem = document.createElement('div'); const divElem = document.createElement('div');
divElem.innerHTML = text; divElem.innerHTML = await renderKatexSanitized(text, config);
divElem.id = 'katex-temp'; divElem.id = 'katex-temp';
divElem.style.visibility = 'hidden'; divElem.style.visibility = 'hidden';
divElem.style.position = 'absolute'; divElem.style.position = 'absolute';
@@ -325,14 +324,7 @@ export const calculateMathMLDimensions = async (text: string, config: MermaidCon
return dim; return dim;
}; };
/** const renderKatexUnsanitized = async (text: string, config: MermaidConfig): Promise<string> => {
* 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<string> => {
if (!hasKatex(text)) { if (!hasKatex(text)) {
return 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<string> => {
return sanitizeText(await renderKatexUnsanitized(text, config), config);
};
export default { export default {
getRows, getRows,
sanitizeText, sanitizeText,

View File

@@ -167,7 +167,10 @@ export const getTasks = function () {
}; };
export const isInvalidDate = function (date, dateFormat, excludes, includes) { 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; return false;
} }
if ( if (
@@ -180,7 +183,7 @@ export const isInvalidDate = function (date, dateFormat, excludes, includes) {
if (excludes.includes(date.format('dddd').toLowerCase())) { if (excludes.includes(date.format('dddd').toLowerCase())) {
return true; return true;
} }
return excludes.includes(date.format(dateFormat.trim())); return excludes.includes(formattedDate) || excludes.includes(dateOnly);
}; };
export const setWeekday = function (txt) { export const setWeekday = function (txt) {

View File

@@ -581,17 +581,11 @@ export const draw = function (text, id, version, diagObj) {
rectangles rectangles
.append('rect') .append('rect')
.attr('id', function (d) { .attr('id', (d) => 'exclude-' + d.start.format('YYYY-MM-DD'))
return 'exclude-' + d.start.format('YYYY-MM-DD'); .attr('x', (d) => timeScale(d.start.startOf('day')) + theSidePad)
})
.attr('x', function (d) {
return timeScale(d.start) + theSidePad;
})
.attr('y', conf.gridLineStartPadding) .attr('y', conf.gridLineStartPadding)
.attr('width', function (d) { .attr('width', (d) => timeScale(d.end.endOf('day')) - timeScale(d.start.startOf('day')))
const renderEnd = d.end.add(1, 'day');
return timeScale(renderEnd) - timeScale(d.start);
})
.attr('height', h - theTopPad - conf.gridLineStartPadding) .attr('height', h - theTopPad - conf.gridLineStartPadding)
.attr('transform-origin', function (d, i) { .attr('transform-origin', function (d, i) {
return ( return (
@@ -615,9 +609,20 @@ export const draw = function (text, id, version, diagObj) {
* @param h * @param h
*/ */
function makeGrid(theSidePad, theTopPad, w, 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) let bottomXAxis = axisBottom(timeScale)
.tickSize(-h + theTopPad + conf.gridLineStartPadding) .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 reTickInterval = /^([1-9]\d*)(millisecond|second|minute|hour|day|week|month)$/;
const resultTickInterval = reTickInterval.exec( const resultTickInterval = reTickInterval.exec(
@@ -669,7 +674,7 @@ export const draw = function (text, id, version, diagObj) {
if (diagObj.db.topAxisEnabled() || conf.topAxis) { if (diagObj.db.topAxisEnabled() || conf.topAxis) {
let topXAxis = axisTop(timeScale) let topXAxis = axisTop(timeScale)
.tickSize(-h + theTopPad + conf.gridLineStartPadding) .tickSize(-h + theTopPad + conf.gridLineStartPadding)
.tickFormat(timeFormat(diagObj.db.getAxisFormat() || conf.axisFormat || '%Y-%m-%d')); .tickFormat(timeFormat(axisFormat));
if (resultTickInterval !== null) { if (resultTickInterval !== null) {
const every = resultTickInterval[1]; const every = resultTickInterval[1];

View File

@@ -139,6 +139,32 @@ describe('pie', () => {
}).rejects.toThrowError(); }).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 () => { it('should handle unsafe properties', async () => {
await expect( await expect(
parser.parse(`pie title Unsafe props test parser.parse(`pie title Unsafe props test

View File

@@ -34,6 +34,11 @@ const clear = (): void => {
}; };
const addSection = ({ label, value }: D3Section): 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)) { if (!sections.has(label)) {
sections.set(label, value); sections.set(label, value);
log.debug(`added new section: ${label}, with value: ${value}`); log.debug(`added new section: ${label}, with value: ${value}`);

View File

@@ -10,20 +10,14 @@ import { cleanAndMerge, parseFontSize } from '../../utils.js';
import type { D3Section, PieDB, Sections } from './pieTypes.js'; import type { D3Section, PieDB, Sections } from './pieTypes.js';
const createPieArcs = (sections: Sections): d3.PieArcDatum<D3Section>[] => { const createPieArcs = (sections: Sections): d3.PieArcDatum<D3Section>[] => {
// Compute the position of each group on the pie: const sum = [...sections.values()].reduce((acc, val) => acc + val, 0);
const pieData: D3Section[] = [...sections.entries()] const pieData: D3Section[] = [...sections.entries()]
.map((element: [string, number]): D3Section => { .map(([label, value]) => ({ label, value }))
return { .filter((d) => (d.value / sum) * 100 >= 1) // Remove values < 1%
label: element[0], .sort((a, b) => b.value - a.value);
value: element[1],
}; const pie: d3.Pie<unknown, D3Section> = d3pie<D3Section>().value((d) => d.value);
})
.sort((a: D3Section, b: D3Section): number => {
return b.value - a.value;
});
const pie: d3.Pie<unknown, D3Section> = d3pie<D3Section>().value(
(d3Section: D3Section): number => d3Section.value
);
return pie(pieData); return pie(pieData);
}; };
@@ -89,13 +83,21 @@ export const draw: DrawDefinition = (text, id, _version, diagObj) => {
themeVariables.pie11, themeVariables.pie11,
themeVariables.pie12, 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 // Set the color scale
const color: d3.ScaleOrdinal<string, 12, never> = scaleOrdinal(myGeneratedColors); const color: d3.ScaleOrdinal<string, 12, never> = scaleOrdinal(myGeneratedColors);
// Build the pie chart: each part of the pie is a path that we build using the arc function. // Build the pie chart: each part of the pie is a path that we build using the arc function.
group group
.selectAll('mySlices') .selectAll('mySlices')
.data(arcs) .data(filteredArcs)
.enter() .enter()
.append('path') .append('path')
.attr('d', arcGenerator) .attr('d', arcGenerator)
@@ -104,15 +106,11 @@ export const draw: DrawDefinition = (text, id, _version, diagObj) => {
}) })
.attr('class', 'pieCircle'); .attr('class', 'pieCircle');
let sum = 0;
sections.forEach((section) => {
sum += section;
});
// Now add the percentage. // Now add the percentage.
// Use the centroid method to get the best coordinates. // Use the centroid method to get the best coordinates.
group group
.selectAll('mySlices') .selectAll('mySlices')
.data(arcs) .data(filteredArcs)
.enter() .enter()
.append('text') .append('text')
.text((datum: d3.PieArcDatum<D3Section>): string => { .text((datum: d3.PieArcDatum<D3Section>): string => {
@@ -133,15 +131,20 @@ export const draw: DrawDefinition = (text, id, _version, diagObj) => {
.attr('class', 'pieTitleText'); .attr('class', 'pieTitleText');
// Add the legends/annotations for each section // Add the legends/annotations for each section
const allSectionData: D3Section[] = [...sections.entries()].map(([label, value]) => ({
label,
value,
}));
const legend = group const legend = group
.selectAll('.legend') .selectAll('.legend')
.data(color.domain()) .data(allSectionData)
.enter() .enter()
.append('g') .append('g')
.attr('class', 'legend') .attr('class', 'legend')
.attr('transform', (_datum, index: number): string => { .attr('transform', (_datum, index: number): string => {
const height = LEGEND_RECT_SIZE + LEGEND_SPACING; 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 horizontal = 12 * LEGEND_RECT_SIZE;
const vertical = index * height - offset; const vertical = index * height - offset;
return 'translate(' + horizontal + ',' + vertical + ')'; return 'translate(' + horizontal + ',' + vertical + ')';
@@ -151,20 +154,18 @@ export const draw: DrawDefinition = (text, id, _version, diagObj) => {
.append('rect') .append('rect')
.attr('width', LEGEND_RECT_SIZE) .attr('width', LEGEND_RECT_SIZE)
.attr('height', LEGEND_RECT_SIZE) .attr('height', LEGEND_RECT_SIZE)
.style('fill', color) .style('fill', (d) => color(d.label))
.style('stroke', color); .style('stroke', (d) => color(d.label));
legend legend
.data(arcs)
.append('text') .append('text')
.attr('x', LEGEND_RECT_SIZE + LEGEND_SPACING) .attr('x', LEGEND_RECT_SIZE + LEGEND_SPACING)
.attr('y', LEGEND_RECT_SIZE - LEGEND_SPACING) .attr('y', LEGEND_RECT_SIZE - LEGEND_SPACING)
.text((datum: d3.PieArcDatum<D3Section>): string => { .text((d) => {
const { label, value } = datum.data;
if (db.getShowData()) { if (db.getShowData()) {
return `${label} [${value}]`; return `${d.label} [${d.value}]`;
} }
return label; return d.label;
}); });
const longestTextWidth = Math.max( const longestTextWidth = Math.max(

View File

@@ -27,6 +27,7 @@ TEXTDATA [\u0020-\u0021\u0023-\u002B\u002D-\u007E]
%% %%
<INITIAL>"sankey-beta" { this.pushState('csv'); return 'SANKEY'; } <INITIAL>"sankey-beta" { this.pushState('csv'); return 'SANKEY'; }
<INITIAL>"sankey" { this.pushState('csv'); return 'SANKEY'; }
<INITIAL,csv><<EOF>> { return 'EOF' } // match end of file <INITIAL,csv><<EOF>> { return 'EOF' } // match end of file
<INITIAL,csv>({CRLF}|{LF}) { return 'NEWLINE' } <INITIAL,csv>({CRLF}|{LF}) { return 'NEWLINE' }
<INITIAL,csv>{COMMA} { return 'COMMA' } <INITIAL,csv>{COMMA} { return 'COMMA' }

View File

@@ -13,7 +13,7 @@ describe('Sankey diagram', function () {
sankey.parser.yy.clear(); sankey.parser.yy.clear();
}); });
it('parses csv', () => { it('parses csv with sankey-beta syntax', () => {
const csv = path.resolve(__dirname, './energy.csv'); const csv = path.resolve(__dirname, './energy.csv');
const data = fs.readFileSync(csv, 'utf8'); const data = fs.readFileSync(csv, 'utf8');
const graphDefinition = prepareTextForParsing(cleanupComments('sankey-beta\n\n ' + data)); const graphDefinition = prepareTextForParsing(cleanupComments('sankey-beta\n\n ' + data));
@@ -21,7 +21,15 @@ describe('Sankey diagram', function () {
sankey.parser.parse(graphDefinition); 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( sankey.parser.parse(
prepareTextForParsing(`sankey-beta prepareTextForParsing(`sankey-beta
__proto__,A,0.597 __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
`)
);
});
}); });
}); });

View File

@@ -3,7 +3,7 @@ import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-a
const id = 'sankey'; const id = 'sankey';
const detector: DiagramDetector = (txt) => { const detector: DiagramDetector = (txt) => {
return /^\s*sankey-beta/.test(txt); return /^\s*sankey(-beta)?/.test(txt);
}; };
const loader = async () => { const loader = async () => {

View File

@@ -33,7 +33,7 @@
"actor" { this.begin('ID'); return 'participant_actor'; } "actor" { this.begin('ID'); return 'participant_actor'; }
"create" return 'create'; "create" return 'create';
"destroy" { this.begin('ID'); return 'destroy'; } "destroy" { this.begin('ID'); return 'destroy'; }
<ID>[^\<->\->:\n,;]+?([\-]*[^\<->\->:\n,;]+?)*?(?=((?!\n)\s)+"as"(?!\n)\s|[#\n;]|$) { yytext = yytext.trim(); this.begin('ALIAS'); return 'ACTOR'; } <ID>[^<\->\->:\n,;]+?([\-]*[^<\->\->:\n,;]+?)*?(?=((?!\n)\s)+"as"(?!\n)\s|[#\n;]|$) { yytext = yytext.trim(); this.begin('ALIAS'); return 'ACTOR'; }
<ALIAS>"as" { this.popState(); this.popState(); this.begin('LINE'); return 'AS'; } <ALIAS>"as" { this.popState(); this.popState(); this.begin('LINE'); return 'AS'; }
<ALIAS>(?:) { this.popState(); this.popState(); return 'NEWLINE'; } <ALIAS>(?:) { this.popState(); this.popState(); return 'NEWLINE'; }
"loop" { this.begin('LINE'); return 'loop'; } "loop" { this.begin('LINE'); return 'loop'; }
@@ -73,7 +73,7 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multili
"off" return 'off'; "off" return 'off';
"," return ','; "," return ',';
";" return 'NEWLINE'; ";" return 'NEWLINE';
[^\+\<->\->:\n,;]+((?!(\-x|\-\-x|\-\)|\-\-\)))[\-]*[^\+\<->\->:\n,;]+)* { yytext = yytext.trim(); return 'ACTOR'; } [^+<\->\->:\n,;]+((?!(\-x|\-\-x|\-\)|\-\-\)))[\-]*[^\+<\->\->:\n,;]+)* { yytext = yytext.trim(); return 'ACTOR'; }
"->>" return 'SOLID_ARROW'; "->>" return 'SOLID_ARROW';
"<<->>" return 'BIDIRECTIONAL_SOLID_ARROW'; "<<->>" return 'BIDIRECTIONAL_SOLID_ARROW';
"-->>" return 'DOTTED_ARROW'; "-->>" return 'DOTTED_ARROW';

View File

@@ -350,6 +350,26 @@ Bob-->Alice-in-Wonderland:I am good thanks!`);
expect(messages[1].from).toBe('Bob'); 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 () => { it('should alias participants', async () => {
const diagram = await Diagram.fromText(` const diagram = await Diagram.fromText(`
sequenceDiagram sequenceDiagram

View File

@@ -476,7 +476,29 @@ const drawMessage = async function (diagram, msgModel, lineStartY: number, diagO
// add node number // add node number
if (sequenceVisible || conf.showSequenceNumbers) { if (sequenceVisible || conf.showSequenceNumbers) {
line.attr('marker-start', 'url(' + url + '#sequencenumber)'); const isBidirectional =
type === diagObj.db.LINETYPE.BIDIRECTIONAL_SOLID ||
type === diagObj.db.LINETYPE.BIDIRECTIONAL_DOTTED;
if (isBidirectional) {
const SEQUENCE_NUMBER_RADIUS = 6;
if (startx < stopx) {
line.attr('x1', startx + 2 * SEQUENCE_NUMBER_RADIUS);
} else {
line.attr('x1', startx + SEQUENCE_NUMBER_RADIUS);
}
}
diagram
.append('line')
.attr('x1', startx)
.attr('y1', lineStartY)
.attr('x2', startx)
.attr('y2', lineStartY)
.attr('stroke-width', 0)
.attr('marker-start', 'url(' + url + '#sequencenumber)');
diagram diagram
.append('text') .append('text')
.attr('x', startx) .attr('x', startx)

View File

@@ -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 { sanitizeUrl } from '@braintree/sanitize-url';
import * as configApi from '../../config.js'; 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; export const ACTOR_TYPE_WIDTH = 18 * 2;
const TOP_ACTOR_CLASS = 'actor-top'; const TOP_ACTOR_CLASS = 'actor-top';
@@ -87,13 +91,13 @@ const popupMenuToggle = function (popId) {
export const drawKatex = async function (elem, textData, msgModel = null) { export const drawKatex = async function (elem, textData, msgModel = null) {
let textElem = elem.append('foreignObject'); let textElem = elem.append('foreignObject');
const lines = await renderKatex(textData.text, configApi.getConfig()); const linesSanitized = await renderKatexSanitized(textData.text, configApi.getConfig());
const divElem = textElem const divElem = textElem
.append('xhtml:div') .append('xhtml:div')
.attr('style', 'width: fit-content;') .attr('style', 'width: fit-content;')
.attr('xmlns', 'http://www.w3.org/1999/xhtml') .attr('xmlns', 'http://www.w3.org/1999/xhtml')
.html(lines); .html(linesSanitized);
const dim = divElem.node().getBoundingClientRect(); const dim = divElem.node().getBoundingClientRect();
textElem.attr('height', Math.round(dim.height)).attr('width', Math.round(dim.width)); textElem.attr('height', Math.round(dim.height)).attr('width', Math.round(dim.width));
@@ -965,7 +969,7 @@ const _drawTextCandidateFunc = (function () {
.append('div') .append('div')
.style('text-align', 'center') .style('text-align', 'center')
.style('vertical-align', 'middle') .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); byTspan(content, s, x, y, width, height, textAttrs, conf);
_setTextAttrs(text, textAttrs); _setTextAttrs(text, textAttrs);

View File

@@ -1,38 +0,0 @@
import type { DiagramDB } from '../../diagram-api/types.js';
import type { UsecaseDiagramConfig, UsecaseNode } from './types.js';
import { cleanAndMerge } from '../../utils.js';
export class UsecaseDiagramDB implements DiagramDB {
public getNodes() {
return [];
}
public getConfig() {
return cleanAndMerge({}) as Required<UsecaseDiagramConfig>;
}
public addNode(node: UsecaseNode, level: number) {
if (level === 0) {
// TODO
}
}
public getRoot() {
return { name: '', children: [] };
}
public addClass(_id: string, _style: string) {
// TODO
}
public getClasses() {
// TODO
}
public getStylesForClass(_classSelector: string) {
// TODO
}
public clear() {
// commonClear();
}
}

View File

@@ -1,22 +0,0 @@
import type {
DiagramDetector,
DiagramLoader,
ExternalDiagramDefinition,
} from '../../diagram-api/types.js';
const id = 'usecase';
const detector: DiagramDetector = (txt) => {
return /^\s*usecase/.test(txt);
};
const loader: DiagramLoader = async () => {
const { diagram } = await import('./diagram.js');
return { id, diagram };
};
export const usecase: ExternalDiagramDefinition = {
id,
detector,
loader,
};

View File

@@ -1,14 +0,0 @@
import type { DiagramDefinition } from '../../diagram-api/types.js';
import { UsecaseDiagramDB } from './db.js';
import { parser } from './parser.js';
import { renderer } from './renderer.js';
import styles from './styles.js';
export const diagram: DiagramDefinition = {
parser,
get db() {
return new UsecaseDiagramDB();
},
renderer,
styles,
};

View File

@@ -1,40 +0,0 @@
import { parse } from '@mermaid-js/parser';
import type { ParserDefinition } from '../../diagram-api/types.js';
import { log } from '../../logger.js';
import { populateCommonDb } from '../common/populateCommonDb.js';
import type { UsecaseAst } from './types.js';
import { UsecaseDiagramDB } from './db.js';
/**
* Populates the database with data from the Usecase AST
* @param ast - The Usecase AST
*/
const populate = (ast: UsecaseAst, db: UsecaseDiagramDB) => {
// We need to bypass the type checking for populateCommonDb
// eslint-disable-next-line @typescript-eslint/no-explicit-any
populateCommonDb(ast as any, db);
};
export const parser: ParserDefinition = {
// @ts-expect-error - UsecaseDB is not assignable to DiagramDB
parser: { yy: undefined },
parse: async (text: string): Promise<void> => {
try {
// Use a generic parse that accepts any diagram type
const parseFunc = parse as (diagramType: string, text: string) => Promise<UsecaseAst>;
const ast = await parseFunc('usecase', text);
log.debug('Usecase AST:', ast);
const db = parser.parser?.yy;
if (!(db instanceof UsecaseDiagramDB)) {
throw new Error(
'parser.parser?.yy was not a UsecaseDiagramDB. This is due to a bug within Mermaid, please report this issue at https://github.com/mermaid-js/mermaid/issues.'
);
}
populate(ast, db);
} catch (error) {
log.error('Error parsing usecase:', error);
throw error;
}
},
};

View File

@@ -1,21 +0,0 @@
import type { Diagram } from '../../Diagram.js';
import type {
DiagramRenderer,
DiagramStyleClassDef,
DrawDefinition,
} from '../../diagram-api/types.js';
/**
* Draws the Usecase diagram
*/
const draw: DrawDefinition = (_text, _id, _version, _diagram: Diagram) => {
// TODO: Implement the draw function for the usecase diagram
};
const getClasses = function (
_text: string,
_diagramObj: Pick<Diagram, 'db'>
): Map<string, DiagramStyleClassDef> {
return new Map<string, DiagramStyleClassDef>();
};
export const renderer: DiagramRenderer = { draw, getClasses };

View File

@@ -1,51 +0,0 @@
import type { DiagramStylesProvider } from '../../diagram-api/types.js';
import { cleanAndMerge } from '../../utils.js';
import type { UsecaseStyleOptions } from './types.js';
const defaultUsecaseStyleOptions: UsecaseStyleOptions = {
sectionStrokeColor: 'black',
sectionStrokeWidth: '1',
sectionFillColor: '#efefef',
leafStrokeColor: 'black',
leafStrokeWidth: '1',
leafFillColor: '#efefef',
labelColor: 'black',
labelFontSize: '12px',
valueFontSize: '10px',
valueColor: 'black',
titleColor: 'black',
titleFontSize: '14px',
};
export const getStyles: DiagramStylesProvider = ({
usecase,
}: { usecase?: UsecaseStyleOptions } = {}) => {
const options = cleanAndMerge(defaultUsecaseStyleOptions, usecase);
return `
.usecaseNode.section {
stroke: ${options.sectionStrokeColor};
stroke-width: ${options.sectionStrokeWidth};
fill: ${options.sectionFillColor};
}
.usecaseNode.leaf {
stroke: ${options.leafStrokeColor};
stroke-width: ${options.leafStrokeWidth};
fill: ${options.leafFillColor};
}
.usecaseLabel {
fill: ${options.labelColor};
font-size: ${options.labelFontSize};
}
.usecaseValue {
fill: ${options.valueColor};
font-size: ${options.valueFontSize};
}
.usecaseTitle {
fill: ${options.titleColor};
font-size: ${options.titleFontSize};
}
`;
};
export default getStyles;

View File

@@ -1,68 +0,0 @@
import type { DiagramDBBase, DiagramStyleClassDef } from '../../diagram-api/types.js';
import type { BaseDiagramConfig } from '../../config.type.js';
export interface UsecaseNode {
name: string;
children?: UsecaseNode[];
value?: number;
parent?: UsecaseNode;
classSelector?: string;
cssCompiledStyles?: string[];
}
export interface UsecaseDiagramDB extends DiagramDBBase<UsecaseDiagramConfig> {
getNodes: () => UsecaseNode[];
addNode: (node: UsecaseNode, level: number) => void;
getRoot: () => UsecaseNode | undefined;
getClasses: () => Map<string, DiagramStyleClassDef>;
addClass: (className: string, style: string) => void;
getStylesForClass: (classSelector: string) => string[];
// Update
}
export interface UsecaseStyleOptions {
sectionStrokeColor?: string;
sectionStrokeWidth?: string;
sectionFillColor?: string;
leafStrokeColor?: string;
leafStrokeWidth?: string;
leafFillColor?: string;
labelColor?: string;
labelFontSize?: string;
valueFontSize?: string;
valueColor?: string;
titleColor?: string;
titleFontSize?: string;
}
export interface UsecaseData {
nodes: UsecaseNode[];
levels: Map<UsecaseNode, number>;
root?: UsecaseNode;
outerNodes: UsecaseNode[];
}
export interface UsecaseItem {
$type: string;
name: string;
value?: number;
classSelector?: string;
}
export interface UsecaseAst {
title?: string;
description?: string;
}
// Define the UsecaseDiagramConfig interface
export interface UsecaseDiagramConfig extends BaseDiagramConfig {
padding?: number;
diagramPadding?: number;
showValues?: boolean;
nodeWidth?: number;
nodeHeight?: number;
borderWidth?: number;
valueFontSize?: number;
labelFontSize?: number;
valueFormat?: string;
}

View File

@@ -30,6 +30,7 @@
<acc_descr_multiline>[^\}]* { return "acc_descr_multiline_value"; } <acc_descr_multiline>[^\}]* { return "acc_descr_multiline_value"; }
"xychart-beta" {return 'XYCHART';} "xychart-beta" {return 'XYCHART';}
"xychart" {return 'XYCHART';}
(?:"vertical"|"horizontal") {return 'CHART_ORIENTATION'} (?:"vertical"|"horizontal") {return 'CHART_ORIENTATION'}
"x-axis" { this.pushState("axis_data"); return "X_AXIS"; } "x-axis" { this.pushState("axis_data"); return "X_AXIS"; }

View File

@@ -33,44 +33,44 @@ describe('Testing xychart jison file', () => {
clearMocks(); clearMocks();
}); });
it('should throw error if xychart-beta text is not there', () => { it('should throw error if xychart text is not there', () => {
const str = 'xychart-beta-1'; const str = 'xychart-1';
expect(parserFnConstructor(str)).toThrow(); expect(parserFnConstructor(str)).toThrow();
}); });
it('should not throw error if only xychart is there', () => { it('should not throw error if only xychart is there', () => {
const str = 'xychart-beta'; const str = 'xychart';
expect(parserFnConstructor(str)).not.toThrow(); expect(parserFnConstructor(str)).not.toThrow();
}); });
it('parse title of the chart within "', () => { 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(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setDiagramTitle).toHaveBeenCalledWith('This is a title'); expect(mockDB.setDiagramTitle).toHaveBeenCalledWith('This is a title');
}); });
it('parse title of the chart without "', () => { 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(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setDiagramTitle).toHaveBeenCalledWith('oneLinertitle'); expect(mockDB.setDiagramTitle).toHaveBeenCalledWith('oneLinertitle');
}); });
it('parse chart orientation', () => { it('parse chart orientation', () => {
const str = 'xychart-beta vertical'; const str = 'xychart vertical';
expect(parserFnConstructor(str)).not.toThrow(); expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setOrientation).toHaveBeenCalledWith('vertical'); expect(mockDB.setOrientation).toHaveBeenCalledWith('vertical');
}); });
it('parse chart orientation with spaces', () => { it('parse chart orientation with spaces', () => {
let str = 'xychart-beta horizontal '; let str = 'xychart horizontal ';
expect(parserFnConstructor(str)).not.toThrow(); expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setOrientation).toHaveBeenCalledWith('horizontal'); expect(mockDB.setOrientation).toHaveBeenCalledWith('horizontal');
str = 'xychart-beta abc'; str = 'xychart abc';
expect(parserFnConstructor(str)).toThrow(); expect(parserFnConstructor(str)).toThrow();
}); });
it('parse x-axis', () => { 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(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
text: 'xAxisName', text: 'xAxisName',
@@ -79,7 +79,7 @@ describe('Testing xychart jison file', () => {
}); });
it('parse x-axis with axis name without "', () => { 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(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
text: 'xAxisName', text: 'xAxisName',
@@ -88,7 +88,7 @@ describe('Testing xychart jison file', () => {
}); });
it('parse x-axis with axis name with "', () => { 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(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
text: 'xAxisName has space', text: 'xAxisName has space',
@@ -97,7 +97,7 @@ describe('Testing xychart jison file', () => {
}); });
it('parse x-axis with axis name with " with spaces', () => { 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(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
text: ' xAxisName has space ', text: ' xAxisName has space ',
@@ -106,7 +106,7 @@ describe('Testing xychart jison file', () => {
}); });
it('parse x-axis with axis name and range data', () => { 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(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
text: 'xAxisName', text: 'xAxisName',
@@ -115,11 +115,11 @@ describe('Testing xychart jison file', () => {
expect(mockDB.setXAxisRangeData).toHaveBeenCalledWith(45.5, 33); expect(mockDB.setXAxisRangeData).toHaveBeenCalledWith(45.5, 33);
}); });
it('parse x-axis throw error for invalid range data', () => { 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(); expect(parserFnConstructor(str)).toThrow();
}); });
it('parse x-axis with axis name and range data with only decimal part', () => { 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(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
text: 'xAxisName', text: 'xAxisName',
@@ -129,7 +129,7 @@ describe('Testing xychart jison file', () => {
}); });
it('parse x-axis without axis name and range data', () => { 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(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
text: '', text: '',
@@ -139,7 +139,7 @@ describe('Testing xychart jison file', () => {
}); });
it('parse x-axis with axis name and category data', () => { 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(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
text: 'xAxisName', text: 'xAxisName',
@@ -155,7 +155,7 @@ describe('Testing xychart jison file', () => {
}); });
it('parse x-axis without axis name and category data', () => { 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(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
text: '', text: '',
@@ -171,14 +171,14 @@ describe('Testing xychart jison file', () => {
}); });
it('parse x-axis throw error if unbalanced bracket', () => { 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(); 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(); expect(parserFnConstructor(str)).toThrow();
}); });
it('parse x-axis complete variant 1', () => { 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(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'this is x axis', type: 'text' }); expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'this is x axis', type: 'text' });
expect(mockDB.setXAxisBand).toHaveBeenCalledWith([ expect(mockDB.setXAxisBand).toHaveBeenCalledWith([
@@ -189,8 +189,7 @@ describe('Testing xychart jison file', () => {
}); });
it('parse x-axis complete variant 2', () => { it('parse x-axis complete variant 2', () => {
const str = const str = 'xychart \nx-axis xAxisName [ "cat1 with space" , cat2 , cat3] \n ';
'xychart-beta \nx-axis xAxisName [ "cat1 with space" , cat2 , cat3] \n ';
expect(parserFnConstructor(str)).not.toThrow(); expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' }); expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
expect(mockDB.setXAxisBand).toHaveBeenCalledWith([ expect(mockDB.setXAxisBand).toHaveBeenCalledWith([
@@ -202,7 +201,7 @@ describe('Testing xychart jison file', () => {
it('parse x-axis complete variant 3', () => { it('parse x-axis complete variant 3', () => {
const str = 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(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' }); expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
expect(mockDB.setXAxisBand).toHaveBeenCalledWith([ expect(mockDB.setXAxisBand).toHaveBeenCalledWith([
@@ -213,17 +212,17 @@ describe('Testing xychart jison file', () => {
}); });
it('parse y-axis with axis name', () => { 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(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' }); expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
}); });
it('parse y-axis with axis name with spaces', () => { 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(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' }); expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
}); });
it('parse y-axis with axis name with "', () => { 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(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({
text: 'yAxisName has space', text: 'yAxisName has space',
@@ -231,7 +230,7 @@ describe('Testing xychart jison file', () => {
}); });
}); });
it('parse y-axis with axis name with " and spaces', () => { 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(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({
text: ' yAxisName has space ', text: ' yAxisName has space ',
@@ -239,39 +238,39 @@ describe('Testing xychart jison file', () => {
}); });
}); });
it('parse y-axis with axis name with range data', () => { 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(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' }); expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
expect(mockDB.setYAxisRangeData).toHaveBeenCalledWith(45.5, 33); expect(mockDB.setYAxisRangeData).toHaveBeenCalledWith(45.5, 33);
}); });
it('parse y-axis without axis name with range data', () => { 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(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: '', type: 'text' }); expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: '', type: 'text' });
expect(mockDB.setYAxisRangeData).toHaveBeenCalledWith(45.5, 33); expect(mockDB.setYAxisRangeData).toHaveBeenCalledWith(45.5, 33);
}); });
it('parse y-axis with axis name with range data with only decimal part', () => { 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(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' }); expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
expect(mockDB.setYAxisRangeData).toHaveBeenCalledWith(45.5, 0.33); expect(mockDB.setYAxisRangeData).toHaveBeenCalledWith(45.5, 0.33);
}); });
it('parse y-axis throw error for invalid number in range data', () => { 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(); expect(parserFnConstructor(str)).toThrow();
}); });
it('parse y-axis throws error if range data is passed', () => { 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(); expect(parserFnConstructor(str)).toThrow();
}); });
it('parse both axis at once', () => { 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(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' }); expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' }); expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
}); });
it('parse line Data', () => { 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(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setLineData).toHaveBeenCalledWith( expect(mockDB.setLineData).toHaveBeenCalledWith(
{ text: 'lineTitle', type: 'text' }, { text: 'lineTitle', type: 'text' },
@@ -282,7 +281,7 @@ describe('Testing xychart jison file', () => {
}); });
it('parse line Data with spaces and +,- symbols', () => { it('parse line Data with spaces and +,- symbols', () => {
const str = 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(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' }); expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', 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', () => { it('parse line Data without title', () => {
const str = const str = 'xychart\nx-axis xAxisName\ny-axis yAxisName\n line [ +23 , -45 , 56.6 , .33] ';
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line [ +23 , -45 , 56.6 , .33] ';
expect(parserFnConstructor(str)).not.toThrow(); expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' }); expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', 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', () => { it('parse line Data throws error unbalanced brackets', () => {
let str = 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(); expect(parserFnConstructor(str)).toThrow();
str = 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(); expect(parserFnConstructor(str)).toThrow();
}); });
it('parse line Data throws error if data is not provided', () => { 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(); expect(parserFnConstructor(str)).toThrow();
}); });
it('parse line Data throws error if data is empty', () => { it('parse line Data throws error if data is empty', () => {
const str = const str = 'xychart\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ ] ';
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ ] ';
expect(parserFnConstructor(str)).toThrow(); expect(parserFnConstructor(str)).toThrow();
}); });
it('parse line Data throws error if , is not in proper', () => { it('parse line Data throws error if , is not in proper', () => {
const str = 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(); expect(parserFnConstructor(str)).toThrow();
}); });
it('parse line Data throws error if not number', () => { it('parse line Data throws error if not number', () => {
const str = 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(); expect(parserFnConstructor(str)).toThrow();
}); });
it('parse bar Data', () => { it('parse bar Data', () => {
const str = const str = 'xychart\nx-axis xAxisName\ny-axis yAxisName\n bar barTitle [23, 45, 56.6, .22]';
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar barTitle [23, 45, 56.6, .22]';
expect(parserFnConstructor(str)).not.toThrow(); expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' }); expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', 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', () => { it('parse bar Data spaces and +,- symbol', () => {
const str = 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(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' }); expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', 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', () => { it('parse bar Data without plot title', () => {
const str = const str = 'xychart\nx-axis xAxisName\ny-axis yAxisName\n bar [ +23 , -45 , 56.6 ] ';
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar [ +23 , -45 , 56.6 ] ';
expect(parserFnConstructor(str)).not.toThrow(); expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' }); expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', 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', () => { it('parse bar should throw for unbalanced brackets', () => {
let str = 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(); expect(parserFnConstructor(str)).toThrow();
str = 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(); expect(parserFnConstructor(str)).toThrow();
}); });
it('parse bar should throw error if data is not provided', () => { 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(); expect(parserFnConstructor(str)).toThrow();
}); });
it('parse bar should throw error if data is empty', () => { it('parse bar should throw error if data is empty', () => {
const str = 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(); expect(parserFnConstructor(str)).toThrow();
}); });
it('parse bar should throw error if comma is not proper', () => { it('parse bar should throw error if comma is not proper', () => {
const str = 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(); expect(parserFnConstructor(str)).toThrow();
}); });
it('parse bar should throw error if number is not passed', () => { it('parse bar should throw error if number is not passed', () => {
const str = 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(); expect(parserFnConstructor(str)).toThrow();
}); });
it('parse multiple bar and line variant 1', () => { it('parse multiple bar and line variant 1', () => {
const str = 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(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' }); expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', 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', () => { it('parse multiple bar and line variant 2', () => {
const str = ` const str = `
xychart-beta horizontal xychart horizontal
title Basic xychart title "Basic xychart"
x-axis "this is x axis" [category1, "category 2", category3] x-axis "this is x axis" [category1, "category 2", category3]
y-axis yaxisText 10 --> 150 y-axis yaxisText 10 --> 150
bar barTitle1 [23, 45, 56.6] bar barTitle1 [23, 45, 56.6]

Some files were not shown because too many files have changed in this diff Show More