Compare commits

..

201 Commits

Author SHA1 Message Date
Sidharth Vinod
0518e9cfd7 Merge pull request #5984 from mermaid-js/renovate/eslint
chore(deps): update eslint (minor)
2025-02-21 10:26:12 +00:00
autofix-ci[bot]
f43e35039f [autofix.ci] apply automated fixes 2025-02-20 18:31:20 +00:00
renovate[bot]
dbf885b077 chore(deps): update eslint 2025-02-20 18:25:55 +00:00
Sidharth Vinod
ad2f17205a Merge pull request #6272 from mermaid-js/saurabh/refactor/convert-sequenceDb-to-class
Refactor: Change SequenceDB to class based architecture.
2025-02-20 07:20:14 +00:00
Sidharth Vinod
98fe7a6e03 Merge pull request #5997 from mermaid-js/renovate/major-eslint
chore(deps): update eslint (major)
2025-02-19 12:48:14 +05:30
saurabhg772244
5857953d51 Merge branch 'develop' of https://github.com/mermaid-js/mermaid into saurabh/refactor/convert-sequenceDb-to-class 2025-02-19 11:26:22 +05:30
Sidharth Vinod
34a12103d0 Merge branch 'renovate/major-eslint' of https://github.com/mermaid-js/mermaid into renovate/major-eslint
* 'renovate/major-eslint' of https://github.com/mermaid-js/mermaid:
  chore(deps): update eslint
2025-02-19 00:34:03 +05:30
Sidharth Vinod
46b8a75199 chore: Remove deprecated rule 2025-02-19 00:33:56 +05:30
renovate[bot]
1dca45a76d chore(deps): update eslint 2025-02-18 19:01:39 +00:00
Sidharth Vinod
d1d5bd14f6 Merge branch 'develop' into renovate/major-eslint
* develop:
  chore: Add tslib
  [autofix.ci] apply automated fixes
  fix(deps): update all patch dependencies
2025-02-19 00:28:32 +05:30
Sidharth Vinod
974867a089 Merge pull request #5961 from mermaid-js/renovate/patch-all-patch
fix(deps): update all patch dependencies (patch)
2025-02-19 00:24:41 +05:30
Sidharth Vinod
52532a7801 Merge pull request #6295 from mermaid-js/omkar/fix-state-diagram-default-direction
Fix: state diagram default direction update
2025-02-18 18:53:57 +00:00
Sidharth Vinod
6eb56b9363 Merge branch 'develop' into renovate/patch-all-patch
* develop: (97 commits)
  chore: Update actions/cache
  chore: Update actions/cache
  fix: CodeQL double escape warning
  chore(deps): update eslint
  Added changeset.
  refactor: handle StateDB `.extract()` properly
  chore(deps): update dependency esbuild to ^0.25.0 [security]
  Update .changeset/grumpy-cheetahs-deliver.md
  chore: Use RUN_VISUAL_TEST in cypress config
  chore: Use argos tokenless auth
  chore: Add tokenless auth to argos
  fix(deps): update dependency dompurify to v3.2.4 [security]
  chore: Update argos token
  Ignore huehive
  chore: Run argos on all PRs, except renovate bot's
  chore: Fix exclude
  [autofix.ci] apply automated fixes
  chore(deps): update dependency vitest to v1.6.1 [security]
  docs: Cleanup minor issues
  Add files via upload
  ...
2025-02-19 00:08:50 +05:30
Sidharth Vinod
f7c91a72cb chore: Add tslib 2025-02-19 00:06:45 +05:30
renovate[bot]
c53e044559 chore(deps): update eslint 2025-02-18 18:26:30 +00:00
Sidharth Vinod
d846a8c65a chore: Minor refactor 2025-02-18 23:48:19 +05:30
Sidharth Vinod
c3ba23a4e9 Merge branch 'develop' into omkar/fix-state-diagram-default-direction 2025-02-18 23:44:19 +05:30
Sidharth Vinod
c688c387a0 Merge pull request #6298 from mermaid-js/saurabh/fix/sanitizeText-codeql-warning
fix: CodeQL double escape warning
2025-02-18 23:41:31 +05:30
Sidharth Vinod
300fb85a73 chore: Update actions/cache 2025-02-18 23:41:01 +05:30
Sidharth Vinod
9c6e554153 chore: Update actions/cache 2025-02-18 23:40:53 +05:30
Sidharth Vinod
b5c78b7225 Merge pull request #5908 from mermaid-js/renovate/patch-eslint
chore(deps): update eslint (patch)
2025-02-18 21:42:23 +05:30
omkarht
da6361f652 added changeset 2025-02-18 18:36:52 +05:30
omkarht
167fef5cff added test cases to check state diagram direction 2025-02-18 17:23:48 +05:30
saurabhg772244
3233c63fc0 Updated variable name 2025-02-18 16:59:35 +05:30
saurabhg772244
1182aaaf4d fix: CodeQL double escape warning 2025-02-18 15:42:25 +05:30
omkarht
b78c061a8f refatored code 2025-02-18 15:40:45 +05:30
renovate[bot]
ebfcf3ea07 chore(deps): update eslint 2025-02-17 15:45:31 +00:00
Sidharth Vinod
62edea6b33 Merge pull request #6293 from mermaid-js/saurabh/refactor/handle-StateDB-.extract-properly
Handle StateDB `.extract()` properly
2025-02-17 21:13:26 +05:30
omkarht
72eda9ce52 Fix: state diagram default direction update 2025-02-17 20:53:31 +05:30
saurabhg772244
cfd84e54d5 Added changeset. 2025-02-17 16:14:55 +05:30
Alois Klink
cfe710f42b refactor: handle StateDB .extract() properly
Fix the StateDB properly for stateDiagram-v1 vs stateDiagram-v2.
2025-02-17 15:54:19 +05:30
saurabhg772244
fe6f05eec9 Merge branch 'develop' of github.com-mermaid:mermaid-js/mermaid into saurabh/refactor/convert-sequenceDb-to-class 2025-02-15 22:56:53 +05:30
Sidharth Vinod
548256507d Merge pull request #6269 from mermaid-js/renovate/npm-esbuild-vulnerability
chore(deps): update dependency esbuild to ^0.25.0 [security]
2025-02-15 16:51:26 +00:00
Sidharth Vinod
d8ebf7a136 Merge pull request #6250 from mermaid-js/saurabh/refactor/convert-stateDb-to-class-v2
Refactor: V2. Change StateDB to class based architecture.
2025-02-15 16:50:55 +00:00
renovate[bot]
a758b24b75 chore(deps): update dependency esbuild to ^0.25.0 [security] 2025-02-15 16:16:28 +00:00
Saurabh Gore
88abf46fc3 Update .changeset/grumpy-cheetahs-deliver.md
Co-authored-by: Sidharth Vinod <github@sidharth.dev>
2025-02-15 21:33:58 +05:30
Sidharth Vinod
2eeba0e999 Merge branch 'develop' into saurabh/refactor/convert-stateDb-to-class-v2 2025-02-15 21:31:14 +05:30
Sidharth Vinod
397684fe49 Merge pull request #6284 from mermaid-js/renovate/npm-dompurify-vulnerability
fix(deps): update dependency dompurify to v3.2.4 [security]
2025-02-15 16:00:56 +00:00
Sidharth Vinod
bc1f769f13 Merge pull request #6287 from sidharthv96/sidv/tokenlessArgos
chore: Add tokenless auth to argos
2025-02-15 21:30:39 +05:30
Sidharth Vinod
f6592235a2 chore: Use RUN_VISUAL_TEST in cypress config 2025-02-15 21:05:47 +05:30
Sidharth Vinod
57805dafa4 chore: Use argos tokenless auth 2025-02-15 20:51:56 +05:30
Sidharth Vinod
3b92f979e3 chore: Add tokenless auth to argos 2025-02-15 20:28:55 +05:30
renovate[bot]
7a7e4b4e6f fix(deps): update dependency dompurify to v3.2.4 [security] 2025-02-15 14:39:21 +00:00
Sidharth Vinod
c5843bee23 chore: Update argos token
We have added a check in e2e, to ensure events in forks will not trigger the visual tests.

This will not protect against malicious users, but there is no other way to support PRs from forks.

A proposal has been sent to Argos team to add a secure approach for public repos, fingers crossed.
2025-02-15 20:07:41 +05:30
Sidharth Vinod
ada42b892c Ignore huehive 2025-02-14 21:41:53 +05:30
Sidharth Vinod
62f9261c4e Merge branch 'develop' into saurabh/refactor/convert-stateDb-to-class-v2 2025-02-14 21:21:00 +05:30
Sidharth Vinod
a19b42f3c2 Merge pull request #6283 from mermaid-js/sidv/argos-skip-renovate
Run visual test on all PRs, except renovate bot's
2025-02-14 21:20:38 +05:30
Sidharth Vinod
9f90f4f23a chore: Run argos on all PRs, except renovate bot's 2025-02-14 21:17:29 +05:30
saurabhg772244
451c886f50 Code refactor. 2025-02-14 19:17:09 +05:30
saurabhg772244
0a1a112605 Move setWrap below clear in constructor. 2025-02-14 17:51:17 +05:30
Sidharth Vinod
348401c4f4 Merge pull request #6253 from mermaid-js/renovate/npm-vitest-vulnerability
chore(deps): update dependency vitest to v1.6.1 [security]
2025-02-13 19:48:12 +00:00
Sidharth Vinod
8145199203 Merge pull request #6265 from Mandzhi/Mandzhi-patch-2
Update tutorials.md
2025-02-13 19:47:54 +00:00
Sidharth Vinod
f408e938d4 chore: Fix exclude 2025-02-14 01:01:48 +05:30
autofix-ci[bot]
af6e2b4cb6 [autofix.ci] apply automated fixes 2025-02-13 08:23:14 +00:00
renovate[bot]
7a4a52b50a chore(deps): update dependency vitest to v1.6.1 [security] 2025-02-13 08:21:24 +00:00
Sidharth Vinod
ee05d8588f Merge pull request #6245 from homersimpsons/patch-1
Add git graph preview in README.md
2025-02-13 13:49:08 +05:30
Sidharth Vinod
58175f647e docs: Cleanup minor issues 2025-02-13 13:47:49 +05:30
saurabhg772244
6ca8f46d37 Updated unit tests. 2025-02-12 16:15:06 +05:30
saurabhg772244
b2dfbb6ffd Merge branch 'develop' of https://github.com/mermaid-js/mermaid into saurabh/refactor/convert-sequenceDb-to-class 2025-02-12 16:04:54 +05:30
saurabhg772244
ffa7804af0 added changeset 2025-02-12 16:04:22 +05:30
saurabhg772244
f454865b97 Updated unit tests to reflect new DB instance per parse. 2025-02-12 16:00:14 +05:30
saurabhg772244
d83b1a5dbc Refactored arrow function to regular function and assigned unique ID to messages during parsing. 2025-02-12 15:54:51 +05:30
Radmila M.
d07f85e6ac Add files via upload 2025-02-10 14:05:55 +03:00
Radmila M.
a79c0f4c00 Update tutorials.md 2025-02-10 14:01:09 +03:00
Radmila M.
4a19740aea Update tutorials.md 2025-02-10 13:24:38 +03:00
saurabhg772244
4dbaa2b5d6 code refactor 2025-02-04 19:18:46 +05:30
saurabhg772244
9cad3c7aea added changeset 2025-02-04 17:09:09 +05:30
saurabhg772244
56d66cdabc Fix issue where data was not being set in the db after parsing. 2025-02-04 16:45:45 +05:30
saurabhg772244
a0e5408850 convert stateDb to class, added test case. 2025-02-04 16:41:54 +05:30
homersimpsons
d155e414a0 Add git graph preview in README.md 2025-02-01 11:20:06 +01:00
Ashish Jain
8dd0e7a794 Merge pull request #6229 from mermaid-js/patch/font-family-legend-user-diagram
Set custom font family for legend in user diagrams.
2025-01-28 10:30:20 +01:00
saurabhg772244
5e9c887385 Fixed unit tests. 2025-01-27 16:30:35 +05:30
saurabhg772244
fdb8ae5b53 Set custom font family for legend in user diagrams. 2025-01-27 16:16:43 +05:30
Sidharth Vinod
e2de55202f Merge pull request #6224 from theHacker/patch-1
Fix: Wrong link to d3-shape documentation in Flowchart docs
2025-01-26 00:40:08 +05:30
autofix-ci[bot]
b4043840ca [autofix.ci] apply automated fixes 2025-01-25 12:03:03 +00:00
Alexander Münch
8f3e17e386 Fix: Wrong link to d3-shape documentation in Flowchart docs 2025-01-25 12:47:59 +01:00
Sidharth Vinod
4e950e7256 Merge pull request #6177 from Ryuno-Ki/forgejo-integration
docs: add Forgejo as integration
2025-01-25 16:24:52 +05:30
autofix-ci[bot]
de3e381ccf [autofix.ci] apply automated fixes 2025-01-25 10:41:45 +00:00
Sidharth Vinod
b2fde76753 Add Forgejo to cspell 2025-01-25 16:06:46 +05:30
Sidharth Vinod
b5587d8b87 test: Fix duplicate test name 2025-01-25 15:45:42 +05:30
André Jaenisch
9b75aeb224 Update integrations-community.md
Added Forgejo as integration
2025-01-25 10:22:35 +01:00
André Jaenisch
993858cdc8 Merge branch 'mermaid-js:develop' into forgejo-integration 2025-01-25 10:20:39 +01:00
Sidharth Vinod
f4e1f07412 chore: Update mermaid repo link to mermaid-js/mermaid
https://github.com/mermaid-js/mermaid/actions/runs/12963524805/job/36161210394
2025-01-25 14:31:24 +05:30
Sidharth Vinod
09e0de6053 chore: Update upload-artifact to v4
Verified that the other hash was infact valid and in the repo, but the scorecard action was not picking it up.
2025-01-25 14:27:18 +05:30
Sidharth Vinod
9a50bf5237 chore: Fix cypress record flag 2025-01-25 14:21:11 +05:30
Sidharth Vinod
5747009c8f chore: Fix failing tests 2025-01-25 14:09:09 +05:30
Sidharth Vinod
dc513ec211 Merge pull request #6098 from royaljain/feature/mermaid-ai-bot
Add Mermaid AI Bot in Readme
2025-01-25 12:18:07 +05:30
Sidharth Vinod
5f58d4f7b0 Merge pull request #6106 from zackkatz/patch-1
Youtube --> YouTube
2025-01-25 12:14:53 +05:30
Sidharth Vinod
3536ceb5d3 Merge branch 'develop' into patch-1 2025-01-25 12:14:31 +05:30
Sidharth Vinod
7ed33a91c0 Merge pull request #6183 from mermaid-js/renovate/autofix-ci-action-digest
chore(deps): update autofix-ci/action digest to 551dded
2025-01-25 12:13:59 +05:30
Sidharth Vinod
f8bf03d365 Merge pull request #6180 from mermaid-js/renovate/actions-upload-artifact-digest
chore(deps): update actions/upload-artifact digest to ff15f03
2025-01-25 12:13:41 +05:30
Sidharth Vinod
4202ee521a Merge pull request #6209 from mermaid-js/renovate/npm-vite-vulnerability
chore(deps): update dependency vite to v5.4.12 [security]
2025-01-25 12:12:52 +05:30
renovate[bot]
0e25fd42f9 chore(deps): update autofix-ci/action digest to 551dded 2025-01-25 06:42:31 +00:00
renovate[bot]
feee5d1c8c chore(deps): update actions/upload-artifact digest to ff15f03 2025-01-25 06:42:28 +00:00
renovate[bot]
ab6d92c544 chore(deps): update dependency vite to v5.4.12 [security] 2025-01-25 06:41:59 +00:00
Sidharth Vinod
d27d4abab7 Merge pull request #6181 from politbuero-kampagnen/patch-2
Update integrations-community.md
2025-01-25 12:10:34 +05:30
Sidharth Vinod
3162cff7a9 Merge branch 'develop' into forgejo-integration 2025-01-25 12:03:20 +05:30
Sidharth Vinod
9681a27b31 chore: Skip running E2E on comments without visual test command 2025-01-25 11:48:26 +05:30
Sidharth Vinod
ba534985ec Merge pull request #6222 from mermaid-js/sidv/visualTestComment
chore: Add a command to execute visual test
2025-01-25 11:34:09 +05:30
Sidharth Vinod
edc1ae1e0c chore: Update default values 2025-01-25 11:23:30 +05:30
Sidharth Vinod
c00f3fb090 chore: Add a command to execute visual test 2025-01-25 11:01:23 +05:30
Ashish Jain
74a56fc58a Merge pull request #6218 from mermaid-js/revert-state-diagram-class-architecture
Revert state diagram class based architecture
2025-01-24 15:09:54 +01:00
Saurabh Gore
08ffbb61e9 remove unused import 2025-01-24 19:32:17 +05:30
Saurabh Gore
232e60c8cb Added changeset 2025-01-24 19:25:44 +05:30
Saurabh Gore
cd9ca76e39 Revert state diagram class based architecture 2025-01-24 19:20:40 +05:30
Ashish Jain
c13d988392 Merge pull request #6212 from mermaid-js/saurabh/refactor/convert-classDb-to-class
Refactor: Change ClassDB to class based architecture.
2025-01-24 12:28:20 +01:00
saurabhg772244
15ffe2021a Merge branch 'develop' of https://github.com/mermaid-js/mermaid into saurabh/refactor/convert-classDb-to-class 2025-01-24 16:48:22 +05:30
Ashish Jain
4fbc19e0d7 Merge pull request #6185 from mermaid-js/saurabh/refactor/convert-stateDb-to-class
Refactor: Change StateDB to class based architecture.
2025-01-24 10:46:42 +01:00
saurabhg772244
2b8998fdd1 Merge branch 'develop' of https://github.com/mermaid-js/mermaid into saurabh/refactor/convert-classDb-to-class 2025-01-23 14:59:41 +05:30
saurabhg772244
202ef31071 Fixed binding issue 2025-01-23 14:58:16 +05:30
saurabhg772244
b09f2e836a Updated as per PR comments 2025-01-23 12:25:38 +05:30
saurabhg772244
6a814a0d91 Merge branch 'develop' of https://github.com/mermaid-js/mermaid into saurabh/refactor/convert-stateDb-to-class 2025-01-23 11:53:01 +05:30
saurabhg772244
b07bb9b3ff Minor change 2025-01-23 11:44:06 +05:30
Ashish Jain
5120ed09ab Merge pull request #6161 from mermaid-js/saurabh/refactor/convert-flowDb-to-class
Refactor: Change flowDB to class based architecture.
2025-01-22 22:41:52 +01:00
saurabhg772244
61f3fc5ede Use static reference for relationType in StateDB 2025-01-22 19:17:38 +05:30
saurabhg772244
90bbf90a83 Added changeset 2025-01-22 19:10:48 +05:30
saurabhg772244
92efc24283 Refactored arrow functions to standard function 2025-01-22 19:07:53 +05:30
saurabhg772244
1c45df4567 Updated as per PR comments 2025-01-22 17:53:51 +05:30
saurabhg772244
1575a93136 Merge branch 'develop' of https://github.com/mermaid-js/mermaid into saurabh/refactor/convert-flowDb-to-class 2025-01-22 16:22:20 +05:30
saurabhg772244
bde653b1c2 Updated as per Alois suggestion 2025-01-22 15:49:51 +05:30
Ashish Jain
e9e663ffa3 Merge pull request #6198 from mermaid-js/edge-flicker-fix
edge flickering fix
2025-01-22 11:12:23 +01:00
Ashish Jain
963efa64c7 Added changeset 2025-01-22 11:01:37 +01:00
Ashish Jain
e2e5101005 Handle more override edge animate 2025-01-22 10:57:57 +01:00
saurabhg772244
6ea13cded3 Fixed binding issue 2025-01-22 12:27:32 +05:30
Ashish Jain
c063b92cc9 Handle more edge cases, and lint fixes 2025-01-22 02:03:29 +01:00
autofix-ci[bot]
304f133227 [autofix.ci] apply automated fixes 2025-01-22 00:14:56 +00:00
Ashish Jain
54a0dd0af6 Make flowchart edge Ids consistent across getEdges and getData 2025-01-22 01:09:49 +01:00
Ashish Jain
ab5b7694c6 Merge branch 'develop' into edge-flicker-fix 2025-01-21 17:31:06 +01:00
Ashish Jain
eb76dfb1ca Merge pull request #6205 from mermaid-js/Refactor/fix-styles
fix: styles for Sankey, Gantt, and User Journey diagrams
2025-01-21 17:30:51 +01:00
Saurabh Gore
28d7ec092c Merge branch 'develop' into Refactor/fix-styles 2025-01-21 20:10:43 +05:30
Ashish Jain
84b03f3a08 Merge pull request #6196 from mermaid-js/6195-at-signs-in-labels
#6195 at signs in labels
2025-01-21 15:19:39 +01:00
saurabhg772244
f9ac9867c1 Updated as per Alois suggestion. 2025-01-21 19:21:56 +05:30
saurabhg772244
ee6fb83265 Used 'options' instead of 'var(--mermaid-font-family)' 2025-01-21 18:27:05 +05:30
saurabhg772244
46c16c963b Minor change. 2025-01-21 15:32:53 +05:30
saurabhg772244
32a68d489e Added changeset 2025-01-21 11:35:23 +05:30
saurabhg772244
7bbebff583 Updated styles implementation 2025-01-20 20:30:28 +05:30
saurabhg772244
c432aec2f6 fix: styles for Sankey, Gantt, and User Journey diagrams 2025-01-20 20:05:51 +05:30
Feroz Mujawar
64237fbaa7 updated addSingleLink for multiple outgoing edges to same end node 2025-01-20 19:59:46 +05:30
Feroz Mujawar
7ba415dad1 edge flickering fix 2025-01-17 21:23:30 +05:30
Knut Sveidqvist
7f47678862 Spellfix in changeset 2025-01-17 11:50:22 +01:00
Knut Sveidqvist
127bac1147 Adding changeset 2025-01-17 11:48:28 +01:00
Knut Sveidqvist
9a90d795ca #6195 Updated lexer to not allow quotes in link ids 2025-01-17 11:46:44 +01:00
saurabhg772244
f7fe8f2f59 Merge branch 'develop' of https://github.com/mermaid-js/mermaid into saurabh/refactor/convert-flowDb-to-class 2025-01-16 15:17:24 +05:30
Ashish Jain
1d9c2aab8d #6186 Fix for flowchart new syntax with link 2025-01-15 13:45:04 +01:00
saurabhg772244
8fba9c1236 convert flowDb to class and added test cases. 2025-01-15 18:02:04 +05:30
Knut Sveidqvist
04800ff677 Merge pull request #6187 from mermaid-js/flowchart-new-syntax-bugs
#6186 Fixes the flowchart node metadata syntax bugs
2025-01-15 11:45:11 +01:00
saurabhg772244
5d3d1047a4 convert sequenceDb to class. 2025-01-15 15:37:33 +05:30
saurabhg772244
0f08c3bc9c Updated FlowDB instance. 2025-01-14 19:02:50 +05:30
Ashish Jain
7809b5a93f #6186 Fixes the flowchaart node metadata syntax bugs 2025-01-14 14:07:25 +01:00
saurabhg772244
ef9bb53e67 Code refactor 2025-01-14 15:32:47 +05:30
saurabhg772244
3e32332814 Added changeset. 2025-01-14 15:22:14 +05:30
saurabhg772244
e1aab25144 Updated changeset message. 2025-01-14 12:45:56 +05:30
saurabhg772244
c8697301ee Code refactor. 2025-01-14 12:21:07 +05:30
saurabhg772244
fcb1de915b convert stateDb to class, added test case. 2025-01-13 20:30:38 +05:30
autofix-ci[bot]
e345294658 [autofix.ci] apply automated fixes 2025-01-12 14:01:18 +00:00
Balthasar Glättli
9936099e25 Update integrations-community.md
Replaced outdated and lo longer maintained WordPress plugins with actually maintained MerPress Plugin
2025-01-12 14:53:19 +01:00
autofix-ci[bot]
59352ad4d8 [autofix.ci] apply automated fixes 2025-01-11 16:39:40 +00:00
renovate[bot]
ba70f15de5 fix(deps): update all patch dependencies 2025-01-11 16:32:14 +00:00
autofix-ci[bot]
e70b069576 [autofix.ci] apply automated fixes 2025-01-10 14:23:09 +00:00
André Jaenisch
28bab4a323 Update integrations-community.md
Added Forgejo as integration
2025-01-10 15:11:22 +01:00
Saurabh Gore
6cc31b7453 Added changeset 2025-01-10 13:33:04 +05:30
Saurabh Gore
29ca1504dd Added unit test cases for flow DB to have functions used in flow JISON 2025-01-10 13:19:13 +05:30
saurabhg772244
16d2251e43 Merge branch 'develop' of https://github.com/mermaid-js/mermaid into saurabh/refactor/convert-flowDb-to-class 2025-01-10 11:15:39 +05:30
Ashish Jain
bc2cc61240 Merge pull request #6136 from mermaid-js/5813-edge-bugfix
Adding animations to flowchart edges also fixing bug with invisible edges
2025-01-07 09:59:52 +01:00
Saurabh Gore
6836e9c7a8 Updated test cases 2025-01-07 12:03:54 +05:30
Saurabh Gore
8dc016e7f9 Update packages/mermaid/src/mermaidAPI.spec.ts
Co-authored-by: Alois Klink <alois@aloisklink.com>
2025-01-06 16:43:49 +05:30
Saurabh Gore
3cad7984a3 Update packages/mermaid/src/mermaidAPI.spec.ts
Co-authored-by: Alois Klink <alois@aloisklink.com>
2025-01-06 16:37:51 +05:30
Saurabh Gore
f5bae98098 Set generation to gen-2 in clear 2025-01-03 14:55:20 +05:30
Saurabh Gore
0695893e30 Added test cases 2025-01-03 11:30:21 +05:30
Saurabh Gore
9ef6090c8c convert flowDb to class. 2024-12-31 17:40:52 +05:30
Knut Sveidqvist
ec0d9c389a Adding changeset 2024-12-18 11:59:39 +01:00
Knut Sveidqvist
323b07a2e4 Typescript fix and updating documentation 2024-12-18 11:56:48 +01:00
Knut Sveidqvist
c153d0455f #5574 Fixed issue linkStyles 2024-12-17 16:28:38 +01:00
Knut Sveidqvist
9b00f1f2fb #5574 Adding support for edge ids and animations 2024-12-17 14:56:18 +01:00
autofix-ci[bot]
a055ff7db3 [autofix.ci] apply automated fixes 2024-12-02 18:14:21 +00:00
Zack Katz
d032723a47 Youtube --> YouTube 2024-12-02 11:56:17 -05:00
Royal Jain
daf83f596d Add Mermaid AI Bot in Readme 2024-11-29 16:46:15 +05:30
Sidharth Vinod
df636c6d0a Merge pull request #6001 from michaelbaudino/patch-1
Fix a configuration example in `gantt.md`
2024-11-28 09:10:56 +05:30
Ashish Jain
64554a6c60 Merge pull request #6092 from mermaid-js/master
Merge back master to develop
2024-11-27 18:24:31 +01:00
Knut Sveidqvist
becadf0a7d Merge pull request #6091 from mermaid-js/changeset-release/master
Version Packages
2024-11-27 18:14:40 +01:00
Sidharth Vinod
54d485f173 Merge branch 'develop' into patch-1 2024-11-27 21:50:42 +05:30
Ashish Jain
b4f5b8ddaf Update CHANGELOG.md 2024-11-27 17:13:25 +01:00
github-actions[bot]
cb5c1ae367 Version Packages 2024-11-27 16:10:54 +00:00
Knut Sveidqvist
b29081d4e8 Merge pull request #6090 from mermaid-js/hotfix/elk-0.1.7
Hotfix/elk 0.1.7
2024-11-27 17:08:48 +01:00
Knut Sveidqvist
654097c438 Added changeset 2024-11-27 17:05:58 +01:00
Knut Sveidqvist
1e672868c4 #6088 Updated offset calculations 2024-11-27 17:05:58 +01:00
Sidharth Vinod
bff32827b5 Merge pull request #6064 from NicolasNewman/5952/architecture-extreme-height
Fix: edge case causing extreme height in Architecture Diagrams
2024-11-27 17:18:41 +05:30
Ashish Jain
65f9b29b86 Merge back master 11.4.1 to develop 2024-11-27 12:08:28 +01:00
Sidharth Vinod
b4879d13b8 Merge pull request #6036 from docxml/patch-1
Typo kanban.md
2024-11-27 15:08:57 +05:30
Sidharth Vinod
95964b5487 Merge pull request #6055 from agokhale/no-dev-elk-import
Use layout-elk in example.html
2024-11-27 15:07:13 +05:30
Sidharth Vinod
4e17da0a30 fix: Add layout-elk in example.html 2024-11-27 15:05:40 +05:30
NicolasNewman
2a91849a38 chore(#5952): changeset 2024-11-16 10:03:13 -06:00
Nicolas Newman
082de76eef Merge branch 'mermaid-js:develop' into 5952/architecture-extreme-height 2024-11-16 09:55:48 -06:00
NicolasNewman
570ae78b15 cicd(#5952): added test case for diagram that instigated the issue 2024-11-15 10:28:50 -06:00
NicolasNewman
885ac6f947 fix(#5952): handled additional edge cases 2024-11-15 10:27:20 -06:00
agokhale
193fdb225e the ELK imports break the dev playground, drop them 2024-11-13 05:16:01 -05:00
autofix-ci[bot]
7cbd80af33 [autofix.ci] apply automated fixes 2024-11-08 11:05:26 +00:00
docxml
16c448b89b Typo kanban.md 2024-11-08 10:59:10 +00:00
NicolasNewman
cb0a4703bd fix(#5952): initial fix for architecture diagrams with extreme heights 2024-11-03 15:53:09 -06:00
autofix-ci[bot]
8cb1c68166 [autofix.ci] apply automated fixes 2024-10-29 13:09:54 +01:00
Michael Baudino
d752240efc Fix a configuration example in gantt.md
According to the [config schema docs](https://mermaid.js.org/config/schema-docs/config-defs-gantt-diagram-config.html#tickinterval-constraints), Gantt's `tickInterval` configuration must match the following regular expression, which does **not** allow any space:

```regexp
/^([1-9][0-9]*)(millisecond|second|minute|hour|day|week|month)$/
```
2024-10-29 13:09:54 +01:00
124 changed files with 8473 additions and 4641 deletions

View File

@@ -0,0 +1,5 @@
---
'mermaid': patch
---
fix: architecture diagrams no longer grow to extreme heights due to conflicting alignments

View File

@@ -0,0 +1,5 @@
---
'mermaid': patch
---
Fixes for consistent edge id creation & handling edge cases for animate edge feature

View File

@@ -0,0 +1,5 @@
---
'mermaid': patch
---
Fix for issue #6195 - allowing @ signs inside node labels

View File

@@ -0,0 +1,5 @@
---
'mermaid': patch
---
fix: `mermaidAPI.getDiagramFromText()` now returns a new different db for each class diagram

View File

@@ -0,0 +1,5 @@
---
'mermaid': patch
---
fix: revert state db to resolve getData returning empty nodes and edges

View File

@@ -0,0 +1,8 @@
---
'mermaid': minor
---
Flowchart new syntax for node metadata bugs
- Incorrect label mapping for nodes when using `&`
- Syntax error when `}` with trailing spaces before new line

View File

@@ -0,0 +1,5 @@
---
'mermaid': patch
---
`mermaidAPI.getDiagramFromText()` now returns a new db instance on each call for state diagrams

View File

@@ -0,0 +1,5 @@
---
'mermaid': patch
---
Added versioning to StateDB and updated tests and diagrams to use it.

View File

@@ -0,0 +1,5 @@
---
'mermaid': minor
---
Adding support for animation of flowchart edges

View File

@@ -0,0 +1,5 @@
---
'mermaid': patch
---
fix: `mermaidAPI.getDiagramFromText()` now returns a new different db for each flowchart

View File

@@ -0,0 +1,5 @@
---
'mermaid': patch
---
fix: `mermaidAPI.getDiagramFromText()` now returns a new different db for each sequence diagram. Added unique IDs for messages.

View File

@@ -0,0 +1,5 @@
---
'mermaid': patch
---
fix: Gantt, Sankey and User Journey diagram are now able to pick font-family from mermaid config.

View File

@@ -0,0 +1,5 @@
---
'mermaid': patch
---
fix: `getDirection` and `setDirection` in `stateDb` refactored to return and set actual direction

View File

@@ -0,0 +1,5 @@
---
'mermaid': patch
---
`mermaidAPI.getDiagramFromText()` now returns a new different db for each state diagram

View File

@@ -26,6 +26,7 @@ dompurify
elkjs
fcose
fontawesome
Forgejo
Foswiki
Gitea
graphlib

5
.github/lychee.toml vendored
View File

@@ -47,7 +47,10 @@ exclude = [
"https://(www.)?drupal.org",
# Swimm returns 404, eventhough the link is valid
"https://docs.swimm.io"
"https://docs.swimm.io",
# Timeout
"https://huehive.co"
]
# Exclude all private IPs from checking.

View File

@@ -42,4 +42,4 @@ jobs:
working-directory: ./packages/mermaid
run: pnpm run docs:build
- uses: autofix-ci/action@ff86a557419858bb967097bfc916833f5647fa8c # main
- uses: autofix-ci/action@551dded8c6cc8a1054039c8bc0b8b48c51dfc6ef # main

View File

@@ -36,7 +36,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12
uses: github/codeql-action/init@f779452ac5af1c261dce0346a8f964149f49322b # v3.26.13
with:
config-file: ./.github/codeql/codeql-config.yml
languages: ${{ matrix.language }}
@@ -48,7 +48,7 @@ jobs:
# 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)
- name: Autobuild
uses: github/codeql-action/autobuild@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12
uses: github/codeql-action/autobuild@f779452ac5af1c261dce0346a8f964149f49322b # v3.26.13
# 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
@@ -62,4 +62,4 @@ jobs:
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12
uses: github/codeql-action/analyze@f779452ac5af1c261dce0346a8f964149f49322b # v3.26.13

View File

@@ -17,4 +17,4 @@ jobs:
- name: 'Checkout Repository'
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: 'Dependency Review'
uses: actions/dependency-review-action@5a2ce3f5b92ee19cbb1541a4984c76d921601d7c # v4.3.4
uses: actions/dependency-review-action@a6993e2c61fd5dc440b409aa1d6904921c5e1894 # v4.3.5

View File

@@ -26,11 +26,11 @@ jobs:
with:
node-version-file: '.node-version'
- name: Install dependencies
uses: cypress-io/github-action@0da3c06ed8217b912deea9d8ee69630baed1737e # v6.7.6
uses: cypress-io/github-action@57b70560982e6a11d23d4b8bec7f8a487cdbb71b # v6.7.8
with:
runTests: false
- name: Cypress run
uses: cypress-io/github-action@0da3c06ed8217b912deea9d8ee69630baed1737e # v6.7.6
uses: cypress-io/github-action@57b70560982e6a11d23d4b8bec7f8a487cdbb71b # v6.7.8
id: cypress
with:
install: false

View File

@@ -28,6 +28,8 @@ env:
) ||
github.event.before
}}
RUN_VISUAL_TEST: >-
${{ github.repository == 'mermaid-js/mermaid' && (github.event_name != 'pull_request' || !startsWith(github.head_ref, 'renovate/')) }}
jobs:
cache:
runs-on: ubuntu-latest
@@ -43,9 +45,8 @@ jobs:
node-version-file: '.node-version'
- name: Cache snapshots
id: cache-snapshot
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
uses: actions/cache@0c907a75c2c80ebcb7f088228285e798b750cf8f # v4.2.1
with:
save-always: true
path: ./cypress/snapshots
key: ${{ runner.os }}-snapshots-${{ env.targetHash }}
@@ -58,7 +59,7 @@ jobs:
- name: Install dependencies
if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' }}
uses: cypress-io/github-action@0da3c06ed8217b912deea9d8ee69630baed1737e # v6.7.6
uses: cypress-io/github-action@57b70560982e6a11d23d4b8bec7f8a487cdbb71b # v6.7.8
with:
# just perform install
runTests: false
@@ -94,13 +95,13 @@ jobs:
# These cached snapshots are downloaded, providing the reference snapshots.
- name: Cache snapshots
id: cache-snapshot
uses: actions/cache/restore@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
uses: actions/cache/restore@0c907a75c2c80ebcb7f088228285e798b750cf8f # v4.2.1
with:
path: ./cypress/snapshots
key: ${{ runner.os }}-snapshots-${{ env.targetHash }}
- name: Install dependencies
uses: cypress-io/github-action@0da3c06ed8217b912deea9d8ee69630baed1737e # v6.7.6
uses: cypress-io/github-action@57b70560982e6a11d23d4b8bec7f8a487cdbb71b # v6.7.8
with:
runTests: false
@@ -116,7 +117,7 @@ jobs:
# Install NPM dependencies, cache them correctly
# and run all Cypress tests
- name: Cypress run
uses: cypress-io/github-action@0da3c06ed8217b912deea9d8ee69630baed1737e # v6.7.6
uses: cypress-io/github-action@57b70560982e6a11d23d4b8bec7f8a487cdbb71b # v6.7.8
id: cypress
with:
install: false
@@ -125,18 +126,17 @@ jobs:
browser: chrome
# Disable recording if we don't have an API key
# e.g. if this action was run from a fork
record: ${{ secrets.CYPRESS_RECORD_KEY != '' }}
record: ${{ env.RUN_VISUAL_TEST == 'true' && secrets.CYPRESS_RECORD_KEY != '' }}
env:
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
VITEST_COVERAGE: true
ARGOS_PARALLEL: ${{ env.RUN_VISUAL_TEST == 'true' }}
ARGOS_PARALLEL_TOTAL: ${{ env.RUN_VISUAL_TEST == 'true' && strategy.job-total || 1 }}
ARGOS_PARALLEL_INDEX: ${{ env.RUN_VISUAL_TEST == 'true' && matrix.containers || 1 }}
CYPRESS_COMMIT: ${{ github.sha }}
ARGOS_TOKEN: ${{ secrets.ARGOS_TOKEN }}
ARGOS_PARALLEL: true
ARGOS_PARALLEL_TOTAL: ${{ strategy.job-total }}
ARGOS_PARALLEL_INDEX: ${{ matrix.containers }}
CYPRESS_RECORD_KEY: ${{ env.RUN_VISUAL_TEST == 'true' && secrets.CYPRESS_RECORD_KEY || ''}}
SPLIT: ${{ strategy.job-total }}
SPLIT_INDEX: ${{ strategy.job-index }}
SPLIT_FILE: 'cypress/timings.json'
VITEST_COVERAGE: true
- name: Upload Coverage to Codecov
uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # v4.5.0

View File

@@ -32,7 +32,7 @@ jobs:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Restore lychee cache
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
uses: actions/cache@0c907a75c2c80ebcb7f088228285e798b750cf8f # v4.2.1
with:
path: .lycheecache
key: cache-lychee-${{ github.sha }}

View File

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

View File

@@ -26,12 +26,12 @@ jobs:
results_format: sarif
publish_results: true
- name: Upload artifact
uses: actions/upload-artifact@97a0fba1372883ab732affbe8f94b823f91727db # v3.pre.node20
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: SARIF file
path: results.sarif
retention-days: 5
- name: Upload to code-scanning
uses: github/codeql-action/upload-sarif@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12
uses: github/codeql-action/upload-sarif@f779452ac5af1c261dce0346a8f964149f49322b # v3.26.13
with:
sarif_file: results.sarif

View File

@@ -95,6 +95,10 @@ In our release process we rely heavily on visual regression tests using [applito
<!-- </Main description> -->
## Mermaid AI Bot
[Mermaid](https://codeparrot.ai/oracle?owner=mermaid-js&repo=mermaid) Bot will help you understand this repository better. You can ask for code examples, installation guide, debugging help and much more.
## Examples
**The following are some examples of the diagrams, charts and graphs that can be made using Mermaid. Click here to jump into the [text syntax](https://mermaid.js.org/intro/syntax-reference.html).**
@@ -253,6 +257,34 @@ pie
### Git graph [experimental - <a href="https://mermaid.live/edit#pako:eNqNkMFugzAMhl8F-VyVAR1tOW_aA-zKxSSGRCMJCk6lCvHuNZPKZdM0n-zf3_8r8QIqaIIGMqnB8kfEybQ--y4VnLP8-9RF9Mpkmm40hmlnDKmvkPiH_kfS7nFo_VN0FAf6XwocQGgxa_nGsm1bYEOOWmik1dRjGrmF1q-Cpkkj07u2HCI0PY4zHQATh8-7V9BwTPSE3iwOEd1OjQE1iWkBvk_bzQY7s0Sq4Hs7bHqKo8iGeZqbPN_WR7mpSd1RHpvPVhuMbG7XOq_L-oJlRfW5wteq0qorrpe-PBW9Pr8UJcK6rg-BLYPQ">live editor</a>]
```
gitGraph
commit
commit
branch develop
checkout develop
commit
commit
checkout main
merge develop
commit
commit
```
```mermaid
gitGraph
commit
commit
branch develop
checkout develop
commit
commit
checkout main
merge develop
commit
commit
```
### Bar chart (using gantt chart) [<a href="https://mermaid.js.org/syntax/gantt.html">docs</a> - <a href="https://mermaid.live/edit#pako:eNptkU1vhCAQhv8KIenNugiI4rkf6bmXpvEyFVxJFDYyNt1u9r8X63Z7WQ9m5pknLzieaBeMpQ3dg0dsPUkPOhwteXZIXmJcbCT3xMAxkuh8Z8kIEclyMIB209fqKcwTICFvG4IvFy_oLrZ-g9F26ILfQgvNFN94VaRXQ1iWqpumZBcu1J8p1E1TXDx59eQNr5LyEqjJn6hv5QnGNlxevZJmdLLpy5xJSzut45biYCfb0iaVxvawjNjS1p-TCguG16PvaIPzYjO67e3BwX6GiTY9jPFKH43DMF_hGMDY1J4oHg-_f8hFTJFd8L3br3yZx4QHxENsdrt1nO8dDstH3oVpF50ZYMbhU6ud4qoGLqyqBJRCmO6j0HXPZdGbihUc6Pmc0QP49xD-b5X69ZQv2gjO81IwzWqhC1lKrjJ6pA3nVS7SMiVjrKirWlYp5fs3osgrWeo00lorLWvOzz8JVbXm">live editor</a>]
```
@@ -435,7 +467,7 @@ A quick note from Knut Sveidqvist:
>
> _Thank you to [Tyler Long](https://github.com/tylerlong) who has been a collaborator since April 2017._
>
> _Thank you to the ever-growing list of [contributors](https://github.com/knsv/mermaid/graphs/contributors) that brought the project this far!_
> _Thank you to the ever-growing list of [contributors](https://github.com/mermaid-js/mermaid/graphs/contributors) that brought the project this far!_
---

View File

@@ -358,7 +358,7 @@ _很不幸的是鱼与熊掌不可兼得在这个场景下它意味着在
> _特别感谢 [d3](https://d3js.org/) 和 [dagre-d3](https://github.com/cpettitt/dagre-d3) 这两个优秀的项目它们提供了图形布局和绘图工具库_ > _同样感谢 [js-sequence-diagram](https://bramp.github.io/js-sequence-diagrams) 提供了时序图语法的使用。 感谢 Jessica Peter 提供了甘特图渲染的灵感。_ > _感谢 [Tyler Long](https://github.com/tylerlong) 从 2017 年四月开始成为了项目的合作者。_
>
> _感谢越来越多的 [贡献者们](https://github.com/knsv/mermaid/graphs/contributors)没有你们就没有这个项目的今天_
> _感谢越来越多的 [贡献者们](https://github.com/mermaid-js/mermaid/graphs/contributors)没有你们就没有这个项目的今天_
---

View File

@@ -23,12 +23,10 @@ export default eyesPlugin(
});
// copy any needed variables from process.env to config.env
config.env.useAppli = process.env.USE_APPLI ? true : false;
config.env.useArgos = !!process.env.CI;
config.env.useArgos = process.env.RUN_VISUAL_TEST === 'true';
if (config.env.useArgos) {
registerArgosTask(on, config, {
token: 'fc3a35cf5200db928d65b2047861582d9444032b',
});
registerArgosTask(on, config);
} else {
addMatchImageSnapshotPlugin(on, config);
}

View File

@@ -132,3 +132,10 @@ export const verifyScreenshot = (name: string): void => {
cy.matchImageSnapshot(name);
}
};
export const verifyNumber = (value: number, expected: number, deltaPercent = 10): void => {
expect(value).to.be.within(
expected * (1 - deltaPercent / 100),
expected * (1 + deltaPercent / 100)
);
};

View File

@@ -171,6 +171,58 @@ describe.skip('architecture diagram', () => {
`
);
});
it('should render an architecture diagram with a resonable height', () => {
imgSnapshotTest(
`architecture-beta
group federated(cloud)[Federated Environment]
service server1(server)[System] in federated
service edge(server)[Edge Device] in federated
server1:R -- L:edge
group on_prem(cloud)[Hub]
service firewall(server)[Firewall Device] in on_prem
service server(server)[Server] in on_prem
firewall:R -- L:server
service db1(database)[db1] in on_prem
service db2(database)[db2] in on_prem
service db3(database)[db3] in on_prem
service db4(database)[db4] in on_prem
service db5(database)[db5] in on_prem
service db6(database)[db6] in on_prem
junction mid in on_prem
server:B -- T:mid
junction 1Leftofmid in on_prem
1Leftofmid:R -- L:mid
1Leftofmid:B -- T:db1
junction 2Leftofmid in on_prem
2Leftofmid:R -- L:1Leftofmid
2Leftofmid:B -- T:db2
junction 3Leftofmid in on_prem
3Leftofmid:R -- L:2Leftofmid
3Leftofmid:B -- T:db3
junction 1RightOfMid in on_prem
mid:R -- L:1RightOfMid
1RightOfMid:B -- T:db4
junction 2RightOfMid in on_prem
1RightOfMid:R -- L:2RightOfMid
2RightOfMid:B -- T:db5
junction 3RightOfMid in on_prem
2RightOfMid:R -- L:3RightOfMid
3RightOfMid:B -- T:db6
edge:R -- L:firewall
`
);
});
});
// Skipped as the layout is not deterministic, and causes issues in E2E tests.

View File

@@ -1,4 +1,4 @@
import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
import { imgSnapshotTest, renderGraph, verifyNumber } from '../../helpers/util.ts';
describe('Flowchart ELK', () => {
it('1-elk: should render a simple flowchart', () => {
@@ -109,7 +109,7 @@ describe('Flowchart ELK', () => {
const style = svg.attr('style');
expect(style).to.match(/^max-width: [\d.]+px;$/);
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
expect(maxWidthValue).to.be.within(230 * 0.95, 230 * 1.05);
verifyNumber(maxWidthValue, 380);
});
});
it('8-elk: should render a flowchart when useMaxWidth is false', () => {
@@ -128,7 +128,7 @@ describe('Flowchart ELK', () => {
const width = parseFloat(svg.attr('width'));
// use within because the absolute value can be slightly different depending on the environment ±5%
// expect(height).to.be.within(446 * 0.95, 446 * 1.05);
expect(width).to.be.within(230 * 0.95, 230 * 1.05);
verifyNumber(width, 380);
expect(svg).to.not.have.attr('style');
});
});
@@ -692,7 +692,7 @@ A --> B
{}
);
cy.get('svg').should((svg) => {
const edges = svg.querySelectorAll('.edges > path');
const edges = svg[0].querySelectorAll('.edges > path');
edges.forEach((edge) => {
expect(edge).to.have.class('flowchart-link');
});
@@ -739,7 +739,7 @@ NL\`") --"\`1o **bold**\`"--> c
{ flowchart: { titleTopMargin: 0 } }
);
});
it('Wrapping long text with a new line', () => {
it.skip('Wrapping long text with a new line', () => {
imgSnapshotTest(
`%%{init: {"flowchart": {"htmlLabels": true}} }%%
flowchart-elk LR
@@ -841,7 +841,7 @@ end
{ flowchart: { titleTopMargin: 0 } }
);
});
it('Sub graphs and markdown strings', () => {
it('Sub graphs', () => {
imgSnapshotTest(
`---
config:
@@ -900,6 +900,153 @@ flowchart LR
n7@{ shape: rect}
n8@{ shape: rect}
`,
{ flowchart: { titleTopMargin: 0 } }
);
});
it('6088-1: should handle diamond shape intersections', () => {
imgSnapshotTest(
`---
config:
layout: elk
---
flowchart LR
subgraph S2
subgraph s1["APA"]
D{"Use the editor"}
end
D -- Mermaid js --> I{"fa:fa-code Text"}
D --> I
D --> I
end
`,
{ flowchart: { titleTopMargin: 0 } }
);
});
it('6088-2: should handle diamond shape intersections', () => {
imgSnapshotTest(
`---
config:
layout: elk
---
flowchart LR
a
subgraph s0["APA"]
subgraph s8["APA"]
subgraph s1["APA"]
D{"X"}
E[Q]
end
subgraph s3["BAPA"]
F[Q]
I
end
D --> I
D --> I
D --> I
I{"X"}
end
end
`,
{ flowchart: { titleTopMargin: 0 } }
);
});
it('6088-3: should handle diamond shape intersections', () => {
imgSnapshotTest(
`---
config:
layout: elk
---
flowchart LR
a
D{"Use the editor"}
D -- Mermaid js --> I{"fa:fa-code Text"}
D-->I
D-->I
`,
{ flowchart: { titleTopMargin: 0 } }
);
});
it('6088-4: should handle diamond shape intersections', () => {
imgSnapshotTest(
`---
config:
layout: elk
---
flowchart LR
subgraph s1["Untitled subgraph"]
n1["Evaluate"]
n2["Option 1"]
n3["Option 2"]
n4["fa:fa-car Option 3"]
end
subgraph s2["Untitled subgraph"]
n5["Evaluate"]
n6["Option 1"]
n7["Option 2"]
n8["fa:fa-car Option 3"]
end
A["Start"] -- Some text --> B("Continue")
B --> C{"Evaluate"}
C -- One --> D["Option 1"]
C -- Two --> E["Option 2"]
C -- Three --> F["fa:fa-car Option 3"]
n1 -- One --> n2
n1 -- Two --> n3
n1 -- Three --> n4
n5 -- One --> n6
n5 -- Two --> n7
n5 -- Three --> n8
n1@{ shape: diam}
n2@{ shape: rect}
n3@{ shape: rect}
n4@{ shape: rect}
n5@{ shape: diam}
n6@{ shape: rect}
n7@{ shape: rect}
n8@{ shape: rect}
`,
{ flowchart: { titleTopMargin: 0 } }
);
});
it('6088-5: should handle diamond shape intersections', () => {
imgSnapshotTest(
`---
config:
layout: elk
---
flowchart LR
A{A} --> B & C
`,
{ flowchart: { titleTopMargin: 0 } }
);
});
it('6088-6: should handle diamond shape intersections', () => {
imgSnapshotTest(
`---
config:
layout: elk
---
flowchart LR
A{A} --> B & C
subgraph "subbe"
A
end
`,
{ flowchart: { titleTopMargin: 0 } }
);

View File

@@ -1076,4 +1076,41 @@ end
);
});
});
describe('New @ sytax for node metadata edge cases', () => {
it('should be possible to use @ syntax to add labels on multi nodes', () => {
imgSnapshotTest(
`flowchart TB
n2["label for n2"] & n4@{ label: "labe for n4"} & n5@{ label: "labe for n5"}
`,
{}
);
});
it('should be possible to use @ syntax to add labels with trail spaces and &', () => {
imgSnapshotTest(
`flowchart TB
n2["label for n2"] & n4@{ label: "labe for n4"} & n5@{ label: "labe for n5"}
`,
{}
);
});
it('should be possible to use @ syntax to add labels with trail spaces', () => {
imgSnapshotTest(
`flowchart TB
n2["label for n2"]
n4@{ label: "labe for n4"}
n5@{ label: "labe for n5"}
`,
{}
);
});
it('should be possible to use @ syntax to add labels with trail spaces and edge/link', () => {
imgSnapshotTest(
`flowchart TD
A["A"] --> B["for B"] & C@{ label: "for c"} & E@{label : "for E"}
D@{label: "for D"}
`,
{}
);
});
});
});

View File

@@ -11,7 +11,7 @@
rel="stylesheet"
/>
<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"
/>
<link
@@ -78,45 +78,116 @@
font-family: monospace;
font-size: 72px;
}
pre {
width: 100%;
}
/* tspan {
font-size: 6px !important;
} */
/* .flowchart-link {
stroke-dasharray: 4, 4 !important;
animation: flow 1s linear infinite;
animation: dashdraw 4.93282s linear infinite;
stroke-width: 2px !important;
} */
@keyframes dashdraw {
from {
stroke-dashoffset: 0;
}
}
/*stroke-width:2;stroke-dasharray:10.000000,9.865639;stroke-dashoffset:-198.656393;animation: 4.932820s linear infinite;*/
/* stroke-width:2;stroke-dasharray:10.000000,9.865639;stroke-dashoffset:-198.656393;animation: dashdraw 4.932820s linear infinite;*/
</style>
</head>
<body>
<pre id="diagram4" class="mermaid">
flowchart LR
AB["apa@apa@"] --> B(("`apa@apa`"))
</pre>
<pre id="diagram4" class="mermaid">
flowchart
D(("for D"))
</pre>
<pre id="diagram4" class="mermaid">
flowchart LR
A e1@==> B
e1@{ animate: true}
</pre>
<pre id="diagram4" class="mermaid">
flowchart LR
A e1@--> B
classDef animate stroke-width:2,stroke-dasharray:10\,8,stroke-dashoffset:-180,animation: edge-animation-frame 6s linear infinite, stroke-linecap: round
class e1 animate
</pre>
<h2>infinite</h2>
<pre id="diagram4" class="mermaid2">
flowchart LR
A e1@--> B
classDef animate stroke-dasharray: 9\,5,stroke-dashoffset: 900,animation: dash 25s linear infinite;
class e1 animate
</pre>
<h2>Mermaid - edge-animation-slow</h2>
<pre id="diagram4" class="mermaid2">
flowchart LR
A e1@--> B
e1@{ animation: fast}
</pre>
<h2>Mermaid - edge-animation-fast</h2>
<pre id="diagram4" class="mermaid2">
flowchart LR
A e1@--> B
classDef animate stroke-dasharray: 1000,stroke-dashoffset: 1000,animation: dash 10s linear;
class e1 edge-animation-fast
</pre>
<pre id="diagram4" class="mermaid2">
info </pre
>
<pre id="diagram4" class="mermaid2">
---
config:
layout: elk
---
flowchart LR
subgraph s1["Untitled subgraph"]
n1["Evaluate"]
n2["Option 1"]
n3["Option 2"]
n4["fa:fa-car Option 3"]
end
n1 -- One --> n2
n1 -- Two --> n3
n1 -- Three --> n4
n5
n1@{ shape: diam}
n2@{ shape: rect}
n3@{ shape: rect}
n4@{ shape: rect}
A["Start"] -- Some text --> B("Continue")
B --> C{"Evaluate"}
C -- One --> D["Option 1"]
C -- Two --> E["Option 2"]
C -- Three --> F["fa:fa-car Option 3"]
flowchart LR
a
subgraph s0["APA"]
subgraph s8["APA"]
subgraph s1["APA"]
D{"X"}
E[Q]
end
subgraph s3["BAPA"]
F[Q]
I
end
D --> I
D --> I
D --> I
I{"X"}
end
end
</pre>
<pre id="diagram4" class="mermaid">
<pre id="diagram4" class="mermaid2">
---
config:
layout: elk
---
flowchart LR
a
D{"Use the editor"}
D -- Mermaid js --> I{"fa:fa-code Text"}
D-->I
D-->I
</pre>
<pre id="diagram4" class="mermaid2">
---
config:
layout: elk
@@ -185,6 +256,18 @@ flowchart LR
config:
layout: elk
---
flowchart LR
A{A} --> B & C
subgraph "subbe"
A
end
</pre
>
<pre id="diagram4" class="mermaid2">
---
config:
layout: elk
---
flowchart LR
n2@{ shape: rect}
n3@{ shape: rect}
@@ -351,7 +434,10 @@ kanban
window.callback = function () {
alert('A callback was triggered');
};
mermaid.initialize({
function callback() {
alert('It worked');
}
await mermaid.initialize({
// theme: 'base',
// theme: 'default',
// theme: 'forest',
@@ -363,9 +449,11 @@ kanban
// layout: 'fixed',
// htmlLabels: false,
flowchart: { titleTopMargin: 10 },
// fontFamily: 'Caveat',
// fontFamily: 'Kalam',
// fontFamily: 'courier',
fontFamily: 'arial',
sequence: {
actorFontFamily: 'courier',
noteFontFamily: 'courier',
@@ -377,10 +465,9 @@ kanban
fontSize: 12,
logLevel: 0,
securityLevel: 'loose',
callback,
});
function callback() {
alert('It worked');
}
mermaid.parseError = function (err, hash) {
console.error('In parse error:');
console.error(err);

View File

@@ -62,56 +62,23 @@
<body style="display: flex; gap: 2rem; flex-direction: row">
<pre id="diagram4" class="mermaid">
flowchart LR
A@{ icon: "fa:window-minimize", form: circle }
E@{ icon: "fa:window-minimize", form: circle }
B@{ icon: "fa:bell", form: circle }
B2@{ icon: "fa:bell", form: circle }
C@{ icon: "fa:address-book", form: square }
D@{ icon: "fa:star-half", form: square }
A --> E
B --> B2
flowchart
A --> A
subgraph B
B1 --> B1
end
subgraph C
subgraph C1
C2 --> C2
subgraph D
D1 --> D1
end
D --> D
end
C1 --> C1
end
</pre>
<pre id="diagram4" class="mermaid2">
flowchart TB
A --test2--> B2@{ icon: "fa:bell", form: "rounded", label: "B2 aiduaid uyawduad uaduabd uyduadb", pos: "b" }
B2 --test--> C
D --> B2 --> E
style B2 fill:#f9f,stroke:#333,stroke-width:4px
</pre
>
<pre id="diagram43" class="mermaid2">
flowchart BT
A --test2--> B2@{ icon: "fa:bell", form: "square", label: "B2", pos: "t", h: 40, w: 30 }
B2 --test--> C
D --> B2 --> E
</pre
>
<pre id="diagram4" class="mermaid2">
flowchart BT
A --test2--> B2@{ icon: "fa:bell", label: "B2 awiugdawu uydgayuiwd wuydguy", pos: "b", h: 40, w: 30 }
B2 --test--> C
</pre
>
<pre id="diagram43" class="mermaid2">
flowchart BT
A --test2--> B2@{ icon: "fa:bell", label: "B2 dawuygd ayuwgd uy", pos: "t", h: 40, w: 30 }
B2 --test--> C
</pre
>
<pre id="diagram6" class="mermaid2">
flowchart TB
A --> B2@{ icon: "fa:bell", form: "circle", label: "test augfuyfavf ydvaubfuac", pos: "t", w: 200, h: 100 } --> C
</pre
>
<pre id="diagram6" class="mermaid2">
flowchart TB
A --> B2@{ icon: "fa:bell", form: "circle", label: "test augfuyfavf ydvaubfuac", pos: "b", w: 200, h: 100 } --> C
D --> B2 --> E
</pre
>
<script type="module">
import mermaid from './mermaid.esm.mjs';
import layouts from './mermaid-layout-elk.esm.mjs';

View File

@@ -39,8 +39,8 @@ graph TB
<script type="module">
import mermaid from '/mermaid.esm.mjs';
import flowchartELK from '/mermaid-flowchart-elk.esm.mjs';
await mermaid.registerExternalDiagrams([flowchartELK]);
import layouts from '/mermaid-layout-elk.esm.mjs';
mermaid.registerLayoutLoaders(layouts);
async function render(str) {
const { svg } = await mermaid.render('dynamic', str);
document.getElementById('dynamicDiagram').innerHTML = svg;

View File

@@ -6,12 +6,12 @@
# Frequently Asked Questions
1. [How to add title to flowchart?](https://github.com/knsv/mermaid/issues/556#issuecomment-363182217)
1. [How to add title to flowchart?](https://github.com/mermaid-js/mermaid/issues/556#issuecomment-363182217)
2. [How to specify custom CSS file?](https://github.com/mermaidjs/mermaid.cli/pull/24#issuecomment-373402785)
3. [How to fix tooltip misplacement issue?](https://github.com/knsv/mermaid/issues/542#issuecomment-3343564621)
4. [How to specify gantt diagram xAxis format?](https://github.com/knsv/mermaid/issues/269#issuecomment-373229136)
5. [How to bind an event?](https://github.com/knsv/mermaid/issues/372)
6. [How to add newline in the text?](https://github.com/knsv/mermaid/issues/384#issuecomment-281339381)
7. [How to have special characters in link text?](https://github.com/knsv/mermaid/issues/407#issuecomment-329944735)
8. [How to change Flowchart curve style?](https://github.com/knsv/mermaid/issues/580#issuecomment-373929046)
3. [How to fix tooltip misplacement issue?](https://github.com/mermaid-js/mermaid/issues/542#issuecomment-3343564621)
4. [How to specify gantt diagram xAxis format?](https://github.com/mermaid-js/mermaid/issues/269#issuecomment-373229136)
5. [How to bind an event?](https://github.com/mermaid-js/mermaid/issues/372)
6. [How to add newline in the text?](https://github.com/mermaid-js/mermaid/issues/384#issuecomment-281339381)
7. [How to have special characters in link text?](https://github.com/mermaid-js/mermaid/issues/407#issuecomment-329944735)
8. [How to change Flowchart curve style?](https://github.com/mermaid-js/mermaid/issues/580#issuecomment-373929046)
9. [How to create a Flowchart end-Node that says "End"](https://github.com/mermaid-js/mermaid/issues/1444#issuecomment-639528897)

View File

@@ -20,7 +20,7 @@
#### Defined in
[packages/mermaid/src/rendering-util/types.ts:144](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/types.ts#L144)
[packages/mermaid/src/rendering-util/types.ts:148](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/types.ts#L148)
---
@@ -30,7 +30,7 @@
#### Defined in
[packages/mermaid/src/rendering-util/types.ts:143](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/types.ts#L143)
[packages/mermaid/src/rendering-util/types.ts:147](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/types.ts#L147)
---
@@ -40,4 +40,4 @@
#### Defined in
[packages/mermaid/src/rendering-util/types.ts:142](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/types.ts#L142)
[packages/mermaid/src/rendering-util/types.ts:146](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/types.ts#L146)

View File

@@ -19,4 +19,4 @@ The `parseError` function will not be called.
#### Defined in
[packages/mermaid/src/types.ts:59](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L59)
[packages/mermaid/src/types.ts:64](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L64)

View File

@@ -18,7 +18,7 @@ The config passed as YAML frontmatter or directives
#### Defined in
[packages/mermaid/src/types.ts:70](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L70)
[packages/mermaid/src/types.ts:75](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L75)
---
@@ -30,4 +30,4 @@ The diagram type, e.g. 'flowchart', 'sequence', etc.
#### Defined in
[packages/mermaid/src/types.ts:66](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L66)
[packages/mermaid/src/types.ts:71](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L71)

View File

@@ -39,7 +39,7 @@ bindFunctions?.(div); // To call bindFunctions only if it's present.
#### Defined in
[packages/mermaid/src/types.ts:98](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L98)
[packages/mermaid/src/types.ts:103](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L103)
---
@@ -51,7 +51,7 @@ The diagram type, e.g. 'flowchart', 'sequence', etc.
#### Defined in
[packages/mermaid/src/types.ts:88](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L88)
[packages/mermaid/src/types.ts:93](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L93)
---
@@ -63,4 +63,4 @@ The svg code for the rendered graph.
#### Defined in
[packages/mermaid/src/types.ts:84](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L84)
[packages/mermaid/src/types.ts:89](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L89)

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

View File

@@ -44,6 +44,7 @@ To add an integration to this list, see the [Integrations - create page](./integ
- [Deepdwn](https://billiam.itch.io/deepdwn) ✅
- [Doctave](https://www.doctave.com/) ✅
- [Mermaid in Markdown code blocks](https://docs.doctave.com/components/mermaid) ✅
- [Forgejo](https://forgejo.org/) ✅
- [GitBook](https://gitbook.com)
- [Mermaid Plugin](https://github.com/JozoVilcek/gitbook-plugin-mermaid)
- [Mermaid plugin for GitBook](https://github.com/wwformat/gitbook-plugin-mermaid-pdf)
@@ -99,8 +100,7 @@ Blogging frameworks and platforms
- [Nextra](https://nextra.site/)
- [Mermaid](https://nextra.site/docs/guide/mermaid)
- [WordPress](https://wordpress.org)
- [WordPress Markdown Editor](https://wordpress.org/plugins/wp-githuber-md)
- [WP-ReliableMD](https://wordpress.org/plugins/wp-reliablemd/)
- [MerPRess](https://wordpress.org/plugins/merpress/)
### CMS/ECM

View File

@@ -52,28 +52,33 @@ Examples are provided in [Getting Started](../intro/getting-started.md)
[K8s.dev blog: Improve your documentation with Mermaid.js diagrams](https://www.kubernetes.dev/blog/2021/12/01/improve-your-documentation-with-mermaid.js-diagrams/)
## Jupyter Integration with mermaid-js
## Jupyter / Python Integration with mermaid-js
Here's an example of Python integration with mermaid-js which uses the mermaid.ink service, that displays the graph in a Jupyter notebook.
Here's an example of Python integration with mermaid-js which uses the mermaid.ink service, that displays the graph in a Jupyter notebook and save it as _.png_ image with the stated resolution (in this example, `dpi=1200`).
```python
import base64
import io, requests
from IPython.display import Image, display
from PIL import Image as im
import matplotlib.pyplot as plt
def mm(graph):
graphbytes = graph.encode("utf8")
base64_bytes = base64.urlsafe_b64encode(graphbytes)
base64_string = base64_bytes.decode("ascii")
display(Image(url="https://mermaid.ink/img/" + base64_string))
img = im.open(io.BytesIO(requests.get('https://mermaid.ink/img/' + base64_string).content))
plt.imshow(img)
plt.axis('off') # allow to hide axis
plt.savefig('image.png', dpi=1200)
mm("""
graph LR;
A--> B & C & D;
B--> A & E;
C--> A & E;
D--> A & E;
E--> B & C & D;
A--> B & C & D
B--> A & E
C--> A & E
D--> A & E
E--> B & C & D
""")
```
@@ -81,4 +86,4 @@ graph LR;
![Example graph of the Python integration](img/python-mermaid-integration.png)
<!--- cspell:ignore Elle Jaoude Neurodiverse graphbytes --->
<!--- cspell:ignore Elle Jaoude Neurodiverse graphbytes imshow savefig --->

View File

@@ -49,7 +49,7 @@ For a more detailed introduction to Mermaid and some of its more basic uses, loo
🌐 [CDN](https://www.jsdelivr.com/package/npm/mermaid) | 📖 [Documentation](https://mermaidjs.github.io) | 🙌 [Contribution](../community/contributing.md) | 🔌 [Plug-Ins](../ecosystem/integrations-community.md)
> 🖖 Keep a steady pulse: mermaid needs more Collaborators, [Read More](https://github.com/knsv/mermaid/issues/866).
> 🖖 Keep a steady pulse: mermaid needs more Collaborators, [Read More](https://github.com/mermaid-js/mermaid/issues/866).
:trophy: **Mermaid was nominated and won the [JS Open Source Awards (2019)](https://osawards.com/javascript/#nominees) in the category "The most exciting use of technology"!!!**
@@ -453,7 +453,7 @@ A quick note from Knut Sveidqvist:
>
> _Thank you to [Tyler Long](https://github.com/tylerlong) who has been a collaborator since April 2017._
>
> _Thank you to the ever-growing list of [contributors](https://github.com/knsv/mermaid/graphs/contributors) that brought the project this far!_
> _Thank you to the ever-growing list of [contributors](https://github.com/mermaid-js/mermaid/graphs/contributors) that brought the project this far!_
---

View File

@@ -1183,6 +1183,91 @@ flowchart TB
B --> D
```
### Attaching an ID to Edges
Mermaid now supports assigning IDs to edges, similar to how IDs and metadata can be attached to nodes. This feature lays the groundwork for more advanced styling, classes, and animation capabilities on edges.
**Syntax:**
To give an edge an ID, prepend the edge syntax with the ID followed by an `@` character. For example:
```mermaid-example
flowchart LR
A e1@> B
```
```mermaid
flowchart LR
A e1@> B
```
In this example, `e1` is the ID of the edge connecting `A` to `B`. You can then use this ID in later definitions or style statements, just like with nodes.
### Turning an Animation On
Once you have assigned an ID to an edge, you can turn on animations for that edge by defining the edges properties:
```mermaid-example
flowchart LR
A e1@==> B
e1@{ animate: true }
```
```mermaid
flowchart LR
A e1@==> B
e1@{ animate: true }
```
This tells Mermaid that the edge `e1` should be animated.
### Selecting Type of Animation
In the initial version, two animation speeds are supported: `fast` and `slow`. Selecting a specific animation type is a shorthand for enabling animation and setting the animation speed in one go.
**Examples:**
```mermaid-example
flowchart LR
A e1@> B
e1@{ animation: fast }
```
```mermaid
flowchart LR
A e1@> B
e1@{ animation: fast }
```
This is equivalent to `{ animate: true, animation: fast }`.
### Using classDef Statements for Animations
You can also animate edges by assigning a class to them and then defining animation properties in a `classDef` statement. For example:
```mermaid-example
flowchart LR
A e1@> B
classDef animate stroke-dasharray: 9,5,stroke-dashoffset: 900,animation: dash 25s linear infinite;
class e1 animate
```
```mermaid
flowchart LR
A e1@> B
classDef animate stroke-dasharray: 9,5,stroke-dashoffset: 900,animation: dash 25s linear infinite;
class e1 animate
```
In this snippet:
- `e1@-->` creates an edge with ID `e1`.
- `classDef animate` defines a class named `animate` with styling and animation properties.
- `class e1 animate` applies the `animate` class to the edge `e1`.
**Note on Escaping Commas:**
When setting the `stroke-dasharray` property, remember to escape commas as `\,` since commas are used as delimiters in Mermaids style definitions.
## New arrow types
There are new types of arrows supported:
@@ -1707,8 +1792,7 @@ graph LR
```
For a full list of available curves, including an explanation of custom curves, refer to
the [Shapes](https://github.com/d3/d3-shape/blob/main/README.md#curves) documentation in the
[d3-shape](https://github.com/d3/d3-shape/) project.
the [Shapes](https://d3js.org/d3-shape/curve) documentation in the [d3-shape](https://github.com/d3/d3-shape/) project.
### Styling a node

View File

@@ -500,7 +500,7 @@ mermaid.ganttConfig = {
sectionFontSize: 24, // Font size for sections
numberSectionStyles: 1, // The number of alternating section styles
axisFormat: '%d/%m', // Date/time format of the axis
tickInterval: '1 week', // Axis ticks
tickInterval: '1week', // Axis ticks
topAxis: true, // When this flag is set, date labels will be added to the top of the chart
displayMode: 'compact', // Turns compact mode on
weekday: 'sunday', // On which day a week-based interval should start

View File

@@ -86,7 +86,7 @@ todo[Todo]
## Configuration Options
You can customize the Kanban diagram using a configuration block at the beginning of your markdown file. This is useful for setting global settings like a base URL for tickets. Currently there is one configuration option for kanban diagrams tacketBaseUrl. This can be set as in the the following example:
You can customize the Kanban diagram using a configuration block at the beginning of your markdown file. This is useful for setting global settings like a base URL for tickets. Currently there is one configuration option for kanban diagrams `ticketBaseUrl`. This can be set as in the the following example:
```yaml
---

View File

@@ -18,7 +18,7 @@ timeline
2002 : LinkedIn
2004 : Facebook
: Google
2005 : Youtube
2005 : YouTube
2006 : Twitter
```
@@ -28,7 +28,7 @@ timeline
2002 : LinkedIn
2004 : Facebook
: Google
2005 : Youtube
2005 : YouTube
2006 : Twitter
```
@@ -67,7 +67,7 @@ timeline
title History of Social Media Platform
2002 : LinkedIn
2004 : Facebook : Google
2005 : Youtube
2005 : YouTube
2006 : Twitter
```
@@ -76,7 +76,7 @@ timeline
title History of Social Media Platform
2002 : LinkedIn
2004 : Facebook : Google
2005 : Youtube
2005 : YouTube
2006 : Twitter
```
@@ -198,7 +198,7 @@ However, if there is no section defined, then we have two possibilities:
title History of Social Media Platform
2002 : LinkedIn
2004 : Facebook : Google
2005 : Youtube
2005 : YouTube
2006 : Twitter
```
@@ -208,7 +208,7 @@ However, if there is no section defined, then we have two possibilities:
title History of Social Media Platform
2002 : LinkedIn
2004 : Facebook : Google
2005 : Youtube
2005 : YouTube
2006 : Twitter
```
@@ -239,7 +239,7 @@ let us look at same example, where we have disabled the multiColor option.
title History of Social Media Platform
2002 : LinkedIn
2004 : Facebook : Google
2005 : Youtube
2005 : YouTube
2006 : Twitter
```
@@ -250,7 +250,7 @@ let us look at same example, where we have disabled the multiColor option.
title History of Social Media Platform
2002 : LinkedIn
2004 : Facebook : Google
2005 : Youtube
2005 : YouTube
2006 : Twitter
```
@@ -278,7 +278,7 @@ Now let's override the default values for the `cScale0` to `cScale2` variables:
title History of Social Media Platform
2002 : LinkedIn
2004 : Facebook : Google
2005 : Youtube
2005 : YouTube
2006 : Twitter
2007 : Tumblr
2008 : Instagram
@@ -296,7 +296,7 @@ Now let's override the default values for the `cScale0` to `cScale2` variables:
title History of Social Media Platform
2002 : LinkedIn
2004 : Facebook : Google
2005 : Youtube
2005 : YouTube
2006 : Twitter
2007 : Tumblr
2008 : Instagram
@@ -329,7 +329,7 @@ Let's put them to use, and see how our sample diagram looks in different themes:
title History of Social Media Platform
2002 : LinkedIn
2004 : Facebook : Google
2005 : Youtube
2005 : YouTube
2006 : Twitter
2007 : Tumblr
2008 : Instagram
@@ -342,7 +342,7 @@ Let's put them to use, and see how our sample diagram looks in different themes:
title History of Social Media Platform
2002 : LinkedIn
2004 : Facebook : Google
2005 : Youtube
2005 : YouTube
2006 : Twitter
2007 : Tumblr
2008 : Instagram
@@ -357,7 +357,7 @@ Let's put them to use, and see how our sample diagram looks in different themes:
title History of Social Media Platform
2002 : LinkedIn
2004 : Facebook : Google
2005 : Youtube
2005 : YouTube
2006 : Twitter
2007 : Tumblr
2008 : Instagram
@@ -370,7 +370,7 @@ Let's put them to use, and see how our sample diagram looks in different themes:
title History of Social Media Platform
2002 : LinkedIn
2004 : Facebook : Google
2005 : Youtube
2005 : YouTube
2006 : Twitter
2007 : Tumblr
2008 : Instagram
@@ -385,7 +385,7 @@ Let's put them to use, and see how our sample diagram looks in different themes:
title History of Social Media Platform
2002 : LinkedIn
2004 : Facebook : Google
2005 : Youtube
2005 : YouTube
2006 : Twitter
2007 : Tumblr
2008 : Instagram
@@ -398,7 +398,7 @@ Let's put them to use, and see how our sample diagram looks in different themes:
title History of Social Media Platform
2002 : LinkedIn
2004 : Facebook : Google
2005 : Youtube
2005 : YouTube
2006 : Twitter
2007 : Tumblr
2008 : Instagram
@@ -413,7 +413,7 @@ Let's put them to use, and see how our sample diagram looks in different themes:
title History of Social Media Platform
2002 : LinkedIn
2004 : Facebook : Google
2005 : Youtube
2005 : YouTube
2006 : Twitter
2007 : Tumblr
2008 : Instagram
@@ -426,7 +426,7 @@ Let's put them to use, and see how our sample diagram looks in different themes:
title History of Social Media Platform
2002 : LinkedIn
2004 : Facebook : Google
2005 : Youtube
2005 : YouTube
2006 : Twitter
2007 : Tumblr
2008 : Instagram
@@ -441,7 +441,7 @@ Let's put them to use, and see how our sample diagram looks in different themes:
title History of Social Media Platform
2002 : LinkedIn
2004 : Facebook : Google
2005 : Youtube
2005 : YouTube
2006 : Twitter
2007 : Tumblr
2008 : Instagram
@@ -454,7 +454,7 @@ Let's put them to use, and see how our sample diagram looks in different themes:
title History of Social Media Platform
2002 : LinkedIn
2004 : Facebook : Google
2005 : Youtube
2005 : YouTube
2006 : Twitter
2007 : Tumblr
2008 : Instagram

View File

@@ -137,7 +137,6 @@ export default tseslint.config(
'unicorn/no-instanceof-array': 'error',
'unicorn/no-typeof-undefined': 'error',
'unicorn/no-unnecessary-await': 'error',
'unicorn/no-unsafe-regex': 'warn',
'unicorn/no-useless-promise-resolve-reject': 'error',
'unicorn/prefer-array-find': 'error',
'unicorn/prefer-array-flat-map': 'error',

View File

@@ -92,10 +92,10 @@
"cypress": "^13.14.1",
"cypress-image-snapshot": "^4.0.1",
"cypress-split": "^1.24.0",
"esbuild": "^0.21.5",
"esbuild": "^0.25.0",
"eslint": "^9.4.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-cypress": "^3.3.0",
"eslint-config-prettier": "^10.0.0",
"eslint-plugin-cypress": "^4.0.0",
"eslint-plugin-html": "^8.1.1",
"eslint-plugin-jest": "^28.6.0",
"eslint-plugin-jsdoc": "^50.0.0",
@@ -103,8 +103,8 @@
"eslint-plugin-lodash": "^8.0.0",
"eslint-plugin-markdown": "^5.0.0",
"eslint-plugin-no-only-tests": "^3.1.0",
"eslint-plugin-tsdoc": "^0.3.0",
"eslint-plugin-unicorn": "^56.0.0",
"eslint-plugin-tsdoc": "^0.4.0",
"eslint-plugin-unicorn": "^57.0.0",
"express": "^4.19.1",
"globals": "^15.4.0",
"globby": "^14.0.1",
@@ -123,6 +123,7 @@
"rimraf": "^5.0.5",
"rollup-plugin-visualizer": "^5.12.0",
"start-server-and-test": "^2.0.3",
"tslib": "^2.8.1",
"tsx": "^4.7.1",
"typescript": "~5.4.5",
"typescript-eslint": "^8.0.0-alpha.34",

View File

@@ -1,5 +1,11 @@
# @mermaid-js/layout-elk
## 0.1.7
### Patch Changes
- [#6090](https://github.com/mermaid-js/mermaid/pull/6090) [`654097c`](https://github.com/mermaid-js/mermaid/commit/654097c43801b2d606bc3d2bef8c6fbc3301e9e4) Thanks [@knsv](https://github.com/knsv)! - fix: Updated offset calculations for diamond shape when handling intersections
## 0.1.6
### Patch Changes

View File

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

View File

@@ -705,14 +705,11 @@ export const render = async (
bounds: { x: any; y: any; width: any; height: any; padding: any },
isDiamond: boolean
) => {
log.debug('UIO cutPathAtIntersect Points:', _points, 'node:', bounds, 'isDiamond', isDiamond);
log.debug('APA18 cutPathAtIntersect Points:', _points, 'node:', bounds, 'isDiamond', isDiamond);
const points: any[] = [];
let lastPointOutside = _points[0];
let isInside = false;
_points.forEach((point: any) => {
// const node = clusterDb[edge.toCluster].node;
log.debug(' checking point', point, bounds);
// check if point is inside the boundary rect
if (!outsideNode(bounds, point) && !isInside) {
// First point inside the rect found
@@ -906,7 +903,7 @@ export const render = async (
const offset = calcOffset(sourceId, targetId, parentLookupDb);
log.debug(
'offset',
'APA18 offset',
offset,
sourceId,
' ==> ',
@@ -971,29 +968,22 @@ export const render = async (
}
if (startNode.shape === 'diamond' || startNode.shape === 'diam') {
edge.points.unshift({
x: startNode.x + startNode.width / 2 + offset.x,
y: startNode.y + startNode.height / 2 + offset.y,
x: startNode.offset.posX + startNode.width / 2,
y: startNode.offset.posY + startNode.height / 2,
});
}
if (endNode.shape === 'diamond' || endNode.shape === 'diam') {
const x = endNode.x + endNode.width / 2 + offset.x;
// Add a point at the center of the diamond
if (
Math.abs(edge.points[edge.points.length - 1].y - endNode.y - offset.y) > 0.01 ||
Math.abs(edge.points[edge.points.length - 1].x - x) > 0.001
) {
edge.points.push({
x: endNode.x + endNode.width / 2 + offset.x,
y: endNode.y + endNode.height / 2 + offset.y,
});
}
edge.points.push({
x: endNode.offset.posX + endNode.width / 2,
y: endNode.offset.posY + endNode.height / 2,
});
}
edge.points = cutPathAtIntersect(
edge.points.reverse(),
{
x: startNode.x + startNode.width / 2 + offset.x,
y: startNode.y + startNode.height / 2 + offset.y,
x: startNode.offset.posX + startNode.width / 2,
y: startNode.offset.posY + startNode.height / 2,
width: sw,
height: startNode.height,
padding: startNode.padding,
@@ -1004,8 +994,8 @@ export const render = async (
edge.points = cutPathAtIntersect(
edge.points,
{
x: endNode.x + ew / 2 + endNode.offset.x,
y: endNode.y + endNode.height / 2 + endNode.offset.y,
x: endNode.offset.posX + endNode.width / 2,
y: endNode.offset.posY + endNode.height / 2,
width: ew,
height: endNode.height,
padding: endNode.padding,

View File

@@ -230,7 +230,7 @@ const ConfigWarning = {
} as const;
type ConfigWarningStrings = keyof typeof ConfigWarning;
const issuedWarnings: { [key in ConfigWarningStrings]?: boolean } = {};
const issuedWarnings: Partial<Record<ConfigWarningStrings, boolean>> = {};
const issueWarning = (warning: ConfigWarningStrings) => {
if (issuedWarnings[warning]) {
return;

View File

@@ -13,6 +13,7 @@ import {
setDiagramTitle,
} from '../common/commonDb.js';
import type {
ArchitectureAlignment,
ArchitectureDB,
ArchitectureDirectionPair,
ArchitectureDirectionPairMap,
@@ -25,6 +26,7 @@ import type {
ArchitectureState,
} from './architectureTypes.js';
import {
getArchitectureDirectionAlignment,
getArchitectureDirectionPair,
isArchitectureDirection,
isArchitectureJunction,
@@ -211,12 +213,18 @@ const addEdge = function ({
const getEdges = (): ArchitectureEdge[] => state.records.edges;
/**
* Returns the current diagram's adjacency list & spatial map.
* Returns the current diagram's adjacency list, spatial map, & group alignments.
* If they have not been created, run the algorithms to generate them.
* @returns
*/
const getDataStructures = () => {
if (state.records.dataStructures === undefined) {
// Tracks how groups are aligned with one another. Generated while creating the adj list
const groupAlignments: Record<
string,
Record<string, Exclude<ArchitectureAlignment, 'bend'>>
> = {};
// Create an adjacency list of the diagram to perform BFS on
// Outer reduce applied on all services
// Inner reduce applied on the edges for a service
@@ -224,6 +232,19 @@ const getDataStructures = () => {
Record<string, ArchitectureDirectionPairMap>
>((prevOuter, [id, service]) => {
prevOuter[id] = service.edges.reduce<ArchitectureDirectionPairMap>((prevInner, edge) => {
// track the direction groups connect to one another
const lhsGroupId = getNode(edge.lhsId)?.in;
const rhsGroupId = getNode(edge.rhsId)?.in;
if (lhsGroupId && rhsGroupId && lhsGroupId !== rhsGroupId) {
const alignment = getArchitectureDirectionAlignment(edge.lhsDir, edge.rhsDir);
if (alignment !== 'bend') {
groupAlignments[lhsGroupId] ??= {};
groupAlignments[lhsGroupId][rhsGroupId] = alignment;
groupAlignments[rhsGroupId] ??= {};
groupAlignments[rhsGroupId][lhsGroupId] = alignment;
}
}
if (edge.lhsId === id) {
// source is LHS
const pair = getArchitectureDirectionPair(edge.lhsDir, edge.rhsDir);
@@ -245,6 +266,7 @@ const getDataStructures = () => {
// Configuration for the initial pass of BFS
const firstId = Object.keys(adjList)[0];
const visited = { [firstId]: 1 };
// If a key is present in this object, it has not been visited
const notVisited = Object.keys(adjList).reduce(
(prev, id) => (id === firstId ? prev : { ...prev, [id]: 1 }),
{} as Record<string, number>
@@ -283,6 +305,7 @@ const getDataStructures = () => {
state.records.dataStructures = {
adjList,
spatialMaps,
groupAlignments,
};
}
return state.records.dataStructures;

View File

@@ -12,7 +12,9 @@ import { setupGraphViewbox } from '../../setupGraphViewbox.js';
import { getConfigField } from './architectureDb.js';
import { architectureIcons } from './architectureIcons.js';
import type {
ArchitectureAlignment,
ArchitectureDataStructures,
ArchitectureGroupAlignments,
ArchitectureJunction,
ArchitectureSpatialMap,
EdgeSingular,
@@ -149,25 +151,91 @@ function addEdges(edges: ArchitectureEdge[], cy: cytoscape.Core) {
});
}
function getAlignments(spatialMaps: ArchitectureSpatialMap[]): fcose.FcoseAlignmentConstraint {
function getAlignments(
db: ArchitectureDB,
spatialMaps: ArchitectureSpatialMap[],
groupAlignments: ArchitectureGroupAlignments
): fcose.FcoseAlignmentConstraint {
/**
* Flattens the alignment object so nodes in different groups will be in the same alignment array IFF their groups don't connect in a conflicting alignment
*
* i.e., two groups which connect horizontally should not have nodes with vertical alignments to one another
*
* See: #5952
*
* @param alignmentObj - alignment object with the outer key being the row/col # and the inner key being the group name mapped to the nodes on that axis in the group
* @param alignmentDir - alignment direction
* @returns flattened alignment object with an arbitrary key mapping to nodes in the same row/col
*/
const flattenAlignments = (
alignmentObj: Record<number, Record<string, string[]>>,
alignmentDir: ArchitectureAlignment
): Record<string, string[]> => {
return Object.entries(alignmentObj).reduce(
(prev, [dir, alignments]) => {
// prev is the mapping of x/y coordinate to an array of the nodes in that row/column
let cnt = 0;
const arr = Object.entries(alignments); // [group name, array of nodes within the group on axis dir]
if (arr.length === 1) {
// If only one group exists in the row/column, we don't need to do anything else
prev[dir] = arr[0][1];
return prev;
}
for (let i = 0; i < arr.length - 1; i++) {
for (let j = i + 1; j < arr.length; j++) {
const [aGroupId, aNodeIds] = arr[i];
const [bGroupId, bNodeIds] = arr[j];
const alignment = groupAlignments[aGroupId]?.[bGroupId]; // Get how the two groups are intended to align (undefined if they aren't)
if (alignment === alignmentDir) {
// If the intended alignment between the two groups is the same as the alignment we are parsing
prev[dir] ??= [];
prev[dir] = [...prev[dir], ...aNodeIds, ...bNodeIds]; // add the node ids of both groups to the axis array in prev
} else if (aGroupId === 'default' || bGroupId === 'default') {
// If either of the groups are in the default space (not in a group), use the same behavior as above
prev[dir] ??= [];
prev[dir] = [...prev[dir], ...aNodeIds, ...bNodeIds];
} else {
// Otherwise, the nodes in the two groups are not intended to align
const keyA = `${dir}-${cnt++}`;
prev[keyA] = aNodeIds;
const keyB = `${dir}-${cnt++}`;
prev[keyB] = bNodeIds;
}
}
}
return prev;
},
{} as Record<string, string[]>
);
};
const alignments = spatialMaps.map((spatialMap) => {
const horizontalAlignments: Record<number, string[]> = {};
const verticalAlignments: Record<number, string[]> = {};
const horizontalAlignments: Record<number, Record<string, string[]>> = {};
const verticalAlignments: Record<number, Record<string, string[]>> = {};
// Group service ids in an object with their x and y coordinate as the key
Object.entries(spatialMap).forEach(([id, [x, y]]) => {
if (!horizontalAlignments[y]) {
horizontalAlignments[y] = [];
}
if (!verticalAlignments[x]) {
verticalAlignments[x] = [];
}
horizontalAlignments[y].push(id);
verticalAlignments[x].push(id);
const nodeGroup = db.getNode(id)?.in ?? 'default';
horizontalAlignments[y] ??= {};
horizontalAlignments[y][nodeGroup] ??= [];
horizontalAlignments[y][nodeGroup].push(id);
verticalAlignments[x] ??= {};
verticalAlignments[x][nodeGroup] ??= [];
verticalAlignments[x][nodeGroup].push(id);
});
// Merge the values of each object into a list if the inner list has at least 2 elements
return {
horiz: Object.values(horizontalAlignments).filter((arr) => arr.length > 1),
vert: Object.values(verticalAlignments).filter((arr) => arr.length > 1),
horiz: Object.values(flattenAlignments(horizontalAlignments, 'horizontal')).filter(
(arr) => arr.length > 1
),
vert: Object.values(flattenAlignments(verticalAlignments, 'vertical')).filter(
(arr) => arr.length > 1
),
};
});
@@ -244,7 +312,8 @@ function layoutArchitecture(
junctions: ArchitectureJunction[],
groups: ArchitectureGroup[],
edges: ArchitectureEdge[],
{ spatialMaps }: ArchitectureDataStructures
db: ArchitectureDB,
{ spatialMaps, groupAlignments }: ArchitectureDataStructures
): Promise<cytoscape.Core> {
return new Promise((resolve) => {
const renderEl = select('body').append('div').attr('id', 'cy').attr('style', 'display:none');
@@ -318,9 +387,8 @@ function layoutArchitecture(
addServices(services, cy);
addJunctions(junctions, cy);
addEdges(edges, cy);
// Use the spatial map to create alignment arrays for fcose
const alignmentConstraint = getAlignments(spatialMaps);
const alignmentConstraint = getAlignments(db, spatialMaps, groupAlignments);
// Create the relative constraints for fcose by using an inverse of the spatial map and performing BFS on it
const relativePlacementConstraint = getRelativeConstraints(spatialMaps);
@@ -454,7 +522,7 @@ export const draw: DrawDefinition = async (text, id, _version, diagObj: Diagram)
await drawServices(db, servicesElem, services);
drawJunctions(db, servicesElem, junctions);
const cy = await layoutArchitecture(services, junctions, groups, edges, ds);
const cy = await layoutArchitecture(services, junctions, groups, edges, db, ds);
await drawEdges(edgesElem, cy);
await drawGroups(groupElem, cy);

View File

@@ -7,6 +7,8 @@ import type cytoscape from 'cytoscape';
| Architecture Diagram Types |
\*=======================================*/
export type ArchitectureAlignment = 'vertical' | 'horizontal' | 'bend';
export type ArchitectureDirection = 'L' | 'R' | 'T' | 'B';
export type ArchitectureDirectionX = Extract<ArchitectureDirection, 'L' | 'R'>;
export type ArchitectureDirectionY = Extract<ArchitectureDirection, 'T' | 'B'>;
@@ -104,9 +106,7 @@ export const isValidArchitectureDirectionPair = function (
return x !== 'LL' && x !== 'RR' && x !== 'TT' && x !== 'BB';
};
export type ArchitectureDirectionPairMap = {
[key in ArchitectureDirectionPair]?: string;
};
export type ArchitectureDirectionPairMap = Partial<Record<ArchitectureDirectionPair, string>>;
/**
* Creates a pair of the directions of each side of an edge. This function should be used instead of manually creating it to ensure that the source is always the first character.
@@ -170,6 +170,18 @@ export const getArchitectureDirectionXYFactors = function (
}
};
export const getArchitectureDirectionAlignment = function (
a: ArchitectureDirection,
b: ArchitectureDirection
): ArchitectureAlignment {
if (isArchitectureDirectionXY(a, b)) {
return 'bend';
} else if (isArchitectureDirectionX(a)) {
return 'horizontal';
}
return 'vertical';
};
export interface ArchitectureStyleOptions {
archEdgeColor: string;
archEdgeArrowColor: string;
@@ -249,9 +261,27 @@ export interface ArchitectureDB extends DiagramDB {
export type ArchitectureAdjacencyList = Record<string, ArchitectureDirectionPairMap>;
export type ArchitectureSpatialMap = Record<string, number[]>;
/**
* Maps the direction that groups connect from.
*
* **Outer key**: ID of group A
*
* **Inner key**: ID of group B
*
* **Value**: 'vertical' or 'horizontal'
*
* Note: tmp[groupA][groupB] == tmp[groupB][groupA]
*/
export type ArchitectureGroupAlignments = Record<
string,
Record<string, Exclude<ArchitectureAlignment, 'bend'>>
>;
export interface ArchitectureDataStructures {
adjList: ArchitectureAdjacencyList;
spatialMaps: ArchitectureSpatialMap[];
groupAlignments: ArchitectureGroupAlignments;
}
export interface ArchitectureState extends Record<string, unknown> {

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,11 @@
import { parser } from './parser/classDiagram.jison';
import classDb from './classDb.js';
import { ClassDB } from './classDb.js';
describe('class diagram, ', function () {
describe('when parsing data from a classDiagram it', function () {
let classDb;
beforeEach(function () {
classDb = new ClassDB();
parser.yy = classDb;
parser.yy.clear();
});

View File

@@ -1,13 +1,15 @@
import type { DiagramDefinition } from '../../diagram-api/types.js';
// @ts-ignore: JISON doesn't support types
import parser from './parser/classDiagram.jison';
import db from './classDb.js';
import { ClassDB } from './classDb.js';
import styles from './styles.js';
import renderer from './classRenderer-v3-unified.js';
export const diagram: DiagramDefinition = {
parser,
db,
get db() {
return new ClassDB();
},
renderer,
styles,
init: (cnf) => {
@@ -15,6 +17,5 @@ export const diagram: DiagramDefinition = {
cnf.class = {};
}
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
db.clear();
},
};

View File

@@ -1,6 +1,7 @@
/* eslint-disable @typescript-eslint/unbound-method -- Broken for Vitest mocks, see https://github.com/vitest-dev/eslint-plugin-vitest/pull/286 */
// @ts-expect-error Jison doesn't export types
import { parser } from './parser/classDiagram.jison';
import classDb from './classDb.js';
import { ClassDB } from './classDb.js';
import { vi, describe, it, expect } from 'vitest';
import type { ClassMap, NamespaceNode } from './classTypes.js';
const spyOn = vi.spyOn;
@@ -10,8 +11,9 @@ const abstractCssStyle = 'font-style:italic;';
describe('given a basic class diagram, ', function () {
describe('when parsing class definition', function () {
let classDb: ClassDB;
beforeEach(function () {
classDb.clear();
classDb = new ClassDB();
parser.yy = classDb;
});
it('should handle classes within namespaces', () => {
@@ -564,8 +566,9 @@ class C13["With Città foreign language"]
});
describe('when parsing class defined in brackets', function () {
let classDb: ClassDB;
beforeEach(function () {
classDb.clear();
classDb = new ClassDB();
parser.yy = classDb;
});
@@ -656,8 +659,9 @@ class C13["With Città foreign language"]
});
describe('when parsing comments', function () {
let classDb: ClassDB;
beforeEach(function () {
classDb.clear();
classDb = new ClassDB();
parser.yy = classDb;
});
@@ -746,8 +750,9 @@ foo()
});
describe('when parsing click statements', function () {
let classDb: ClassDB;
beforeEach(function () {
classDb.clear();
classDb = new ClassDB();
parser.yy = classDb;
});
it('should handle href link', function () {
@@ -857,8 +862,9 @@ foo()
});
describe('when parsing annotations', function () {
let classDb: ClassDB;
beforeEach(function () {
classDb.clear();
classDb = new ClassDB();
parser.yy = classDb;
});
@@ -921,8 +927,9 @@ foo()
describe('given a class diagram with members and methods ', function () {
describe('when parsing members', function () {
let classDb: ClassDB;
beforeEach(function () {
classDb.clear();
classDb = new ClassDB();
parser.yy = classDb;
});
@@ -980,8 +987,9 @@ describe('given a class diagram with members and methods ', function () {
});
describe('when parsing method definition', function () {
let classDb: ClassDB;
beforeEach(function () {
classDb.clear();
classDb = new ClassDB();
parser.yy = classDb;
});
@@ -1067,8 +1075,9 @@ describe('given a class diagram with members and methods ', function () {
describe('given a class diagram with generics, ', function () {
describe('when parsing valid generic classes', function () {
let classDb: ClassDB;
beforeEach(function () {
classDb.clear();
classDb = new ClassDB();
parser.yy = classDb;
});
@@ -1180,8 +1189,9 @@ namespace space {
describe('given a class diagram with relationships, ', function () {
describe('when parsing basic relationships', function () {
let classDb: ClassDB;
beforeEach(function () {
classDb.clear();
classDb = new ClassDB();
parser.yy = classDb;
});
@@ -1714,7 +1724,9 @@ class Class2
});
describe('when parsing classDiagram with text labels', () => {
let classDb: ClassDB;
beforeEach(function () {
classDb = new ClassDB();
parser.yy = classDb;
parser.yy.clear();
});
@@ -1897,3 +1909,40 @@ class C13["With Città foreign language"]
});
});
});
describe('class db class', () => {
let classDb: ClassDB;
beforeEach(() => {
classDb = new ClassDB();
});
// This is to ensure that functions used in class JISON are exposed as function from ClassDB
it('should have functions used in class JISON as own property', () => {
const functionsUsedInParser = [
'addRelation',
'cleanupLabel',
'setAccTitle',
'setAccDescription',
'addClassesToNamespace',
'addNamespace',
'setCssClass',
'addMembers',
'addClass',
'setClassLabel',
'addAnnotation',
'addMember',
'addNote',
'defineClass',
'setDirection',
'relationType',
'lineType',
'setClickEvent',
'setTooltip',
'setLink',
'setCssStyle',
] as const satisfies (keyof ClassDB)[];
for (const fun of functionsUsedInParser) {
expect(Object.hasOwn(classDb, fun)).toBe(true);
}
});
});

View File

@@ -1,13 +1,15 @@
import type { DiagramDefinition } from '../../diagram-api/types.js';
// @ts-ignore: JISON doesn't support types
import parser from './parser/classDiagram.jison';
import db from './classDb.js';
import { ClassDB } from './classDb.js';
import styles from './styles.js';
import renderer from './classRenderer-v3-unified.js';
export const diagram: DiagramDefinition = {
parser,
db,
get db() {
return new ClassDB();
},
renderer,
styles,
init: (cnf) => {
@@ -15,6 +17,5 @@ export const diagram: DiagramDefinition = {
cnf.class = {};
}
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
db.clear();
},
};

View File

@@ -1,8 +1,10 @@
import { parser } from './classDiagram.jison';
import classDb from '../classDb.js';
import { ClassDB } from '../classDb.js';
describe('class diagram', function () {
let classDb;
beforeEach(function () {
classDb = new ClassDB();
parser.yy = classDb;
parser.yy.clear();
});

View File

@@ -1,9 +1,11 @@
import flowDb from './flowDb.js';
import { FlowDB } from './flowDb.js';
import type { FlowSubGraph } from './types.js';
describe('flow db subgraphs', () => {
let flowDb: FlowDB;
let subgraphs: FlowSubGraph[];
beforeEach(() => {
flowDb = new FlowDB();
subgraphs = [
{ nodes: ['a', 'b', 'c', 'e'] },
{ nodes: ['f', 'g', 'h'] },
@@ -44,8 +46,9 @@ describe('flow db subgraphs', () => {
});
describe('flow db addClass', () => {
let flowDb: FlowDB;
beforeEach(() => {
flowDb.clear();
flowDb = new FlowDB();
});
it('should detect many classes', () => {
flowDb.addClass('a,b', ['stroke-width: 8px']);
@@ -65,3 +68,33 @@ describe('flow db addClass', () => {
expect(classes.get('a')?.styles).toEqual(['stroke-width: 8px']);
});
});
describe('flow db class', () => {
let flowDb: FlowDB;
beforeEach(() => {
flowDb = new FlowDB();
});
// This is to ensure that functions used in flow JISON are exposed as function from FlowDB
it('should have functions used in flow JISON as own property', () => {
const functionsUsedInParser = [
'setDirection',
'addSubGraph',
'setAccTitle',
'setAccDescription',
'addVertex',
'addLink',
'setClass',
'destructLink',
'addClass',
'setClickEvent',
'setTooltip',
'setLink',
'updateLink',
'updateLinkInterpolate',
] as const satisfies (keyof FlowDB)[];
for (const fun of functionsUsedInParser) {
expect(Object.hasOwn(flowDb, fun)).toBe(true);
}
});
});

File diff suppressed because it is too large Load Diff

View File

@@ -1,14 +1,17 @@
import type { MermaidConfig } from '../../config.type.js';
import { setConfig } from '../../diagram-api/diagramAPI.js';
import flowDb from './flowDb.js';
import { FlowDB } from './flowDb.js';
import renderer from './flowRenderer-v3-unified.js';
// @ts-ignore: JISON doesn't support types
import flowParser from './parser/flow.jison';
//import flowParser from './parser/flow.jison';
import flowParser from './parser/flowParser.ts';
import flowStyles from './styles.js';
export const diagram = {
parser: flowParser,
db: flowDb,
get db() {
return new FlowDB();
},
renderer,
styles: flowStyles,
init: (cnf: MermaidConfig) => {
@@ -20,7 +23,5 @@ export const diagram = {
}
cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
setConfig({ flowchart: { arrowMarkerAbsolute: cnf.arrowMarkerAbsolute } });
flowDb.clear();
flowDb.setGen('gen-2');
},
};

View File

@@ -7,7 +7,6 @@ import { getRegisteredLayoutAlgorithm, render } from '../../rendering-util/rende
import { setupViewPortForSVG } from '../../rendering-util/setupViewPortForSVG.js';
import type { LayoutData } from '../../rendering-util/types.js';
import utils from '../../utils.js';
import { getDirection } from './flowDb.js';
export const getClasses = function (
text: string,
@@ -37,7 +36,7 @@ export const draw = async function (text: string, id: string, _version: string,
log.debug('Data: ', data4Layout);
// Create the root SVG
const svg = getDiagramElement(id, securityLevel);
const direction = getDirection();
const direction = diag.db.getDirection();
data4Layout.type = diag.type;
data4Layout.layoutAlgorithm = getRegisteredLayoutAlgorithm(layout);

View File

@@ -1,5 +1,5 @@
import flowDb from '../flowDb.js';
import flow from './flow.jison';
import { FlowDB } from '../flowDb.js';
import flow from './flowParser.ts';
import { setConfig } from '../../../config.js';
setConfig({
@@ -8,7 +8,7 @@ setConfig({
describe('[Arrows] when parsing', () => {
beforeEach(function () {
flow.parser.yy = flowDb;
flow.parser.yy = new FlowDB();
flow.parser.yy.clear();
});

View File

@@ -1,5 +1,5 @@
import flowDb from '../flowDb.js';
import flow from './flow.jison';
import { FlowDB } from '../flowDb.js';
import flow from './flowParser.ts';
import { setConfig } from '../../../config.js';
import { cleanupComments } from '../../../diagram-api/comments.js';
@@ -9,7 +9,7 @@ setConfig({
describe('[Comments] when parsing', () => {
beforeEach(function () {
flow.parser.yy = flowDb;
flow.parser.yy = new FlowDB();
flow.parser.yy.clear();
});

View File

@@ -1,5 +1,5 @@
import flowDb from '../flowDb.js';
import flow from './flow.jison';
import { FlowDB } from '../flowDb.js';
import flow from './flowParser.ts';
import { setConfig } from '../../../config.js';
setConfig({
@@ -8,7 +8,7 @@ setConfig({
describe('when parsing directions', function () {
beforeEach(function () {
flow.parser.yy = flowDb;
flow.parser.yy = new FlowDB();
flow.parser.yy.clear();
flow.parser.yy.setGen('gen-2');
});

View File

@@ -1,5 +1,5 @@
import flowDb from '../flowDb.js';
import flow from './flow.jison';
import { FlowDB } from '../flowDb.js';
import flow from './flowParser.ts';
import { setConfig } from '../../../config.js';
setConfig({
@@ -39,10 +39,31 @@ const doubleEndedEdges = [
{ edgeStart: '<==', edgeEnd: '==>', stroke: 'thick', type: 'double_arrow_point' },
{ edgeStart: '<-.', edgeEnd: '.->', stroke: 'dotted', type: 'double_arrow_point' },
];
const regularEdges = [
{ edgeStart: '--', edgeEnd: '--x', stroke: 'normal', type: 'arrow_cross' },
{ edgeStart: '==', edgeEnd: '==x', stroke: 'thick', type: 'arrow_cross' },
{ edgeStart: '-.', edgeEnd: '.-x', stroke: 'dotted', type: 'arrow_cross' },
{ edgeStart: '--', edgeEnd: '--o', stroke: 'normal', type: 'arrow_circle' },
{ edgeStart: '==', edgeEnd: '==o', stroke: 'thick', type: 'arrow_circle' },
{ edgeStart: '-.', edgeEnd: '.-o', stroke: 'dotted', type: 'arrow_circle' },
{ edgeStart: '--', edgeEnd: '-->', stroke: 'normal', type: 'arrow_point' },
{ edgeStart: '==', edgeEnd: '==>', stroke: 'thick', type: 'arrow_point' },
{ edgeStart: '-.', edgeEnd: '.->', stroke: 'dotted', type: 'arrow_point' },
{ edgeStart: '--', edgeEnd: '----x', stroke: 'normal', type: 'arrow_cross' },
{ edgeStart: '==', edgeEnd: '====x', stroke: 'thick', type: 'arrow_cross' },
{ edgeStart: '-.', edgeEnd: '...-x', stroke: 'dotted', type: 'arrow_cross' },
{ edgeStart: '--', edgeEnd: '----o', stroke: 'normal', type: 'arrow_circle' },
{ edgeStart: '==', edgeEnd: '====o', stroke: 'thick', type: 'arrow_circle' },
{ edgeStart: '-.', edgeEnd: '...-o', stroke: 'dotted', type: 'arrow_circle' },
{ edgeStart: '--', edgeEnd: '---->', stroke: 'normal', type: 'arrow_point' },
{ edgeStart: '==', edgeEnd: '====>', stroke: 'thick', type: 'arrow_point' },
{ edgeStart: '-.', edgeEnd: '...->', stroke: 'dotted', type: 'arrow_point' },
];
describe('[Edges] when parsing', () => {
beforeEach(function () {
flow.parser.yy = flowDb;
flow.parser.yy = new FlowDB();
flow.parser.yy.clear();
});
@@ -67,6 +88,74 @@ describe('[Edges] when parsing', () => {
expect(edges[0].type).toBe('arrow_circle');
});
describe('edges with ids', function () {
describe('open ended edges with ids and labels', function () {
regularEdges.forEach((edgeType) => {
it(`should handle ${edgeType.stroke} ${edgeType.type} with no text`, function () {
const res = flow.parser.parse(
`flowchart TD;\nA e1@${edgeType.edgeStart}${edgeType.edgeEnd} B;`
);
const vert = flow.parser.yy.getVertices();
const edges = flow.parser.yy.getEdges();
expect(vert.get('A').id).toBe('A');
expect(vert.get('B').id).toBe('B');
expect(edges.length).toBe(1);
expect(edges[0].id).toBe('e1');
expect(edges[0].start).toBe('A');
expect(edges[0].end).toBe('B');
expect(edges[0].type).toBe(`${edgeType.type}`);
expect(edges[0].text).toBe('');
expect(edges[0].stroke).toBe(`${edgeType.stroke}`);
});
it(`should handle ${edgeType.stroke} ${edgeType.type} with text`, function () {
const res = flow.parser.parse(
`flowchart TD;\nA e1@${edgeType.edgeStart}${edgeType.edgeEnd} B;`
);
const vert = flow.parser.yy.getVertices();
const edges = flow.parser.yy.getEdges();
expect(vert.get('A').id).toBe('A');
expect(vert.get('B').id).toBe('B');
expect(edges.length).toBe(1);
expect(edges[0].id).toBe('e1');
expect(edges[0].start).toBe('A');
expect(edges[0].end).toBe('B');
expect(edges[0].type).toBe(`${edgeType.type}`);
expect(edges[0].text).toBe('');
expect(edges[0].stroke).toBe(`${edgeType.stroke}`);
});
});
it('should handle normal edges where you also have a node with metadata', function () {
const res = flow.parser.parse(`flowchart LR
A id1@-->B
A@{ shape: 'rect' }
`);
const edges = flow.parser.yy.getEdges();
expect(edges[0].id).toBe('id1');
});
});
describe('double ended edges with ids and labels', function () {
doubleEndedEdges.forEach((edgeType) => {
it(`should handle ${edgeType.stroke} ${edgeType.type} with text`, function () {
const res = flow.parser.parse(
`flowchart TD;\nA e1@${edgeType.edgeStart} label ${edgeType.edgeEnd} B;`
);
const vert = flow.parser.yy.getVertices();
const edges = flow.parser.yy.getEdges();
expect(vert.get('A').id).toBe('A');
expect(vert.get('B').id).toBe('B');
expect(edges.length).toBe(1);
expect(edges[0].id).toBe('e1');
expect(edges[0].start).toBe('A');
expect(edges[0].end).toBe('B');
expect(edges[0].type).toBe(`${edgeType.type}`);
expect(edges[0].text).toBe('label');
expect(edges[0].stroke).toBe(`${edgeType.stroke}`);
});
});
});
});
describe('edges', function () {
doubleEndedEdges.forEach((edgeType) => {
it(`should handle ${edgeType.stroke} ${edgeType.type} with no text`, function () {

View File

@@ -1,5 +1,5 @@
import flowDb from '../flowDb.js';
import flow from './flow.jison';
import { FlowDB } from '../flowDb.js';
import flow from './flowParser.ts';
import { setConfig } from '../../../config.js';
setConfig({
@@ -8,7 +8,7 @@ setConfig({
describe('[Text] when parsing', () => {
beforeEach(function () {
flow.parser.yy = flowDb;
flow.parser.yy = new FlowDB();
flow.parser.yy.clear();
});

View File

@@ -1,5 +1,5 @@
import flowDb from '../flowDb.js';
import flow from './flow.jison';
import { FlowDB } from '../flowDb.js';
import flow from './flowParser.ts';
import { setConfig } from '../../../config.js';
import { vi } from 'vitest';
const spyOn = vi.spyOn;
@@ -9,7 +9,9 @@ setConfig({
});
describe('[Interactions] when parsing', () => {
let flowDb;
beforeEach(function () {
flowDb = new FlowDB();
flow.parser.yy = flowDb;
flow.parser.yy.clear();
});

View File

@@ -1,5 +1,5 @@
import flowDb from '../flowDb.js';
import flow from './flow.jison';
import { FlowDB } from '../flowDb.js';
import flow from './flowParser.ts';
import { setConfig } from '../../../config.js';
setConfig({
@@ -8,7 +8,7 @@ setConfig({
describe('[Lines] when parsing', () => {
beforeEach(function () {
flow.parser.yy = flowDb;
flow.parser.yy = new FlowDB();
flow.parser.yy.clear();
});

View File

@@ -1,5 +1,5 @@
import flowDb from '../flowDb.js';
import flow from './flow.jison';
import { FlowDB } from '../flowDb.js';
import flow from './flowParser.ts';
import { setConfig } from '../../../config.js';
setConfig({
@@ -8,7 +8,7 @@ setConfig({
describe('parsing a flow chart with markdown strings', function () {
beforeEach(function () {
flow.parser.yy = flowDb;
flow.parser.yy = new FlowDB();
flow.parser.yy.clear();
});

View File

@@ -1,5 +1,5 @@
import flowDb from '../flowDb.js';
import flow from './flow.jison';
import { FlowDB } from '../flowDb.js';
import flow from './flowParser.ts';
import { setConfig } from '../../../config.js';
setConfig({
@@ -8,7 +8,7 @@ setConfig({
describe('when parsing directions', function () {
beforeEach(function () {
flow.parser.yy = flowDb;
flow.parser.yy = new FlowDB();
flow.parser.yy.clear();
flow.parser.yy.setGen('gen-2');
});
@@ -251,7 +251,7 @@ describe('when parsing directions', function () {
expect(data4Layout.nodes[0].shape).toEqual('squareRect');
expect(data4Layout.nodes[0].label).toEqual('This is a<br/>multiline string');
});
it(' should be possible to use } in strings', function () {
it('should be possible to use } in strings', function () {
const res = flow.parser.parse(`flowchart TB
A@{
label: "This is a string with }"
@@ -264,7 +264,7 @@ describe('when parsing directions', function () {
expect(data4Layout.nodes[0].shape).toEqual('squareRect');
expect(data4Layout.nodes[0].label).toEqual('This is a string with }');
});
it(' should be possible to use @ in strings', function () {
it('should be possible to use @ in strings', function () {
const res = flow.parser.parse(`flowchart TB
A@{
label: "This is a string with @"
@@ -277,7 +277,7 @@ describe('when parsing directions', function () {
expect(data4Layout.nodes[0].shape).toEqual('squareRect');
expect(data4Layout.nodes[0].label).toEqual('This is a string with @');
});
it(' should be possible to use @ in strings', function () {
it('should be possible to use @ in strings', function () {
const res = flow.parser.parse(`flowchart TB
A@{
label: "This is a string with}"
@@ -290,4 +290,126 @@ describe('when parsing directions', function () {
expect(data4Layout.nodes[0].shape).toEqual('squareRect');
expect(data4Layout.nodes[0].label).toEqual('This is a string with}');
});
it('should be possible to use @ syntax to add labels on multi nodes', function () {
const res = flow.parser.parse(`flowchart TB
n2["label for n2"] & n4@{ label: "labe for n4"} & n5@{ label: "labe for n5"}
`);
const data4Layout = flow.parser.yy.getData();
expect(data4Layout.nodes.length).toBe(3);
expect(data4Layout.nodes[0].label).toEqual('label for n2');
expect(data4Layout.nodes[1].label).toEqual('labe for n4');
expect(data4Layout.nodes[2].label).toEqual('labe for n5');
});
it('should be possible to use @ syntax to add labels on multi nodes with edge/link', function () {
const res = flow.parser.parse(`flowchart TD
A["A"] --> B["for B"] & C@{ label: "for c"} & E@{label : "for E"}
D@{label: "for D"}
`);
const data4Layout = flow.parser.yy.getData();
expect(data4Layout.nodes.length).toBe(5);
expect(data4Layout.nodes[0].label).toEqual('A');
expect(data4Layout.nodes[1].label).toEqual('for B');
expect(data4Layout.nodes[2].label).toEqual('for c');
expect(data4Layout.nodes[3].label).toEqual('for E');
expect(data4Layout.nodes[4].label).toEqual('for D');
});
it('should be possible to use @ syntax in labels', function () {
const res = flow.parser.parse(`flowchart TD
A["@A@"] --> B["@for@ B@"] & C@{ label: "@for@ c@"} & E{"\`@for@ E@\`"} & D(("@for@ D@"))
H1{{"@for@ H@"}}
H2{{"\`@for@ H@\`"}}
Q1{"@for@ Q@"}
Q2{"\`@for@ Q@\`"}
AS1>"@for@ AS@"]
AS2>"\`@for@ AS@\`"]
`);
const data4Layout = flow.parser.yy.getData();
expect(data4Layout.nodes.length).toBe(11);
expect(data4Layout.nodes[0].label).toEqual('@A@');
expect(data4Layout.nodes[1].label).toEqual('@for@ B@');
expect(data4Layout.nodes[2].label).toEqual('@for@ c@');
expect(data4Layout.nodes[3].label).toEqual('@for@ E@');
expect(data4Layout.nodes[4].label).toEqual('@for@ D@');
expect(data4Layout.nodes[5].label).toEqual('@for@ H@');
expect(data4Layout.nodes[6].label).toEqual('@for@ H@');
expect(data4Layout.nodes[7].label).toEqual('@for@ Q@');
expect(data4Layout.nodes[8].label).toEqual('@for@ Q@');
expect(data4Layout.nodes[9].label).toEqual('@for@ AS@');
expect(data4Layout.nodes[10].label).toEqual('@for@ AS@');
});
it('should handle unique edge creation with using @ and &', function () {
const res = flow.parser.parse(`flowchart TD
A & B e1@--> C & D
A1 e2@--> C1 & D1
`);
const data4Layout = flow.parser.yy.getData();
expect(data4Layout.nodes.length).toBe(7);
expect(data4Layout.edges.length).toBe(6);
expect(data4Layout.edges[0].id).toEqual('L_A_C_0');
expect(data4Layout.edges[1].id).toEqual('L_A_D_0');
expect(data4Layout.edges[2].id).toEqual('e1');
expect(data4Layout.edges[3].id).toEqual('L_B_D_0');
expect(data4Layout.edges[4].id).toEqual('e2');
expect(data4Layout.edges[5].id).toEqual('L_A1_D1_0');
});
it('should handle redefine same edge ids again', function () {
const res = flow.parser.parse(`flowchart TD
A & B e1@--> C & D
A1 e1@--> C1 & D1
`);
const data4Layout = flow.parser.yy.getData();
expect(data4Layout.nodes.length).toBe(7);
expect(data4Layout.edges.length).toBe(6);
expect(data4Layout.edges[0].id).toEqual('L_A_C_0');
expect(data4Layout.edges[1].id).toEqual('L_A_D_0');
expect(data4Layout.edges[2].id).toEqual('e1');
expect(data4Layout.edges[3].id).toEqual('L_B_D_0');
expect(data4Layout.edges[4].id).toEqual('L_A1_C1_0');
expect(data4Layout.edges[5].id).toEqual('L_A1_D1_0');
});
it('should handle overriding edge animate again', function () {
const res = flow.parser.parse(`flowchart TD
A e1@--> B
C e2@--> D
E e3@--> F
e1@{ animate: true }
e2@{ animate: false }
e3@{ animate: true }
e3@{ animate: false }
`);
const data4Layout = flow.parser.yy.getData();
expect(data4Layout.nodes.length).toBe(6);
expect(data4Layout.edges.length).toBe(3);
expect(data4Layout.edges[0].id).toEqual('e1');
expect(data4Layout.edges[0].animate).toEqual(true);
expect(data4Layout.edges[1].id).toEqual('e2');
expect(data4Layout.edges[1].animate).toEqual(false);
expect(data4Layout.edges[2].id).toEqual('e3');
expect(data4Layout.edges[2].animate).toEqual(false);
});
it.skip('should be possible to use @ syntax to add labels with trail spaces', function () {
const res = flow.parser.parse(
`flowchart TB
n2["label for n2"] & n4@{ label: "labe for n4"} & n5@{ label: "labe for n5"} `
);
const data4Layout = flow.parser.yy.getData();
expect(data4Layout.nodes.length).toBe(3);
expect(data4Layout.nodes[0].label).toEqual('label for n2');
expect(data4Layout.nodes[1].label).toEqual('labe for n4');
expect(data4Layout.nodes[2].label).toEqual('labe for n5');
});
});

View File

@@ -1,5 +1,5 @@
import flowDb from '../flowDb.js';
import flow from './flow.jison';
import { FlowDB } from '../flowDb.js';
import flow from './flowParser.ts';
import { setConfig } from '../../../config.js';
setConfig({
@@ -31,7 +31,7 @@ const specialChars = ['#', ':', '0', '&', ',', '*', '.', '\\', 'v', '-', '/', '_
describe('[Singlenodes] when parsing', () => {
beforeEach(function () {
flow.parser.yy = flowDb;
flow.parser.yy = new FlowDB();
flow.parser.yy.clear();
});

View File

@@ -1,5 +1,5 @@
import flowDb from '../flowDb.js';
import flow from './flow.jison';
import { FlowDB } from '../flowDb.js';
import flow from './flowParser.ts';
import { setConfig } from '../../../config.js';
setConfig({
@@ -8,7 +8,7 @@ setConfig({
describe('[Style] when parsing', () => {
beforeEach(function () {
flow.parser.yy = flowDb;
flow.parser.yy = new FlowDB();
flow.parser.yy.clear();
flow.parser.yy.setGen('gen-2');
});

View File

@@ -1,5 +1,5 @@
import flowDb from '../flowDb.js';
import flow from './flow.jison';
import { FlowDB } from '../flowDb.js';
import flow from './flowParser.ts';
import { setConfig } from '../../../config.js';
setConfig({
@@ -8,7 +8,7 @@ setConfig({
describe('[Text] when parsing', () => {
beforeEach(function () {
flow.parser.yy = flowDb;
flow.parser.yy = new FlowDB();
flow.parser.yy.clear();
});

View File

@@ -1,5 +1,5 @@
import flowDb from '../flowDb.js';
import flow from './flow.jison';
import { FlowDB } from '../flowDb.js';
import flow from './flowParser.ts';
import { setConfig } from '../../../config.js';
setConfig({
@@ -8,7 +8,7 @@ setConfig({
describe('when parsing flowcharts', function () {
beforeEach(function () {
flow.parser.yy = flowDb;
flow.parser.yy = new FlowDB();
flow.parser.yy.clear();
flow.parser.yy.setGen('gen-2');
});

View File

@@ -141,6 +141,7 @@ that id.
.*direction\s+RL[^\n]* return 'direction_rl';
.*direction\s+LR[^\n]* return 'direction_lr';
[^\s\"]+\@(?=[^\{\"]) { return 'LINK_ID'; }
[0-9]+ return 'NUM';
\# return 'BRKT';
":::" return 'STYLE_SEPARATOR';
@@ -201,7 +202,9 @@ that id.
"*" return 'MULT';
"#" return 'BRKT';
"&" return 'AMP';
([A-Za-z0-9!"\#$%&'*+\.`?\\_\/]|\-(?=[^\>\-\.])|=(?!=))+ return 'NODE_STRING';
([A-Za-z0-9!"\#$%&'*+\.`?\\_\/]|\-(?=[^\>\-\.])|=(?!=))+ {
return 'NODE_STRING';
}
"-" return 'MINUS'
[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|
[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|
@@ -361,7 +364,7 @@ spaceList
statement
: vertexStatement separator
{ /* console.warn('finat vs', $vertexStatement.nodes); */ $$=$vertexStatement.nodes}
{ $$=$vertexStatement.nodes}
| styleStatement separator
{$$=[];}
| linkStyleStatement separator
@@ -396,7 +399,7 @@ shapeData:
;
vertexStatement: vertexStatement link node shapeData
{ /* console.warn('vs shapeData',$vertexStatement.stmt,$node, $shapeData);*/ yy.addVertex($node[0],undefined,undefined,undefined, undefined,undefined, undefined,$shapeData); yy.addLink($vertexStatement.stmt,$node,$link); $$ = { stmt: $node, nodes: $node.concat($vertexStatement.nodes) } }
{ /* console.warn('vs shapeData',$vertexStatement.stmt,$node, $shapeData);*/ yy.addVertex($node[$node.length-1],undefined,undefined,undefined, undefined,undefined, undefined,$shapeData); yy.addLink($vertexStatement.stmt,$node,$link); $$ = { stmt: $node, nodes: $node.concat($vertexStatement.nodes) } }
| vertexStatement link node
{ /*console.warn('vs',$vertexStatement.stmt,$node);*/ yy.addLink($vertexStatement.stmt,$node,$link); $$ = { stmt: $node, nodes: $node.concat($vertexStatement.nodes) } }
| vertexStatement link node spaceList
@@ -404,7 +407,7 @@ vertexStatement: vertexStatement link node shapeData
|node spaceList { /*console.warn('vertexStatement: node spaceList', $node);*/ $$ = {stmt: $node, nodes:$node }}
|node shapeData {
/*console.warn('vertexStatement: node shapeData', $node[0], $shapeData);*/
yy.addVertex($node[0],undefined,undefined,undefined, undefined,undefined, undefined,$shapeData);
yy.addVertex($node[$node.length-1],undefined,undefined,undefined, undefined,undefined, undefined,$shapeData);
$$ = {stmt: $node, nodes:$node, shapeData: $shapeData}
}
|node { /* console.warn('vertexStatement: single node', $node); */ $$ = {stmt: $node, nodes:$node }}
@@ -413,7 +416,7 @@ vertexStatement: vertexStatement link node shapeData
node: styledVertex
{ /*console.warn('nod', $styledVertex);*/ $$ = [$styledVertex];}
| node shapeData spaceList AMP spaceList styledVertex
{ yy.addVertex($node[0],undefined,undefined,undefined, undefined,undefined, undefined,$shapeData); $$ = $node.concat($styledVertex); /*console.warn('pip2', $node[0], $styledVertex, $$);*/ }
{ yy.addVertex($node[$node.length-1],undefined,undefined,undefined, undefined,undefined, undefined,$shapeData); $$ = $node.concat($styledVertex); /*console.warn('pip2', $node[0], $styledVertex, $$);*/ }
| node spaceList AMP spaceList styledVertex
{ $$ = $node.concat($styledVertex); /*console.warn('pip', $node[0], $styledVertex, $$);*/ }
;
@@ -472,6 +475,8 @@ link: linkStatement arrowText
{$$ = $linkStatement;}
| START_LINK edgeText LINK
{var inf = yy.destructLink($LINK, $START_LINK); $$ = {"type":inf.type,"stroke":inf.stroke,"length":inf.length,"text":$edgeText};}
| LINK_ID START_LINK edgeText LINK
{var inf = yy.destructLink($LINK, $START_LINK); $$ = {"type":inf.type,"stroke":inf.stroke,"length":inf.length,"text":$edgeText, "id": $LINK_ID};}
;
edgeText: edgeTextToken
@@ -487,6 +492,8 @@ edgeText: edgeTextToken
linkStatement: LINK
{var inf = yy.destructLink($LINK);$$ = {"type":inf.type,"stroke":inf.stroke,"length":inf.length};}
| LINK_ID LINK
{var inf = yy.destructLink($LINK);$$ = {"type":inf.type,"stroke":inf.stroke,"length":inf.length, "id": $LINK_ID};}
;
arrowText:

View File

@@ -1,5 +1,5 @@
import flowDb from '../flowDb.js';
import flow from './flow.jison';
import { FlowDB } from '../flowDb.js';
import flow from './flowParser.ts';
import { cleanupComments } from '../../../diagram-api/comments.js';
import { setConfig } from '../../../config.js';
@@ -9,7 +9,7 @@ setConfig({
describe('parsing a flow chart', function () {
beforeEach(function () {
flow.parser.yy = flowDb;
flow.parser.yy = new FlowDB();
flow.parser.yy.clear();
});

View File

@@ -0,0 +1,12 @@
// @ts-ignore: JISON doesn't support types
import flowJisonParser from './flow.jison';
const newParser = Object.assign({}, flowJisonParser);
newParser.parse = (src: string): unknown => {
// remove the trailing whitespace after closing curly braces when ending a line break
const newSrc = src.replace(/}\s*\n/g, '}\n');
return flowJisonParser.parse(newSrc);
};
export default newParser;

View File

@@ -1,5 +1,5 @@
import flowDb from '../flowDb.js';
import flow from './flow.jison';
import { FlowDB } from '../flowDb.js';
import flow from './flowParser.ts';
import { setConfig } from '../../../config.js';
setConfig({
@@ -8,7 +8,7 @@ setConfig({
describe('when parsing subgraphs', function () {
beforeEach(function () {
flow.parser.yy = flowDb;
flow.parser.yy = new FlowDB();
flow.parser.yy.clear();
flow.parser.yy.setGen('gen-2');
});

View File

@@ -53,6 +53,7 @@ export interface FlowText {
}
export interface FlowEdge {
isUserDefinedId: boolean;
start: string;
end: string;
interpolate?: string;
@@ -62,6 +63,10 @@ export interface FlowEdge {
length?: number;
text: string;
labelType: 'text';
classes: string[];
id?: string;
animation?: 'fast' | 'slow';
animate?: boolean;
}
export interface FlowClass {

View File

@@ -1,7 +1,7 @@
const getStyles = (options) =>
`
.mermaid-main-font {
font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif);
font-family: ${options.fontFamily};
}
.exclude-range {
@@ -45,7 +45,7 @@ const getStyles = (options) =>
.sectionTitle {
text-anchor: start;
font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif);
font-family: ${options.fontFamily};
}
@@ -86,13 +86,13 @@ const getStyles = (options) =>
.taskText {
text-anchor: middle;
font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif);
font-family: ${options.fontFamily};
}
.taskTextOutsideRight {
fill: ${options.taskTextDarkColor};
text-anchor: start;
font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif);
font-family: ${options.fontFamily};
}
.taskTextOutsideLeft {
@@ -248,7 +248,7 @@ const getStyles = (options) =>
text-anchor: middle;
font-size: 18px;
fill: ${options.titleColor || options.textColor};
font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif);
font-family: ${options.fontFamily};
}
`;

View File

@@ -4,11 +4,13 @@ import parser from './parser/sankey.jison';
import db from './sankeyDB.js';
import renderer from './sankeyRenderer.js';
import { prepareTextForParsing } from './sankeyUtils.js';
import sankeyStyles from './styles.js';
const originalParse = parser.parse.bind(parser);
parser.parse = (text: string) => originalParse(prepareTextForParsing(text));
export const diagram: DiagramDefinition = {
styles: sankeyStyles,
parser,
db,
renderer,

View File

@@ -136,7 +136,6 @@ export const draw = function (text: string, id: string, _version: string, diagOb
svg
.append('g')
.attr('class', 'node-labels')
.attr('font-family', 'sans-serif')
.attr('font-size', 14)
.selectAll('text')
.data(graph.nodes)

View File

@@ -0,0 +1,6 @@
const getStyles = (options) =>
`.label {
font-family: ${options.fontFamily};
}`;
export default getStyles;

File diff suppressed because it is too large Load Diff

View File

@@ -1,16 +1,26 @@
import type { DiagramDefinition } from '../../diagram-api/types.js';
// @ts-ignore: JISON doesn't support types
import parser from './parser/sequenceDiagram.jison';
import db from './sequenceDb.js';
import { SequenceDB } from './sequenceDb.js';
import styles from './styles.js';
import { setConfig } from '../../diagram-api/diagramAPI.js';
import renderer from './sequenceRenderer.js';
import type { MermaidConfig } from '../../config.type.js';
export const diagram: DiagramDefinition = {
parser,
db,
get db() {
return new SequenceDB();
},
renderer,
styles,
init: ({ wrap }) => {
db.setWrap(wrap);
init: (cnf: MermaidConfig) => {
if (!cnf.sequence) {
cnf.sequence = {};
}
if (cnf.wrap) {
cnf.sequence.wrap = cnf.wrap;
setConfig({ sequence: { wrap: cnf.wrap } });
}
},
};

View File

@@ -1538,7 +1538,6 @@ const calculateLoopBounds = async function (messages, actors, _maxWidthPerActor,
let current, noteModel, msgModel;
for (const msg of messages) {
msg.id = utils.random({ length: 10 });
switch (msg.type) {
case diagObj.db.LINETYPE.LOOP_START:
case diagObj.db.LINETYPE.ALT_START:

View File

@@ -20,6 +20,7 @@ export interface Actor {
}
export interface Message {
id: string;
from?: string;
to?: string;
message:

View File

@@ -1,4 +1,4 @@
import stateDb from '../stateDb.js';
import { StateDB } from '../stateDb.js';
import stateDiagram from './stateDiagram.jison';
import { setConfig } from '../../../config.js';
@@ -7,7 +7,9 @@ setConfig({
});
describe('state parser can parse...', () => {
let stateDb;
beforeEach(function () {
stateDb = new StateDB(2);
stateDiagram.parser.yy = stateDb;
stateDiagram.parser.yy.clear();
});
@@ -18,7 +20,6 @@ describe('state parser can parse...', () => {
const diagramText = `stateDiagram-v2
state "Small State 1" as namedState1`;
stateDiagram.parser.parse(diagramText);
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
const states = stateDiagram.parser.yy.getStates();
expect(states.get('namedState1')).not.toBeUndefined();
@@ -31,7 +32,6 @@ describe('state parser can parse...', () => {
const diagramText = `stateDiagram-v2
namedState1 : Small State 1`;
stateDiagram.parser.parse(diagramText);
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
const states = stateDiagram.parser.yy.getStates();
expect(states.get('namedState1')).not.toBeUndefined();
@@ -42,7 +42,6 @@ describe('state parser can parse...', () => {
const diagramText = `stateDiagram-v2
namedState1:Small State 1`;
stateDiagram.parser.parse(diagramText);
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
const states = stateDiagram.parser.yy.getStates();
expect(states.get('namedState1')).not.toBeUndefined();
@@ -60,7 +59,6 @@ describe('state parser can parse...', () => {
state assemblies
`;
stateDiagram.parser.parse(diagramText);
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
const states = stateDiagram.parser.yy.getStates();
expect(states.get('assemble')).not.toBeUndefined();
expect(states.get('assemblies')).not.toBeUndefined();
@@ -71,7 +69,6 @@ describe('state parser can parse...', () => {
state "as" as as
`;
stateDiagram.parser.parse(diagramText);
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
const states = stateDiagram.parser.yy.getStates();
expect(states.get('as')).not.toBeUndefined();
expect(states.get('as').descriptions.join(' ')).toEqual('as');
@@ -96,7 +93,6 @@ describe('state parser can parse...', () => {
namedState2 --> bigState2: should point to \\nbigState2 container`;
stateDiagram.parser.parse(diagramText);
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
const states = stateDiagram.parser.yy.getStates();
expect(states.get('namedState1')).not.toBeUndefined();
@@ -120,7 +116,6 @@ describe('state parser can parse...', () => {
inner1 --> inner2
}`;
stateDiagram.parser.parse(diagramText);
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
const states = stateDiagram.parser.yy.getStates();
expect(states.get('bigState1')).not.toBeUndefined();
@@ -137,7 +132,6 @@ describe('state parser can parse...', () => {
stateDiagram-v2
[*] --> ${prop}
${prop} --> [*]`);
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
const states = stateDiagram.parser.yy.getStates();
expect(states.get(prop)).not.toBeUndefined();
});

View File

@@ -1,13 +1,15 @@
import stateDb from '../stateDb.js';
import stateDiagram from './stateDiagram.jison';
import { setConfig } from '../../../config.js';
import { StateDB } from '../stateDb.js';
import stateDiagram from './stateDiagram.jison';
setConfig({
securityLevel: 'strict',
});
describe('ClassDefs and classes when parsing a State diagram', () => {
let stateDb;
beforeEach(function () {
stateDb = new StateDB(2);
stateDiagram.parser.yy = stateDb;
stateDiagram.parser.yy.clear();
});
@@ -16,7 +18,6 @@ describe('ClassDefs and classes when parsing a State diagram', () => {
describe('defining (classDef)', () => {
it('has "classDef" as a keyword, an id, and can set a css style attribute', function () {
stateDiagram.parser.parse('stateDiagram-v2\n classDef exampleClass background:#bbb;');
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
const styleClasses = stateDb.getClasses();
expect(styleClasses.get('exampleClass').styles.length).toEqual(1);
@@ -27,7 +28,6 @@ describe('ClassDefs and classes when parsing a State diagram', () => {
stateDiagram.parser.parse(
'stateDiagram-v2\n classDef exampleClass background:#bbb, font-weight:bold, font-style:italic;'
);
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
const styleClasses = stateDb.getClasses();
expect(styleClasses.get('exampleClass').styles.length).toEqual(3);
@@ -41,7 +41,6 @@ describe('ClassDefs and classes when parsing a State diagram', () => {
stateDiagram.parser.parse(
'stateDiagram-v2\n classDef exampleStyleClass background:#bbb,border:1.5px solid red;'
);
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
const classes = stateDiagram.parser.yy.getClasses();
expect(classes.get('exampleStyleClass').styles.length).toBe(2);
@@ -53,7 +52,6 @@ describe('ClassDefs and classes when parsing a State diagram', () => {
stateDiagram.parser.parse(
'stateDiagram-v2\n classDef exampleStyleClass background: #bbb,border:1.5px solid red;'
);
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
const classes = stateDiagram.parser.yy.getClasses();
expect(classes.get('exampleStyleClass').styles.length).toBe(2);
@@ -65,7 +63,6 @@ describe('ClassDefs and classes when parsing a State diagram', () => {
stateDiagram.parser.parse(
'stateDiagram-v2\n classDef __proto__ background:#bbb,border:1.5px solid red;\n classDef constructor background:#bbb,border:1.5px solid red;'
);
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
const classes = stateDiagram.parser.yy.getClasses();
expect(classes.get('__proto__').styles.length).toBe(2);
expect(classes.get('constructor').styles.length).toBe(2);
@@ -81,7 +78,6 @@ describe('ClassDefs and classes when parsing a State diagram', () => {
diagram += 'class a exampleStyleClass';
stateDiagram.parser.parse(diagram);
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
const classes = stateDb.getClasses();
expect(classes.get('exampleStyleClass').styles.length).toEqual(2);
@@ -102,7 +98,6 @@ describe('ClassDefs and classes when parsing a State diagram', () => {
diagram += 'class a_a exampleStyleClass';
stateDiagram.parser.parse(diagram);
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
const classes = stateDiagram.parser.yy.getClasses();
expect(classes.get('exampleStyleClass').styles.length).toBe(2);
@@ -122,7 +117,6 @@ describe('ClassDefs and classes when parsing a State diagram', () => {
diagram += 'a --> b:::exampleStyleClass' + '\n';
stateDiagram.parser.parse(diagram);
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
const states = stateDiagram.parser.yy.getStates();
const classes = stateDiagram.parser.yy.getClasses();
@@ -141,7 +135,6 @@ describe('ClassDefs and classes when parsing a State diagram', () => {
diagram += '[*]:::exampleStyleClass --> b\n';
stateDiagram.parser.parse(diagram);
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
const states = stateDiagram.parser.yy.getStates();
const classes = stateDiagram.parser.yy.getClasses();
@@ -161,7 +154,6 @@ describe('ClassDefs and classes when parsing a State diagram', () => {
diagram += 'class a,b exampleStyleClass';
stateDiagram.parser.parse(diagram);
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
let classes = stateDiagram.parser.yy.getClasses();
let states = stateDiagram.parser.yy.getStates();
@@ -180,7 +172,6 @@ describe('ClassDefs and classes when parsing a State diagram', () => {
diagram += 'class a,b,c, d, e exampleStyleClass';
stateDiagram.parser.parse(diagram);
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
const classes = stateDiagram.parser.yy.getClasses();
const states = stateDiagram.parser.yy.getStates();
@@ -208,7 +199,6 @@ describe('ClassDefs and classes when parsing a State diagram', () => {
diagram += '}\n';
stateDiagram.parser.parse(diagram);
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
const states = stateDiagram.parser.yy.getStates();
@@ -224,7 +214,6 @@ describe('ClassDefs and classes when parsing a State diagram', () => {
stateDiagram.parser.parse(`stateDiagram-v2
id1
style id1 background:#bbb`);
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
const data4Layout = stateDiagram.parser.yy.getData();
expect(data4Layout.nodes[0].cssStyles).toEqual(['background:#bbb']);
@@ -234,7 +223,6 @@ describe('ClassDefs and classes when parsing a State diagram', () => {
id1
id2
style id1,id2 background:#bbb`);
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
const data4Layout = stateDiagram.parser.yy.getData();
expect(data4Layout.nodes[0].cssStyles).toEqual(['background:#bbb']);
@@ -247,7 +235,6 @@ describe('ClassDefs and classes when parsing a State diagram', () => {
id2
style id1,id2 background:#bbb, font-weight:bold, font-style:italic;`);
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
const data4Layout = stateDiagram.parser.yy.getData();
expect(data4Layout.nodes[0].cssStyles).toEqual([

View File

@@ -1,6 +1,6 @@
import { line, curveBasis } from 'd3';
import idCache from './id-cache.js';
import stateDb from './stateDb.js';
import { StateDB } from './stateDb.js';
import utils from '../../utils.js';
import common from '../common/common.js';
import { getConfig } from '../../diagram-api/diagramAPI.js';
@@ -414,13 +414,13 @@ let edgeCount = 0;
export const drawEdge = function (elem, path, relation) {
const getRelationType = function (type) {
switch (type) {
case stateDb.relationType.AGGREGATION:
case StateDB.relationType.AGGREGATION:
return 'aggregation';
case stateDb.relationType.EXTENSION:
case StateDB.relationType.EXTENSION:
return 'extension';
case stateDb.relationType.COMPOSITION:
case StateDB.relationType.COMPOSITION:
return 'composition';
case stateDb.relationType.DEPENDENCY:
case StateDB.relationType.DEPENDENCY:
return 'dependency';
}
};
@@ -459,7 +459,7 @@ export const drawEdge = function (elem, path, relation) {
svgPath.attr(
'marker-end',
'url(' + url + '#' + getRelationType(stateDb.relationType.DEPENDENCY) + 'End' + ')'
'url(' + url + '#' + getRelationType(StateDB.relationType.DEPENDENCY) + 'End' + ')'
);
if (relation.title !== undefined) {

View File

@@ -3,11 +3,14 @@
*/
// default diagram direction
export const DEFAULT_DIAGRAM_DIRECTION = 'LR';
export const DEFAULT_DIAGRAM_DIRECTION = 'TB';
// default direction for any nested documents (composites)
export const DEFAULT_NESTED_DOC_DIR = 'TB';
// parsed statement type for a direction
export const STMT_DIRECTION = 'dir';
// parsed statement type for a state
export const STMT_STATE = 'state';
// parsed statement type for a relation

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,9 @@
import stateDb from './stateDb.js';
import { StateDB } from './stateDb.js';
describe('State Diagram stateDb', () => {
let stateDb;
beforeEach(() => {
stateDb.clear();
stateDb = new StateDB(1);
});
describe('addStyleClass', () => {
@@ -20,8 +21,9 @@ describe('State Diagram stateDb', () => {
});
describe('addDescription to a state', () => {
let stateDb;
beforeEach(() => {
stateDb.clear();
stateDb = new StateDB(1);
stateDb.addState('state1');
});
@@ -73,3 +75,25 @@ describe('State Diagram stateDb', () => {
});
});
});
describe('state db class', () => {
let stateDb;
beforeEach(() => {
stateDb = new StateDB(1);
});
// This is to ensure that functions used in state JISON are exposed as function from StateDb
it('should have functions used in flow JISON as own property', () => {
const functionsUsedInParser = [
'setRootDoc',
'trimColon',
'getDividerId',
'setAccTitle',
'setAccDescription',
'setDirection',
];
for (const fun of functionsUsedInParser) {
expect(Object.hasOwn(stateDb, fun)).toBe(true);
}
});
});

View File

@@ -1,11 +1,13 @@
import { parser } from './parser/stateDiagram.jison';
import stateDb from './stateDb.js';
import stateDiagram from './parser/stateDiagram.jison';
import stateDiagram, { parser } from './parser/stateDiagram.jison';
import { DEFAULT_DIAGRAM_DIRECTION } from './stateCommon.js';
import { StateDB } from './stateDb.js';
describe('state diagram V2, ', function () {
// TODO - these examples should be put into ./parser/stateDiagram.spec.js
describe('when parsing an info graph it', function () {
let stateDb;
beforeEach(function () {
stateDb = new StateDB(2);
parser.yy = stateDb;
stateDiagram.parser.yy = stateDb;
stateDiagram.parser.yy.clear();
@@ -127,7 +129,6 @@ describe('state diagram V2, ', function () {
`;
stateDiagram.parser.parse(diagram);
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
const rels = stateDb.getRelations();
const rel_1_2 = rels.find((rel) => rel.id1 === 'State1' && rel.id2 === 'State2');
@@ -402,7 +403,6 @@ describe('state diagram V2, ', function () {
`;
stateDiagram.parser.parse(diagram);
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
const states = stateDb.getStates();
expect(states.get('Active').doc[0].id).toEqual('Idle');
@@ -413,5 +413,34 @@ describe('state diagram V2, ', function () {
const rel_Active_Active = rels.find((rel) => rel.id1 === 'Active' && rel.id2 === 'Active');
expect(rel_Active_Active.relationTitle).toEqual('LOG');
});
it('should check default diagram direction', () => {
const diagram = `
stateDiagram
[*] --> Still
Still --> [*]
`;
parser.parse(diagram);
// checking default direction if no direction is specified
const defaultDir = stateDb.getDirection();
expect(defaultDir).toEqual(DEFAULT_DIAGRAM_DIRECTION);
});
it('retrieve the diagram direction correctly', () => {
const diagram = `
stateDiagram
direction LR
[*] --> Still
Still --> [*]
`;
parser.parse(diagram);
//retrieve the diagram direction
const currentDirection = stateDb.getDirection();
expect(currentDirection).toEqual('LR');
});
});
});

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