mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-10-26 08:24:07 +01:00
Compare commits
215 Commits
848f69a75c
...
6671-code-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f8e71102fd | ||
|
|
642b781317 | ||
|
|
4d26480075 | ||
|
|
f35aae313c | ||
|
|
d0cabd080f | ||
|
|
c9eae01d06 | ||
|
|
df9abe0be9 | ||
|
|
c33484f9bc | ||
|
|
82800a2c84 | ||
|
|
27e700debd | ||
|
|
01e47333d5 | ||
|
|
d47ba7c2d1 | ||
|
|
b1c4eb3f5c | ||
|
|
310fcd2292 | ||
|
|
04b6fc1280 | ||
|
|
f46a151075 | ||
|
|
b7e9d02b7c | ||
|
|
00f5700320 | ||
|
|
e32dc8513f | ||
|
|
50127f3ffe | ||
|
|
29bb0e3dca | ||
|
|
1221de4c2d | ||
|
|
c41e08cb7a | ||
|
|
4760ed8893 | ||
|
|
31ecf31c2e | ||
|
|
b52766653c | ||
|
|
6d9fad01a9 | ||
|
|
8322a63598 | ||
|
|
075e1b5e1f | ||
|
|
3c9bd7be29 | ||
|
|
6995248443 | ||
|
|
93467a6fce | ||
|
|
95d48e3497 | ||
|
|
29886b8dd4 | ||
|
|
e438e035bc | ||
|
|
2bc5b6d2fa | ||
|
|
e0b45c2d2b | ||
|
|
d4c76968e9 | ||
|
|
2cfebef122 | ||
|
|
c0e2d4a23b | ||
|
|
7171237b96 | ||
|
|
066883f4cd | ||
|
|
7bdcf93412 | ||
|
|
d86e46b705 | ||
|
|
96778f7789 | ||
|
|
d4c058bd56 | ||
|
|
b638a0a9c1 | ||
|
|
fd9aa36c77 | ||
|
|
46a9f1b31e | ||
|
|
83c6224cc0 | ||
|
|
d8161b1923 | ||
|
|
8223141af9 | ||
|
|
99f98a6876 | ||
|
|
ef28f548df | ||
|
|
e448c53b53 | ||
|
|
71e09bcaef | ||
|
|
cad144734d | ||
|
|
5e57f22e23 | ||
|
|
fc2c32603d | ||
|
|
8c7da5af56 | ||
|
|
4b89af3aca | ||
|
|
c534d3d364 | ||
|
|
4db72f5357 | ||
|
|
2aa8330279 | ||
|
|
803e2e14be | ||
|
|
685516a85e | ||
|
|
880f7454a3 | ||
|
|
cba659d097 | ||
|
|
f7a0844a31 | ||
|
|
2817383714 | ||
|
|
1f46c9e9bb | ||
|
|
ec7099dc27 | ||
|
|
e6ee145edf | ||
|
|
5cc264feb7 | ||
|
|
690cc73259 | ||
|
|
b9ef683fb6 | ||
|
|
6a6289f2aa | ||
|
|
accb4c6369 | ||
|
|
52be254ad3 | ||
|
|
9c071a9064 | ||
|
|
91d7229f1b | ||
|
|
60feec465b | ||
|
|
d1ae687d1e | ||
|
|
7af6723ac0 | ||
|
|
da90f6760b | ||
|
|
d74013c642 | ||
|
|
ce996346f8 | ||
|
|
29edfa7f56 | ||
|
|
14a4ab81c9 | ||
|
|
13d72262d9 | ||
|
|
62dee0bad4 | ||
|
|
9e81e1146a | ||
|
|
2260948b7b | ||
|
|
186429ae32 | ||
|
|
657a9ef785 | ||
|
|
4f24489d81 | ||
|
|
2a514fa69e | ||
|
|
80c6faf4d5 | ||
|
|
9f6ee53382 | ||
|
|
3248bf3da4 | ||
|
|
bf3ca9d1ef | ||
|
|
e7a7ff8a2a | ||
|
|
68fc68c239 | ||
|
|
e53c17a012 | ||
|
|
bb2d6973ba | ||
|
|
769b362005 | ||
|
|
e4d3aa4610 | ||
|
|
716548548a | ||
|
|
aeaf626bb5 | ||
|
|
9322771b5c | ||
|
|
2fe3063bf5 | ||
|
|
4e55a45b1b | ||
|
|
4bece53a3c | ||
|
|
3d319824a6 | ||
|
|
aa5d443a46 | ||
|
|
356da0b4d7 | ||
|
|
22530a8bdf | ||
|
|
e6574ef40c | ||
|
|
c4eb526162 | ||
|
|
4d62d59632 | ||
|
|
5af489d8dd | ||
|
|
297be4a868 | ||
|
|
fb6ace73b5 | ||
|
|
096fbe933e | ||
|
|
e539909e87 | ||
|
|
074701e316 | ||
|
|
cfc76ef1cb | ||
|
|
bf362673fc | ||
|
|
d042b21b12 | ||
|
|
677ff82d13 | ||
|
|
4b31361506 | ||
|
|
981829a426 | ||
|
|
327a5aa9fd | ||
|
|
20a18971ea | ||
|
|
e1e36dfcb3 | ||
|
|
165ffefad5 | ||
|
|
9258b2933b | ||
|
|
f5445b266e | ||
|
|
7a1530d911 | ||
|
|
e32e80ea7f | ||
|
|
3256807d25 | ||
|
|
0133f1c0c5 | ||
|
|
12e01bdb5c | ||
|
|
a776b4f0ab | ||
|
|
8d79bc9b19 | ||
|
|
ecf7ab4355 | ||
|
|
c61a431e2d | ||
|
|
526b35c602 | ||
|
|
8090580c67 | ||
|
|
9d685178d2 | ||
|
|
b451c66d7c | ||
|
|
1dd11705d9 | ||
|
|
17142ef8d7 | ||
|
|
29de40478f | ||
|
|
bcd3e33243 | ||
|
|
b2754bc553 | ||
|
|
b65a73f432 | ||
|
|
a14cd0e2a1 | ||
|
|
0823e08a54 | ||
|
|
5cafe241d0 | ||
|
|
c847817a54 | ||
|
|
3ab0961bdc | ||
|
|
0892870b5d | ||
|
|
500f90a105 | ||
|
|
14983158a2 | ||
|
|
3fea9e8759 | ||
|
|
e5ea2ed0b1 | ||
|
|
34e7f9704b | ||
|
|
1176d30668 | ||
|
|
6728852b7a | ||
|
|
15e7c890ed | ||
|
|
0451e343ef | ||
|
|
a2dbc8e4b3 | ||
|
|
aea16eaf7e | ||
|
|
bb7cd70034 | ||
|
|
35a92efcdc | ||
|
|
fce7cabb71 | ||
|
|
38e6dc497a | ||
|
|
5f0c53c8a7 | ||
|
|
f9da4433ff | ||
|
|
fc07f0d8ab | ||
|
|
ce7a487dfc | ||
|
|
8c0d12027d | ||
|
|
ea72740d1f | ||
|
|
427dc38857 | ||
|
|
ec21042c53 | ||
|
|
4a86b68e01 | ||
|
|
1414380181 | ||
|
|
6686ee9253 | ||
|
|
7f109c7b94 | ||
|
|
b9c3375be3 | ||
|
|
4254bdd473 | ||
|
|
4012cbf013 | ||
|
|
8693be56ee | ||
|
|
814b68b4a9 | ||
|
|
bfa0eefa32 | ||
|
|
579c22cf5d | ||
|
|
33e08daf17 | ||
|
|
24257de8a6 | ||
|
|
42ac1848dd | ||
|
|
3920ad442d | ||
|
|
53d27b771d | ||
|
|
2c0931da46 | ||
|
|
8224a81ab6 | ||
|
|
98442294ed | ||
|
|
a3d164fde8 | ||
|
|
9dc987b28b | ||
|
|
72c0d9df26 | ||
|
|
cfbce54638 | ||
|
|
6979aa1013 | ||
|
|
ea60525988 | ||
|
|
9da6fb39ae | ||
|
|
83b9a17277 | ||
|
|
6cc192680a | ||
|
|
3dd6107e76 |
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
'@mermaid-js/mermaid-zenuml': patch
|
|
||||||
---
|
|
||||||
|
|
||||||
Fixed a critical bug that the ZenUML diagram is not rendered.
|
|
||||||
5
.changeset/crazy-loops-matter.md
Normal file
5
.changeset/crazy-loops-matter.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'mermaid': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: Handle arrows correctly when auto number is enabled
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
'mermaid': patch
|
|
||||||
---
|
|
||||||
|
|
||||||
fix: Update casing of ID in requirement diagram
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
'mermaid': minor
|
|
||||||
---
|
|
||||||
|
|
||||||
feat: Added support for per link curve styling in flowchart diagram using edge ids
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
'mermaid': patch
|
|
||||||
---
|
|
||||||
|
|
||||||
fix: Make flowchart elk detector regex match less greedy
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
---
|
|
||||||
'mermaid': patch
|
|
||||||
---
|
|
||||||
|
|
||||||
fix(block): overflowing blocks no longer affect later lines
|
|
||||||
|
|
||||||
This may change the layout of block diagrams that have overflowing lines
|
|
||||||
(i.e. block diagrams that use up more columns that the `columns` specifier).
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
---
|
|
||||||
'mermaid': patch
|
|
||||||
---
|
|
||||||
|
|
||||||
fix: log warning for blocks exceeding column width
|
|
||||||
|
|
||||||
This update adds a validation check that logs a warning message when a block's width exceeds the defined column layout.
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
'mermaid': patch
|
|
||||||
---
|
|
||||||
|
|
||||||
fix: Add escaped class literal name on namespace
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
'mermaid': patch
|
|
||||||
---
|
|
||||||
|
|
||||||
chore: migrate to class-based ArchitectureDB implementation
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
'mermaid': patch
|
|
||||||
---
|
|
||||||
|
|
||||||
fix: Update flowchart direction TD's behavior to be the same as TB
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
'mermaid': patch
|
|
||||||
---
|
|
||||||
|
|
||||||
chore: Update packet diagram to use new class-based database structure
|
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
Ashish Jain
|
Ashish Jain
|
||||||
cpettitt
|
cpettitt
|
||||||
Dong Cai
|
Dong Cai
|
||||||
|
fourcube
|
||||||
knsv
|
knsv
|
||||||
Knut Sveidqvist
|
Knut Sveidqvist
|
||||||
Nikolay Rozhkov
|
Nikolay Rozhkov
|
||||||
|
|||||||
1
.github/lychee.toml
vendored
1
.github/lychee.toml
vendored
@@ -59,6 +59,7 @@ exclude = [
|
|||||||
"https://huehive.co",
|
"https://huehive.co",
|
||||||
"https://foswiki.org",
|
"https://foswiki.org",
|
||||||
"https://www.gnu.org",
|
"https://www.gnu.org",
|
||||||
|
"https://redmine.org",
|
||||||
"https://mermaid-preview.com"
|
"https://mermaid-preview.com"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
3
.github/workflows/e2e-applitools.yml
vendored
3
.github/workflows/e2e-applitools.yml
vendored
@@ -23,9 +23,6 @@ env:
|
|||||||
jobs:
|
jobs:
|
||||||
e2e-applitools:
|
e2e-applitools:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
|
||||||
image: cypress/browsers:node-20.11.0-chrome-121.0.6167.85-1-ff-120.0-edge-121.0.2277.83-1
|
|
||||||
options: --user 1001
|
|
||||||
steps:
|
steps:
|
||||||
- if: ${{ ! env.USE_APPLI }}
|
- if: ${{ ! env.USE_APPLI }}
|
||||||
name: Warn if not using Applitools
|
name: Warn if not using Applitools
|
||||||
|
|||||||
2
.github/workflows/e2e-timings.yml
vendored
2
.github/workflows/e2e-timings.yml
vendored
@@ -58,7 +58,7 @@ jobs:
|
|||||||
echo "EOF" >> $GITHUB_OUTPUT
|
echo "EOF" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Commit and create pull request
|
- name: Commit and create pull request
|
||||||
uses: peter-evans/create-pull-request@07cbaebb4bfc9c5d7db426ea5a5f585df29dd0a0
|
uses: peter-evans/create-pull-request@18e469570b1cf0dfc11d60ec121099f8ff3e617a
|
||||||
with:
|
with:
|
||||||
add-paths: |
|
add-paths: |
|
||||||
cypress/timings.json
|
cypress/timings.json
|
||||||
|
|||||||
114
.github/workflows/e2e.yml
vendored
114
.github/workflows/e2e.yml
vendored
@@ -38,6 +38,8 @@ jobs:
|
|||||||
options: --user 1001
|
options: --user 1001
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
- uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
|
- uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
|
||||||
- name: Setup Node.js
|
- name: Setup Node.js
|
||||||
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
||||||
@@ -55,6 +57,7 @@ jobs:
|
|||||||
if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' }}
|
if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' }}
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
with:
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
ref: ${{ env.targetHash }}
|
ref: ${{ env.targetHash }}
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
@@ -83,6 +86,8 @@ jobs:
|
|||||||
containers: [1, 2, 3, 4, 5]
|
containers: [1, 2, 3, 4, 5]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
- uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
|
- uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
|
||||||
# uses version from "packageManager" field in package.json
|
# uses version from "packageManager" field in package.json
|
||||||
@@ -137,13 +142,118 @@ jobs:
|
|||||||
SPLIT_INDEX: ${{ strategy.job-index }}
|
SPLIT_INDEX: ${{ strategy.job-index }}
|
||||||
SPLIT_FILE: 'cypress/timings.json'
|
SPLIT_FILE: 'cypress/timings.json'
|
||||||
VITEST_COVERAGE: true
|
VITEST_COVERAGE: true
|
||||||
|
- name: Debug coverage generation
|
||||||
|
if: ${{ steps.cypress.conclusion == 'success' }}
|
||||||
|
run: |
|
||||||
|
echo "Checking if coverage files were generated:"
|
||||||
|
ls -la coverage/ || echo "No coverage directory"
|
||||||
|
ls -la coverage/cypress/ || echo "No coverage/cypress directory"
|
||||||
|
echo "Looking for any .info files:"
|
||||||
|
find . -name "*.info" -type f | head -10 || echo "No .info files found"
|
||||||
|
- name: Prepare coverage artifacts
|
||||||
|
if: ${{ steps.cypress.conclusion == 'success' }}
|
||||||
|
run: |
|
||||||
|
mkdir -p coverage/cypress
|
||||||
|
if [ -f coverage/cypress/coverage-final.json ]; then
|
||||||
|
cp coverage/cypress/coverage-final.json coverage/cypress/coverage-final-${{ matrix.containers }}.json
|
||||||
|
echo "Created coverage-final-${{ matrix.containers }}.json"
|
||||||
|
ls -la coverage/cypress/coverage-final-${{ matrix.containers }}.json
|
||||||
|
else
|
||||||
|
echo "Error: coverage/cypress/coverage-final.json not found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
- name: Upload e2e coverage artifact
|
||||||
|
if: ${{ steps.cypress.conclusion == 'success' }}
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: e2e-coverage-${{ matrix.containers }}
|
||||||
|
path: coverage/cypress/coverage-final-${{ matrix.containers }}.json
|
||||||
|
|
||||||
|
coverage-merge:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: e2e
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
||||||
|
with:
|
||||||
|
node-version-file: '.node-version'
|
||||||
|
- name: Download e2e coverage shards
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
pattern: e2e-coverage-*
|
||||||
|
path: coverage/e2e-shards
|
||||||
|
merge-multiple: true
|
||||||
|
- name: Debug downloaded artifacts
|
||||||
|
run: |
|
||||||
|
echo "Contents of coverage/e2e-shards:"
|
||||||
|
find coverage/e2e-shards -type f -name "*.info" | head -20
|
||||||
|
echo "All files in coverage/e2e-shards:"
|
||||||
|
ls -la coverage/e2e-shards/
|
||||||
|
echo "Directory structure:"
|
||||||
|
find coverage/e2e-shards -type f | head -20
|
||||||
|
echo "Looking for coverage-final.json files:"
|
||||||
|
find coverage/e2e-shards -name "coverage-final.json" | head -20
|
||||||
|
- name: Install dependencies for merging
|
||||||
|
run: pnpm install --frozen-lockfile
|
||||||
|
env:
|
||||||
|
CYPRESS_CACHE_FOLDER: .cache/Cypress
|
||||||
|
- name: Prepare coverage files for merge script
|
||||||
|
run: |
|
||||||
|
mkdir -p coverage/vitest coverage/cypress
|
||||||
|
# Copy E2E coverage-final.json files to the structure expected by scripts/coverage.ts
|
||||||
|
for i in {1..5}; do
|
||||||
|
if [ -f "coverage/e2e-shards/coverage-final-$i.json" ]; then
|
||||||
|
cp "coverage/e2e-shards/coverage-final-$i.json" "coverage/cypress/coverage-final.json"
|
||||||
|
echo "Copied coverage-final-$i.json to cypress/"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
# Create a minimal but valid vitest coverage-final.json
|
||||||
|
echo '{"type":"Coverage","version":"1.1","data":{}}' > coverage/vitest/coverage-final.json
|
||||||
|
echo "Prepared coverage files:"
|
||||||
|
ls -la coverage/vitest/
|
||||||
|
ls -la coverage/cypress/
|
||||||
|
echo "Checking file contents:"
|
||||||
|
echo "Vitest coverage file:"
|
||||||
|
cat coverage/vitest/coverage-final.json
|
||||||
|
echo "Cypress coverage file:"
|
||||||
|
cat coverage/cypress/coverage-final.json
|
||||||
|
echo "Validating JSON files:"
|
||||||
|
if jq . coverage/vitest/coverage-final.json > /dev/null; then
|
||||||
|
echo "✓ Vitest coverage file is valid JSON"
|
||||||
|
else
|
||||||
|
echo "✗ Vitest coverage file is invalid JSON"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if jq . coverage/cypress/coverage-final.json > /dev/null; then
|
||||||
|
echo "✓ Cypress coverage file is valid JSON"
|
||||||
|
else
|
||||||
|
echo "✗ Cypress coverage file is invalid JSON"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
- name: Generate LCOV from coverage data
|
||||||
|
run: |
|
||||||
|
mkdir -p coverage/combined
|
||||||
|
# Convert coverage-final.json to LCOV format using nyc
|
||||||
|
if [ -f coverage/cypress/coverage-final.json ]; then
|
||||||
|
echo "Converting Cypress coverage to LCOV..."
|
||||||
|
npx nyc report --reporter=lcov --report-dir=coverage/combined --cwd=. --temp-dir=coverage/cypress
|
||||||
|
echo "LCOV generation completed"
|
||||||
|
ls -la coverage/combined/
|
||||||
|
else
|
||||||
|
echo "No Cypress coverage file found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
- name: Upload Coverage to Codecov
|
- name: Upload Coverage to Codecov
|
||||||
uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # v5.3.1
|
uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # v5.3.1
|
||||||
# Run step only pushes to develop and pull_requests
|
# Run step only pushes to develop and pull_requests
|
||||||
if: ${{ steps.cypress.conclusion == 'success' && (github.event_name == 'pull_request' || github.ref == 'refs/heads/develop')}}
|
if: ${{ github.event_name == 'pull_request' || github.ref == 'refs/heads/develop'}}
|
||||||
with:
|
with:
|
||||||
files: coverage/cypress/lcov.info
|
files: coverage/combined/lcov.info
|
||||||
flags: e2e
|
flags: e2e
|
||||||
name: mermaid-codecov
|
name: mermaid-codecov
|
||||||
fail_ci_if_error: false
|
fail_ci_if_error: false
|
||||||
|
|||||||
3
.github/workflows/test.yml
vendored
3
.github/workflows/test.yml
vendored
@@ -10,6 +10,8 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
- uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
|
- uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
|
||||||
# uses version from "packageManager" field in package.json
|
# uses version from "packageManager" field in package.json
|
||||||
@@ -41,7 +43,6 @@ jobs:
|
|||||||
- name: Verify out-of-tree build with TypeScript
|
- name: Verify out-of-tree build with TypeScript
|
||||||
run: |
|
run: |
|
||||||
pnpm test:check:tsc
|
pnpm test:check:tsc
|
||||||
|
|
||||||
- name: Upload Coverage to Codecov
|
- name: Upload Coverage to Codecov
|
||||||
uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # v5.3.1
|
uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # v5.3.1
|
||||||
# Run step only pushes to develop and pull_requests
|
# Run step only pushes to develop and pull_requests
|
||||||
|
|||||||
14
.nycrc
Normal file
14
.nycrc
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"reporter": ["text", "lcov", "json", "html"],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules/**/*",
|
||||||
|
"cypress/**/*",
|
||||||
|
"coverage/**/*",
|
||||||
|
"**/*.spec.js",
|
||||||
|
"**/*.spec.ts",
|
||||||
|
"**/*.test.js",
|
||||||
|
"**/*.test.ts"
|
||||||
|
],
|
||||||
|
"all": true,
|
||||||
|
"check-coverage": false
|
||||||
|
}
|
||||||
27
codecov.yml
Normal file
27
codecov.yml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
coverage:
|
||||||
|
status:
|
||||||
|
project:
|
||||||
|
default:
|
||||||
|
target: auto
|
||||||
|
threshold: 1%
|
||||||
|
patch:
|
||||||
|
default:
|
||||||
|
target: auto
|
||||||
|
threshold: 1%
|
||||||
|
|
||||||
|
comment:
|
||||||
|
layout: 'reach,diff,flags,tree'
|
||||||
|
behavior: default
|
||||||
|
require_changes: false
|
||||||
|
|
||||||
|
flags:
|
||||||
|
unit:
|
||||||
|
paths:
|
||||||
|
- packages/
|
||||||
|
e2e:
|
||||||
|
paths:
|
||||||
|
- packages/
|
||||||
|
|
||||||
|
# Wait for both unit and e2e coverage uploads before finalizing
|
||||||
|
notify:
|
||||||
|
after_n_builds: 2
|
||||||
@@ -15,6 +15,13 @@ export default eyesPlugin(
|
|||||||
setupNodeEvents(on, config) {
|
setupNodeEvents(on, config) {
|
||||||
coverage(on, config);
|
coverage(on, config);
|
||||||
cypressSplit(on, config);
|
cypressSplit(on, config);
|
||||||
|
|
||||||
|
// Ensure coverage generates LCOV format
|
||||||
|
on('task', {
|
||||||
|
coverage: () => {
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
});
|
||||||
on('before:browser:launch', (browser, launchOptions) => {
|
on('before:browser:launch', (browser, launchOptions) => {
|
||||||
if (browser.name === 'chrome' && browser.isHeadless) {
|
if (browser.name === 'chrome' && browser.isHeadless) {
|
||||||
launchOptions.args.push('--window-size=1440,1024', '--force-device-scale-factor=1');
|
launchOptions.args.push('--window-size=1440,1024', '--force-device-scale-factor=1');
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ interface CodeObject {
|
|||||||
mermaid: CypressMermaidConfig;
|
mermaid: CypressMermaidConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
const utf8ToB64 = (str: string): string => {
|
export const utf8ToB64 = (str: string): string => {
|
||||||
return Buffer.from(decodeURIComponent(encodeURIComponent(str))).toString('base64');
|
return Buffer.from(decodeURIComponent(encodeURIComponent(str))).toString('base64');
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ const batchId: string =
|
|||||||
'mermaid-batch-' +
|
'mermaid-batch-' +
|
||||||
(Cypress.env('useAppli')
|
(Cypress.env('useAppli')
|
||||||
? Date.now().toString()
|
? Date.now().toString()
|
||||||
: Cypress.env('CYPRESS_COMMIT') || Date.now().toString());
|
: (Cypress.env('CYPRESS_COMMIT') ?? Date.now().toString()));
|
||||||
|
|
||||||
export const mermaidUrl = (
|
export const mermaidUrl = (
|
||||||
graphStr: string | string[],
|
graphStr: string | string[],
|
||||||
@@ -61,9 +61,7 @@ export const imgSnapshotTest = (
|
|||||||
sequence: {
|
sequence: {
|
||||||
...(_options.sequence ?? {}),
|
...(_options.sequence ?? {}),
|
||||||
actorFontFamily: 'courier',
|
actorFontFamily: 'courier',
|
||||||
noteFontFamily: _options.sequence?.noteFontFamily
|
noteFontFamily: _options.sequence?.noteFontFamily ?? 'courier',
|
||||||
? _options.sequence.noteFontFamily
|
|
||||||
: 'courier',
|
|
||||||
messageFontFamily: 'courier',
|
messageFontFamily: 'courier',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { mermaidUrl } from '../../helpers/util.ts';
|
import { imgSnapshotTest, mermaidUrl, utf8ToB64 } from '../../helpers/util.ts';
|
||||||
describe('XSS', () => {
|
describe('XSS', () => {
|
||||||
it('should handle xss in tags', () => {
|
it('should handle xss in tags', () => {
|
||||||
const str =
|
const str =
|
||||||
@@ -141,4 +141,37 @@ describe('XSS', () => {
|
|||||||
cy.wait(1000);
|
cy.wait(1000);
|
||||||
cy.get('#the-malware').should('not.exist');
|
cy.get('#the-malware').should('not.exist');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should sanitize icon labels in architecture diagrams', () => {
|
||||||
|
const str = JSON.stringify({
|
||||||
|
code: `architecture-beta
|
||||||
|
group api(cloud)[API]
|
||||||
|
service db "<img src=x onerror=\\"xssAttack()\\">" [Database] in api`,
|
||||||
|
});
|
||||||
|
imgSnapshotTest(utf8ToB64(str), {}, true);
|
||||||
|
cy.wait(1000);
|
||||||
|
cy.get('#the-malware').should('not.exist');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should sanitize katex blocks', () => {
|
||||||
|
const str = JSON.stringify({
|
||||||
|
code: `sequenceDiagram
|
||||||
|
participant A as Alice<img src="x" onerror="xssAttack()">$$\\text{Alice}$$
|
||||||
|
A->>John: Hello John, how are you?`,
|
||||||
|
});
|
||||||
|
imgSnapshotTest(utf8ToB64(str), {}, true);
|
||||||
|
cy.wait(1000);
|
||||||
|
cy.get('#the-malware').should('not.exist');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should sanitize labels', () => {
|
||||||
|
const str = JSON.stringify({
|
||||||
|
code: `erDiagram
|
||||||
|
"<img src=x onerror=xssAttack()>" ||--|| ENTITY2 : "<img src=x onerror=xssAttack()>"
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
imgSnapshotTest(utf8ToB64(str), {}, true);
|
||||||
|
cy.wait(1000);
|
||||||
|
cy.get('#the-malware').should('not.exist');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL2: should handle columns statement in sub-blocks', () => {
|
it('BL2: should handle columns statement in sub-blocks', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block-beta
|
`block
|
||||||
id1["Hello"]
|
id1["Hello"]
|
||||||
block
|
block
|
||||||
columns 3
|
columns 3
|
||||||
@@ -32,7 +32,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL3: should align block widths and handle columns statement in sub-blocks', () => {
|
it('BL3: should align block widths and handle columns statement in sub-blocks', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block-beta
|
`block
|
||||||
block
|
block
|
||||||
columns 1
|
columns 1
|
||||||
id1
|
id1
|
||||||
@@ -48,7 +48,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL4: should align block widths and handle columns statements in deeper sub-blocks then 1 level', () => {
|
it('BL4: should align block widths and handle columns statements in deeper sub-blocks then 1 level', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block-beta
|
`block
|
||||||
columns 1
|
columns 1
|
||||||
block
|
block
|
||||||
columns 1
|
columns 1
|
||||||
@@ -68,7 +68,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL5: should align block widths and handle columns statements in deeper sub-blocks then 1 level (alt)', () => {
|
it('BL5: should align block widths and handle columns statements in deeper sub-blocks then 1 level (alt)', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block-beta
|
`block
|
||||||
columns 1
|
columns 1
|
||||||
block
|
block
|
||||||
id1
|
id1
|
||||||
@@ -87,7 +87,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL6: should handle block arrows and spece statements', () => {
|
it('BL6: should handle block arrows and spece statements', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block-beta
|
`block
|
||||||
columns 3
|
columns 3
|
||||||
space:3
|
space:3
|
||||||
ida idb idc
|
ida idb idc
|
||||||
@@ -106,7 +106,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL7: should handle different types of edges', () => {
|
it('BL7: should handle different types of edges', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block-beta
|
`block
|
||||||
columns 3
|
columns 3
|
||||||
A space:5
|
A space:5
|
||||||
A --o B
|
A --o B
|
||||||
@@ -119,7 +119,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL8: should handle sub-blocks without columns statements', () => {
|
it('BL8: should handle sub-blocks without columns statements', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block-beta
|
`block
|
||||||
columns 2
|
columns 2
|
||||||
C A B
|
C A B
|
||||||
block
|
block
|
||||||
@@ -133,7 +133,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL9: should handle edges from blocks in sub blocks to other blocks', () => {
|
it('BL9: should handle edges from blocks in sub blocks to other blocks', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block-beta
|
`block
|
||||||
columns 3
|
columns 3
|
||||||
B space
|
B space
|
||||||
block
|
block
|
||||||
@@ -147,7 +147,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL10: should handle edges from composite blocks', () => {
|
it('BL10: should handle edges from composite blocks', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block-beta
|
`block
|
||||||
columns 3
|
columns 3
|
||||||
B space
|
B space
|
||||||
block BL
|
block BL
|
||||||
@@ -161,7 +161,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL11: should handle edges to composite blocks', () => {
|
it('BL11: should handle edges to composite blocks', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block-beta
|
`block
|
||||||
columns 3
|
columns 3
|
||||||
B space
|
B space
|
||||||
block BL
|
block BL
|
||||||
@@ -175,7 +175,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL12: edges should handle labels', () => {
|
it('BL12: edges should handle labels', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block-beta
|
`block
|
||||||
A
|
A
|
||||||
space
|
space
|
||||||
A -- "apa" --> E
|
A -- "apa" --> E
|
||||||
@@ -186,7 +186,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL13: should handle block arrows in different directions', () => {
|
it('BL13: should handle block arrows in different directions', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block-beta
|
`block
|
||||||
columns 3
|
columns 3
|
||||||
space blockArrowId1<["down"]>(down) space
|
space blockArrowId1<["down"]>(down) space
|
||||||
blockArrowId2<["right"]>(right) blockArrowId3<["Sync"]>(x, y) blockArrowId4<["left"]>(left)
|
blockArrowId2<["right"]>(right) blockArrowId3<["Sync"]>(x, y) blockArrowId4<["left"]>(left)
|
||||||
@@ -199,7 +199,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL14: should style statements and class statements', () => {
|
it('BL14: should style statements and class statements', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block-beta
|
`block
|
||||||
A
|
A
|
||||||
B
|
B
|
||||||
classDef blue fill:#66f,stroke:#333,stroke-width:2px;
|
classDef blue fill:#66f,stroke:#333,stroke-width:2px;
|
||||||
@@ -212,7 +212,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL15: width alignment - D and E should share available space', () => {
|
it('BL15: width alignment - D and E should share available space', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block-beta
|
`block
|
||||||
block
|
block
|
||||||
D
|
D
|
||||||
E
|
E
|
||||||
@@ -225,7 +225,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL16: width alignment - C should be as wide as the composite block', () => {
|
it('BL16: width alignment - C should be as wide as the composite block', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block-beta
|
`block
|
||||||
block
|
block
|
||||||
A("This is the text")
|
A("This is the text")
|
||||||
B
|
B
|
||||||
@@ -238,7 +238,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL17: width alignment - blocks should be equal in width', () => {
|
it('BL17: width alignment - blocks should be equal in width', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block-beta
|
`block
|
||||||
A("This is the text")
|
A("This is the text")
|
||||||
B
|
B
|
||||||
C
|
C
|
||||||
@@ -249,7 +249,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL18: block types 1 - square, rounded and circle', () => {
|
it('BL18: block types 1 - square, rounded and circle', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block-beta
|
`block
|
||||||
A["square"]
|
A["square"]
|
||||||
B("rounded")
|
B("rounded")
|
||||||
C(("circle"))
|
C(("circle"))
|
||||||
@@ -260,7 +260,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL19: block types 2 - odd, diamond and hexagon', () => {
|
it('BL19: block types 2 - odd, diamond and hexagon', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block-beta
|
`block
|
||||||
A>"rect_left_inv_arrow"]
|
A>"rect_left_inv_arrow"]
|
||||||
B{"diamond"}
|
B{"diamond"}
|
||||||
C{{"hexagon"}}
|
C{{"hexagon"}}
|
||||||
@@ -271,7 +271,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL20: block types 3 - stadium', () => {
|
it('BL20: block types 3 - stadium', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block-beta
|
`block
|
||||||
A(["stadium"])
|
A(["stadium"])
|
||||||
`,
|
`,
|
||||||
{}
|
{}
|
||||||
@@ -280,7 +280,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL21: block types 4 - lean right, lean left, trapezoid and inv trapezoid', () => {
|
it('BL21: block types 4 - lean right, lean left, trapezoid and inv trapezoid', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block-beta
|
`block
|
||||||
A[/"lean right"/]
|
A[/"lean right"/]
|
||||||
B[\"lean left"\]
|
B[\"lean left"\]
|
||||||
C[/"trapezoid"\]
|
C[/"trapezoid"\]
|
||||||
@@ -292,7 +292,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL22: block types 1 - square, rounded and circle', () => {
|
it('BL22: block types 1 - square, rounded and circle', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block-beta
|
`block
|
||||||
A["square"]
|
A["square"]
|
||||||
B("rounded")
|
B("rounded")
|
||||||
C(("circle"))
|
C(("circle"))
|
||||||
@@ -303,7 +303,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL23: sizing - it should be possible to make a block wider', () => {
|
it('BL23: sizing - it should be possible to make a block wider', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block-beta
|
`block
|
||||||
A("rounded"):2
|
A("rounded"):2
|
||||||
B:2
|
B:2
|
||||||
C
|
C
|
||||||
@@ -314,7 +314,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL24: sizing - it should be possible to make a composite block wider', () => {
|
it('BL24: sizing - it should be possible to make a composite block wider', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block-beta
|
`block
|
||||||
block:2
|
block:2
|
||||||
A
|
A
|
||||||
end
|
end
|
||||||
@@ -326,7 +326,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL25: block in the middle with space on each side', () => {
|
it('BL25: block in the middle with space on each side', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block-beta
|
`block
|
||||||
columns 3
|
columns 3
|
||||||
space
|
space
|
||||||
middle["In the middle"]
|
middle["In the middle"]
|
||||||
@@ -337,7 +337,7 @@ describe('Block diagram', () => {
|
|||||||
});
|
});
|
||||||
it('BL26: space and an edge', () => {
|
it('BL26: space and an edge', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block-beta
|
`block
|
||||||
columns 5
|
columns 5
|
||||||
A space B
|
A space B
|
||||||
A --x B
|
A --x B
|
||||||
@@ -347,7 +347,7 @@ describe('Block diagram', () => {
|
|||||||
});
|
});
|
||||||
it('BL27: block sizes for regular blocks', () => {
|
it('BL27: block sizes for regular blocks', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block-beta
|
`block
|
||||||
columns 3
|
columns 3
|
||||||
a["A wide one"] b:2 c:2 d
|
a["A wide one"] b:2 c:2 d
|
||||||
`,
|
`,
|
||||||
@@ -356,7 +356,7 @@ describe('Block diagram', () => {
|
|||||||
});
|
});
|
||||||
it('BL28: composite block with a set width - f should use the available space', () => {
|
it('BL28: composite block with a set width - f should use the available space', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block-beta
|
`block
|
||||||
columns 3
|
columns 3
|
||||||
a:3
|
a:3
|
||||||
block:e:3
|
block:e:3
|
||||||
@@ -370,7 +370,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL29: composite block with a set width - f and g should split the available space', () => {
|
it('BL29: composite block with a set width - f and g should split the available space', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block-beta
|
`block
|
||||||
columns 3
|
columns 3
|
||||||
a:3
|
a:3
|
||||||
block:e:3
|
block:e:3
|
||||||
@@ -393,6 +393,17 @@ describe('Block diagram', () => {
|
|||||||
overflow:3
|
overflow:3
|
||||||
short:1
|
short:1
|
||||||
also_overflow:2
|
also_overflow:2
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('BL31: edge without arrow syntax should render with no arrowheads', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`block-beta
|
||||||
|
a
|
||||||
|
b
|
||||||
|
a --- b
|
||||||
`,
|
`,
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1053,6 +1053,21 @@ flowchart LR
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('6647-elk: should keep node order when using elk layout unless it would add crossings', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`---
|
||||||
|
config:
|
||||||
|
layout: elk
|
||||||
|
---
|
||||||
|
flowchart TB
|
||||||
|
a --> a1 & a2 & a3 & a4
|
||||||
|
b --> b1 & b2
|
||||||
|
b2 --> b3
|
||||||
|
b1 --> b4
|
||||||
|
`
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Title and arrow styling #4813', () => {
|
describe('Title and arrow styling #4813', () => {
|
||||||
|
|||||||
@@ -1113,6 +1113,37 @@ end
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
describe('Flowchart Node Shape Rendering', () => {
|
||||||
|
it('should render a stadium-shaped node', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`flowchart TB
|
||||||
|
A(["Start"]) --> n1["Untitled Node"]
|
||||||
|
A --> n2["Untitled Node"]
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('should render a diamond-shaped node using shape config', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`flowchart BT
|
||||||
|
n2["Untitled Node"] --> n1["Diamond"]
|
||||||
|
n1@{ shape: diam}
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('should render a rounded rectangle and a normal rectangle', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`flowchart BT
|
||||||
|
n2["Untitled Node"] --> n1["Rounded Rectangle"]
|
||||||
|
n3["Untitled Node"] --> n1
|
||||||
|
n1@{ shape: rounded}
|
||||||
|
n3@{ shape: rect}
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('6617: Per Link Curve Styling using edge Ids', () => {
|
it('6617: Per Link Curve Styling using edge Ids', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
@@ -1133,4 +1164,26 @@ end
|
|||||||
`
|
`
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('when rendering unsuported markdown', () => {
|
||||||
|
const graph = `flowchart TB
|
||||||
|
mermaid{"What is\nyourmermaid version?"} --> v10["<11"] --"\`<**1**1\`"--> fine["No bug"]
|
||||||
|
mermaid --> v11[">= v11"] -- ">= v11" --> broken["Affected by https://github.com/mermaid-js/mermaid/issues/5824"]
|
||||||
|
subgraph subgraph1["\`How to fix **fix**\`"]
|
||||||
|
broken --> B["B"]
|
||||||
|
end
|
||||||
|
githost["Github, Gitlab, BitBucket, etc."]
|
||||||
|
githost2["\`Github, Gitlab, BitBucket, etc.\`"]
|
||||||
|
a["1."]
|
||||||
|
b["- x"]
|
||||||
|
`;
|
||||||
|
|
||||||
|
it('should render raw strings', () => {
|
||||||
|
imgSnapshotTest(graph);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render raw strings with htmlLabels: false', () => {
|
||||||
|
imgSnapshotTest(graph, { htmlLabels: false });
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -565,6 +565,18 @@ describe('Gantt diagram', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should render only the day when using dateFormat D', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
gantt
|
||||||
|
title Test
|
||||||
|
dateFormat D
|
||||||
|
A :a, 1, 1d
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
// TODO: fix it
|
// TODO: fix it
|
||||||
//
|
//
|
||||||
// This test is skipped deliberately
|
// This test is skipped deliberately
|
||||||
@@ -647,6 +659,49 @@ describe('Gantt diagram', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should render a gantt diagram excluding a specific date in YYYY-MM-DD HH:mm:ss format', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
gantt
|
||||||
|
dateFormat YYYY-MM-DD HH:mm:ss
|
||||||
|
excludes 2025-07-07
|
||||||
|
section Section
|
||||||
|
A task :a1, 2025-07-04 20:30:30, 2025-07-08 10:30:30
|
||||||
|
Another task:after a1, 20h
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render a gantt diagram excluding saturday and sunday in YYYY-MM-DD HH:mm:ss format', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
gantt
|
||||||
|
dateFormat YYYY-MM-DD HH:mm:ss
|
||||||
|
excludes weekends
|
||||||
|
weekend saturday
|
||||||
|
section Section
|
||||||
|
A task :a1, 2025-07-04 20:30:30, 2025-07-08 10:30:30
|
||||||
|
Another task:after a1, 20h
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('should render a gantt diagram excluding friday and saturday in YYYY-MM-DD HH:mm:ss format', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
gantt
|
||||||
|
dateFormat YYYY-MM-DD HH:mm:ss
|
||||||
|
excludes weekends
|
||||||
|
weekend friday
|
||||||
|
section Section
|
||||||
|
A task :a1, 2025-07-04 20:30:30, 2025-07-08 10:30:30
|
||||||
|
Another task:after a1, 20h
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it("should render when there's a semicolon in the title", () => {
|
it("should render when there's a semicolon in the title", () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
|
|||||||
@@ -82,4 +82,13 @@ describe('pie chart', () => {
|
|||||||
`
|
`
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
it('should render pie slices only for non-zero values but shows all legends', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
` pie title Pets adopted by volunteers
|
||||||
|
"Dogs" : 386
|
||||||
|
"Cats" : 85
|
||||||
|
"Rats" : 1
|
||||||
|
`
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ describe('Sankey Diagram', () => {
|
|||||||
describe('when given a linkColor', function () {
|
describe('when given a linkColor', function () {
|
||||||
this.beforeAll(() => {
|
this.beforeAll(() => {
|
||||||
cy.wrap(
|
cy.wrap(
|
||||||
`sankey-beta
|
`sankey
|
||||||
a,b,10
|
a,b,10
|
||||||
`
|
`
|
||||||
).as('graph');
|
).as('graph');
|
||||||
@@ -62,7 +62,7 @@ describe('Sankey Diagram', () => {
|
|||||||
this.beforeAll(() => {
|
this.beforeAll(() => {
|
||||||
cy.wrap(
|
cy.wrap(
|
||||||
`
|
`
|
||||||
sankey-beta
|
sankey
|
||||||
|
|
||||||
a,b,8
|
a,b,8
|
||||||
b,c,8
|
b,c,8
|
||||||
|
|||||||
@@ -2,49 +2,50 @@ import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
|
|||||||
|
|
||||||
const looks = ['classic'];
|
const looks = ['classic'];
|
||||||
const participantTypes = [
|
const participantTypes = [
|
||||||
'participant',
|
{ type: 'participant', display: 'participant' },
|
||||||
'actor',
|
{ type: 'actor', display: 'actor' },
|
||||||
'boundary',
|
{ type: 'boundary', display: 'boundary' },
|
||||||
'control',
|
{ type: 'control', display: 'control' },
|
||||||
'entity',
|
{ type: 'entity', display: 'entity' },
|
||||||
'database',
|
{ type: 'database', display: 'database' },
|
||||||
'collections',
|
{ type: 'collections', display: 'collections' },
|
||||||
'queue',
|
{ type: 'queue', display: 'queue' },
|
||||||
];
|
];
|
||||||
|
|
||||||
const interactionTypes = [
|
const restrictedTypes = ['boundary', 'control', 'entity', 'database', 'collections', 'queue'];
|
||||||
'->>', // Solid arrow with arrowhead
|
|
||||||
'-->>', // Dotted arrow with arrowhead
|
const interactionTypes = ['->>', '-->>', '->', '-->', '-x', '--x', '->>+', '-->>+'];
|
||||||
'->', // Solid arrow without arrowhead
|
|
||||||
'-->', // Dotted arrow without arrowhead
|
|
||||||
'-x', // Solid arrow with cross
|
|
||||||
'--x', // Dotted arrow with cross
|
|
||||||
'->>+', // Solid arrow with arrowhead (activate)
|
|
||||||
'-->>+', // Dotted arrow with arrowhead (activate)
|
|
||||||
];
|
|
||||||
|
|
||||||
const notePositions = ['left of', 'right of', 'over'];
|
const notePositions = ['left of', 'right of', 'over'];
|
||||||
|
|
||||||
|
function getParticipantLine(name, type, alias) {
|
||||||
|
if (restrictedTypes.includes(type)) {
|
||||||
|
return ` participant ${name}@{ "type" : "${type}" }\n`;
|
||||||
|
} else if (alias) {
|
||||||
|
return ` participant ${name}@{ "type" : "${type}" } \n`;
|
||||||
|
} else {
|
||||||
|
return ` participant ${name}@{ "type" : "${type}" }\n`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
looks.forEach((look) => {
|
looks.forEach((look) => {
|
||||||
describe(`Sequence Diagram Tests - ${look} look`, () => {
|
describe(`Sequence Diagram Tests - ${look} look`, () => {
|
||||||
it('should render all participant types', () => {
|
it('should render all participant types', () => {
|
||||||
let diagramCode = `sequenceDiagram\n`;
|
let diagramCode = `sequenceDiagram\n`;
|
||||||
participantTypes.forEach((type, index) => {
|
participantTypes.forEach((pt, index) => {
|
||||||
diagramCode += ` ${type} ${type}${index} as ${type} ${index}\n`;
|
const name = `${pt.display}${index}`;
|
||||||
|
diagramCode += getParticipantLine(name, pt.type);
|
||||||
});
|
});
|
||||||
// Add some basic interactions
|
|
||||||
for (let i = 0; i < participantTypes.length - 1; i++) {
|
for (let i = 0; i < participantTypes.length - 1; i++) {
|
||||||
diagramCode += ` ${participantTypes[i]}${i} ->> ${participantTypes[i + 1]}${i + 1}: Message ${i}\n`;
|
diagramCode += ` ${participantTypes[i].display}${i} ->> ${participantTypes[i + 1].display}${i + 1}: Message ${i}\n`;
|
||||||
}
|
}
|
||||||
imgSnapshotTest(diagramCode, { look, sequence: { diagramMarginX: 50, diagramMarginY: 10 } });
|
imgSnapshotTest(diagramCode, { look, sequence: { diagramMarginX: 50, diagramMarginY: 10 } });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render all interaction types', () => {
|
it('should render all interaction types', () => {
|
||||||
let diagramCode = `sequenceDiagram\n`;
|
let diagramCode = `sequenceDiagram\n`;
|
||||||
// Create two participants
|
diagramCode += getParticipantLine('A', 'actor');
|
||||||
// Add all interaction types
|
diagramCode += getParticipantLine('B', 'boundary');
|
||||||
diagramCode += ` participant A\n`;
|
|
||||||
diagramCode += ` participant B\n`;
|
|
||||||
interactionTypes.forEach((interaction, index) => {
|
interactionTypes.forEach((interaction, index) => {
|
||||||
diagramCode += ` A ${interaction} B: ${interaction} message ${index}\n`;
|
diagramCode += ` A ${interaction} B: ${interaction} message ${index}\n`;
|
||||||
});
|
});
|
||||||
@@ -53,13 +54,14 @@ looks.forEach((look) => {
|
|||||||
|
|
||||||
it('should render participant creation and destruction', () => {
|
it('should render participant creation and destruction', () => {
|
||||||
let diagramCode = `sequenceDiagram\n`;
|
let diagramCode = `sequenceDiagram\n`;
|
||||||
participantTypes.forEach((type, index) => {
|
participantTypes.forEach((pt, index) => {
|
||||||
diagramCode += ` ${type} A\n`;
|
const name = `${pt.display}${index}`;
|
||||||
diagramCode += ` ${type} B\n`;
|
diagramCode += getParticipantLine('A', pt.type);
|
||||||
diagramCode += ` create ${type} ${type}${index}\n`;
|
diagramCode += getParticipantLine('B', pt.type);
|
||||||
diagramCode += ` A ->> ${type}${index}: Hello ${type}\n`;
|
diagramCode += ` create participant ${name}@{ "type" : "${pt.type}" }\n`;
|
||||||
|
diagramCode += ` A ->> ${name}: Hello ${pt.display}\n`;
|
||||||
if (index % 2 === 0) {
|
if (index % 2 === 0) {
|
||||||
diagramCode += ` destroy ${type}${index}\n`;
|
diagramCode += ` destroy ${name}\n`;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
imgSnapshotTest(diagramCode, { look });
|
imgSnapshotTest(diagramCode, { look });
|
||||||
@@ -67,8 +69,8 @@ looks.forEach((look) => {
|
|||||||
|
|
||||||
it('should render notes in all positions', () => {
|
it('should render notes in all positions', () => {
|
||||||
let diagramCode = `sequenceDiagram\n`;
|
let diagramCode = `sequenceDiagram\n`;
|
||||||
diagramCode += ` participant A\n`;
|
diagramCode += getParticipantLine('A', 'actor');
|
||||||
diagramCode += ` participant B\n`;
|
diagramCode += getParticipantLine('B', 'boundary');
|
||||||
notePositions.forEach((position, index) => {
|
notePositions.forEach((position, index) => {
|
||||||
diagramCode += ` Note ${position} A: Note ${position} ${index}\n`;
|
diagramCode += ` Note ${position} A: Note ${position} ${index}\n`;
|
||||||
});
|
});
|
||||||
@@ -78,12 +80,12 @@ looks.forEach((look) => {
|
|||||||
|
|
||||||
it('should render parallel interactions', () => {
|
it('should render parallel interactions', () => {
|
||||||
let diagramCode = `sequenceDiagram\n`;
|
let diagramCode = `sequenceDiagram\n`;
|
||||||
participantTypes.slice(0, 4).forEach((type, index) => {
|
participantTypes.slice(0, 4).forEach((pt, index) => {
|
||||||
diagramCode += ` ${type} ${type}${index}\n`;
|
diagramCode += getParticipantLine(`${pt.display}${index}`, pt.type);
|
||||||
});
|
});
|
||||||
diagramCode += ` par Parallel actions\n`;
|
diagramCode += ` par Parallel actions\n`;
|
||||||
for (let i = 0; i < participantTypes.length - 1; i += 2) {
|
for (let i = 0; i < 3; i += 2) {
|
||||||
diagramCode += ` ${participantTypes[i]}${i} ->> ${participantTypes[i + 1]}${i + 1}: Message ${i}\n`;
|
diagramCode += ` ${participantTypes[i].display}${i} ->> ${participantTypes[i + 1].display}${i + 1}: Message ${i}\n`;
|
||||||
if (i < participantTypes.length - 2) {
|
if (i < participantTypes.length - 2) {
|
||||||
diagramCode += ` and\n`;
|
diagramCode += ` and\n`;
|
||||||
}
|
}
|
||||||
@@ -94,8 +96,8 @@ looks.forEach((look) => {
|
|||||||
|
|
||||||
it('should render alternative flows', () => {
|
it('should render alternative flows', () => {
|
||||||
let diagramCode = `sequenceDiagram\n`;
|
let diagramCode = `sequenceDiagram\n`;
|
||||||
diagramCode += ` participant A\n`;
|
diagramCode += getParticipantLine('A', 'actor');
|
||||||
diagramCode += ` participant B\n`;
|
diagramCode += getParticipantLine('B', 'boundary');
|
||||||
diagramCode += ` alt Successful case\n`;
|
diagramCode += ` alt Successful case\n`;
|
||||||
diagramCode += ` A ->> B: Request\n`;
|
diagramCode += ` A ->> B: Request\n`;
|
||||||
diagramCode += ` B -->> A: Success\n`;
|
diagramCode += ` B -->> A: Success\n`;
|
||||||
@@ -108,12 +110,12 @@ looks.forEach((look) => {
|
|||||||
|
|
||||||
it('should render loops', () => {
|
it('should render loops', () => {
|
||||||
let diagramCode = `sequenceDiagram\n`;
|
let diagramCode = `sequenceDiagram\n`;
|
||||||
participantTypes.slice(0, 3).forEach((type, index) => {
|
participantTypes.slice(0, 3).forEach((pt, index) => {
|
||||||
diagramCode += ` ${type} ${type}${index}\n`;
|
diagramCode += getParticipantLine(`${pt.display}${index}`, pt.type);
|
||||||
});
|
});
|
||||||
diagramCode += ` loop For each participant\n`;
|
diagramCode += ` loop For each participant\n`;
|
||||||
for (let i = 0; i < 3; i++) {
|
for (let i = 0; i < 3; i++) {
|
||||||
diagramCode += ` ${participantTypes[0]}0 ->> ${participantTypes[1]}1: Message ${i}\n`;
|
diagramCode += ` ${participantTypes[0].display}0 ->> ${participantTypes[1].display}1: Message ${i}\n`;
|
||||||
}
|
}
|
||||||
diagramCode += ` end\n`;
|
diagramCode += ` end\n`;
|
||||||
imgSnapshotTest(diagramCode, { look });
|
imgSnapshotTest(diagramCode, { look });
|
||||||
@@ -122,27 +124,26 @@ looks.forEach((look) => {
|
|||||||
it('should render boxes around groups', () => {
|
it('should render boxes around groups', () => {
|
||||||
let diagramCode = `sequenceDiagram\n`;
|
let diagramCode = `sequenceDiagram\n`;
|
||||||
diagramCode += ` box Group 1\n`;
|
diagramCode += ` box Group 1\n`;
|
||||||
participantTypes.slice(0, 3).forEach((type, index) => {
|
participantTypes.slice(0, 3).forEach((pt, index) => {
|
||||||
diagramCode += ` ${type} ${type}${index}\n`;
|
diagramCode += ` ${getParticipantLine(`${pt.display}${index}`, pt.type)}`;
|
||||||
});
|
});
|
||||||
diagramCode += ` end\n`;
|
diagramCode += ` end\n`;
|
||||||
diagramCode += ` box rgb(200,220,255) Group 2\n`;
|
diagramCode += ` box rgb(200,220,255) Group 2\n`;
|
||||||
participantTypes.slice(3, 6).forEach((type, index) => {
|
participantTypes.slice(3, 6).forEach((pt, index) => {
|
||||||
diagramCode += ` ${type} ${type}${index}\n`;
|
diagramCode += ` ${getParticipantLine(`${pt.display}${index}`, pt.type)}`;
|
||||||
});
|
});
|
||||||
diagramCode += ` end\n`;
|
diagramCode += ` end\n`;
|
||||||
// Add some interactions
|
diagramCode += ` ${participantTypes[0].display}0 ->> ${participantTypes[3].display}0: Cross-group message\n`;
|
||||||
diagramCode += ` ${participantTypes[0]}0 ->> ${participantTypes[3]}0: Cross-group message\n`;
|
|
||||||
imgSnapshotTest(diagramCode, { look });
|
imgSnapshotTest(diagramCode, { look });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render with different font settings', () => {
|
it('should render with different font settings', () => {
|
||||||
let diagramCode = `sequenceDiagram\n`;
|
let diagramCode = `sequenceDiagram\n`;
|
||||||
participantTypes.slice(0, 3).forEach((type, index) => {
|
participantTypes.slice(0, 3).forEach((pt, index) => {
|
||||||
diagramCode += ` ${type} ${type}${index}\n`;
|
diagramCode += getParticipantLine(`${pt.display}${index}`, pt.type);
|
||||||
});
|
});
|
||||||
diagramCode += ` ${participantTypes[0]}0 ->> ${participantTypes[1]}1: Regular message\n`;
|
diagramCode += ` ${participantTypes[0].display}0 ->> ${participantTypes[1].display}1: Regular message\n`;
|
||||||
diagramCode += ` Note right of ${participantTypes[1]}1: Regular note\n`;
|
diagramCode += ` Note right of ${participantTypes[1].display}1: Regular note\n`;
|
||||||
imgSnapshotTest(diagramCode, {
|
imgSnapshotTest(diagramCode, {
|
||||||
look,
|
look,
|
||||||
sequence: {
|
sequence: {
|
||||||
@@ -166,15 +167,15 @@ describe('Sequence Diagram Special Cases', () => {
|
|||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
box rgb(200,220,255) Authentication
|
box rgb(200,220,255) Authentication
|
||||||
actor User
|
actor User
|
||||||
boundary LoginUI
|
participant LoginUI@{ "type": "boundary" }
|
||||||
control AuthService
|
participant AuthService@{ "type": "control" }
|
||||||
database UserDB
|
participant UserDB@{ "type": "database" }
|
||||||
end
|
end
|
||||||
|
|
||||||
box rgb(200,255,220) Order Processing
|
box rgb(200,255,220) Order Processing
|
||||||
entity Order
|
participant Order@{ "type": "entity" }
|
||||||
queue OrderQueue
|
participant OrderQueue@{ "type": "queue" }
|
||||||
collections AuditLogs
|
participant AuditLogs@{ "type": "collections" }
|
||||||
end
|
end
|
||||||
|
|
||||||
User ->> LoginUI: Enter credentials
|
User ->> LoginUI: Enter credentials
|
||||||
@@ -230,70 +231,87 @@ describe('Sequence Diagram Special Cases', () => {
|
|||||||
it('should render a sequence diagram with various participant types', () => {
|
it('should render a sequence diagram with various participant types', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
actor User
|
participant User@{ "type": "actor" }
|
||||||
participant AuthService as Authentication Service
|
participant AuthService@{ "type": "control" }
|
||||||
boundary UI
|
participant UI@{ "type": "boundary" }
|
||||||
control OrderController
|
participant OrderController@{ "type": "control" }
|
||||||
entity Product
|
participant Product@{ "type": "entity" }
|
||||||
database MongoDB
|
participant MongoDB@{ "type": "database" }
|
||||||
collections Products
|
participant Products@{ "type": "collections" }
|
||||||
queue OrderQueue
|
participant OrderQueue@{ "type": "queue" }
|
||||||
User ->> UI: Login request
|
User ->> UI: Login request
|
||||||
UI ->> AuthService: Validate credentials
|
UI ->> AuthService: Validate credentials
|
||||||
AuthService -->> UI: Authentication token
|
AuthService -->> UI: Authentication token
|
||||||
UI ->> OrderController: Place order
|
UI ->> OrderController: Place order
|
||||||
OrderController ->> Product: Check availability
|
OrderController ->> Product: Check availability
|
||||||
Product -->> OrderController: Available
|
Product -->> OrderController: Available
|
||||||
OrderController ->> MongoDB: Save order
|
OrderController ->> MongoDB: Save order
|
||||||
MongoDB -->> OrderController: Order saved
|
MongoDB -->> OrderController: Order saved
|
||||||
OrderController ->> OrderQueue: Process payment
|
OrderController ->> OrderQueue: Process payment
|
||||||
OrderQueue -->> User: Order confirmation
|
OrderQueue -->> User: Order confirmation
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render participant creation and destruction with different types', () => {
|
it('should render participant creation and destruction with different types', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(`
|
||||||
`
|
sequenceDiagram
|
||||||
sequenceDiagram
|
participant Alice@{ "type" : "boundary" }
|
||||||
actor Customer
|
Alice->>Bob: Hello Bob, how are you ?
|
||||||
participant Frontend
|
Bob->>Alice: Fine, thank you. And you?
|
||||||
boundary PaymentGateway
|
create participant Carl@{ "type" : "control" }
|
||||||
Customer ->> Frontend: Place order
|
Alice->>Carl: Hi Carl!
|
||||||
Frontend ->> OrderProcessor: Process order
|
create actor D as Donald
|
||||||
create database OrderDB
|
Carl->>D: Hi!
|
||||||
OrderProcessor ->> OrderDB: Save order
|
destroy Carl
|
||||||
`
|
Alice-xCarl: We are too many
|
||||||
);
|
destroy Bob
|
||||||
|
Bob->>Alice: I agree
|
||||||
|
`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle complex interactions between different participant types', () => {
|
it('should handle complex interactions between different participant types', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
box rgba(200,220,255,0.5) System Components
|
box rgb(200,220,255) Authentication
|
||||||
actor User
|
participant User@{ "type": "actor" }
|
||||||
boundary WebUI
|
participant LoginUI@{ "type": "boundary" }
|
||||||
control API
|
participant AuthService@{ "type": "control" }
|
||||||
entity BusinessLogic
|
participant UserDB@{ "type": "database" }
|
||||||
database MainDB
|
end
|
||||||
end
|
|
||||||
box rgba(200,255,220,0.5) External Services
|
|
||||||
queue MessageQueue
|
|
||||||
database AuditLogs
|
|
||||||
end
|
|
||||||
|
|
||||||
User ->> WebUI: Submit request
|
box rgb(200,255,220) Order Processing
|
||||||
WebUI ->> API: Process request
|
participant Order@{ "type": "entity" }
|
||||||
API ->> BusinessLogic: Execute business rules
|
participant OrderQueue@{ "type": "queue" }
|
||||||
BusinessLogic ->> MainDB: Query data
|
participant AuditLogs@{ "type": "collections" }
|
||||||
MainDB -->> BusinessLogic: Return results
|
end
|
||||||
BusinessLogic ->> MessageQueue: Publish event
|
|
||||||
MessageQueue -->> AuditLogs: Store audit trail
|
User ->> LoginUI: Enter credentials
|
||||||
AuditLogs -->> API: Audit complete
|
LoginUI ->> AuthService: Validate
|
||||||
API -->> WebUI: Return response
|
AuthService ->> UserDB: Query user
|
||||||
WebUI -->> User: Show results
|
UserDB -->> AuthService: User data
|
||||||
|
|
||||||
|
alt Valid credentials
|
||||||
|
AuthService -->> LoginUI: Success
|
||||||
|
LoginUI -->> User: Welcome
|
||||||
|
|
||||||
|
par Place order
|
||||||
|
User ->> Order: New order
|
||||||
|
Order ->> OrderQueue: Process
|
||||||
|
and
|
||||||
|
Order ->> AuditLogs: Record
|
||||||
|
end
|
||||||
|
|
||||||
|
loop Until confirmed
|
||||||
|
OrderQueue ->> Order: Update status
|
||||||
|
Order -->> User: Notification
|
||||||
|
end
|
||||||
|
else Invalid credentials
|
||||||
|
AuthService --x LoginUI: Failure
|
||||||
|
LoginUI --x User: Retry
|
||||||
|
end
|
||||||
`,
|
`,
|
||||||
{ sequence: { useMaxWidth: false } }
|
{ sequence: { useMaxWidth: false } }
|
||||||
);
|
);
|
||||||
@@ -302,15 +320,15 @@ describe('Sequence Diagram Special Cases', () => {
|
|||||||
it('should render parallel processes with different participant types', () => {
|
it('should render parallel processes with different participant types', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
actor Customer
|
participant Customer@{ "type": "actor" }
|
||||||
participant Frontend
|
participant Frontend@{ "type": "participant" }
|
||||||
boundary PaymentService
|
participant PaymentService@{ "type": "boundary" }
|
||||||
control InventoryManager
|
participant InventoryManager@{ "type": "control" }
|
||||||
entity Order
|
participant Order@{ "type": "entity" }
|
||||||
database OrdersDB
|
participant OrdersDB@{ "type": "database" }
|
||||||
queue NotificationQueue
|
participant NotificationQueue@{ "type": "queue" }
|
||||||
|
|
||||||
Customer ->> Frontend: Place order
|
Customer ->> Frontend: Place order
|
||||||
Frontend ->> Order: Create order
|
Frontend ->> Order: Create order
|
||||||
par Parallel Processing
|
par Parallel Processing
|
||||||
@@ -327,18 +345,18 @@ describe('Sequence Diagram Special Cases', () => {
|
|||||||
`
|
`
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
it('should render different participant types with notes and loops', () => {
|
it('should render different participant types with notes and loops', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
actor Admin
|
actor Admin
|
||||||
participant Dashboard
|
participant Dashboard
|
||||||
boundary AuthService
|
participant AuthService@{ "type" : "boundary" }
|
||||||
control UserManager
|
participant UserManager@{ "type" : "control" }
|
||||||
entity UserProfile
|
participant UserProfile@{ "type" : "entity" }
|
||||||
database UserDB
|
participant UserDB@{ "type" : "database" }
|
||||||
database Logs
|
participant Logs@{ "type" : "database" }
|
||||||
|
|
||||||
Admin ->> Dashboard: Open user management
|
Admin ->> Dashboard: Open user management
|
||||||
loop Authentication check
|
loop Authentication check
|
||||||
@@ -354,217 +372,214 @@ describe('Sequence Diagram Special Cases', () => {
|
|||||||
UserManager ->> Dashboard: Display users
|
UserManager ->> Dashboard: Display users
|
||||||
Dashboard ->> Logs: Record access
|
Dashboard ->> Logs: Record access
|
||||||
Logs ->> Admin: Audit trail
|
Logs ->> Admin: Audit trail
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render different participant types with alternative flows', () => {
|
it('should render different participant types with alternative flows', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
|
||||||
sequenceDiagram
|
|
||||||
actor Client
|
|
||||||
participant MobileApp
|
|
||||||
boundary CloudService
|
|
||||||
control DataProcessor
|
|
||||||
entity Transaction
|
|
||||||
database TransactionsDB
|
|
||||||
queue EventBus
|
|
||||||
|
|
||||||
Client ->> MobileApp: Initiate transaction
|
|
||||||
MobileApp ->> CloudService: Authenticate
|
|
||||||
alt Authentication successful
|
|
||||||
CloudService -->> MobileApp: Auth token
|
|
||||||
MobileApp ->> DataProcessor: Process data
|
|
||||||
DataProcessor ->> Transaction: Create transaction
|
|
||||||
Transaction ->> TransactionsDB: Save record
|
|
||||||
TransactionsDB -->> Transaction: Confirmation
|
|
||||||
Transaction ->> EventBus: Publish event
|
|
||||||
EventBus -->> Client: Notification
|
|
||||||
else Authentication failed
|
|
||||||
CloudService -->> MobileApp: Error
|
|
||||||
MobileApp -->> Client: Show error
|
|
||||||
end
|
|
||||||
`
|
`
|
||||||
);
|
sequenceDiagram
|
||||||
});
|
actor Client
|
||||||
|
participant MobileApp
|
||||||
|
participant CloudService@{ "type" : "boundary" }
|
||||||
|
participant DataProcessor@{ "type" : "control" }
|
||||||
|
participant Transaction@{ "type" : "entity" }
|
||||||
|
participant TransactionsDB@{ "type" : "database" }
|
||||||
|
participant EventBus@{ "type" : "queue" }
|
||||||
|
|
||||||
|
Client ->> MobileApp: Initiate transaction
|
||||||
|
MobileApp ->> CloudService: Authenticate
|
||||||
|
alt Authentication successful
|
||||||
|
CloudService -->> MobileApp: Auth token
|
||||||
|
MobileApp ->> DataProcessor: Process data
|
||||||
|
DataProcessor ->> Transaction: Create transaction
|
||||||
|
Transaction ->> TransactionsDB: Save record
|
||||||
|
TransactionsDB -->> Transaction: Confirmation
|
||||||
|
Transaction ->> EventBus: Publish event
|
||||||
|
EventBus -->> Client: Notification
|
||||||
|
else Authentication failed
|
||||||
|
CloudService -->> MobileApp: Error
|
||||||
|
MobileApp -->> Client: Show error
|
||||||
|
end
|
||||||
|
`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('should render different participant types with wrapping text', () => {
|
it('should render different participant types with wrapping text', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
actor LongNameUser as User With A Very<br/>Long Name
|
participant B@{ "type" : "boundary" }
|
||||||
participant FE as Frontend Service<br/>With Long Name
|
participant C@{ "type" : "control" }
|
||||||
boundary B as Boundary With<br/>Multiline Name
|
participant E@{ "type" : "entity" }
|
||||||
control C as Control With<br/>Multiline Name
|
participant DB@{ "type" : "database" }
|
||||||
entity E as Entity With<br/>Multiline Name
|
participant COL@{ "type" : "collections" }
|
||||||
database DB as Database With<br/>Multiline Name
|
participant Q@{ "type" : "queue" }
|
||||||
collections COL as Collections With<br/>Multiline Name
|
|
||||||
queue Q as Queue With<br/>Multiline Name
|
FE ->> B: Another long message<br/>with explicit<br/>line breaks
|
||||||
|
B -->> FE: Response message that is also quite long and needs to wrap
|
||||||
LongNameUser ->> FE: This is a very long message that should wrap properly in the diagram
|
FE ->> C: Process data
|
||||||
FE ->> B: Another long message<br/>with explicit<br/>line breaks
|
C ->> E: Validate
|
||||||
B -->> FE: Response message that is also quite long and needs to wrap
|
E -->> C: Validation result
|
||||||
FE ->> C: Process data
|
C ->> DB: Save
|
||||||
C ->> E: Validate
|
DB -->> C: Save result
|
||||||
E -->> C: Validation result
|
C ->> COL: Log
|
||||||
C ->> DB: Save
|
COL -->> Q: Forward
|
||||||
DB -->> C: Save result
|
Q -->> LongNameUser: Final response with confirmation of all actions taken
|
||||||
C ->> COL: Log
|
|
||||||
COL -->> Q: Forward
|
|
||||||
Q -->> LongNameUser: Final response with confirmation of all actions taken
|
|
||||||
`,
|
|
||||||
{ sequence: { wrap: true } }
|
|
||||||
);
|
|
||||||
});
|
|
||||||
describe('Sequence Diagram - New Participant Types with Long Notes and Messages', () => {
|
|
||||||
it('should render long notes left of boundary', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
sequenceDiagram
|
|
||||||
boundary Alice
|
|
||||||
actor Bob
|
|
||||||
Alice->>Bob: Hola
|
|
||||||
Note left of Alice: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
|
|
||||||
Bob->>Alice: I'm short though
|
|
||||||
`,
|
`,
|
||||||
{}
|
{ sequence: { wrap: true } }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render wrapped long notes left of control', () => {
|
describe('Sequence Diagram - New Participant Types with Long Notes and Messages', () => {
|
||||||
imgSnapshotTest(
|
it('should render long notes left of boundary', () => {
|
||||||
`
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
control Alice
|
participant Alice@{ "type" : "boundary" }
|
||||||
|
actor Bob
|
||||||
|
Alice->>Bob: Hola
|
||||||
|
Note left of Alice: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
|
||||||
|
Bob->>Alice: I'm short though
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render wrapped long notes left of control', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
sequenceDiagram
|
||||||
|
participant Alice@{ "type" : "control" }
|
||||||
actor Bob
|
actor Bob
|
||||||
Alice->>Bob: Hola
|
Alice->>Bob: Hola
|
||||||
Note left of Alice:wrap: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
|
Note left of Alice:wrap: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
|
||||||
Bob->>Alice: I'm short though
|
Bob->>Alice: I'm short though
|
||||||
`,
|
`,
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render long notes right of entity', () => {
|
it('should render long notes right of entity', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
entity Alice
|
participant Alice@{ "type" : "entity" }
|
||||||
actor Bob
|
actor Bob
|
||||||
Alice->>Bob: Hola
|
Alice->>Bob: Hola
|
||||||
Note right of Alice: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
|
Note right of Alice: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
|
||||||
Bob->>Alice: I'm short though
|
Bob->>Alice: I'm short though
|
||||||
`,
|
`,
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render wrapped long notes right of database', () => {
|
it('should render wrapped long notes right of database', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
database Alice
|
participant Alice@{ "type" : "database" }
|
||||||
actor Bob
|
actor Bob
|
||||||
Alice->>Bob: Hola
|
Alice->>Bob: Hola
|
||||||
Note right of Alice:wrap: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
|
Note right of Alice:wrap: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
|
||||||
Bob->>Alice: I'm short though
|
Bob->>Alice: I'm short though
|
||||||
`,
|
`,
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render long notes over collections', () => {
|
it('should render long notes over collections', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
collections Alice
|
participant Alice@{ "type" : "collections" }
|
||||||
actor Bob
|
actor Bob
|
||||||
Alice->>Bob: Hola
|
Alice->>Bob: Hola
|
||||||
Note over Alice: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
|
Note over Alice: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
|
||||||
Bob->>Alice: I'm short though
|
Bob->>Alice: I'm short though
|
||||||
`,
|
`,
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render wrapped long notes over queue', () => {
|
it('should render wrapped long notes over queue', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
queue Alice
|
participant Alice@{ "type" : "queue" }
|
||||||
actor Bob
|
actor Bob
|
||||||
Alice->>Bob: Hola
|
Alice->>Bob: Hola
|
||||||
Note over Alice:wrap: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
|
Note over Alice:wrap: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
|
||||||
Bob->>Alice: I'm short though
|
Bob->>Alice: I'm short though
|
||||||
`,
|
`,
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render notes over actor and boundary', () => {
|
it('should render notes over actor and boundary', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
actor Alice
|
actor Alice
|
||||||
boundary Charlie
|
participant Charlie@{ "type" : "boundary" }
|
||||||
note over Alice: Some note
|
note over Alice: Some note
|
||||||
note over Charlie: Other note
|
note over Charlie: Other note
|
||||||
`,
|
`,
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render long messages from database to collections', () => {
|
it('should render long messages from database to collections', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
database Alice
|
participant Alice@{ "type" : "database" }
|
||||||
collections Bob
|
participant Bob@{ "type" : "collections" }
|
||||||
Alice->>Bob: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
|
Alice->>Bob: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
|
||||||
Bob->>Alice: I'm short though
|
Bob->>Alice: I'm short though
|
||||||
`,
|
`,
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render wrapped long messages from control to entity', () => {
|
it('should render wrapped long messages from control to entity', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
control Alice
|
participant Alice@{ "type" : "control" }
|
||||||
entity Bob
|
participant Bob@{ "type" : "entity" }
|
||||||
Alice->>Bob:wrap: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
|
Alice->>Bob:wrap: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
|
||||||
Bob->>Alice: I'm short though
|
Bob->>Alice: I'm short though
|
||||||
`,
|
`,
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render long messages from queue to boundary', () => {
|
it('should render long messages from queue to boundary', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
queue Alice
|
participant Alice@{ "type" : "queue" }
|
||||||
boundary Bob
|
participant Bob@{ "type" : "boundary" }
|
||||||
Alice->>Bob: I'm short
|
Alice->>Bob: I'm short
|
||||||
Bob->>Alice: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
|
Bob->>Alice: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
|
||||||
`,
|
`,
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render wrapped long messages from actor to database', () => {
|
it('should render wrapped long messages from actor to database', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
actor Alice
|
actor Alice
|
||||||
database Bob
|
participant Bob@{ "type" : "database" }
|
||||||
Alice->>Bob: I'm short
|
Alice->>Bob: I'm short
|
||||||
Bob->>Alice:wrap: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
|
Bob->>Alice:wrap: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
|
||||||
`,
|
`,
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -574,8 +589,8 @@ describe('Sequence Diagram Special Cases', () => {
|
|||||||
`
|
`
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
actor Alice
|
actor Alice
|
||||||
boundary Bob
|
participant Bob@{ "type" : "boundary" }
|
||||||
control John as John<br/>Second Line
|
participant John@{ "type" : "control" }
|
||||||
Alice ->> Bob: Hello Bob, how are you?
|
Alice ->> Bob: Hello Bob, how are you?
|
||||||
Bob-->>John: How about you John?
|
Bob-->>John: How about you John?
|
||||||
Bob--x Alice: I am good thanks!
|
Bob--x Alice: I am good thanks!
|
||||||
@@ -584,9 +599,9 @@ describe('Sequence Diagram Special Cases', () => {
|
|||||||
Bob-->Alice: Checking with John...
|
Bob-->Alice: Checking with John...
|
||||||
alt either this
|
alt either this
|
||||||
Alice->>John: Yes
|
Alice->>John: Yes
|
||||||
else or this
|
else or this
|
||||||
Alice->>John: No
|
Alice->>John: No
|
||||||
else or this will happen
|
else or this will happen
|
||||||
Alice->John: Maybe
|
Alice->John: Maybe
|
||||||
end
|
end
|
||||||
par this happens in parallel
|
par this happens in parallel
|
||||||
@@ -611,8 +626,8 @@ describe('Sequence Diagram Special Cases', () => {
|
|||||||
`
|
`
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
actor Alice
|
actor Alice
|
||||||
boundary Bob
|
participant Bob@{ "type" : "boundary" }
|
||||||
control John as John<br/>Second Line
|
participant John@{ "type" : "control" }
|
||||||
Alice ->> Bob: Hello Bob, how are you?
|
Alice ->> Bob: Hello Bob, how are you?
|
||||||
Bob-->>John: How about you John?
|
Bob-->>John: How about you John?
|
||||||
Bob--x Alice: I am good thanks!
|
Bob--x Alice: I am good thanks!
|
||||||
@@ -621,9 +636,9 @@ describe('Sequence Diagram Special Cases', () => {
|
|||||||
Bob-->Alice: Checking with John...
|
Bob-->Alice: Checking with John...
|
||||||
alt either this
|
alt either this
|
||||||
Alice->>John: Yes
|
Alice->>John: Yes
|
||||||
else or this
|
else or this
|
||||||
Alice->>John: No
|
Alice->>John: No
|
||||||
else or this will happen
|
else or this will happen
|
||||||
Alice->John: Maybe
|
Alice->John: Maybe
|
||||||
end
|
end
|
||||||
par this happens in parallel
|
par this happens in parallel
|
||||||
|
|||||||
@@ -893,6 +893,17 @@ describe('Sequence diagram', () => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should handle bidirectional arrows with autonumber', () => {
|
||||||
|
imgSnapshotTest(`
|
||||||
|
sequenceDiagram
|
||||||
|
autonumber
|
||||||
|
participant A
|
||||||
|
participant B
|
||||||
|
A<<->>B: This is a bidirectional message
|
||||||
|
A->B: This is a normal message`);
|
||||||
|
});
|
||||||
|
|
||||||
it('should support actor links and properties when not mirrored EXPERIMENTAL: USE WITH CAUTION', () => {
|
it('should support actor links and properties when not mirrored EXPERIMENTAL: USE WITH CAUTION', () => {
|
||||||
//Be aware that the syntax for "properties" is likely to be changed.
|
//Be aware that the syntax for "properties" is likely to be changed.
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
|
|||||||
@@ -602,6 +602,231 @@ State1 --> [*]
|
|||||||
--
|
--
|
||||||
55
|
55
|
||||||
}
|
}
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('should render edge labels correctly', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`---
|
||||||
|
title: On The Way To Something Something DarkSide
|
||||||
|
config:
|
||||||
|
look: default
|
||||||
|
theme: default
|
||||||
|
---
|
||||||
|
|
||||||
|
stateDiagram-v2
|
||||||
|
|
||||||
|
state State1_____________
|
||||||
|
{
|
||||||
|
c0
|
||||||
|
}
|
||||||
|
|
||||||
|
state State2_____________
|
||||||
|
{
|
||||||
|
c1
|
||||||
|
}
|
||||||
|
|
||||||
|
state State3_____________
|
||||||
|
{
|
||||||
|
c7
|
||||||
|
}
|
||||||
|
|
||||||
|
state State4_____________
|
||||||
|
{
|
||||||
|
c2
|
||||||
|
}
|
||||||
|
|
||||||
|
state State5_____________
|
||||||
|
{
|
||||||
|
c3
|
||||||
|
}
|
||||||
|
|
||||||
|
state State6_____________
|
||||||
|
{
|
||||||
|
c4
|
||||||
|
}
|
||||||
|
|
||||||
|
state State7_____________
|
||||||
|
{
|
||||||
|
c5
|
||||||
|
}
|
||||||
|
|
||||||
|
state State8_____________
|
||||||
|
{
|
||||||
|
c6
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[*] --> State1_____________
|
||||||
|
State1_____________ --> State2_____________ : Transition1_____
|
||||||
|
State2_____________ --> State4_____________ : Transition2_____
|
||||||
|
State2_____________ --> State3_____________ : Transition3_____
|
||||||
|
State3_____________ --> State2_____________
|
||||||
|
State4_____________ --> State2_____________ : Transition5_____
|
||||||
|
State4_____________ --> State5_____________ : Transition6_____
|
||||||
|
State5_____________ --> State6_____________ : Transition7_____
|
||||||
|
State6_____________ --> State4_____________ : Transition8_____
|
||||||
|
State2_____________ --> State7_____________ : Transition4_____
|
||||||
|
State4_____________ --> State7_____________ : Transition4_____
|
||||||
|
State5_____________ --> State7_____________ : Transition4_____
|
||||||
|
State6_____________ --> State7_____________ : Transition4_____
|
||||||
|
State7_____________ --> State1_____________ : Transition9_____
|
||||||
|
State5_____________ --> State8_____________ : Transition10____
|
||||||
|
State8_____________ --> State5_____________ : Transition11____
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('should render edge labels correctly with multiple transitions', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`---
|
||||||
|
title: Multiple Transitions
|
||||||
|
config:
|
||||||
|
look: default
|
||||||
|
theme: default
|
||||||
|
---
|
||||||
|
|
||||||
|
stateDiagram-v2
|
||||||
|
|
||||||
|
state State1_____________
|
||||||
|
{
|
||||||
|
c0
|
||||||
|
}
|
||||||
|
|
||||||
|
state State2_____________
|
||||||
|
{
|
||||||
|
c1
|
||||||
|
}
|
||||||
|
|
||||||
|
state State3_____________
|
||||||
|
{
|
||||||
|
c7
|
||||||
|
}
|
||||||
|
|
||||||
|
state State4_____________
|
||||||
|
{
|
||||||
|
c2
|
||||||
|
}
|
||||||
|
|
||||||
|
state State5_____________
|
||||||
|
{
|
||||||
|
c3
|
||||||
|
}
|
||||||
|
|
||||||
|
state State6_____________
|
||||||
|
{
|
||||||
|
c4
|
||||||
|
}
|
||||||
|
|
||||||
|
state State7_____________
|
||||||
|
{
|
||||||
|
c5
|
||||||
|
}
|
||||||
|
|
||||||
|
state State8_____________
|
||||||
|
{
|
||||||
|
c6
|
||||||
|
}
|
||||||
|
|
||||||
|
state State9_____________
|
||||||
|
{
|
||||||
|
c9
|
||||||
|
}
|
||||||
|
|
||||||
|
[*] --> State1_____________
|
||||||
|
State1_____________ --> State2_____________ : Transition1_____
|
||||||
|
State2_____________ --> State4_____________ : Transition2_____
|
||||||
|
State2_____________ --> State3_____________ : Transition3_____
|
||||||
|
State3_____________ --> State2_____________
|
||||||
|
State4_____________ --> State2_____________ : Transition5_____
|
||||||
|
State4_____________ --> State5_____________ : Transition6_____
|
||||||
|
State5_____________ --> State6_____________ : Transition7_____
|
||||||
|
State6_____________ --> State4_____________ : Transition8_____
|
||||||
|
State2_____________ --> State7_____________ : Transition4_____
|
||||||
|
State4_____________ --> State7_____________ : Transition4_____
|
||||||
|
State5_____________ --> State7_____________ : Transition4_____
|
||||||
|
State6_____________ --> State7_____________ : Transition4_____
|
||||||
|
State7_____________ --> State1_____________ : Transition9_____
|
||||||
|
State5_____________ --> State8_____________ : Transition10____
|
||||||
|
State8_____________ --> State5_____________ : Transition11____
|
||||||
|
State9_____________ --> State8_____________ : Transition12____
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render edge labels correctly with multiple states', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`---
|
||||||
|
title: Multiple States
|
||||||
|
config:
|
||||||
|
look: default
|
||||||
|
theme: default
|
||||||
|
---
|
||||||
|
|
||||||
|
stateDiagram-v2
|
||||||
|
|
||||||
|
state State1_____________
|
||||||
|
{
|
||||||
|
c0
|
||||||
|
}
|
||||||
|
|
||||||
|
state State2_____________
|
||||||
|
{
|
||||||
|
c1
|
||||||
|
}
|
||||||
|
|
||||||
|
state State3_____________
|
||||||
|
{
|
||||||
|
c7
|
||||||
|
}
|
||||||
|
|
||||||
|
state State4_____________
|
||||||
|
{
|
||||||
|
c2
|
||||||
|
}
|
||||||
|
|
||||||
|
state State5_____________
|
||||||
|
{
|
||||||
|
c3
|
||||||
|
}
|
||||||
|
|
||||||
|
state State6_____________
|
||||||
|
{
|
||||||
|
c4
|
||||||
|
}
|
||||||
|
|
||||||
|
state State7_____________
|
||||||
|
{
|
||||||
|
c5
|
||||||
|
}
|
||||||
|
|
||||||
|
state State8_____________
|
||||||
|
{
|
||||||
|
c6
|
||||||
|
}
|
||||||
|
|
||||||
|
state State9_____________
|
||||||
|
{
|
||||||
|
c9
|
||||||
|
}
|
||||||
|
|
||||||
|
state State10_____________
|
||||||
|
{
|
||||||
|
c10
|
||||||
|
}
|
||||||
|
|
||||||
|
[*] --> State1_____________
|
||||||
|
State1_____________ --> State2_____________ : Transition1_____
|
||||||
|
State2_____________ --> State3_____________ : Transition2_____
|
||||||
|
State3_____________ --> State4_____________ : Transition3_____
|
||||||
|
State4_____________ --> State5_____________ : Transition4_____
|
||||||
|
State5_____________ --> State6_____________ : Transition5_____
|
||||||
|
State6_____________ --> State7_____________ : Transition6_____
|
||||||
|
State7_____________ --> State8_____________ : Transition7_____
|
||||||
|
State8_____________ --> State9_____________ : Transition8_____
|
||||||
|
State9_____________ --> State10_____________ : Transition9_____
|
||||||
`,
|
`,
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
|
import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
|
||||||
|
|
||||||
describe('XY Chart', () => {
|
describe('XY Chart', () => {
|
||||||
it('should render the simplest possible chart', () => {
|
it('should render the simplest possible xy-beta chart', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
xychart-beta
|
xychart-beta
|
||||||
@@ -10,10 +10,19 @@ describe('XY Chart', () => {
|
|||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
it('should render the simplest possible xy chart', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
xychart
|
||||||
|
line [10, 30, 20]
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
});
|
||||||
it('Should render a complete chart', () => {
|
it('Should render a complete chart', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
xychart-beta
|
xychart
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
@@ -26,7 +35,7 @@ describe('XY Chart', () => {
|
|||||||
it('Should render a chart without title', () => {
|
it('Should render a chart without title', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
xychart-beta
|
xychart
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000]
|
bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000]
|
||||||
@@ -38,7 +47,7 @@ describe('XY Chart', () => {
|
|||||||
it('y-axis title not required', () => {
|
it('y-axis title not required', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
xychart-beta
|
xychart
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis 4000 --> 11000
|
y-axis 4000 --> 11000
|
||||||
bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000]
|
bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000]
|
||||||
@@ -50,7 +59,7 @@ describe('XY Chart', () => {
|
|||||||
it('Should render a chart without y-axis with different range', () => {
|
it('Should render a chart without y-axis with different range', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
xychart-beta
|
xychart
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
bar [5000, 6000, 7500, 8200, 9500, 10500, 14000, 3200, 9200, 9900, 3400, 6000]
|
bar [5000, 6000, 7500, 8200, 9500, 10500, 14000, 3200, 9200, 9900, 3400, 6000]
|
||||||
line [2000, 7000, 6500, 9200, 9500, 7500, 11000, 10200, 3200, 8500, 7000, 8800]
|
line [2000, 7000, 6500, 9200, 9500, 7500, 11000, 10200, 3200, 8500, 7000, 8800]
|
||||||
@@ -61,7 +70,7 @@ describe('XY Chart', () => {
|
|||||||
it('x axis title not required', () => {
|
it('x axis title not required', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
xychart-beta
|
xychart
|
||||||
x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
bar [5000, 6000, 7500, 8200, 9500, 10500, 14000, 3200, 9200, 9900, 3400, 6000]
|
bar [5000, 6000, 7500, 8200, 9500, 10500, 14000, 3200, 9200, 9900, 3400, 6000]
|
||||||
line [2000, 7000, 6500, 9200, 9500, 7500, 11000, 10200, 3200, 8500, 7000, 8800]
|
line [2000, 7000, 6500, 9200, 9500, 7500, 11000, 10200, 3200, 8500, 7000, 8800]
|
||||||
@@ -72,7 +81,7 @@ describe('XY Chart', () => {
|
|||||||
it('Multiple plots can be rendered', () => {
|
it('Multiple plots can be rendered', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
xychart-beta
|
xychart
|
||||||
line [23, 46, 77, 34]
|
line [23, 46, 77, 34]
|
||||||
line [45, 32, 33, 12]
|
line [45, 32, 33, 12]
|
||||||
bar [87, 54, 99, 85]
|
bar [87, 54, 99, 85]
|
||||||
@@ -86,7 +95,7 @@ describe('XY Chart', () => {
|
|||||||
it('Decimals and negative numbers are supported', () => {
|
it('Decimals and negative numbers are supported', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
xychart-beta
|
xychart
|
||||||
y-axis -2.4 --> 3.5
|
y-axis -2.4 --> 3.5
|
||||||
line [+1.3, .6, 2.4, -.34]
|
line [+1.3, .6, 2.4, -.34]
|
||||||
`,
|
`,
|
||||||
@@ -104,7 +113,7 @@ describe('XY Chart', () => {
|
|||||||
height: 20
|
height: 20
|
||||||
plotReservedSpacePercent: 100
|
plotReservedSpacePercent: 100
|
||||||
---
|
---
|
||||||
xychart-beta
|
xychart
|
||||||
line [5000, 9000, 7500, 6200, 9500, 5500, 11000, 8200, 9200, 9500, 7000, 8800]
|
line [5000, 9000, 7500, 6200, 9500, 5500, 11000, 8200, 9200, 9500, 7000, 8800]
|
||||||
`,
|
`,
|
||||||
{}
|
{}
|
||||||
@@ -130,7 +139,7 @@ describe('XY Chart', () => {
|
|||||||
showTick: false
|
showTick: false
|
||||||
showAxisLine: false
|
showAxisLine: false
|
||||||
---
|
---
|
||||||
xychart-beta
|
xychart
|
||||||
bar [5000, 9000, 7500, 6200, 9500, 5500, 11000, 8200, 9200, 9500, 7000, 8800]
|
bar [5000, 9000, 7500, 6200, 9500, 5500, 11000, 8200, 9200, 9500, 7000, 8800]
|
||||||
`,
|
`,
|
||||||
{}
|
{}
|
||||||
@@ -140,7 +149,7 @@ describe('XY Chart', () => {
|
|||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
%%{init: {"xyChart": {"width": 1000, "height": 600, "titlePadding": 5, "titleFontSize": 10, "xAxis": {"labelFontSize": "20", "labelPadding": 10, "titleFontSize": 30, "titlePadding": 20, "tickLength": 10, "tickWidth": 5}, "yAxis": {"labelFontSize": "20", "labelPadding": 10, "titleFontSize": 30, "titlePadding": 20, "tickLength": 10, "tickWidth": 5}, "plotBorderWidth": 5, "chartOrientation": "horizontal", "plotReservedSpacePercent": 60 }}}%%
|
%%{init: {"xyChart": {"width": 1000, "height": 600, "titlePadding": 5, "titleFontSize": 10, "xAxis": {"labelFontSize": "20", "labelPadding": 10, "titleFontSize": 30, "titlePadding": 20, "tickLength": 10, "tickWidth": 5}, "yAxis": {"labelFontSize": "20", "labelPadding": 10, "titleFontSize": 30, "titlePadding": 20, "tickLength": 10, "tickWidth": 5}, "plotBorderWidth": 5, "chartOrientation": "horizontal", "plotReservedSpacePercent": 60 }}}%%
|
||||||
xychart-beta
|
xychart
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
@@ -181,7 +190,7 @@ describe('XY Chart', () => {
|
|||||||
plotReservedSpacePercent: 60
|
plotReservedSpacePercent: 60
|
||||||
showDataLabel: true
|
showDataLabel: true
|
||||||
---
|
---
|
||||||
xychart-beta
|
xychart
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
@@ -202,7 +211,7 @@ describe('XY Chart', () => {
|
|||||||
yAxis:
|
yAxis:
|
||||||
showTitle: false
|
showTitle: false
|
||||||
---
|
---
|
||||||
xychart-beta
|
xychart
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
@@ -223,7 +232,7 @@ describe('XY Chart', () => {
|
|||||||
yAxis:
|
yAxis:
|
||||||
showLabel: false
|
showLabel: false
|
||||||
---
|
---
|
||||||
xychart-beta
|
xychart
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
@@ -244,7 +253,7 @@ describe('XY Chart', () => {
|
|||||||
yAxis:
|
yAxis:
|
||||||
showTick: false
|
showTick: false
|
||||||
---
|
---
|
||||||
xychart-beta
|
xychart
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
@@ -265,7 +274,7 @@ describe('XY Chart', () => {
|
|||||||
yAxis:
|
yAxis:
|
||||||
showAxisLine: false
|
showAxisLine: false
|
||||||
---
|
---
|
||||||
xychart-beta
|
xychart
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
@@ -294,7 +303,7 @@ describe('XY Chart', () => {
|
|||||||
xAxisLineColor: "#87ceeb"
|
xAxisLineColor: "#87ceeb"
|
||||||
plotColorPalette: "#008000, #faba63"
|
plotColorPalette: "#008000, #faba63"
|
||||||
---
|
---
|
||||||
xychart-beta
|
xychart
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
@@ -307,7 +316,7 @@ describe('XY Chart', () => {
|
|||||||
it('should use the correct distances between data points', () => {
|
it('should use the correct distances between data points', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
xychart-beta
|
xychart
|
||||||
x-axis 0 --> 2
|
x-axis 0 --> 2
|
||||||
line [0, 1, 0, 1]
|
line [0, 1, 0, 1]
|
||||||
bar [1, 0, 1, 0]
|
bar [1, 0, 1, 0]
|
||||||
@@ -325,7 +334,7 @@ describe('XY Chart', () => {
|
|||||||
xyChart:
|
xyChart:
|
||||||
showDataLabel: true
|
showDataLabel: true
|
||||||
---
|
---
|
||||||
xychart-beta
|
xychart
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
@@ -344,7 +353,7 @@ describe('XY Chart', () => {
|
|||||||
showDataLabel: true
|
showDataLabel: true
|
||||||
chartOrientation: horizontal
|
chartOrientation: horizontal
|
||||||
---
|
---
|
||||||
xychart-beta
|
xychart
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
@@ -357,7 +366,7 @@ describe('XY Chart', () => {
|
|||||||
it('should render vertical bar chart without labels by default', () => {
|
it('should render vertical bar chart without labels by default', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
xychart-beta
|
xychart
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
@@ -375,7 +384,7 @@ describe('XY Chart', () => {
|
|||||||
xyChart:
|
xyChart:
|
||||||
chartOrientation: horizontal
|
chartOrientation: horizontal
|
||||||
---
|
---
|
||||||
xychart-beta
|
xychart
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
@@ -393,7 +402,7 @@ describe('XY Chart', () => {
|
|||||||
xyChart:
|
xyChart:
|
||||||
showDataLabel: true
|
showDataLabel: true
|
||||||
---
|
---
|
||||||
xychart-beta
|
xychart
|
||||||
title "Multiple Bar Plots"
|
title "Multiple Bar Plots"
|
||||||
x-axis Categories [A, B, C]
|
x-axis Categories [A, B, C]
|
||||||
y-axis "Values" 0 --> 100
|
y-axis "Values" 0 --> 100
|
||||||
@@ -412,7 +421,7 @@ describe('XY Chart', () => {
|
|||||||
showDataLabel: true
|
showDataLabel: true
|
||||||
chartOrientation: horizontal
|
chartOrientation: horizontal
|
||||||
---
|
---
|
||||||
xychart-beta
|
xychart
|
||||||
title "Multiple Bar Plots"
|
title "Multiple Bar Plots"
|
||||||
x-axis Categories [A, B, C]
|
x-axis Categories [A, B, C]
|
||||||
y-axis "Values" 0 --> 100
|
y-axis "Values" 0 --> 100
|
||||||
@@ -430,7 +439,7 @@ describe('XY Chart', () => {
|
|||||||
xyChart:
|
xyChart:
|
||||||
showDataLabel: true
|
showDataLabel: true
|
||||||
---
|
---
|
||||||
xychart-beta
|
xychart
|
||||||
title "Single Bar Chart"
|
title "Single Bar Chart"
|
||||||
x-axis Categories [A]
|
x-axis Categories [A]
|
||||||
y-axis "Value" 0 --> 100
|
y-axis "Value" 0 --> 100
|
||||||
@@ -449,7 +458,7 @@ describe('XY Chart', () => {
|
|||||||
showDataLabel: true
|
showDataLabel: true
|
||||||
chartOrientation: horizontal
|
chartOrientation: horizontal
|
||||||
---
|
---
|
||||||
xychart-beta
|
xychart
|
||||||
title "Single Bar Chart"
|
title "Single Bar Chart"
|
||||||
x-axis Categories [A]
|
x-axis Categories [A]
|
||||||
y-axis "Value" 0 --> 100
|
y-axis "Value" 0 --> 100
|
||||||
@@ -467,7 +476,7 @@ describe('XY Chart', () => {
|
|||||||
xyChart:
|
xyChart:
|
||||||
showDataLabel: true
|
showDataLabel: true
|
||||||
---
|
---
|
||||||
xychart-beta
|
xychart
|
||||||
title "Decimal and Negative Values"
|
title "Decimal and Negative Values"
|
||||||
x-axis Categories [A, B, C]
|
x-axis Categories [A, B, C]
|
||||||
y-axis -10 --> 10
|
y-axis -10 --> 10
|
||||||
@@ -486,7 +495,7 @@ describe('XY Chart', () => {
|
|||||||
showDataLabel: true
|
showDataLabel: true
|
||||||
chartOrientation: horizontal
|
chartOrientation: horizontal
|
||||||
---
|
---
|
||||||
xychart-beta
|
xychart
|
||||||
title "Decimal and Negative Values"
|
title "Decimal and Negative Values"
|
||||||
x-axis Categories [A, B, C]
|
x-axis Categories [A, B, C]
|
||||||
y-axis -10 --> 10
|
y-axis -10 --> 10
|
||||||
@@ -504,7 +513,7 @@ describe('XY Chart', () => {
|
|||||||
xyChart:
|
xyChart:
|
||||||
showDataLabel: true
|
showDataLabel: true
|
||||||
---
|
---
|
||||||
xychart-beta
|
xychart
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan,b,c]
|
x-axis Months [jan,b,c]
|
||||||
y-axis "Revenue (in $)" 4000 --> 12000
|
y-axis "Revenue (in $)" 4000 --> 12000
|
||||||
@@ -561,7 +570,7 @@ describe('XY Chart', () => {
|
|||||||
showDataLabel: true
|
showDataLabel: true
|
||||||
chartOrientation: horizontal
|
chartOrientation: horizontal
|
||||||
---
|
---
|
||||||
xychart-beta
|
xychart
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan,b,c]
|
x-axis Months [jan,b,c]
|
||||||
y-axis "Revenue (in $)" 4000 --> 12000
|
y-axis "Revenue (in $)" 4000 --> 12000
|
||||||
@@ -615,7 +624,7 @@ describe('XY Chart', () => {
|
|||||||
xyChart:
|
xyChart:
|
||||||
showDataLabel: true
|
showDataLabel: true
|
||||||
---
|
---
|
||||||
xychart-beta
|
xychart
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s]
|
x-axis Months [jan,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s]
|
||||||
y-axis "Revenue (in $)" 4000 --> 12000
|
y-axis "Revenue (in $)" 4000 --> 12000
|
||||||
@@ -672,7 +681,7 @@ describe('XY Chart', () => {
|
|||||||
showDataLabel: true
|
showDataLabel: true
|
||||||
chartOrientation: horizontal
|
chartOrientation: horizontal
|
||||||
---
|
---
|
||||||
xychart-beta
|
xychart
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s]
|
x-axis Months [jan,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s]
|
||||||
y-axis "Revenue (in $)" 4000 --> 12000
|
y-axis "Revenue (in $)" 4000 --> 12000
|
||||||
@@ -726,7 +735,7 @@ describe('XY Chart', () => {
|
|||||||
xyChart:
|
xyChart:
|
||||||
showDataLabel: true
|
showDataLabel: true
|
||||||
---
|
---
|
||||||
xychart-beta
|
xychart
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan]
|
x-axis Months [jan]
|
||||||
y-axis "Revenue (in $)" 3000 --> 12000
|
y-axis "Revenue (in $)" 3000 --> 12000
|
||||||
@@ -783,7 +792,7 @@ describe('XY Chart', () => {
|
|||||||
showDataLabel: true
|
showDataLabel: true
|
||||||
chartOrientation: horizontal
|
chartOrientation: horizontal
|
||||||
---
|
---
|
||||||
xychart-beta
|
xychart
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan]
|
x-axis Months [jan]
|
||||||
y-axis "Revenue (in $)" 3000 --> 12000
|
y-axis "Revenue (in $)" 3000 --> 12000
|
||||||
|
|||||||
35
cypress/platform/darshan.html
Normal file
35
cypress/platform/darshan.html
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<title>Mermaid Quick Test Page</title>
|
||||||
|
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=" />
|
||||||
|
<style>
|
||||||
|
div.mermaid {
|
||||||
|
font-family: 'Courier New', Courier, monospace !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>Pie chart demos</h1>
|
||||||
|
<pre class="mermaid">
|
||||||
|
pie title Default text position: Animal adoption
|
||||||
|
accTitle: simple pie char demo
|
||||||
|
accDescr: pie chart with 3 sections: dogs, cats, rats. Most are dogs.
|
||||||
|
"dogs" : -60.67
|
||||||
|
"rats" : 40.12
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
<script type="module">
|
||||||
|
import mermaid from '/mermaid.esm.mjs';
|
||||||
|
mermaid.initialize({
|
||||||
|
theme: 'forest',
|
||||||
|
logLevel: 3,
|
||||||
|
securityLevel: 'loose',
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -131,6 +131,22 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
<pre id="diagram4" class="mermaid">
|
<pre id="diagram4" class="mermaid">
|
||||||
|
---
|
||||||
|
config:
|
||||||
|
layout: elk
|
||||||
|
elk:
|
||||||
|
mergeEdges: false
|
||||||
|
forceNodeModelOrder: false
|
||||||
|
considerModelOrder: NONE
|
||||||
|
|
||||||
|
---
|
||||||
|
flowchart TB
|
||||||
|
a --> a1 & a2 & a3 & a4
|
||||||
|
b --> b1 & b2
|
||||||
|
b2 --> b3
|
||||||
|
b1 --> b4</pre
|
||||||
|
>
|
||||||
|
<pre id="diagram4" class="mermaid">
|
||||||
treemap
|
treemap
|
||||||
"Section 1"
|
"Section 1"
|
||||||
"Leaf 1.1": 12
|
"Leaf 1.1": 12
|
||||||
|
|||||||
@@ -41,10 +41,6 @@ graph TB
|
|||||||
const { svg } = await mermaid.render('d22', value);
|
const { svg } = await mermaid.render('d22', value);
|
||||||
console.log(svg);
|
console.log(svg);
|
||||||
el.innerHTML = svg;
|
el.innerHTML = svg;
|
||||||
// mermaid.test1('first_slow', 1200).then((r) => console.info(r));
|
|
||||||
// mermaid.test1('second_fast', 200).then((r) => console.info(r));
|
|
||||||
// mermaid.test1('third_fast', 200).then((r) => console.info(r));
|
|
||||||
// mermaid.test1('forth_slow', 1200).then((r) => console.info(r));
|
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ const contentLoadedApi = async function () {
|
|||||||
for (let i = 0; i < numCodes; i++) {
|
for (let i = 0; i < numCodes; i++) {
|
||||||
const { svg, bindFunctions } = await mermaid.render('newid' + i, graphObj.code[i], divs[i]);
|
const { svg, bindFunctions } = await mermaid.render('newid' + i, graphObj.code[i], divs[i]);
|
||||||
div.innerHTML = svg;
|
div.innerHTML = svg;
|
||||||
bindFunctions(div);
|
bindFunctions?.(div);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
@@ -194,7 +194,7 @@ const contentLoadedApi = async function () {
|
|||||||
const { svg, bindFunctions } = await mermaid.render('newid', graphObj.code, div);
|
const { svg, bindFunctions } = await mermaid.render('newid', graphObj.code, div);
|
||||||
div.innerHTML = svg;
|
div.innerHTML = svg;
|
||||||
console.log(div.innerHTML);
|
console.log(div.innerHTML);
|
||||||
bindFunctions(div);
|
bindFunctions?.(div);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,219 +2,223 @@
|
|||||||
"durations": [
|
"durations": [
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/other/configuration.spec.js",
|
"spec": "cypress/integration/other/configuration.spec.js",
|
||||||
"duration": 5672
|
"duration": 6162
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/other/external-diagrams.spec.js",
|
"spec": "cypress/integration/other/external-diagrams.spec.js",
|
||||||
"duration": 1990
|
"duration": 2148
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/other/ghsa.spec.js",
|
"spec": "cypress/integration/other/ghsa.spec.js",
|
||||||
"duration": 3186
|
"duration": 3585
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/other/iife.spec.js",
|
"spec": "cypress/integration/other/iife.spec.js",
|
||||||
"duration": 1948
|
"duration": 2099
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/other/interaction.spec.js",
|
"spec": "cypress/integration/other/interaction.spec.js",
|
||||||
"duration": 11938
|
"duration": 12119
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/other/rerender.spec.js",
|
"spec": "cypress/integration/other/rerender.spec.js",
|
||||||
"duration": 1932
|
"duration": 2063
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/other/xss.spec.js",
|
"spec": "cypress/integration/other/xss.spec.js",
|
||||||
"duration": 27237
|
"duration": 31921
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/appli.spec.js",
|
"spec": "cypress/integration/rendering/appli.spec.js",
|
||||||
"duration": 3170
|
"duration": 3385
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/architecture.spec.ts",
|
"spec": "cypress/integration/rendering/architecture.spec.ts",
|
||||||
"duration": 104
|
"duration": 108
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/block.spec.js",
|
"spec": "cypress/integration/rendering/block.spec.js",
|
||||||
"duration": 17390
|
"duration": 18063
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/c4.spec.js",
|
"spec": "cypress/integration/rendering/c4.spec.js",
|
||||||
"duration": 5296
|
"duration": 5519
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/classDiagram-elk-v3.spec.js",
|
"spec": "cypress/integration/rendering/classDiagram-elk-v3.spec.js",
|
||||||
"duration": 39004
|
"duration": 40040
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/classDiagram-handDrawn-v3.spec.js",
|
"spec": "cypress/integration/rendering/classDiagram-handDrawn-v3.spec.js",
|
||||||
"duration": 37653
|
"duration": 38665
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/classDiagram-v2.spec.js",
|
"spec": "cypress/integration/rendering/classDiagram-v2.spec.js",
|
||||||
"duration": 23278
|
"duration": 22836
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/classDiagram-v3.spec.js",
|
"spec": "cypress/integration/rendering/classDiagram-v3.spec.js",
|
||||||
"duration": 36645
|
"duration": 37096
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/classDiagram.spec.js",
|
"spec": "cypress/integration/rendering/classDiagram.spec.js",
|
||||||
"duration": 15418
|
"duration": 16452
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/conf-and-directives.spec.js",
|
"spec": "cypress/integration/rendering/conf-and-directives.spec.js",
|
||||||
"duration": 9684
|
"duration": 10387
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/current.spec.js",
|
"spec": "cypress/integration/rendering/current.spec.js",
|
||||||
"duration": 2570
|
"duration": 2803
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/erDiagram-unified.spec.js",
|
"spec": "cypress/integration/rendering/erDiagram-unified.spec.js",
|
||||||
"duration": 84687
|
"duration": 86891
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/erDiagram.spec.js",
|
"spec": "cypress/integration/rendering/erDiagram.spec.js",
|
||||||
"duration": 14819
|
"duration": 15206
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/errorDiagram.spec.js",
|
"spec": "cypress/integration/rendering/errorDiagram.spec.js",
|
||||||
"duration": 3371
|
"duration": 3540
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/flowchart-elk.spec.js",
|
"spec": "cypress/integration/rendering/flowchart-elk.spec.js",
|
||||||
"duration": 39925
|
"duration": 41975
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/flowchart-handDrawn.spec.js",
|
"spec": "cypress/integration/rendering/flowchart-handDrawn.spec.js",
|
||||||
"duration": 34694
|
"duration": 30909
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/flowchart-icon.spec.js",
|
"spec": "cypress/integration/rendering/flowchart-icon.spec.js",
|
||||||
"duration": 7137
|
"duration": 7881
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/flowchart-shape-alias.spec.ts",
|
"spec": "cypress/integration/rendering/flowchart-shape-alias.spec.ts",
|
||||||
"duration": 24740
|
"duration": 24294
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/flowchart-v2.spec.js",
|
"spec": "cypress/integration/rendering/flowchart-v2.spec.js",
|
||||||
"duration": 42077
|
"duration": 47652
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/flowchart.spec.js",
|
"spec": "cypress/integration/rendering/flowchart.spec.js",
|
||||||
"duration": 30642
|
"duration": 32049
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/gantt.spec.js",
|
"spec": "cypress/integration/rendering/gantt.spec.js",
|
||||||
"duration": 18085
|
"duration": 20248
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/gitGraph.spec.js",
|
"spec": "cypress/integration/rendering/gitGraph.spec.js",
|
||||||
"duration": 50107
|
"duration": 51202
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/iconShape.spec.ts",
|
"spec": "cypress/integration/rendering/iconShape.spec.ts",
|
||||||
"duration": 276279
|
"duration": 283546
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/imageShape.spec.ts",
|
"spec": "cypress/integration/rendering/imageShape.spec.ts",
|
||||||
"duration": 56505
|
"duration": 57257
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/info.spec.ts",
|
"spec": "cypress/integration/rendering/info.spec.ts",
|
||||||
"duration": 3036
|
"duration": 3352
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/journey.spec.js",
|
"spec": "cypress/integration/rendering/journey.spec.js",
|
||||||
"duration": 6889
|
"duration": 7423
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/kanban.spec.ts",
|
"spec": "cypress/integration/rendering/kanban.spec.ts",
|
||||||
"duration": 7353
|
"duration": 7804
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/katex.spec.js",
|
"spec": "cypress/integration/rendering/katex.spec.js",
|
||||||
"duration": 3580
|
"duration": 3847
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/marker_unique_id.spec.js",
|
"spec": "cypress/integration/rendering/marker_unique_id.spec.js",
|
||||||
"duration": 2508
|
"duration": 2637
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/mindmap.spec.ts",
|
"spec": "cypress/integration/rendering/mindmap.spec.ts",
|
||||||
"duration": 10939
|
"duration": 11658
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/newShapes.spec.ts",
|
"spec": "cypress/integration/rendering/newShapes.spec.ts",
|
||||||
"duration": 149102
|
"duration": 149500
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/oldShapes.spec.ts",
|
"spec": "cypress/integration/rendering/oldShapes.spec.ts",
|
||||||
"duration": 113987
|
"duration": 115427
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/packet.spec.ts",
|
"spec": "cypress/integration/rendering/packet.spec.ts",
|
||||||
"duration": 4060
|
"duration": 4801
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/pie.spec.ts",
|
"spec": "cypress/integration/rendering/pie.spec.ts",
|
||||||
"duration": 5715
|
"duration": 6786
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/quadrantChart.spec.js",
|
"spec": "cypress/integration/rendering/quadrantChart.spec.js",
|
||||||
"duration": 8945
|
"duration": 9422
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/radar.spec.js",
|
"spec": "cypress/integration/rendering/radar.spec.js",
|
||||||
"duration": 5337
|
"duration": 5652
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/requirement.spec.js",
|
"spec": "cypress/integration/rendering/requirement.spec.js",
|
||||||
"duration": 2643
|
"duration": 2787
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/requirementDiagram-unified.spec.js",
|
"spec": "cypress/integration/rendering/requirementDiagram-unified.spec.js",
|
||||||
"duration": 52072
|
"duration": 53631
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/sankey.spec.ts",
|
"spec": "cypress/integration/rendering/sankey.spec.ts",
|
||||||
"duration": 6692
|
"duration": 7075
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"spec": "cypress/integration/rendering/sequencediagram-v2.spec.js",
|
||||||
|
"duration": 20446
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/sequencediagram.spec.js",
|
"spec": "cypress/integration/rendering/sequencediagram.spec.js",
|
||||||
"duration": 35721
|
"duration": 37326
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/stateDiagram-v2.spec.js",
|
"spec": "cypress/integration/rendering/stateDiagram-v2.spec.js",
|
||||||
"duration": 26030
|
"duration": 29208
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/stateDiagram.spec.js",
|
"spec": "cypress/integration/rendering/stateDiagram.spec.js",
|
||||||
"duration": 16333
|
"duration": 16328
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/theme.spec.js",
|
"spec": "cypress/integration/rendering/theme.spec.js",
|
||||||
"duration": 29287
|
"duration": 30541
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/timeline.spec.ts",
|
"spec": "cypress/integration/rendering/timeline.spec.ts",
|
||||||
"duration": 8491
|
"duration": 8611
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/treemap.spec.ts",
|
"spec": "cypress/integration/rendering/treemap.spec.ts",
|
||||||
"duration": 12291
|
"duration": 11878
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/xyChart.spec.js",
|
"spec": "cypress/integration/rendering/xyChart.spec.js",
|
||||||
"duration": 20651
|
"duration": 20400
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/zenuml.spec.js",
|
"spec": "cypress/integration/rendering/zenuml.spec.js",
|
||||||
"duration": 3218
|
"duration": 3528
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<body>
|
<body>
|
||||||
<h1>Block diagram demos</h1>
|
<h1>Block diagram demos</h1>
|
||||||
<pre id="diagram" class="mermaid">
|
<pre id="diagram" class="mermaid">
|
||||||
block-beta
|
block
|
||||||
columns 1
|
columns 1
|
||||||
db(("DB"))
|
db(("DB"))
|
||||||
blockArrowId6<[" "]>(down)
|
blockArrowId6<[" "]>(down)
|
||||||
@@ -26,7 +26,7 @@ columns 1
|
|||||||
style B fill:#f9F,stroke:#333,stroke-width:4px
|
style B fill:#f9F,stroke:#333,stroke-width:4px
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram" class="mermaid">
|
<pre id="diagram" class="mermaid">
|
||||||
block-beta
|
block
|
||||||
A1["square"]
|
A1["square"]
|
||||||
B1("rounded")
|
B1("rounded")
|
||||||
C1(("circle"))
|
C1(("circle"))
|
||||||
@@ -36,7 +36,7 @@ block-beta
|
|||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<pre id="diagram" class="mermaid">
|
<pre id="diagram" class="mermaid">
|
||||||
block-beta
|
block
|
||||||
A1(["stadium"])
|
A1(["stadium"])
|
||||||
A2[["subroutine"]]
|
A2[["subroutine"]]
|
||||||
B1[("cylinder")]
|
B1[("cylinder")]
|
||||||
@@ -48,7 +48,7 @@ block-beta
|
|||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<pre id="diagram" class="mermaid">
|
<pre id="diagram" class="mermaid">
|
||||||
block-beta
|
block
|
||||||
block:e:4
|
block:e:4
|
||||||
columns 2
|
columns 2
|
||||||
f
|
f
|
||||||
@@ -57,7 +57,7 @@ block-beta
|
|||||||
|
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram" class="mermaid">
|
<pre id="diagram" class="mermaid">
|
||||||
block-beta
|
block
|
||||||
block:e:4
|
block:e:4
|
||||||
columns 2
|
columns 2
|
||||||
f
|
f
|
||||||
@@ -67,7 +67,7 @@ block-beta
|
|||||||
|
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram" class="mermaid">
|
<pre id="diagram" class="mermaid">
|
||||||
block-beta
|
block
|
||||||
columns 3
|
columns 3
|
||||||
a:3
|
a:3
|
||||||
block:e:3
|
block:e:3
|
||||||
@@ -80,7 +80,7 @@ block-beta
|
|||||||
|
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram" class="mermaid">
|
<pre id="diagram" class="mermaid">
|
||||||
block-beta
|
block
|
||||||
columns 4
|
columns 4
|
||||||
a b c d
|
a b c d
|
||||||
block:e:4
|
block:e:4
|
||||||
@@ -97,19 +97,19 @@ flowchart LR
|
|||||||
X-- "a label" -->z
|
X-- "a label" -->z
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram" class="mermaid">
|
<pre id="diagram" class="mermaid">
|
||||||
block-beta
|
block
|
||||||
columns 5
|
columns 5
|
||||||
A space B
|
A space B
|
||||||
A --x B
|
A --x B
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram" class="mermaid">
|
<pre id="diagram" class="mermaid">
|
||||||
block-beta
|
block
|
||||||
columns 3
|
columns 3
|
||||||
a["A wide one"] b:2 c:2 d
|
a["A wide one"] b:2 c:2 d
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<pre id="diagram" class="mermaid">
|
<pre id="diagram" class="mermaid">
|
||||||
block-beta
|
block
|
||||||
columns 3
|
columns 3
|
||||||
a b c
|
a b c
|
||||||
e:3
|
e:3
|
||||||
@@ -117,7 +117,7 @@ columns 3
|
|||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<pre id="diagram" class="mermaid">
|
<pre id="diagram" class="mermaid">
|
||||||
block-beta
|
block
|
||||||
|
|
||||||
A1:3
|
A1:3
|
||||||
A2:1
|
A2:1
|
||||||
|
|||||||
@@ -20,12 +20,14 @@
|
|||||||
width: 800
|
width: 800
|
||||||
nodeAlignment: left
|
nodeAlignment: left
|
||||||
---
|
---
|
||||||
sankey-beta
|
sankey
|
||||||
Revenue,Expenses,10
|
a,b,8
|
||||||
Revenue,Profit,10
|
b,c,8
|
||||||
Expenses,Manufacturing,5
|
c,d,8
|
||||||
Expenses,Tax,3
|
d,e,8
|
||||||
Expenses,Research,2
|
|
||||||
|
x,c,4
|
||||||
|
c,y,4
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<h2>Energy flow</h2>
|
<h2>Energy flow</h2>
|
||||||
@@ -40,7 +42,7 @@
|
|||||||
linkColor: gradient
|
linkColor: gradient
|
||||||
nodeAlignment: justify
|
nodeAlignment: justify
|
||||||
---
|
---
|
||||||
sankey-beta
|
sankey
|
||||||
|
|
||||||
Agricultural 'waste',Bio-conversion,124.729
|
Agricultural 'waste',Bio-conversion,124.729
|
||||||
Bio-conversion,Liquid,0.597
|
Bio-conversion,Liquid,0.597
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
<body>
|
<body>
|
||||||
<h1>XY Charts demos</h1>
|
<h1>XY Charts demos</h1>
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
xychart-beta
|
xychart
|
||||||
title "Sales Revenue (in $)"
|
title "Sales Revenue (in $)"
|
||||||
x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
<hr />
|
<hr />
|
||||||
<h1>XY Charts horizontal</h1>
|
<h1>XY Charts horizontal</h1>
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
xychart-beta horizontal
|
xychart horizontal
|
||||||
title "Basic xychart"
|
title "Basic xychart"
|
||||||
x-axis "this is x axis" [category1, "category 2", category3, category4]
|
x-axis "this is x axis" [category1, "category 2", category3, category4]
|
||||||
y-axis yaxisText 10 --> 150
|
y-axis yaxisText 10 --> 150
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
<hr />
|
<hr />
|
||||||
<h1>XY Charts only lines and bar</h1>
|
<h1>XY Charts only lines and bar</h1>
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
xychart-beta
|
xychart
|
||||||
line [23, 46, 77, 34]
|
line [23, 46, 77, 34]
|
||||||
line [45, 32, 33, 12]
|
line [45, 32, 33, 12]
|
||||||
line [87, 54, 99, 85]
|
line [87, 54, 99, 85]
|
||||||
@@ -48,13 +48,13 @@
|
|||||||
<hr />
|
<hr />
|
||||||
<h1>XY Charts with +ve and -ve numbers</h1>
|
<h1>XY Charts with +ve and -ve numbers</h1>
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
xychart-beta
|
xychart
|
||||||
line [+1.3, .6, 2.4, -.34]
|
line [+1.3, .6, 2.4, -.34]
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<h1>XY Charts Bar with multiple category</h1>
|
<h1>XY Charts Bar with multiple category</h1>
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
xychart-beta
|
xychart
|
||||||
title "Basic xychart with many categories"
|
title "Basic xychart with many categories"
|
||||||
x-axis "this is x axis" [category1, "category 2", category3, category4, category5, category6, category7]
|
x-axis "this is x axis" [category1, "category 2", category3, category4, category5, category6, category7]
|
||||||
y-axis yaxisText 10 --> 150
|
y-axis yaxisText 10 --> 150
|
||||||
@@ -63,7 +63,7 @@
|
|||||||
|
|
||||||
<h1>XY Charts line with multiple category</h1>
|
<h1>XY Charts line with multiple category</h1>
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
xychart-beta
|
xychart
|
||||||
title "Line chart with many category"
|
title "Line chart with many category"
|
||||||
x-axis "this is x axis" [category1, "category 2", category3, category4, category5, category6, category7]
|
x-axis "this is x axis" [category1, "category 2", category3, category4, category5, category6, category7]
|
||||||
y-axis yaxisText 10 --> 150
|
y-axis yaxisText 10 --> 150
|
||||||
@@ -72,7 +72,7 @@
|
|||||||
|
|
||||||
<h1>XY Charts category with large text</h1>
|
<h1>XY Charts category with large text</h1>
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
xychart-beta
|
xychart
|
||||||
title "Basic xychart with many categories with category overlap"
|
title "Basic xychart with many categories with category overlap"
|
||||||
x-axis "this is x axis" [category1, "Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint cillum sint consectetur cupidatat.", category3, category4, category5, category6, category7]
|
x-axis "this is x axis" [category1, "Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint cillum sint consectetur cupidatat.", category3, category4, category5, category6, category7]
|
||||||
y-axis yaxisText 10 --> 150
|
y-axis yaxisText 10 --> 150
|
||||||
@@ -89,7 +89,7 @@ config:
|
|||||||
height: 20
|
height: 20
|
||||||
plotReservedSpacePercent: 100
|
plotReservedSpacePercent: 100
|
||||||
---
|
---
|
||||||
xychart-beta
|
xychart
|
||||||
line [5000, 9000, 7500, 6200, 9500, 5500, 11000, 8200, 9200, 9500, 7000, 8800]
|
line [5000, 9000, 7500, 6200, 9500, 5500, 11000, 8200, 9200, 9500, 7000, 8800]
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
@@ -103,7 +103,7 @@ config:
|
|||||||
height: 20
|
height: 20
|
||||||
plotReservedSpacePercent: 100
|
plotReservedSpacePercent: 100
|
||||||
---
|
---
|
||||||
xychart-beta
|
xychart
|
||||||
bar [5000, 9000, 7500, 6200, 9500, 5500, 11000, 8200, 9200, 9500, 7000, 8800]
|
bar [5000, 9000, 7500, 6200, 9500, 5500, 11000, 8200, 9200, 9500, 7000, 8800]
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
@@ -136,7 +136,7 @@ config:
|
|||||||
chartOrientation: horizontal
|
chartOrientation: horizontal
|
||||||
plotReservedSpacePercent: 60
|
plotReservedSpacePercent: 60
|
||||||
---
|
---
|
||||||
xychart-beta
|
xychart
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
@@ -162,7 +162,7 @@ config:
|
|||||||
xAxisLineColor: "#87ceeb"
|
xAxisLineColor: "#87ceeb"
|
||||||
plotColorPalette: "#008000, #faba63"
|
plotColorPalette: "#008000, #faba63"
|
||||||
---
|
---
|
||||||
xychart-beta
|
xychart
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
- [addDirective](functions/addDirective.md)
|
- [addDirective](functions/addDirective.md)
|
||||||
- [getConfig](functions/getConfig.md)
|
- [getConfig](functions/getConfig.md)
|
||||||
- [getSiteConfig](functions/getSiteConfig.md)
|
- [getSiteConfig](functions/getSiteConfig.md)
|
||||||
|
- [getUserDefinedConfig](functions/getUserDefinedConfig.md)
|
||||||
- [reset](functions/reset.md)
|
- [reset](functions/reset.md)
|
||||||
- [sanitize](functions/sanitize.md)
|
- [sanitize](functions/sanitize.md)
|
||||||
- [saveConfigFromInitialize](functions/saveConfigFromInitialize.md)
|
- [saveConfigFromInitialize](functions/saveConfigFromInitialize.md)
|
||||||
|
|||||||
19
docs/config/setup/config/functions/getUserDefinedConfig.md
Normal file
19
docs/config/setup/config/functions/getUserDefinedConfig.md
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
> **Warning**
|
||||||
|
>
|
||||||
|
> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
|
||||||
|
>
|
||||||
|
> ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/setup/config/functions/getUserDefinedConfig.md](../../../../../packages/mermaid/src/docs/config/setup/config/functions/getUserDefinedConfig.md).
|
||||||
|
|
||||||
|
[**mermaid**](../../README.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Function: getUserDefinedConfig()
|
||||||
|
|
||||||
|
> **getUserDefinedConfig**(): [`MermaidConfig`](../../mermaid/interfaces/MermaidConfig.md)
|
||||||
|
|
||||||
|
Defined in: [packages/mermaid/src/config.ts:252](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L252)
|
||||||
|
|
||||||
|
## Returns
|
||||||
|
|
||||||
|
[`MermaidConfig`](../../mermaid/interfaces/MermaidConfig.md)
|
||||||
@@ -12,4 +12,4 @@
|
|||||||
|
|
||||||
> `const` **configKeys**: `Set`<`string`>
|
> `const` **configKeys**: `Set`<`string`>
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/defaultConfig.ts:290](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L290)
|
Defined in: [packages/mermaid/src/defaultConfig.ts:292](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L292)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ Defined in: [packages/mermaid/src/config.type.ts:58](https://github.com/mermaid-
|
|||||||
|
|
||||||
> `optional` **altFontFamily**: `string`
|
> `optional` **altFontFamily**: `string`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:122](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L122)
|
Defined in: [packages/mermaid/src/config.type.ts:132](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L132)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ Defined in: [packages/mermaid/src/config.type.ts:122](https://github.com/mermaid
|
|||||||
|
|
||||||
> `optional` **architecture**: `ArchitectureDiagramConfig`
|
> `optional` **architecture**: `ArchitectureDiagramConfig`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:194](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L194)
|
Defined in: [packages/mermaid/src/config.type.ts:204](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L204)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ Defined in: [packages/mermaid/src/config.type.ts:194](https://github.com/mermaid
|
|||||||
|
|
||||||
> `optional` **arrowMarkerAbsolute**: `boolean`
|
> `optional` **arrowMarkerAbsolute**: `boolean`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:141](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L141)
|
Defined in: [packages/mermaid/src/config.type.ts:151](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L151)
|
||||||
|
|
||||||
Controls whether or arrow markers in html code are absolute paths or anchors.
|
Controls whether or arrow markers in html code are absolute paths or anchors.
|
||||||
This matters if you are using base tag settings.
|
This matters if you are using base tag settings.
|
||||||
@@ -45,7 +45,7 @@ This matters if you are using base tag settings.
|
|||||||
|
|
||||||
> `optional` **block**: `BlockDiagramConfig`
|
> `optional` **block**: `BlockDiagramConfig`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:201](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L201)
|
Defined in: [packages/mermaid/src/config.type.ts:211](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L211)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ Defined in: [packages/mermaid/src/config.type.ts:201](https://github.com/mermaid
|
|||||||
|
|
||||||
> `optional` **c4**: `C4DiagramConfig`
|
> `optional` **c4**: `C4DiagramConfig`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:198](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L198)
|
Defined in: [packages/mermaid/src/config.type.ts:208](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L208)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ Defined in: [packages/mermaid/src/config.type.ts:198](https://github.com/mermaid
|
|||||||
|
|
||||||
> `optional` **class**: `ClassDiagramConfig`
|
> `optional` **class**: `ClassDiagramConfig`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:187](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L187)
|
Defined in: [packages/mermaid/src/config.type.ts:197](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L197)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ Defined in: [packages/mermaid/src/config.type.ts:187](https://github.com/mermaid
|
|||||||
|
|
||||||
> `optional` **darkMode**: `boolean`
|
> `optional` **darkMode**: `boolean`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:113](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L113)
|
Defined in: [packages/mermaid/src/config.type.ts:123](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L123)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ Defined in: [packages/mermaid/src/config.type.ts:113](https://github.com/mermaid
|
|||||||
|
|
||||||
> `optional` **deterministicIds**: `boolean`
|
> `optional` **deterministicIds**: `boolean`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:174](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L174)
|
Defined in: [packages/mermaid/src/config.type.ts:184](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L184)
|
||||||
|
|
||||||
This option controls if the generated ids of nodes in the SVG are
|
This option controls if the generated ids of nodes in the SVG are
|
||||||
generated randomly or based on a seed.
|
generated randomly or based on a seed.
|
||||||
@@ -93,7 +93,7 @@ should not change unless content is changed.
|
|||||||
|
|
||||||
> `optional` **deterministicIDSeed**: `string`
|
> `optional` **deterministicIDSeed**: `string`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:181](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L181)
|
Defined in: [packages/mermaid/src/config.type.ts:191](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L191)
|
||||||
|
|
||||||
This option is the optional seed for deterministic ids.
|
This option is the optional seed for deterministic ids.
|
||||||
If set to `undefined` but deterministicIds is `true`, a simple number iterator is used.
|
If set to `undefined` but deterministicIds is `true`, a simple number iterator is used.
|
||||||
@@ -105,7 +105,7 @@ You can set this attribute to base the seed on a static string.
|
|||||||
|
|
||||||
> `optional` **dompurifyConfig**: `Config`
|
> `optional` **dompurifyConfig**: `Config`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:203](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L203)
|
Defined in: [packages/mermaid/src/config.type.ts:213](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L213)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -115,12 +115,24 @@ Defined in: [packages/mermaid/src/config.type.ts:203](https://github.com/mermaid
|
|||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:91](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L91)
|
Defined in: [packages/mermaid/src/config.type.ts:91](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L91)
|
||||||
|
|
||||||
|
#### considerModelOrder?
|
||||||
|
|
||||||
|
> `optional` **considerModelOrder**: `"NONE"` | `"NODES_AND_EDGES"` | `"PREFER_EDGES"` | `"PREFER_NODES"`
|
||||||
|
|
||||||
|
Preserves the order of nodes and edges in the model file if this does not lead to additional edge crossings. Depending on the strategy this is not always possible since the node and edge order might be conflicting.
|
||||||
|
|
||||||
#### cycleBreakingStrategy?
|
#### cycleBreakingStrategy?
|
||||||
|
|
||||||
> `optional` **cycleBreakingStrategy**: `"GREEDY"` | `"DEPTH_FIRST"` | `"INTERACTIVE"` | `"MODEL_ORDER"` | `"GREEDY_MODEL_ORDER"`
|
> `optional` **cycleBreakingStrategy**: `"GREEDY"` | `"DEPTH_FIRST"` | `"INTERACTIVE"` | `"MODEL_ORDER"` | `"GREEDY_MODEL_ORDER"`
|
||||||
|
|
||||||
This strategy decides how to find cycles in the graph and deciding which edges need adjustment to break loops.
|
This strategy decides how to find cycles in the graph and deciding which edges need adjustment to break loops.
|
||||||
|
|
||||||
|
#### forceNodeModelOrder?
|
||||||
|
|
||||||
|
> `optional` **forceNodeModelOrder**: `boolean`
|
||||||
|
|
||||||
|
The node order given by the model does not change to produce a better layout. E.g. if node A is before node B in the model this is not changed during crossing minimization. This assumes that the node model order is already respected before crossing minimization. This can be achieved by setting considerModelOrder.strategy to NODES_AND_EDGES.
|
||||||
|
|
||||||
#### mergeEdges?
|
#### mergeEdges?
|
||||||
|
|
||||||
> `optional` **mergeEdges**: `boolean`
|
> `optional` **mergeEdges**: `boolean`
|
||||||
@@ -139,7 +151,7 @@ Elk specific option affecting how nodes are placed.
|
|||||||
|
|
||||||
> `optional` **er**: `ErDiagramConfig`
|
> `optional` **er**: `ErDiagramConfig`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:189](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L189)
|
Defined in: [packages/mermaid/src/config.type.ts:199](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L199)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -147,7 +159,7 @@ Defined in: [packages/mermaid/src/config.type.ts:189](https://github.com/mermaid
|
|||||||
|
|
||||||
> `optional` **flowchart**: `FlowchartDiagramConfig`
|
> `optional` **flowchart**: `FlowchartDiagramConfig`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:182](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L182)
|
Defined in: [packages/mermaid/src/config.type.ts:192](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L192)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -155,7 +167,7 @@ Defined in: [packages/mermaid/src/config.type.ts:182](https://github.com/mermaid
|
|||||||
|
|
||||||
> `optional` **fontFamily**: `string`
|
> `optional` **fontFamily**: `string`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:121](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L121)
|
Defined in: [packages/mermaid/src/config.type.ts:131](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L131)
|
||||||
|
|
||||||
Specifies the font to be used in the rendered diagrams.
|
Specifies the font to be used in the rendered diagrams.
|
||||||
Can be any possible CSS `font-family`.
|
Can be any possible CSS `font-family`.
|
||||||
@@ -167,7 +179,7 @@ See <https://developer.mozilla.org/en-US/docs/Web/CSS/font-family>
|
|||||||
|
|
||||||
> `optional` **fontSize**: `number`
|
> `optional` **fontSize**: `number`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:205](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L205)
|
Defined in: [packages/mermaid/src/config.type.ts:215](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L215)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -175,7 +187,7 @@ Defined in: [packages/mermaid/src/config.type.ts:205](https://github.com/mermaid
|
|||||||
|
|
||||||
> `optional` **forceLegacyMathML**: `boolean`
|
> `optional` **forceLegacyMathML**: `boolean`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:163](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L163)
|
Defined in: [packages/mermaid/src/config.type.ts:173](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L173)
|
||||||
|
|
||||||
This option forces Mermaid to rely on KaTeX's own stylesheet for rendering MathML. Due to differences between OS
|
This option forces Mermaid to rely on KaTeX's own stylesheet for rendering MathML. Due to differences between OS
|
||||||
fonts and browser's MathML implementation, this option is recommended if consistent rendering is important.
|
fonts and browser's MathML implementation, this option is recommended if consistent rendering is important.
|
||||||
@@ -187,7 +199,7 @@ If set to true, ignores legacyMathML.
|
|||||||
|
|
||||||
> `optional` **gantt**: `GanttDiagramConfig`
|
> `optional` **gantt**: `GanttDiagramConfig`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:184](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L184)
|
Defined in: [packages/mermaid/src/config.type.ts:194](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L194)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -195,7 +207,7 @@ Defined in: [packages/mermaid/src/config.type.ts:184](https://github.com/mermaid
|
|||||||
|
|
||||||
> `optional` **gitGraph**: `GitGraphDiagramConfig`
|
> `optional` **gitGraph**: `GitGraphDiagramConfig`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:197](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L197)
|
Defined in: [packages/mermaid/src/config.type.ts:207](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L207)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -213,7 +225,7 @@ Defines the seed to be used when using handDrawn look. This is important for the
|
|||||||
|
|
||||||
> `optional` **htmlLabels**: `boolean`
|
> `optional` **htmlLabels**: `boolean`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:114](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L114)
|
Defined in: [packages/mermaid/src/config.type.ts:124](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L124)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -221,7 +233,7 @@ Defined in: [packages/mermaid/src/config.type.ts:114](https://github.com/mermaid
|
|||||||
|
|
||||||
> `optional` **journey**: `JourneyDiagramConfig`
|
> `optional` **journey**: `JourneyDiagramConfig`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:185](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L185)
|
Defined in: [packages/mermaid/src/config.type.ts:195](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L195)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -229,7 +241,7 @@ Defined in: [packages/mermaid/src/config.type.ts:185](https://github.com/mermaid
|
|||||||
|
|
||||||
> `optional` **kanban**: `KanbanDiagramConfig`
|
> `optional` **kanban**: `KanbanDiagramConfig`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:196](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L196)
|
Defined in: [packages/mermaid/src/config.type.ts:206](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L206)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -247,7 +259,7 @@ Defines which layout algorithm to use for rendering the diagram.
|
|||||||
|
|
||||||
> `optional` **legacyMathML**: `boolean`
|
> `optional` **legacyMathML**: `boolean`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:156](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L156)
|
Defined in: [packages/mermaid/src/config.type.ts:166](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L166)
|
||||||
|
|
||||||
This option specifies if Mermaid can expect the dependent to include KaTeX stylesheets for browsers
|
This option specifies if Mermaid can expect the dependent to include KaTeX stylesheets for browsers
|
||||||
without their own MathML implementation. If this option is disabled and MathML is not supported, the math
|
without their own MathML implementation. If this option is disabled and MathML is not supported, the math
|
||||||
@@ -260,7 +272,7 @@ fall back to legacy rendering for KaTeX.
|
|||||||
|
|
||||||
> `optional` **logLevel**: `0` | `2` | `1` | `"trace"` | `"debug"` | `"info"` | `"warn"` | `"error"` | `"fatal"` | `3` | `4` | `5`
|
> `optional` **logLevel**: `0` | `2` | `1` | `"trace"` | `"debug"` | `"info"` | `"warn"` | `"error"` | `"fatal"` | `3` | `4` | `5`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:127](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L127)
|
Defined in: [packages/mermaid/src/config.type.ts:137](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L137)
|
||||||
|
|
||||||
This option decides the amount of logging to be used by mermaid.
|
This option decides the amount of logging to be used by mermaid.
|
||||||
|
|
||||||
@@ -280,7 +292,7 @@ Defines which main look to use for the diagram.
|
|||||||
|
|
||||||
> `optional` **markdownAutoWrap**: `boolean`
|
> `optional` **markdownAutoWrap**: `boolean`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:206](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L206)
|
Defined in: [packages/mermaid/src/config.type.ts:216](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L216)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -308,7 +320,7 @@ The maximum allowed size of the users text diagram
|
|||||||
|
|
||||||
> `optional` **mindmap**: `MindmapDiagramConfig`
|
> `optional` **mindmap**: `MindmapDiagramConfig`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:195](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L195)
|
Defined in: [packages/mermaid/src/config.type.ts:205](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L205)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -316,7 +328,7 @@ Defined in: [packages/mermaid/src/config.type.ts:195](https://github.com/mermaid
|
|||||||
|
|
||||||
> `optional` **packet**: `PacketDiagramConfig`
|
> `optional` **packet**: `PacketDiagramConfig`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:200](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L200)
|
Defined in: [packages/mermaid/src/config.type.ts:210](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L210)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -324,7 +336,7 @@ Defined in: [packages/mermaid/src/config.type.ts:200](https://github.com/mermaid
|
|||||||
|
|
||||||
> `optional` **pie**: `PieDiagramConfig`
|
> `optional` **pie**: `PieDiagramConfig`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:190](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L190)
|
Defined in: [packages/mermaid/src/config.type.ts:200](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L200)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -332,7 +344,7 @@ Defined in: [packages/mermaid/src/config.type.ts:190](https://github.com/mermaid
|
|||||||
|
|
||||||
> `optional` **quadrantChart**: `QuadrantChartConfig`
|
> `optional` **quadrantChart**: `QuadrantChartConfig`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:191](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L191)
|
Defined in: [packages/mermaid/src/config.type.ts:201](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L201)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -340,7 +352,7 @@ Defined in: [packages/mermaid/src/config.type.ts:191](https://github.com/mermaid
|
|||||||
|
|
||||||
> `optional` **radar**: `RadarDiagramConfig`
|
> `optional` **radar**: `RadarDiagramConfig`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:202](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L202)
|
Defined in: [packages/mermaid/src/config.type.ts:212](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L212)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -348,7 +360,7 @@ Defined in: [packages/mermaid/src/config.type.ts:202](https://github.com/mermaid
|
|||||||
|
|
||||||
> `optional` **requirement**: `RequirementDiagramConfig`
|
> `optional` **requirement**: `RequirementDiagramConfig`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:193](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L193)
|
Defined in: [packages/mermaid/src/config.type.ts:203](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L203)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -356,7 +368,7 @@ Defined in: [packages/mermaid/src/config.type.ts:193](https://github.com/mermaid
|
|||||||
|
|
||||||
> `optional` **sankey**: `SankeyDiagramConfig`
|
> `optional` **sankey**: `SankeyDiagramConfig`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:199](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L199)
|
Defined in: [packages/mermaid/src/config.type.ts:209](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L209)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -364,7 +376,7 @@ Defined in: [packages/mermaid/src/config.type.ts:199](https://github.com/mermaid
|
|||||||
|
|
||||||
> `optional` **secure**: `string`\[]
|
> `optional` **secure**: `string`\[]
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:148](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L148)
|
Defined in: [packages/mermaid/src/config.type.ts:158](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L158)
|
||||||
|
|
||||||
This option controls which `currentConfig` keys are considered secure and
|
This option controls which `currentConfig` keys are considered secure and
|
||||||
can only be changed via call to `mermaid.initialize`.
|
can only be changed via call to `mermaid.initialize`.
|
||||||
@@ -376,7 +388,7 @@ This prevents malicious graph directives from overriding a site's default securi
|
|||||||
|
|
||||||
> `optional` **securityLevel**: `"strict"` | `"loose"` | `"antiscript"` | `"sandbox"`
|
> `optional` **securityLevel**: `"strict"` | `"loose"` | `"antiscript"` | `"sandbox"`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:131](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L131)
|
Defined in: [packages/mermaid/src/config.type.ts:141](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L141)
|
||||||
|
|
||||||
Level of trust for parsed diagram
|
Level of trust for parsed diagram
|
||||||
|
|
||||||
@@ -386,7 +398,7 @@ Level of trust for parsed diagram
|
|||||||
|
|
||||||
> `optional` **sequence**: `SequenceDiagramConfig`
|
> `optional` **sequence**: `SequenceDiagramConfig`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:183](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L183)
|
Defined in: [packages/mermaid/src/config.type.ts:193](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L193)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -394,7 +406,7 @@ Defined in: [packages/mermaid/src/config.type.ts:183](https://github.com/mermaid
|
|||||||
|
|
||||||
> `optional` **startOnLoad**: `boolean`
|
> `optional` **startOnLoad**: `boolean`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:135](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L135)
|
Defined in: [packages/mermaid/src/config.type.ts:145](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L145)
|
||||||
|
|
||||||
Dictates whether mermaid starts on Page load
|
Dictates whether mermaid starts on Page load
|
||||||
|
|
||||||
@@ -404,7 +416,7 @@ Dictates whether mermaid starts on Page load
|
|||||||
|
|
||||||
> `optional` **state**: `StateDiagramConfig`
|
> `optional` **state**: `StateDiagramConfig`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:188](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L188)
|
Defined in: [packages/mermaid/src/config.type.ts:198](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L198)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -412,7 +424,7 @@ Defined in: [packages/mermaid/src/config.type.ts:188](https://github.com/mermaid
|
|||||||
|
|
||||||
> `optional` **suppressErrorRendering**: `boolean`
|
> `optional` **suppressErrorRendering**: `boolean`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:212](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L212)
|
Defined in: [packages/mermaid/src/config.type.ts:222](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L222)
|
||||||
|
|
||||||
Suppresses inserting 'Syntax error' diagram in the DOM.
|
Suppresses inserting 'Syntax error' diagram in the DOM.
|
||||||
This is useful when you want to control how to handle syntax errors in your application.
|
This is useful when you want to control how to handle syntax errors in your application.
|
||||||
@@ -450,7 +462,7 @@ Defined in: [packages/mermaid/src/config.type.ts:65](https://github.com/mermaid-
|
|||||||
|
|
||||||
> `optional` **timeline**: `TimelineDiagramConfig`
|
> `optional` **timeline**: `TimelineDiagramConfig`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:186](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L186)
|
Defined in: [packages/mermaid/src/config.type.ts:196](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L196)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -458,7 +470,7 @@ Defined in: [packages/mermaid/src/config.type.ts:186](https://github.com/mermaid
|
|||||||
|
|
||||||
> `optional` **wrap**: `boolean`
|
> `optional` **wrap**: `boolean`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:204](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L204)
|
Defined in: [packages/mermaid/src/config.type.ts:214](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L214)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -466,4 +478,4 @@ Defined in: [packages/mermaid/src/config.type.ts:204](https://github.com/mermaid
|
|||||||
|
|
||||||
> `optional` **xyChart**: `XYChartConfig`
|
> `optional` **xyChart**: `XYChartConfig`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.type.ts:192](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L192)
|
Defined in: [packages/mermaid/src/config.type.ts:202](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L202)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
# Interface: ParseOptions
|
# Interface: ParseOptions
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/types.ts:72](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L72)
|
Defined in: [packages/mermaid/src/types.ts:84](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L84)
|
||||||
|
|
||||||
## Properties
|
## Properties
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ Defined in: [packages/mermaid/src/types.ts:72](https://github.com/mermaid-js/mer
|
|||||||
|
|
||||||
> `optional` **suppressErrors**: `boolean`
|
> `optional` **suppressErrors**: `boolean`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/types.ts:77](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L77)
|
Defined in: [packages/mermaid/src/types.ts:89](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L89)
|
||||||
|
|
||||||
If `true`, parse will return `false` instead of throwing error when the diagram is invalid.
|
If `true`, parse will return `false` instead of throwing error when the diagram is invalid.
|
||||||
The `parseError` function will not be called.
|
The `parseError` function will not be called.
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
# Interface: ParseResult
|
# Interface: ParseResult
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/types.ts:80](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L80)
|
Defined in: [packages/mermaid/src/types.ts:92](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L92)
|
||||||
|
|
||||||
## Properties
|
## Properties
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ Defined in: [packages/mermaid/src/types.ts:80](https://github.com/mermaid-js/mer
|
|||||||
|
|
||||||
> **config**: [`MermaidConfig`](MermaidConfig.md)
|
> **config**: [`MermaidConfig`](MermaidConfig.md)
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/types.ts:88](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L88)
|
Defined in: [packages/mermaid/src/types.ts:100](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L100)
|
||||||
|
|
||||||
The config passed as YAML frontmatter or directives
|
The config passed as YAML frontmatter or directives
|
||||||
|
|
||||||
@@ -28,6 +28,6 @@ The config passed as YAML frontmatter or directives
|
|||||||
|
|
||||||
> **diagramType**: `string`
|
> **diagramType**: `string`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/types.ts:84](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L84)
|
Defined in: [packages/mermaid/src/types.ts:96](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L96)
|
||||||
|
|
||||||
The diagram type, e.g. 'flowchart', 'sequence', etc.
|
The diagram type, e.g. 'flowchart', 'sequence', etc.
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
# Interface: RenderResult
|
# Interface: RenderResult
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/types.ts:98](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L98)
|
Defined in: [packages/mermaid/src/types.ts:110](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L110)
|
||||||
|
|
||||||
## Properties
|
## Properties
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ Defined in: [packages/mermaid/src/types.ts:98](https://github.com/mermaid-js/mer
|
|||||||
|
|
||||||
> `optional` **bindFunctions**: (`element`) => `void`
|
> `optional` **bindFunctions**: (`element`) => `void`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/types.ts:116](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L116)
|
Defined in: [packages/mermaid/src/types.ts:128](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L128)
|
||||||
|
|
||||||
Bind function to be called after the svg has been inserted into the DOM.
|
Bind function to be called after the svg has been inserted into the DOM.
|
||||||
This is necessary for adding event listeners to the elements in the svg.
|
This is necessary for adding event listeners to the elements in the svg.
|
||||||
@@ -45,7 +45,7 @@ bindFunctions?.(div); // To call bindFunctions only if it's present.
|
|||||||
|
|
||||||
> **diagramType**: `string`
|
> **diagramType**: `string`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/types.ts:106](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L106)
|
Defined in: [packages/mermaid/src/types.ts:118](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L118)
|
||||||
|
|
||||||
The diagram type, e.g. 'flowchart', 'sequence', etc.
|
The diagram type, e.g. 'flowchart', 'sequence', etc.
|
||||||
|
|
||||||
@@ -55,6 +55,6 @@ The diagram type, e.g. 'flowchart', 'sequence', etc.
|
|||||||
|
|
||||||
> **svg**: `string`
|
> **svg**: `string`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/types.ts:102](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L102)
|
Defined in: [packages/mermaid/src/types.ts:114](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L114)
|
||||||
|
|
||||||
The svg code for the rendered graph.
|
The svg code for the rendered graph.
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ To add an integration to this list, see the [Integrations - create page](./integ
|
|||||||
- [Obsidian](https://help.obsidian.md/Editing+and+formatting/Advanced+formatting+syntax#Diagram) ✅
|
- [Obsidian](https://help.obsidian.md/Editing+and+formatting/Advanced+formatting+syntax#Diagram) ✅
|
||||||
- [Outline](https://docs.getoutline.com/s/guide/doc/diagrams-KQiKoT4wzK) ✅
|
- [Outline](https://docs.getoutline.com/s/guide/doc/diagrams-KQiKoT4wzK) ✅
|
||||||
- [Redmine](https://redmine.org)
|
- [Redmine](https://redmine.org)
|
||||||
- [Mermaid Macro](https://www.redmine.org/plugins/redmine_mermaid_macro)
|
- [Mermaid Macro](https://redmine.org/plugins/redmine_mermaid_macro)
|
||||||
- [Markdown for mermaid plugin](https://github.com/jamieh-mongolian/markdown-for-mermaid-plugin)
|
- [Markdown for mermaid plugin](https://github.com/jamieh-mongolian/markdown-for-mermaid-plugin)
|
||||||
- [redmine-mermaid](https://github.com/styz/redmine_mermaid)
|
- [redmine-mermaid](https://github.com/styz/redmine_mermaid)
|
||||||
- Visual Studio Code [Polyglot Interactive Notebooks](https://github.com/dotnet/interactive#net-interactive)
|
- Visual Studio Code [Polyglot Interactive Notebooks](https://github.com/dotnet/interactive#net-interactive)
|
||||||
@@ -117,7 +117,7 @@ Content Management Systems/Enterprise Content Management
|
|||||||
- [Grav CMS](https://getgrav.org/)
|
- [Grav CMS](https://getgrav.org/)
|
||||||
- [Mermaid Diagrams Plugin](https://github.com/DanielFlaum/grav-plugin-mermaid-diagrams)
|
- [Mermaid Diagrams Plugin](https://github.com/DanielFlaum/grav-plugin-mermaid-diagrams)
|
||||||
- [GitLab Markdown Adapter](https://github.com/Goutte/grav-plugin-gitlab-markdown-adapter)
|
- [GitLab Markdown Adapter](https://github.com/Goutte/grav-plugin-gitlab-markdown-adapter)
|
||||||
- [Tiki](https://tiki.org)
|
- [Tiki Wiki CMS Groupware](https://tiki.org)
|
||||||
- [Tracker Entity Relationship Diagram](https://doc.tiki.org/Tracker-Entity-Relationship-Diagram)
|
- [Tracker Entity Relationship Diagram](https://doc.tiki.org/Tracker-Entity-Relationship-Diagram)
|
||||||
- [VitePress](https://vitepress.vuejs.org/)
|
- [VitePress](https://vitepress.vuejs.org/)
|
||||||
- [Plugin for Mermaid.js](https://emersonbottero.github.io/vitepress-plugin-mermaid/)
|
- [Plugin for Mermaid.js](https://emersonbottero.github.io/vitepress-plugin-mermaid/)
|
||||||
|
|||||||
@@ -6,6 +6,66 @@
|
|||||||
|
|
||||||
# Blog
|
# Blog
|
||||||
|
|
||||||
|
## [Mermaid introduces the Visual Editor for Entity Relationship diagrams](https://docs.mermaidchart.com/blog/posts/mermaid-introduces-the-visual-editor-for-entity-relationship-diagrams)
|
||||||
|
|
||||||
|
7/15/2025 • 7 mins
|
||||||
|
|
||||||
|
Mermaid just introduced a Visual Editor for Entity Relationship diagrams, letting anyone map database structures through a simple point-and-click interface instead of code. This no-code ER builder now sits alongside Mermaid’s editors for flowcharts, sequence, and class diagrams, enabling teams to craft and share polished data models for apps, AI, and business processes.
|
||||||
|
|
||||||
|
## [Mermaid supports Treemap Diagrams now!!!](https://docs.mermaidchart.com/blog/posts/mermaid-have-treemap-diagrams-now)
|
||||||
|
|
||||||
|
7/3/2025 • 4 mins
|
||||||
|
|
||||||
|
Mermaid has introduced Treemap diagrams, currently in beta, enhancing hierarchical data visualization. Treemap diagrams use nested rectangles to represent data relationships, focusing on size and proportions. They offer various applications, including budget visualization and market analysis. With simple syntax and customization options, users can effectively present complex data hierarchies.
|
||||||
|
|
||||||
|
## [AI Diagram Generators and Data Visualization: Best Practices](https://docs.mermaidchart.com/blog/posts/ai-diagram-generators-and-data-visualization-best-practices)
|
||||||
|
|
||||||
|
7/2/2025 • 6 mins
|
||||||
|
|
||||||
|
AI diagram generators transform complex data into clear, interactive visuals – enabling faster analysis, better decisions, and stronger collaboration across teams. By combining automation with manual refinement, these tools empower anyone to communicate insights effectively, regardless of technical skill level.
|
||||||
|
|
||||||
|
## [How to Choose the Best AI Diagram Generator for Your Needs (2025)](https://docs.mermaidchart.com/blog/posts/how-to-choose-the-best-ai-diagram-generator-for-your-needs-2025)
|
||||||
|
|
||||||
|
6/26/2025 • 14 mins
|
||||||
|
|
||||||
|
AI diagram generators are transforming how developers visualize and communicate complex systems, reducing hours of manual work into minutes. With tools like Mermaid AI, users benefit from both code-based and visual editing, enabling seamless collaboration and precision. Whether you’re diagramming workflows, software architecture, or data relationships, the right AI tool can significantly boost productivity and streamline communication.
|
||||||
|
|
||||||
|
## [5 Time-Saving Tips for Using Mermaid’s AI Diagram Generator Effectively](https://docs.mermaidchart.com/blog/posts/5-time-saving-tips-for-using-mermaids-ai-diagram-generator-effectively)
|
||||||
|
|
||||||
|
6/11/2025 • 10 mins
|
||||||
|
|
||||||
|
See how developers can save time and boost productivity using Mermaid Chart’s AI diagram generator. Learn five practical tips that help turn plain language into powerful, professional diagrams.
|
||||||
|
|
||||||
|
## [Enhancing Team Collaboration with AI-Powered Diagrams](https://docs.mermaidchart.com/blog/posts/enhancing-team-collaboration-with-ai-powered-diagrams)
|
||||||
|
|
||||||
|
5/27/2025 • 6 mins
|
||||||
|
|
||||||
|
Software teams move fast, but old-school diagramming tools can’t keep up. Mermaid Chart replaces static slides and whiteboards with real-time, AI-generated visuals that evolve with your code and ideas. Just describe a process in plain English, and watch it come to life.
|
||||||
|
|
||||||
|
## [What is an AI Diagram Generator? Benefits and Use Cases](https://docs.mermaidchart.com/blog/posts/what-is-an-ai-diagram-generator-benefits-and-use-cases)
|
||||||
|
|
||||||
|
5/22/2025 • 6 mins
|
||||||
|
|
||||||
|
Discover how AI diagram generators like Mermaid Chart transform developer workflows. Instantly turn text into flowcharts, ERDs, and system diagrams, no manual drag-and-drop needed. Learn how it works, key benefits, and real-world use cases.
|
||||||
|
|
||||||
|
## [How to Use Mermaid Chart as an AI Diagram Generator for Developers](https://docs.mermaidchart.com/blog/posts/how-to-use-mermaid-chart-as-an-ai-diagram-generator)
|
||||||
|
|
||||||
|
5/21/2025 • 9 mins
|
||||||
|
|
||||||
|
Would an AI diagram generator make your life easier? We think it would!
|
||||||
|
|
||||||
|
## [Mermaid Chart VS Code Plugin: Create and Edit Mermaid.js Diagrams in Visual Studio Code](https://docs.mermaidchart.com/blog/posts/mermaid-chart-vs-code-plugin-create-and-edit-mermaid-js-diagrams-in-visual-studio-code)
|
||||||
|
|
||||||
|
3/21/2025 • 5 mins
|
||||||
|
|
||||||
|
The Mermaid Chart VS Code Plugin is a powerful developer diagramming tool that brings Mermaid.js diagramming directly into your Visual Studio Code environment. Whether you’re visualizing software architecture, documenting API flows, fixing bad documentation, or managing flowcharts and sequence diagrams, this plugin integrates seamlessly into your workflow. Key Features of the Mermaid Chart VS Code \[…]
|
||||||
|
|
||||||
|
## [Mermaid Chart: The Evolution of Mermaid](https://docs.mermaidchart.com/blog/posts/mermaid-chart-the-evolution-of-mermaid)
|
||||||
|
|
||||||
|
1/30/2025 • 3 mins
|
||||||
|
|
||||||
|
Mermaid revolutionized diagramming with its simple, markdown-style syntax, empowering millions of developers worldwide. Now, Mermaid Chart takes it further with AI-powered visuals, a GUI for seamless editing, real-time collaboration, and advanced design tools. Experience the next generation of diagramming—faster, smarter, and built for modern teams. Try Mermaid Chart today!
|
||||||
|
|
||||||
## [GUI for editing Mermaid Class Diagrams](https://docs.mermaidchart.com/blog/posts/gui-for-editing-mermaid-class-diagrams)
|
## [GUI for editing Mermaid Class Diagrams](https://docs.mermaidchart.com/blog/posts/gui-for-editing-mermaid-class-diagrams)
|
||||||
|
|
||||||
1/17/2025 • 5 mins
|
1/17/2025 • 5 mins
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
## Introduction to Block Diagrams
|
## Introduction to Block Diagrams
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
columns 1
|
columns 1
|
||||||
db(("DB"))
|
db(("DB"))
|
||||||
blockArrowId6<[" "]>(down)
|
blockArrowId6<[" "]>(down)
|
||||||
@@ -26,7 +26,7 @@ columns 1
|
|||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
block-beta
|
block
|
||||||
columns 1
|
columns 1
|
||||||
db(("DB"))
|
db(("DB"))
|
||||||
blockArrowId6<[" "]>(down)
|
blockArrowId6<[" "]>(down)
|
||||||
@@ -80,12 +80,12 @@ At its core, a block diagram consists of blocks representing different entities
|
|||||||
To create a simple block diagram with three blocks labeled 'a', 'b', and 'c', the syntax is as follows:
|
To create a simple block diagram with three blocks labeled 'a', 'b', and 'c', the syntax is as follows:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
a b c
|
a b c
|
||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
block-beta
|
block
|
||||||
a b c
|
a b c
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -101,13 +101,13 @@ While simple block diagrams are linear and straightforward, more complex systems
|
|||||||
In scenarios where you need to distribute blocks across multiple columns, you can specify the number of columns and arrange the blocks accordingly. Here's how to create a block diagram with three columns and four blocks, where the fourth block appears in a second row:
|
In scenarios where you need to distribute blocks across multiple columns, you can specify the number of columns and arrange the blocks accordingly. Here's how to create a block diagram with three columns and four blocks, where the fourth block appears in a second row:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
columns 3
|
columns 3
|
||||||
a b c d
|
a b c d
|
||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
block-beta
|
block
|
||||||
columns 3
|
columns 3
|
||||||
a b c d
|
a b c d
|
||||||
```
|
```
|
||||||
@@ -130,13 +130,13 @@ In more complex diagrams, you may need blocks that span multiple columns to emph
|
|||||||
To create a block diagram where one block spans across two columns, you can specify the desired width for each block:
|
To create a block diagram where one block spans across two columns, you can specify the desired width for each block:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
columns 3
|
columns 3
|
||||||
a["A label"] b:2 c:2 d
|
a["A label"] b:2 c:2 d
|
||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
block-beta
|
block
|
||||||
columns 3
|
columns 3
|
||||||
a["A label"] b:2 c:2 d
|
a["A label"] b:2 c:2 d
|
||||||
```
|
```
|
||||||
@@ -153,7 +153,7 @@ Composite blocks, or blocks within blocks, are an advanced feature in Mermaid's
|
|||||||
Creating a composite block involves defining a parent block and then nesting other blocks within it. Here's how to define a composite block with nested elements:
|
Creating a composite block involves defining a parent block and then nesting other blocks within it. Here's how to define a composite block with nested elements:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
block
|
block
|
||||||
D
|
D
|
||||||
end
|
end
|
||||||
@@ -161,7 +161,7 @@ block-beta
|
|||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
block-beta
|
block
|
||||||
block
|
block
|
||||||
D
|
D
|
||||||
end
|
end
|
||||||
@@ -180,7 +180,7 @@ Mermaid also allows for dynamic adjustment of column widths based on the content
|
|||||||
In diagrams with varying block sizes, Mermaid automatically adjusts the column widths to fit the largest block in each column. Here's an example:
|
In diagrams with varying block sizes, Mermaid automatically adjusts the column widths to fit the largest block in each column. Here's an example:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
columns 3
|
columns 3
|
||||||
a:3
|
a:3
|
||||||
block:group1:2
|
block:group1:2
|
||||||
@@ -195,7 +195,7 @@ block-beta
|
|||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
block-beta
|
block
|
||||||
columns 3
|
columns 3
|
||||||
a:3
|
a:3
|
||||||
block:group1:2
|
block:group1:2
|
||||||
@@ -215,7 +215,7 @@ This example demonstrates how Mermaid dynamically adjusts the width of the colum
|
|||||||
In scenarios where you need to stack blocks horizontally, you can use column width to accomplish the task. Blocks can be arranged vertically by putting them in a single column. Here is how you can create a block diagram in which 4 blocks are stacked on top of each other:
|
In scenarios where you need to stack blocks horizontally, you can use column width to accomplish the task. Blocks can be arranged vertically by putting them in a single column. Here is how you can create a block diagram in which 4 blocks are stacked on top of each other:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
block
|
block
|
||||||
columns 1
|
columns 1
|
||||||
a["A label"] b c d
|
a["A label"] b c d
|
||||||
@@ -223,7 +223,7 @@ block-beta
|
|||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
block-beta
|
block
|
||||||
block
|
block
|
||||||
columns 1
|
columns 1
|
||||||
a["A label"] b c d
|
a["A label"] b c d
|
||||||
@@ -247,12 +247,12 @@ Mermaid supports a range of block shapes to suit different diagramming needs, fr
|
|||||||
To create a block with round edges, which can be used to represent a softer or more flexible component:
|
To create a block with round edges, which can be used to represent a softer or more flexible component:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
id1("This is the text in the box")
|
id1("This is the text in the box")
|
||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
block-beta
|
block
|
||||||
id1("This is the text in the box")
|
id1("This is the text in the box")
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -261,12 +261,12 @@ block-beta
|
|||||||
A stadium-shaped block, resembling an elongated circle, can be used for components that are process-oriented:
|
A stadium-shaped block, resembling an elongated circle, can be used for components that are process-oriented:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
id1(["This is the text in the box"])
|
id1(["This is the text in the box"])
|
||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
block-beta
|
block
|
||||||
id1(["This is the text in the box"])
|
id1(["This is the text in the box"])
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -275,12 +275,12 @@ block-beta
|
|||||||
For representing subroutines or contained processes, a block with double vertical lines is useful:
|
For representing subroutines or contained processes, a block with double vertical lines is useful:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
id1[["This is the text in the box"]]
|
id1[["This is the text in the box"]]
|
||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
block-beta
|
block
|
||||||
id1[["This is the text in the box"]]
|
id1[["This is the text in the box"]]
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -289,12 +289,12 @@ block-beta
|
|||||||
The cylindrical shape is ideal for representing databases or storage components:
|
The cylindrical shape is ideal for representing databases or storage components:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
id1[("Database")]
|
id1[("Database")]
|
||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
block-beta
|
block
|
||||||
id1[("Database")]
|
id1[("Database")]
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -303,12 +303,12 @@ block-beta
|
|||||||
A circle can be used for centralized or pivotal components:
|
A circle can be used for centralized or pivotal components:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
id1(("This is the text in the circle"))
|
id1(("This is the text in the circle"))
|
||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
block-beta
|
block
|
||||||
id1(("This is the text in the circle"))
|
id1(("This is the text in the circle"))
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -319,36 +319,36 @@ For decision points, use a rhombus, and for unique or specialized processes, asy
|
|||||||
**Asymmetric**
|
**Asymmetric**
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
id1>"This is the text in the box"]
|
id1>"This is the text in the box"]
|
||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
block-beta
|
block
|
||||||
id1>"This is the text in the box"]
|
id1>"This is the text in the box"]
|
||||||
```
|
```
|
||||||
|
|
||||||
**Rhombus**
|
**Rhombus**
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
id1{"This is the text in the box"}
|
id1{"This is the text in the box"}
|
||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
block-beta
|
block
|
||||||
id1{"This is the text in the box"}
|
id1{"This is the text in the box"}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Hexagon**
|
**Hexagon**
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
id1{{"This is the text in the box"}}
|
id1{{"This is the text in the box"}}
|
||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
block-beta
|
block
|
||||||
id1{{"This is the text in the box"}}
|
id1{{"This is the text in the box"}}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -357,7 +357,7 @@ block-beta
|
|||||||
Parallelogram and trapezoid shapes are perfect for inputs/outputs and transitional processes:
|
Parallelogram and trapezoid shapes are perfect for inputs/outputs and transitional processes:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
id1[/"This is the text in the box"/]
|
id1[/"This is the text in the box"/]
|
||||||
id2[\"This is the text in the box"\]
|
id2[\"This is the text in the box"\]
|
||||||
A[/"Christmas"\]
|
A[/"Christmas"\]
|
||||||
@@ -365,7 +365,7 @@ block-beta
|
|||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
block-beta
|
block
|
||||||
id1[/"This is the text in the box"/]
|
id1[/"This is the text in the box"/]
|
||||||
id2[\"This is the text in the box"\]
|
id2[\"This is the text in the box"\]
|
||||||
A[/"Christmas"\]
|
A[/"Christmas"\]
|
||||||
@@ -377,12 +377,12 @@ block-beta
|
|||||||
For highlighting critical or high-priority components, a double circle can be effective:
|
For highlighting critical or high-priority components, a double circle can be effective:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
id1((("This is the text in the circle")))
|
id1((("This is the text in the circle")))
|
||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
block-beta
|
block
|
||||||
id1((("This is the text in the circle")))
|
id1((("This is the text in the circle")))
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -395,7 +395,7 @@ Mermaid also offers unique shapes like block arrows and space blocks for directi
|
|||||||
Block arrows can visually indicate direction or flow within a process:
|
Block arrows can visually indicate direction or flow within a process:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
blockArrowId<["Label"]>(right)
|
blockArrowId<["Label"]>(right)
|
||||||
blockArrowId2<["Label"]>(left)
|
blockArrowId2<["Label"]>(left)
|
||||||
blockArrowId3<["Label"]>(up)
|
blockArrowId3<["Label"]>(up)
|
||||||
@@ -406,7 +406,7 @@ block-beta
|
|||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
block-beta
|
block
|
||||||
blockArrowId<["Label"]>(right)
|
blockArrowId<["Label"]>(right)
|
||||||
blockArrowId2<["Label"]>(left)
|
blockArrowId2<["Label"]>(left)
|
||||||
blockArrowId3<["Label"]>(up)
|
blockArrowId3<["Label"]>(up)
|
||||||
@@ -421,14 +421,14 @@ block-beta
|
|||||||
Space blocks can be used to create intentional empty spaces in the diagram, which is useful for layout and readability:
|
Space blocks can be used to create intentional empty spaces in the diagram, which is useful for layout and readability:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
columns 3
|
columns 3
|
||||||
a space b
|
a space b
|
||||||
c d e
|
c d e
|
||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
block-beta
|
block
|
||||||
columns 3
|
columns 3
|
||||||
a space b
|
a space b
|
||||||
c d e
|
c d e
|
||||||
@@ -437,12 +437,12 @@ block-beta
|
|||||||
or
|
or
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
ida space:3 idb idc
|
ida space:3 idb idc
|
||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
block-beta
|
block
|
||||||
ida space:3 idb idc
|
ida space:3 idb idc
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -467,13 +467,13 @@ The most fundamental aspect of connecting blocks is the use of arrows or links.
|
|||||||
A simple link with an arrow can be created to show direction or flow from one block to another:
|
A simple link with an arrow can be created to show direction or flow from one block to another:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
A space B
|
A space B
|
||||||
A-->B
|
A-->B
|
||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
block-beta
|
block
|
||||||
A space B
|
A space B
|
||||||
A-->B
|
A-->B
|
||||||
```
|
```
|
||||||
@@ -490,13 +490,13 @@ Example - Text with Links
|
|||||||
To add text to a link, the syntax includes the text within the link definition:
|
To add text to a link, the syntax includes the text within the link definition:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
A space:2 B
|
A space:2 B
|
||||||
A-- "X" -->B
|
A-- "X" -->B
|
||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
block-beta
|
block
|
||||||
A space:2 B
|
A space:2 B
|
||||||
A-- "X" -->B
|
A-- "X" -->B
|
||||||
```
|
```
|
||||||
@@ -506,7 +506,7 @@ This example show how to add descriptive text to the links, enhancing the inform
|
|||||||
Example - Edges and Styles:
|
Example - Edges and Styles:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
columns 1
|
columns 1
|
||||||
db(("DB"))
|
db(("DB"))
|
||||||
blockArrowId6<[" "]>(down)
|
blockArrowId6<[" "]>(down)
|
||||||
@@ -523,7 +523,7 @@ columns 1
|
|||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
block-beta
|
block
|
||||||
columns 1
|
columns 1
|
||||||
db(("DB"))
|
db(("DB"))
|
||||||
blockArrowId6<[" "]>(down)
|
blockArrowId6<[" "]>(down)
|
||||||
@@ -552,7 +552,7 @@ Mermaid enables detailed styling of individual blocks, allowing you to apply var
|
|||||||
To apply custom styles to a block, you can use the `style` keyword followed by the block identifier and the desired CSS properties:
|
To apply custom styles to a block, you can use the `style` keyword followed by the block identifier and the desired CSS properties:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
id1 space id2
|
id1 space id2
|
||||||
id1("Start")-->id2("Stop")
|
id1("Start")-->id2("Stop")
|
||||||
style id1 fill:#636,stroke:#333,stroke-width:4px
|
style id1 fill:#636,stroke:#333,stroke-width:4px
|
||||||
@@ -560,7 +560,7 @@ block-beta
|
|||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
block-beta
|
block
|
||||||
id1 space id2
|
id1 space id2
|
||||||
id1("Start")-->id2("Stop")
|
id1("Start")-->id2("Stop")
|
||||||
style id1 fill:#636,stroke:#333,stroke-width:4px
|
style id1 fill:#636,stroke:#333,stroke-width:4px
|
||||||
@@ -574,7 +574,7 @@ Mermaid enables applying styling to classes, which could make styling easier if
|
|||||||
#### Example - Styling a Single Class
|
#### Example - Styling a Single Class
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
A space B
|
A space B
|
||||||
A-->B
|
A-->B
|
||||||
classDef blue fill:#6e6ce6,stroke:#333,stroke-width:4px;
|
classDef blue fill:#6e6ce6,stroke:#333,stroke-width:4px;
|
||||||
@@ -583,7 +583,7 @@ block-beta
|
|||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
block-beta
|
block
|
||||||
A space B
|
A space B
|
||||||
A-->B
|
A-->B
|
||||||
classDef blue fill:#6e6ce6,stroke:#333,stroke-width:4px;
|
classDef blue fill:#6e6ce6,stroke:#333,stroke-width:4px;
|
||||||
@@ -608,7 +608,7 @@ Combining the elements of structure, linking, and styling, we can create compreh
|
|||||||
Illustrating a simple software system architecture with interconnected components:
|
Illustrating a simple software system architecture with interconnected components:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
columns 3
|
columns 3
|
||||||
Frontend blockArrowId6<[" "]>(right) Backend
|
Frontend blockArrowId6<[" "]>(right) Backend
|
||||||
space:2 down<[" "]>(down)
|
space:2 down<[" "]>(down)
|
||||||
@@ -621,7 +621,7 @@ block-beta
|
|||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
block-beta
|
block
|
||||||
columns 3
|
columns 3
|
||||||
Frontend blockArrowId6<[" "]>(right) Backend
|
Frontend blockArrowId6<[" "]>(right) Backend
|
||||||
space:2 down<[" "]>(down)
|
space:2 down<[" "]>(down)
|
||||||
@@ -640,7 +640,7 @@ This example shows a basic architecture with a frontend, backend, and database.
|
|||||||
Representing a business process flow with decision points and multiple stages:
|
Representing a business process flow with decision points and multiple stages:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
columns 3
|
columns 3
|
||||||
Start(("Start")) space:2
|
Start(("Start")) space:2
|
||||||
down<[" "]>(down) space:2
|
down<[" "]>(down) space:2
|
||||||
@@ -653,7 +653,7 @@ block-beta
|
|||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
block-beta
|
block
|
||||||
columns 3
|
columns 3
|
||||||
Start(("Start")) space:2
|
Start(("Start")) space:2
|
||||||
down<[" "]>(down) space:2
|
down<[" "]>(down) space:2
|
||||||
@@ -682,7 +682,7 @@ Understanding and avoiding common syntax errors is key to a smooth experience wi
|
|||||||
A common mistake is incorrect linking syntax, which can lead to unexpected results or broken diagrams:
|
A common mistake is incorrect linking syntax, which can lead to unexpected results or broken diagrams:
|
||||||
|
|
||||||
```
|
```
|
||||||
block-beta
|
block
|
||||||
A - B
|
A - B
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -690,13 +690,13 @@ block-beta
|
|||||||
Ensure that links between blocks are correctly specified with arrows (--> or ---) to define the direction and type of connection. Also remember that one of the fundamentals for block diagram is to give the author full control of where the boxes are positioned so in the example you need to add a space between the boxes:
|
Ensure that links between blocks are correctly specified with arrows (--> or ---) to define the direction and type of connection. Also remember that one of the fundamentals for block diagram is to give the author full control of where the boxes are positioned so in the example you need to add a space between the boxes:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
A space B
|
A space B
|
||||||
A --> B
|
A --> B
|
||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
block-beta
|
block
|
||||||
A space B
|
A space B
|
||||||
A --> B
|
A --> B
|
||||||
```
|
```
|
||||||
@@ -706,13 +706,13 @@ block-beta
|
|||||||
Applying styles in the wrong context or with incorrect syntax can lead to blocks not being styled as intended:
|
Applying styles in the wrong context or with incorrect syntax can lead to blocks not being styled as intended:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
A
|
A
|
||||||
style A fill#969;
|
style A fill#969;
|
||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
block-beta
|
block
|
||||||
A
|
A
|
||||||
style A fill#969;
|
style A fill#969;
|
||||||
```
|
```
|
||||||
@@ -721,14 +721,14 @@ Applying styles in the wrong context or with incorrect syntax can lead to blocks
|
|||||||
Correct the syntax by ensuring proper separation of style properties with commas and using the correct CSS property format:
|
Correct the syntax by ensuring proper separation of style properties with commas and using the correct CSS property format:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
A
|
A
|
||||||
style A fill:#969,stroke:#333;
|
style A fill:#969,stroke:#333;
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
block-beta
|
block
|
||||||
A
|
A
|
||||||
style A fill:#969,stroke:#333;
|
style A fill:#969,stroke:#333;
|
||||||
|
|
||||||
|
|||||||
@@ -983,11 +983,23 @@ flowchart TD
|
|||||||
- `b`
|
- `b`
|
||||||
- **w**: The width of the image. If not defined, this will default to the natural width of the image.
|
- **w**: The width of the image. If not defined, this will default to the natural width of the image.
|
||||||
- **h**: The height of the image. If not defined, this will default to the natural height of the image.
|
- **h**: The height of the image. If not defined, this will default to the natural height of the image.
|
||||||
- **constraint**: Determines if the image should constrain the node size. This setting also ensures the image maintains its original aspect ratio, adjusting the height (`h`) accordingly to the width (`w`). If not defined, this will default to `off` Possible values are:
|
- **constraint**: Determines if the image should constrain the node size. This setting also ensures the image maintains its original aspect ratio, adjusting the width (`w`) accordingly to the height (`h`). If not defined, this will default to `off` Possible values are:
|
||||||
- `on`
|
- `on`
|
||||||
- `off`
|
- `off`
|
||||||
|
|
||||||
These new shapes provide additional flexibility and visual appeal to your flowcharts, making them more informative and engaging.
|
If you want to resize an image, but keep the same aspect ratio, set `h`, and set `constraint: on` to constrain the aspect ratio. E.g.
|
||||||
|
|
||||||
|
```mermaid-example
|
||||||
|
flowchart TD
|
||||||
|
%% My image with a constrained aspect ratio
|
||||||
|
A@{ img: "https://mermaid.js.org/favicon.svg", label: "My example image label", pos: "t", h: 60, constraint: "on" }
|
||||||
|
```
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
%% My image with a constrained aspect ratio
|
||||||
|
A@{ img: "https://mermaid.js.org/favicon.svg", label: "My example image label", pos: "t", h: 60, constraint: "on" }
|
||||||
|
```
|
||||||
|
|
||||||
## Links between nodes
|
## Links between nodes
|
||||||
|
|
||||||
@@ -1816,7 +1828,7 @@ config:
|
|||||||
graph LR
|
graph LR
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Edge level curve style using Edge IDs (v\<MERMAID_RELEASE_VERSION>+)
|
#### Edge level curve style using Edge IDs (v11.10.0+)
|
||||||
|
|
||||||
You can assign IDs to [edges](#attaching-an-id-to-edges). After assigning an ID you can modify the line style by modifying the edge's `curve` property using the following syntax:
|
You can assign IDs to [edges](#attaching-an-id-to-edges). After assigning an ID you can modify the line style by modifying the edge's `curve` property using the following syntax:
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,11 @@ Drawing a pie chart is really simple in mermaid.
|
|||||||
- Followed by `:` colon as separator
|
- Followed by `:` colon as separator
|
||||||
- Followed by `positive numeric value` (supported up to two decimal places)
|
- Followed by `positive numeric value` (supported up to two decimal places)
|
||||||
|
|
||||||
|
**Note:**
|
||||||
|
|
||||||
|
> Pie chart values must be **positive numbers greater than zero**.
|
||||||
|
> **Negative values are not allowed** and will result in an error.
|
||||||
|
|
||||||
\[pie] \[showData] (OPTIONAL)
|
\[pie] \[showData] (OPTIONAL)
|
||||||
\[title] \[titlevalue] (OPTIONAL)
|
\[title] \[titlevalue] (OPTIONAL)
|
||||||
"\[datakey1]" : \[dataValue1]
|
"\[datakey1]" : \[dataValue1]
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ config:
|
|||||||
sankey:
|
sankey:
|
||||||
showValues: false
|
showValues: false
|
||||||
---
|
---
|
||||||
sankey-beta
|
sankey
|
||||||
|
|
||||||
Agricultural 'waste',Bio-conversion,124.729
|
Agricultural 'waste',Bio-conversion,124.729
|
||||||
Bio-conversion,Liquid,0.597
|
Bio-conversion,Liquid,0.597
|
||||||
@@ -101,7 +101,7 @@ config:
|
|||||||
sankey:
|
sankey:
|
||||||
showValues: false
|
showValues: false
|
||||||
---
|
---
|
||||||
sankey-beta
|
sankey
|
||||||
|
|
||||||
Agricultural 'waste',Bio-conversion,124.729
|
Agricultural 'waste',Bio-conversion,124.729
|
||||||
Bio-conversion,Liquid,0.597
|
Bio-conversion,Liquid,0.597
|
||||||
@@ -175,7 +175,7 @@ Wind,Electricity grid,289.366
|
|||||||
|
|
||||||
## Syntax
|
## Syntax
|
||||||
|
|
||||||
The idea behind syntax is that a user types `sankey-beta` keyword first, then pastes raw CSV below and get the result.
|
The idea behind syntax is that a user types `sankey` keyword first, then pastes raw CSV below and get the result.
|
||||||
|
|
||||||
It implements CSV standard as [described here](https://www.ietf.org/rfc/rfc4180.txt) with subtle **differences**:
|
It implements CSV standard as [described here](https://www.ietf.org/rfc/rfc4180.txt) with subtle **differences**:
|
||||||
|
|
||||||
@@ -187,7 +187,7 @@ It implements CSV standard as [described here](https://www.ietf.org/rfc/rfc4180.
|
|||||||
It is implied that 3 columns inside CSV should represent `source`, `target` and `value` accordingly:
|
It is implied that 3 columns inside CSV should represent `source`, `target` and `value` accordingly:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
sankey-beta
|
sankey
|
||||||
|
|
||||||
%% source,target,value
|
%% source,target,value
|
||||||
Electricity grid,Over generation / exports,104.453
|
Electricity grid,Over generation / exports,104.453
|
||||||
@@ -196,7 +196,7 @@ Electricity grid,H2 conversion,27.14
|
|||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
sankey-beta
|
sankey
|
||||||
|
|
||||||
%% source,target,value
|
%% source,target,value
|
||||||
Electricity grid,Over generation / exports,104.453
|
Electricity grid,Over generation / exports,104.453
|
||||||
@@ -209,7 +209,7 @@ Electricity grid,H2 conversion,27.14
|
|||||||
CSV does not support empty lines without comma delimiters by default. But you can add them if needed:
|
CSV does not support empty lines without comma delimiters by default. But you can add them if needed:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
sankey-beta
|
sankey
|
||||||
|
|
||||||
Bio-conversion,Losses,26.862
|
Bio-conversion,Losses,26.862
|
||||||
|
|
||||||
@@ -219,7 +219,7 @@ Bio-conversion,Gas,81.144
|
|||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
sankey-beta
|
sankey
|
||||||
|
|
||||||
Bio-conversion,Losses,26.862
|
Bio-conversion,Losses,26.862
|
||||||
|
|
||||||
@@ -233,14 +233,14 @@ Bio-conversion,Gas,81.144
|
|||||||
If you need to have a comma, wrap it in double quotes:
|
If you need to have a comma, wrap it in double quotes:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
sankey-beta
|
sankey
|
||||||
|
|
||||||
Pumped heat,"Heating and cooling, homes",193.026
|
Pumped heat,"Heating and cooling, homes",193.026
|
||||||
Pumped heat,"Heating and cooling, commercial",70.672
|
Pumped heat,"Heating and cooling, commercial",70.672
|
||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
sankey-beta
|
sankey
|
||||||
|
|
||||||
Pumped heat,"Heating and cooling, homes",193.026
|
Pumped heat,"Heating and cooling, homes",193.026
|
||||||
Pumped heat,"Heating and cooling, commercial",70.672
|
Pumped heat,"Heating and cooling, commercial",70.672
|
||||||
@@ -251,14 +251,14 @@ Pumped heat,"Heating and cooling, commercial",70.672
|
|||||||
If you need to have double quote, put a pair of them inside quoted string:
|
If you need to have double quote, put a pair of them inside quoted string:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
sankey-beta
|
sankey
|
||||||
|
|
||||||
Pumped heat,"Heating and cooling, ""homes""",193.026
|
Pumped heat,"Heating and cooling, ""homes""",193.026
|
||||||
Pumped heat,"Heating and cooling, ""commercial""",70.672
|
Pumped heat,"Heating and cooling, ""commercial""",70.672
|
||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
sankey-beta
|
sankey
|
||||||
|
|
||||||
Pumped heat,"Heating and cooling, ""homes""",193.026
|
Pumped heat,"Heating and cooling, ""homes""",193.026
|
||||||
Pumped heat,"Heating and cooling, ""commercial""",70.672
|
Pumped heat,"Heating and cooling, ""commercial""",70.672
|
||||||
|
|||||||
@@ -76,218 +76,122 @@ sequenceDiagram
|
|||||||
|
|
||||||
### Boundary
|
### Boundary
|
||||||
|
|
||||||
If you want to use the boundary symbol for a participant, use the `boundary` statement as shown below.
|
If you want to use the boundary symbol for a participant, use the JSON configuration syntax as shown below.
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
boundary theBoundary
|
participant Alice@{ "type" : "boundary" }
|
||||||
participant Bob
|
participant Bob
|
||||||
theBoundary->>Bob: Request from boundary
|
Alice->>Bob: Request from boundary
|
||||||
Bob->>theBoundary: Response to boundary
|
Bob->>Alice: Response to boundary
|
||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
boundary theBoundary
|
participant Alice@{ "type" : "boundary" }
|
||||||
participant Bob
|
participant Bob
|
||||||
theBoundary->>Bob: Request from boundary
|
Alice->>Bob: Request from boundary
|
||||||
Bob->>theBoundary: Response to boundary
|
Bob->>Alice: Response to boundary
|
||||||
```
|
|
||||||
|
|
||||||
```mermaid-example
|
|
||||||
sequenceDiagram
|
|
||||||
boundary theBoundary
|
|
||||||
participant Bob
|
|
||||||
theBoundary->>Bob: Request from boundary
|
|
||||||
Bob->>theBoundary: Response to boundary
|
|
||||||
```
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
sequenceDiagram
|
|
||||||
boundary theBoundary
|
|
||||||
participant Bob
|
|
||||||
theBoundary->>Bob: Request from boundary
|
|
||||||
Bob->>theBoundary: Response to boundary
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Control
|
### Control
|
||||||
|
|
||||||
If you want to use the control symbol for a participant, use the `control` statement as shown below.
|
If you want to use the control symbol for a participant, use the JSON configuration syntax as shown below.
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
control theControl
|
participant Alice@{ "type" : "control" }
|
||||||
participant Alice
|
participant Bob
|
||||||
theControl->>Alice: Control request
|
Alice->>Bob: Control request
|
||||||
Alice->>theControl: Control response
|
Bob->>Alice: Control response
|
||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
control theControl
|
participant Alice@{ "type" : "control" }
|
||||||
participant Alice
|
participant Bob
|
||||||
theControl->>Alice: Control request
|
Alice->>Bob: Control request
|
||||||
Alice->>theControl: Control response
|
Bob->>Alice: Control response
|
||||||
```
|
|
||||||
|
|
||||||
```mermaid-example
|
|
||||||
sequenceDiagram
|
|
||||||
control theControl
|
|
||||||
participant Alice
|
|
||||||
theControl->>Alice: Control request
|
|
||||||
Alice->>theControl: Control response
|
|
||||||
```
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
sequenceDiagram
|
|
||||||
control theControl
|
|
||||||
participant Alice
|
|
||||||
theControl->>Alice: Control request
|
|
||||||
Alice->>theControl: Control response
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Entity
|
### Entity
|
||||||
|
|
||||||
If you want to use the entity symbol for a participant, use the `entity` statement as shown below.
|
If you want to use the entity symbol for a participant, use the JSON configuration syntax as shown below.
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
entity theEntity
|
participant Alice@{ "type" : "entity" }
|
||||||
participant Bob
|
participant Bob
|
||||||
theEntity->>Bob: Entity request
|
Alice->>Bob: Entity request
|
||||||
Bob->>theEntity: Entity response
|
Bob->>Alice: Entity response
|
||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
entity theEntity
|
participant Alice@{ "type" : "entity" }
|
||||||
participant Bob
|
participant Bob
|
||||||
theEntity->>Bob: Entity request
|
Alice->>Bob: Entity request
|
||||||
Bob->>theEntity: Entity response
|
Bob->>Alice: Entity response
|
||||||
```
|
|
||||||
|
|
||||||
```mermaid-example
|
|
||||||
sequenceDiagram
|
|
||||||
entity theEntity
|
|
||||||
participant Bob
|
|
||||||
theEntity->>Bob: Entity request
|
|
||||||
Bob->>theEntity: Entity response
|
|
||||||
```
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
sequenceDiagram
|
|
||||||
entity theEntity
|
|
||||||
participant Bob
|
|
||||||
theEntity->>Bob: Entity request
|
|
||||||
Bob->>theEntity: Entity response
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Database
|
### Database
|
||||||
|
|
||||||
If you want to use the database symbol for a participant, use the `database` statement as shown below.
|
If you want to use the database symbol for a participant, use the JSON configuration syntax as shown below.
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
database theDb
|
participant Alice@{ "type" : "database" }
|
||||||
participant Alice
|
participant Bob
|
||||||
theDb->>Alice: DB query
|
Alice->>Bob: DB query
|
||||||
Alice->>theDb: DB result
|
Bob->>Alice: DB result
|
||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
database theDb
|
participant Alice@{ "type" : "database" }
|
||||||
participant Alice
|
participant Bob
|
||||||
theDb->>Alice: DB query
|
Alice->>Bob: DB query
|
||||||
Alice->>theDb: DB result
|
Bob->>Alice: DB result
|
||||||
```
|
|
||||||
|
|
||||||
```mermaid-example
|
|
||||||
sequenceDiagram
|
|
||||||
database theDb
|
|
||||||
participant Alice
|
|
||||||
theDb->>Alice: DB query
|
|
||||||
Alice->>theDb: DB result
|
|
||||||
```
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
sequenceDiagram
|
|
||||||
database theDb
|
|
||||||
participant Alice
|
|
||||||
theDb->>Alice: DB query
|
|
||||||
Alice->>theDb: DB result
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Collections
|
### Collections
|
||||||
|
|
||||||
If you want to use the collections symbol for a participant, use the `collections` statement as shown below.
|
If you want to use the collections symbol for a participant, use the JSON configuration syntax as shown below.
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
collections theCollection
|
participant Alice@{ "type" : "collections" }
|
||||||
participant Bob
|
participant Bob
|
||||||
theCollection->>Bob: Collections request
|
Alice->>Bob: Collections request
|
||||||
Bob->>theCollection: Collections response
|
Bob->>Alice: Collections response
|
||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
collections theCollection
|
participant Alice@{ "type" : "collections" }
|
||||||
participant Bob
|
participant Bob
|
||||||
theCollection->>Bob: Collections request
|
Alice->>Bob: Collections request
|
||||||
Bob->>theCollection: Collections response
|
Bob->>Alice: Collections response
|
||||||
```
|
|
||||||
|
|
||||||
```mermaid-example
|
|
||||||
sequenceDiagram
|
|
||||||
collections theCollection
|
|
||||||
participant Bob
|
|
||||||
theCollection->>Bob: Collections request
|
|
||||||
Bob->>theCollection: Collections response
|
|
||||||
```
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
sequenceDiagram
|
|
||||||
collections theCollection
|
|
||||||
participant Bob
|
|
||||||
theCollection->>Bob: Collections request
|
|
||||||
Bob->>theCollection: Collections response
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Queue
|
### Queue
|
||||||
|
|
||||||
If you want to use the queue symbol for a participant, use the `queue` statement as shown below.
|
If you want to use the queue symbol for a participant, use the JSON configuration syntax as shown below.
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
queue theQueue
|
participant Alice@{ "type" : "queue" }
|
||||||
participant Alice
|
participant Bob
|
||||||
theQueue->>Alice: Queue message
|
Alice->>Bob: Queue message
|
||||||
Alice->>theQueue: Queue
|
Bob->>Alice: Queue response
|
||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
queue theQueue
|
participant Alice@{ "type" : "queue" }
|
||||||
participant Alice
|
participant Bob
|
||||||
theQueue->>Alice: Queue message
|
Alice->>Bob: Queue message
|
||||||
Alice->>theQueue: Queue
|
Bob->>Alice: Queue response
|
||||||
```
|
|
||||||
|
|
||||||
```mermaid-example
|
|
||||||
sequenceDiagram
|
|
||||||
queue theQueue
|
|
||||||
participant Alice
|
|
||||||
theQueue->>Alice: Queue message
|
|
||||||
Alice->>theQueue: Queue
|
|
||||||
```
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
sequenceDiagram
|
|
||||||
queue theQueue
|
|
||||||
participant Alice
|
|
||||||
theQueue->>Alice: Queue message
|
|
||||||
Alice->>theQueue: Queue
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Aliases
|
### Aliases
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
## Example
|
## Example
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
xychart-beta
|
xychart
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
@@ -22,7 +22,7 @@ xychart-beta
|
|||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
xychart-beta
|
xychart
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
@@ -40,7 +40,7 @@ xychart-beta
|
|||||||
The chart can be drawn horizontal or vertical, default value is vertical.
|
The chart can be drawn horizontal or vertical, default value is vertical.
|
||||||
|
|
||||||
```
|
```
|
||||||
xychart-beta horizontal
|
xychart horizontal
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ The title is a short description of the chart and it will always render on top o
|
|||||||
#### Example
|
#### Example
|
||||||
|
|
||||||
```
|
```
|
||||||
xychart-beta
|
xychart
|
||||||
title "This is a simple example"
|
title "This is a simple example"
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
@@ -98,10 +98,10 @@ A bar chart offers the capability to graphically depict bars.
|
|||||||
|
|
||||||
#### Simplest example
|
#### Simplest example
|
||||||
|
|
||||||
The only two things required are the chart name (`xychart-beta`) and one data set. So you will be able to draw a chart with a simple config like
|
The only two things required are the chart name (`xychart`) and one data set. So you will be able to draw a chart with a simple config like
|
||||||
|
|
||||||
```
|
```
|
||||||
xychart-beta
|
xychart
|
||||||
line [+1.3, .6, 2.4, -.34]
|
line [+1.3, .6, 2.4, -.34]
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -176,7 +176,7 @@ config:
|
|||||||
xyChart:
|
xyChart:
|
||||||
titleColor: "#ff0000"
|
titleColor: "#ff0000"
|
||||||
---
|
---
|
||||||
xychart-beta
|
xychart
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
@@ -195,7 +195,7 @@ config:
|
|||||||
xyChart:
|
xyChart:
|
||||||
titleColor: "#ff0000"
|
titleColor: "#ff0000"
|
||||||
---
|
---
|
||||||
xychart-beta
|
xychart
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
|
|||||||
@@ -27,9 +27,6 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"mermaid": "workspace:*"
|
"mermaid": "workspace:*"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
|
||||||
"mermaid": "workspace:~"
|
|
||||||
},
|
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,16 @@
|
|||||||
# @mermaid-js/layout-elk
|
# @mermaid-js/layout-elk
|
||||||
|
|
||||||
|
## 0.1.9
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- [#6857](https://github.com/mermaid-js/mermaid/pull/6857) [`b9ef683`](https://github.com/mermaid-js/mermaid/commit/b9ef683fb67b8959abc455d6cc5266c37ba435f6) Thanks [@knsv](https://github.com/knsv)! - feat: Exposing elk configuration forceNodeModelOrder and considerModelOrder to the mermaid configuration
|
||||||
|
|
||||||
|
- [#6849](https://github.com/mermaid-js/mermaid/pull/6849) [`2260948`](https://github.com/mermaid-js/mermaid/commit/2260948b7bda08f00616c2ce678bed1da69eb96c) Thanks [@anderium](https://github.com/anderium)! - Make elk not force node model order, but strongly consider it instead
|
||||||
|
|
||||||
|
- Updated dependencies [[`b9ef683`](https://github.com/mermaid-js/mermaid/commit/b9ef683fb67b8959abc455d6cc5266c37ba435f6), [`2c0931d`](https://github.com/mermaid-js/mermaid/commit/2c0931da46794b49d2523211e25f782900c34e94), [`33e08da`](https://github.com/mermaid-js/mermaid/commit/33e08daf175125295a06b1b80279437004a4e865), [`814b68b`](https://github.com/mermaid-js/mermaid/commit/814b68b4a94813f7c6b3d7fb4559532a7bab2652), [`fce7cab`](https://github.com/mermaid-js/mermaid/commit/fce7cabb71d68a20a66246fe23d066512126a412), [`fc07f0d`](https://github.com/mermaid-js/mermaid/commit/fc07f0d8abca49e4f887d7457b7b94fb07d1e3da), [`12e01bd`](https://github.com/mermaid-js/mermaid/commit/12e01bdb5cacf3569133979a5a4f1d8973e9aec1), [`01aaef3`](https://github.com/mermaid-js/mermaid/commit/01aaef39b4a1ec8bc5a0c6bfa3a20b712d67f4dc), [`daf8d8d`](https://github.com/mermaid-js/mermaid/commit/daf8d8d3befcd600618a629977b76463b38d0ad9), [`c36cd05`](https://github.com/mermaid-js/mermaid/commit/c36cd05c45ac3090181152b4dae41f8d7b569bd6), [`8bb29fc`](https://github.com/mermaid-js/mermaid/commit/8bb29fc879329ad109898e4025b4f4eba2ab0649), [`71b04f9`](https://github.com/mermaid-js/mermaid/commit/71b04f93b07f876df2b30656ef36036c1d0e4e4f), [`c99bce6`](https://github.com/mermaid-js/mermaid/commit/c99bce6bab4c7ce0b81b66d44f44853ce4aeb1c3), [`6cc1926`](https://github.com/mermaid-js/mermaid/commit/6cc192680a2531cab28f87a8061a53b786e010f3), [`9da6fb3`](https://github.com/mermaid-js/mermaid/commit/9da6fb39ae278401771943ac85d6d1b875f78cf1), [`e48b0ba`](https://github.com/mermaid-js/mermaid/commit/e48b0ba61dab7f95aa02da603b5b7d383b894932), [`4d62d59`](https://github.com/mermaid-js/mermaid/commit/4d62d5963238400270e9314c6e4d506f48147074), [`e9ce8cf`](https://github.com/mermaid-js/mermaid/commit/e9ce8cf4da9062d85098042044822100889bb0dd), [`9258b29`](https://github.com/mermaid-js/mermaid/commit/9258b2933bbe1ef41087345ffea3731673671c49), [`da90f67`](https://github.com/mermaid-js/mermaid/commit/da90f6760b6efb0da998bcb63b75eecc29e06c08), [`0133f1c`](https://github.com/mermaid-js/mermaid/commit/0133f1c0c5cff4fc4c8e0b99e9cf0b3d49dcbe71), [`895f9d4`](https://github.com/mermaid-js/mermaid/commit/895f9d43ff98ca05ebfba530789f677f31a011ff)]:
|
||||||
|
- mermaid@11.10.0
|
||||||
|
|
||||||
## 0.1.8
|
## 0.1.8
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@mermaid-js/layout-elk",
|
"name": "@mermaid-js/layout-elk",
|
||||||
"version": "0.1.8",
|
"version": "0.1.9",
|
||||||
"description": "ELK layout engine for mermaid",
|
"description": "ELK layout engine for mermaid",
|
||||||
"module": "dist/mermaid-layout-elk.core.mjs",
|
"module": "dist/mermaid-layout-elk.core.mjs",
|
||||||
"types": "dist/layouts.d.ts",
|
"types": "dist/layouts.d.ts",
|
||||||
|
|||||||
@@ -766,7 +766,10 @@ export const render = async (
|
|||||||
id: 'root',
|
id: 'root',
|
||||||
layoutOptions: {
|
layoutOptions: {
|
||||||
'elk.hierarchyHandling': 'INCLUDE_CHILDREN',
|
'elk.hierarchyHandling': 'INCLUDE_CHILDREN',
|
||||||
'elk.layered.crossingMinimization.forceNodeModelOrder': true,
|
'elk.layered.crossingMinimization.forceNodeModelOrder':
|
||||||
|
data4Layout.config.elk?.forceNodeModelOrder,
|
||||||
|
'elk.layered.considerModelOrder.strategy': data4Layout.config.elk?.considerModelOrder,
|
||||||
|
|
||||||
'elk.algorithm': algorithm,
|
'elk.algorithm': algorithm,
|
||||||
'nodePlacement.strategy': data4Layout.config.elk?.nodePlacementStrategy,
|
'nodePlacement.strategy': data4Layout.config.elk?.nodePlacementStrategy,
|
||||||
'elk.layered.mergeEdges': data4Layout.config.elk?.mergeEdges,
|
'elk.layered.mergeEdges': data4Layout.config.elk?.mergeEdges,
|
||||||
|
|||||||
@@ -1,5 +1,14 @@
|
|||||||
# @mermaid-js/mermaid-zenuml
|
# @mermaid-js/mermaid-zenuml
|
||||||
|
|
||||||
|
## 0.2.2
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- [#6798](https://github.com/mermaid-js/mermaid/pull/6798) [`3ffe961`](https://github.com/mermaid-js/mermaid/commit/3ffe9618aebc9ac96de6e3c826481f542f18c2a9) Thanks [@MrCoder](https://github.com/MrCoder)! - Fixed a critical bug that the ZenUML diagram is not rendered.
|
||||||
|
|
||||||
|
- Updated dependencies [[`b9ef683`](https://github.com/mermaid-js/mermaid/commit/b9ef683fb67b8959abc455d6cc5266c37ba435f6), [`2c0931d`](https://github.com/mermaid-js/mermaid/commit/2c0931da46794b49d2523211e25f782900c34e94), [`33e08da`](https://github.com/mermaid-js/mermaid/commit/33e08daf175125295a06b1b80279437004a4e865), [`814b68b`](https://github.com/mermaid-js/mermaid/commit/814b68b4a94813f7c6b3d7fb4559532a7bab2652), [`fce7cab`](https://github.com/mermaid-js/mermaid/commit/fce7cabb71d68a20a66246fe23d066512126a412), [`fc07f0d`](https://github.com/mermaid-js/mermaid/commit/fc07f0d8abca49e4f887d7457b7b94fb07d1e3da), [`12e01bd`](https://github.com/mermaid-js/mermaid/commit/12e01bdb5cacf3569133979a5a4f1d8973e9aec1), [`01aaef3`](https://github.com/mermaid-js/mermaid/commit/01aaef39b4a1ec8bc5a0c6bfa3a20b712d67f4dc), [`daf8d8d`](https://github.com/mermaid-js/mermaid/commit/daf8d8d3befcd600618a629977b76463b38d0ad9), [`c36cd05`](https://github.com/mermaid-js/mermaid/commit/c36cd05c45ac3090181152b4dae41f8d7b569bd6), [`8bb29fc`](https://github.com/mermaid-js/mermaid/commit/8bb29fc879329ad109898e4025b4f4eba2ab0649), [`71b04f9`](https://github.com/mermaid-js/mermaid/commit/71b04f93b07f876df2b30656ef36036c1d0e4e4f), [`c99bce6`](https://github.com/mermaid-js/mermaid/commit/c99bce6bab4c7ce0b81b66d44f44853ce4aeb1c3), [`6cc1926`](https://github.com/mermaid-js/mermaid/commit/6cc192680a2531cab28f87a8061a53b786e010f3), [`9da6fb3`](https://github.com/mermaid-js/mermaid/commit/9da6fb39ae278401771943ac85d6d1b875f78cf1), [`e48b0ba`](https://github.com/mermaid-js/mermaid/commit/e48b0ba61dab7f95aa02da603b5b7d383b894932), [`4d62d59`](https://github.com/mermaid-js/mermaid/commit/4d62d5963238400270e9314c6e4d506f48147074), [`e9ce8cf`](https://github.com/mermaid-js/mermaid/commit/e9ce8cf4da9062d85098042044822100889bb0dd), [`9258b29`](https://github.com/mermaid-js/mermaid/commit/9258b2933bbe1ef41087345ffea3731673671c49), [`da90f67`](https://github.com/mermaid-js/mermaid/commit/da90f6760b6efb0da998bcb63b75eecc29e06c08), [`0133f1c`](https://github.com/mermaid-js/mermaid/commit/0133f1c0c5cff4fc4c8e0b99e9cf0b3d49dcbe71), [`895f9d4`](https://github.com/mermaid-js/mermaid/commit/895f9d43ff98ca05ebfba530789f677f31a011ff)]:
|
||||||
|
- mermaid@11.10.0
|
||||||
|
|
||||||
## 0.2.1
|
## 0.2.1
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@mermaid-js/mermaid-zenuml",
|
"name": "@mermaid-js/mermaid-zenuml",
|
||||||
"version": "0.2.1",
|
"version": "0.2.2",
|
||||||
"description": "MermaidJS plugin for ZenUML integration",
|
"description": "MermaidJS plugin for ZenUML integration",
|
||||||
"module": "dist/mermaid-zenuml.core.mjs",
|
"module": "dist/mermaid-zenuml.core.mjs",
|
||||||
"types": "dist/detector.d.ts",
|
"types": "dist/detector.d.ts",
|
||||||
|
|||||||
@@ -1,5 +1,72 @@
|
|||||||
# mermaid
|
# mermaid
|
||||||
|
|
||||||
|
## 11.10.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- [#6744](https://github.com/mermaid-js/mermaid/pull/6744) [`daf8d8d`](https://github.com/mermaid-js/mermaid/commit/daf8d8d3befcd600618a629977b76463b38d0ad9) Thanks [@SpecularAura](https://github.com/SpecularAura)! - feat: Added support for per link curve styling in flowchart diagram using edge ids
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- [#6857](https://github.com/mermaid-js/mermaid/pull/6857) [`b9ef683`](https://github.com/mermaid-js/mermaid/commit/b9ef683fb67b8959abc455d6cc5266c37ba435f6) Thanks [@knsv](https://github.com/knsv)! - feat: Exposing elk configuration forceNodeModelOrder and considerModelOrder to the mermaid configuration
|
||||||
|
|
||||||
|
- [#6653](https://github.com/mermaid-js/mermaid/pull/6653) [`2c0931d`](https://github.com/mermaid-js/mermaid/commit/2c0931da46794b49d2523211e25f782900c34e94) Thanks [@darshanr0107](https://github.com/darshanr0107)! - chore: Remove the "-beta" suffix from the XYChart, Block, Sankey diagrams to reflect their stable status
|
||||||
|
|
||||||
|
- [#6683](https://github.com/mermaid-js/mermaid/pull/6683) [`33e08da`](https://github.com/mermaid-js/mermaid/commit/33e08daf175125295a06b1b80279437004a4e865) Thanks [@darshanr0107](https://github.com/darshanr0107)! - fix: Position the edge label in state diagram correctly relative to the edge
|
||||||
|
|
||||||
|
- [#6693](https://github.com/mermaid-js/mermaid/pull/6693) [`814b68b`](https://github.com/mermaid-js/mermaid/commit/814b68b4a94813f7c6b3d7fb4559532a7bab2652) Thanks [@darshanr0107](https://github.com/darshanr0107)! - fix: Apply correct dateFormat in Gantt chart to show only day when specified
|
||||||
|
|
||||||
|
- [#6734](https://github.com/mermaid-js/mermaid/pull/6734) [`fce7cab`](https://github.com/mermaid-js/mermaid/commit/fce7cabb71d68a20a66246fe23d066512126a412) Thanks [@darshanr0107](https://github.com/darshanr0107)! - fix: handle exclude dates properly in Gantt charts when using dateFormat: 'YYYY-MM-DD HH:mm:ss'
|
||||||
|
|
||||||
|
- [#6733](https://github.com/mermaid-js/mermaid/pull/6733) [`fc07f0d`](https://github.com/mermaid-js/mermaid/commit/fc07f0d8abca49e4f887d7457b7b94fb07d1e3da) Thanks [@omkarht](https://github.com/omkarht)! - fix: fixed connection gaps in flowchart for roundedRect, stadium and diamond shape
|
||||||
|
|
||||||
|
- [#6876](https://github.com/mermaid-js/mermaid/pull/6876) [`12e01bd`](https://github.com/mermaid-js/mermaid/commit/12e01bdb5cacf3569133979a5a4f1d8973e9aec1) Thanks [@sidharthv96](https://github.com/sidharthv96)! - fix: sanitize icon labels and icon SVGs
|
||||||
|
|
||||||
|
Resolves CVE-2025-54880 reported by @fourcube
|
||||||
|
|
||||||
|
- [#6801](https://github.com/mermaid-js/mermaid/pull/6801) [`01aaef3`](https://github.com/mermaid-js/mermaid/commit/01aaef39b4a1ec8bc5a0c6bfa3a20b712d67f4dc) Thanks [@sidharthv96](https://github.com/sidharthv96)! - fix: Update casing of ID in requirement diagram
|
||||||
|
|
||||||
|
- [#6796](https://github.com/mermaid-js/mermaid/pull/6796) [`c36cd05`](https://github.com/mermaid-js/mermaid/commit/c36cd05c45ac3090181152b4dae41f8d7b569bd6) Thanks [@HashanCP](https://github.com/HashanCP)! - fix: Make flowchart elk detector regex match less greedy
|
||||||
|
|
||||||
|
- [#6702](https://github.com/mermaid-js/mermaid/pull/6702) [`8bb29fc`](https://github.com/mermaid-js/mermaid/commit/8bb29fc879329ad109898e4025b4f4eba2ab0649) Thanks [@qraqras](https://github.com/qraqras)! - fix(block): overflowing blocks no longer affect later lines
|
||||||
|
|
||||||
|
This may change the layout of block diagrams that have overflowing lines
|
||||||
|
(i.e. block diagrams that use up more columns that the `columns` specifier).
|
||||||
|
|
||||||
|
- [#6717](https://github.com/mermaid-js/mermaid/pull/6717) [`71b04f9`](https://github.com/mermaid-js/mermaid/commit/71b04f93b07f876df2b30656ef36036c1d0e4e4f) Thanks [@darshanr0107](https://github.com/darshanr0107)! - fix: log warning for blocks exceeding column width
|
||||||
|
|
||||||
|
This update adds a validation check that logs a warning message when a block's width exceeds the defined column layout.
|
||||||
|
|
||||||
|
- [#6820](https://github.com/mermaid-js/mermaid/pull/6820) [`c99bce6`](https://github.com/mermaid-js/mermaid/commit/c99bce6bab4c7ce0b81b66d44f44853ce4aeb1c3) Thanks [@kriss-u](https://github.com/kriss-u)! - fix: Add escaped class literal name on namespace
|
||||||
|
|
||||||
|
- [#6332](https://github.com/mermaid-js/mermaid/pull/6332) [`6cc1926`](https://github.com/mermaid-js/mermaid/commit/6cc192680a2531cab28f87a8061a53b786e010f3) Thanks [@ajuckel](https://github.com/ajuckel)! - fix: Allow equals sign in sequenceDiagram labels
|
||||||
|
|
||||||
|
- [#6651](https://github.com/mermaid-js/mermaid/pull/6651) [`9da6fb3`](https://github.com/mermaid-js/mermaid/commit/9da6fb39ae278401771943ac85d6d1b875f78cf1) Thanks [@darshanr0107](https://github.com/darshanr0107)! - Add validation for negative values in pie charts:
|
||||||
|
|
||||||
|
Prevents crashes during parsing by validating values post-parsing.
|
||||||
|
|
||||||
|
Provides clearer, user-friendly error messages for invalid negative inputs.
|
||||||
|
|
||||||
|
- [#6803](https://github.com/mermaid-js/mermaid/pull/6803) [`e48b0ba`](https://github.com/mermaid-js/mermaid/commit/e48b0ba61dab7f95aa02da603b5b7d383b894932) Thanks [@omkarht](https://github.com/omkarht)! - chore: migrate to class-based ArchitectureDB implementation
|
||||||
|
|
||||||
|
- [#6838](https://github.com/mermaid-js/mermaid/pull/6838) [`4d62d59`](https://github.com/mermaid-js/mermaid/commit/4d62d5963238400270e9314c6e4d506f48147074) Thanks [@saurabhg772244](https://github.com/saurabhg772244)! - fix: node border style for handdrawn shapes
|
||||||
|
|
||||||
|
- [#6739](https://github.com/mermaid-js/mermaid/pull/6739) [`e9ce8cf`](https://github.com/mermaid-js/mermaid/commit/e9ce8cf4da9062d85098042044822100889bb0dd) Thanks [@kriss-u](https://github.com/kriss-u)! - fix: Update flowchart direction TD's behavior to be the same as TB
|
||||||
|
|
||||||
|
- [#6833](https://github.com/mermaid-js/mermaid/pull/6833) [`9258b29`](https://github.com/mermaid-js/mermaid/commit/9258b2933bbe1ef41087345ffea3731673671c49) Thanks [@darshanr0107](https://github.com/darshanr0107)! - fix: correctly render non-directional lines for '---' in block diagrams
|
||||||
|
|
||||||
|
- [#6855](https://github.com/mermaid-js/mermaid/pull/6855) [`da90f67`](https://github.com/mermaid-js/mermaid/commit/da90f6760b6efb0da998bcb63b75eecc29e06c08) Thanks [@sidharthv96](https://github.com/sidharthv96)! - fix: fallback to raw text instead of rendering _Unsupported markdown_ or empty blocks
|
||||||
|
|
||||||
|
Instead of printing **Unsupported markdown: XXX**, or empty blocks when using a markdown feature
|
||||||
|
that Mermaid does not yet support when `htmlLabels: true`(default) or `htmlLabels: false`,
|
||||||
|
fallback to the raw markdown text.
|
||||||
|
|
||||||
|
- [#6876](https://github.com/mermaid-js/mermaid/pull/6876) [`0133f1c`](https://github.com/mermaid-js/mermaid/commit/0133f1c0c5cff4fc4c8e0b99e9cf0b3d49dcbe71) Thanks [@sidharthv96](https://github.com/sidharthv96)! - fix: sanitize KATEX blocks
|
||||||
|
|
||||||
|
Resolves CVE-2025-54881 reported by @fourcube
|
||||||
|
|
||||||
|
- [#6804](https://github.com/mermaid-js/mermaid/pull/6804) [`895f9d4`](https://github.com/mermaid-js/mermaid/commit/895f9d43ff98ca05ebfba530789f677f31a011ff) Thanks [@omkarht](https://github.com/omkarht)! - chore: Update packet diagram to use new class-based database structure
|
||||||
|
|
||||||
## 11.9.0
|
## 11.9.0
|
||||||
|
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mermaid",
|
"name": "mermaid",
|
||||||
"version": "11.9.0",
|
"version": "11.10.0",
|
||||||
"description": "Markdown-ish syntax for generating flowcharts, mindmaps, sequence diagrams, class diagrams, gantt charts, git graphs and more.",
|
"description": "Markdown-ish syntax for generating flowcharts, mindmaps, sequence diagrams, class diagrams, gantt charts, git graphs and more.",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"module": "./dist/mermaid.core.mjs",
|
"module": "./dist/mermaid.core.mjs",
|
||||||
@@ -68,7 +68,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@braintree/sanitize-url": "^7.0.4",
|
"@braintree/sanitize-url": "^7.0.4",
|
||||||
"@iconify/utils": "^2.1.33",
|
"@iconify/utils": "^3.0.1",
|
||||||
"@mermaid-js/parser": "workspace:^",
|
"@mermaid-js/parser": "workspace:^",
|
||||||
"@types/d3": "^7.4.3",
|
"@types/d3": "^7.4.3",
|
||||||
"cytoscape": "^3.29.3",
|
"cytoscape": "^3.29.3",
|
||||||
|
|||||||
@@ -78,3 +78,187 @@ describe('when working with site config', () => {
|
|||||||
expect(config_4.altFontFamily).toBeUndefined();
|
expect(config_4.altFontFamily).toBeUndefined();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('getUserDefinedConfig', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
configApi.reset();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return empty object when no user config is defined', () => {
|
||||||
|
const userConfig = configApi.getUserDefinedConfig();
|
||||||
|
expect(userConfig).toEqual({});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return config from initialize only', () => {
|
||||||
|
const initConfig: MermaidConfig = { theme: 'dark', fontFamily: 'Arial' };
|
||||||
|
configApi.saveConfigFromInitialize(initConfig);
|
||||||
|
|
||||||
|
const userConfig = configApi.getUserDefinedConfig();
|
||||||
|
expect(userConfig).toEqual(initConfig);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return config from directives only', () => {
|
||||||
|
const directive1: MermaidConfig = { layout: 'elk', fontSize: 14 };
|
||||||
|
const directive2: MermaidConfig = { theme: 'forest' };
|
||||||
|
|
||||||
|
configApi.addDirective(directive1);
|
||||||
|
configApi.addDirective(directive2);
|
||||||
|
|
||||||
|
expect(configApi.getUserDefinedConfig()).toMatchInlineSnapshot(`
|
||||||
|
{
|
||||||
|
"fontFamily": "Arial",
|
||||||
|
"fontSize": 14,
|
||||||
|
"layout": "elk",
|
||||||
|
"theme": "forest",
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should combine initialize config and directives', () => {
|
||||||
|
const initConfig: MermaidConfig = { theme: 'dark', fontFamily: 'Arial', layout: 'dagre' };
|
||||||
|
const directive1: MermaidConfig = { layout: 'elk', fontSize: 14 };
|
||||||
|
const directive2: MermaidConfig = { theme: 'forest' };
|
||||||
|
|
||||||
|
configApi.saveConfigFromInitialize(initConfig);
|
||||||
|
configApi.addDirective(directive1);
|
||||||
|
configApi.addDirective(directive2);
|
||||||
|
|
||||||
|
const userConfig = configApi.getUserDefinedConfig();
|
||||||
|
expect(userConfig).toMatchInlineSnapshot(`
|
||||||
|
{
|
||||||
|
"fontFamily": "Arial",
|
||||||
|
"fontSize": 14,
|
||||||
|
"layout": "elk",
|
||||||
|
"theme": "forest",
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle nested config objects properly', () => {
|
||||||
|
const initConfig: MermaidConfig = {
|
||||||
|
flowchart: { nodeSpacing: 50, rankSpacing: 100 },
|
||||||
|
theme: 'default',
|
||||||
|
};
|
||||||
|
const directive: MermaidConfig = {
|
||||||
|
flowchart: { nodeSpacing: 75, curve: 'basis' },
|
||||||
|
mindmap: { padding: 20 },
|
||||||
|
};
|
||||||
|
|
||||||
|
configApi.saveConfigFromInitialize(initConfig);
|
||||||
|
configApi.addDirective(directive);
|
||||||
|
|
||||||
|
const userConfig = configApi.getUserDefinedConfig();
|
||||||
|
expect(userConfig).toMatchInlineSnapshot(`
|
||||||
|
{
|
||||||
|
"flowchart": {
|
||||||
|
"curve": "basis",
|
||||||
|
"nodeSpacing": 75,
|
||||||
|
"rankSpacing": 100,
|
||||||
|
},
|
||||||
|
"mindmap": {
|
||||||
|
"padding": 20,
|
||||||
|
},
|
||||||
|
"theme": "default",
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle complex nested overrides', () => {
|
||||||
|
const initConfig: MermaidConfig = {
|
||||||
|
flowchart: {
|
||||||
|
nodeSpacing: 50,
|
||||||
|
rankSpacing: 100,
|
||||||
|
curve: 'linear',
|
||||||
|
},
|
||||||
|
theme: 'default',
|
||||||
|
};
|
||||||
|
const directive1: MermaidConfig = {
|
||||||
|
flowchart: {
|
||||||
|
nodeSpacing: 75,
|
||||||
|
},
|
||||||
|
fontSize: 12,
|
||||||
|
};
|
||||||
|
const directive2: MermaidConfig = {
|
||||||
|
flowchart: {
|
||||||
|
curve: 'basis',
|
||||||
|
nodeSpacing: 100,
|
||||||
|
},
|
||||||
|
mindmap: {
|
||||||
|
padding: 15,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
configApi.saveConfigFromInitialize(initConfig);
|
||||||
|
configApi.addDirective(directive1);
|
||||||
|
configApi.addDirective(directive2);
|
||||||
|
|
||||||
|
const userConfig = configApi.getUserDefinedConfig();
|
||||||
|
expect(userConfig).toMatchInlineSnapshot(`
|
||||||
|
{
|
||||||
|
"flowchart": {
|
||||||
|
"curve": "basis",
|
||||||
|
"nodeSpacing": 100,
|
||||||
|
"rankSpacing": 100,
|
||||||
|
},
|
||||||
|
"fontSize": 12,
|
||||||
|
"mindmap": {
|
||||||
|
"padding": 15,
|
||||||
|
},
|
||||||
|
"theme": "default",
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return independent copies (not references)', () => {
|
||||||
|
const initConfig: MermaidConfig = { theme: 'dark', flowchart: { nodeSpacing: 50 } };
|
||||||
|
configApi.saveConfigFromInitialize(initConfig);
|
||||||
|
|
||||||
|
const userConfig1 = configApi.getUserDefinedConfig();
|
||||||
|
const userConfig2 = configApi.getUserDefinedConfig();
|
||||||
|
|
||||||
|
userConfig1.theme = 'neutral';
|
||||||
|
userConfig1.flowchart!.nodeSpacing = 999;
|
||||||
|
|
||||||
|
expect(userConfig2).toMatchInlineSnapshot(`
|
||||||
|
{
|
||||||
|
"flowchart": {
|
||||||
|
"nodeSpacing": 50,
|
||||||
|
},
|
||||||
|
"theme": "dark",
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle edge cases with undefined values', () => {
|
||||||
|
const initConfig: MermaidConfig = { theme: 'dark', layout: undefined };
|
||||||
|
const directive: MermaidConfig = { fontSize: 14, fontFamily: undefined };
|
||||||
|
|
||||||
|
configApi.saveConfigFromInitialize(initConfig);
|
||||||
|
configApi.addDirective(directive);
|
||||||
|
|
||||||
|
expect(configApi.getUserDefinedConfig()).toMatchInlineSnapshot(`
|
||||||
|
{
|
||||||
|
"fontSize": 14,
|
||||||
|
"layout": undefined,
|
||||||
|
"theme": "dark",
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should retain config from initialize after reset', () => {
|
||||||
|
const initConfig: MermaidConfig = { theme: 'dark' };
|
||||||
|
const directive: MermaidConfig = { layout: 'elk' };
|
||||||
|
|
||||||
|
configApi.saveConfigFromInitialize(initConfig);
|
||||||
|
configApi.addDirective(directive);
|
||||||
|
|
||||||
|
expect(configApi.getUserDefinedConfig()).toMatchInlineSnapshot(`
|
||||||
|
{
|
||||||
|
"layout": "elk",
|
||||||
|
"theme": "dark",
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
|
||||||
|
configApi.reset();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -248,3 +248,17 @@ const checkConfig = (config: MermaidConfig) => {
|
|||||||
issueWarning('LAZY_LOAD_DEPRECATED');
|
issueWarning('LAZY_LOAD_DEPRECATED');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getUserDefinedConfig = (): MermaidConfig => {
|
||||||
|
let userConfig: MermaidConfig = {};
|
||||||
|
|
||||||
|
if (configFromInitialize) {
|
||||||
|
userConfig = assignWithDepth(userConfig, configFromInitialize);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const d of directives) {
|
||||||
|
userConfig = assignWithDepth(userConfig, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
return userConfig;
|
||||||
|
};
|
||||||
|
|||||||
@@ -109,6 +109,16 @@ export interface MermaidConfig {
|
|||||||
| 'INTERACTIVE'
|
| 'INTERACTIVE'
|
||||||
| 'MODEL_ORDER'
|
| 'MODEL_ORDER'
|
||||||
| 'GREEDY_MODEL_ORDER';
|
| 'GREEDY_MODEL_ORDER';
|
||||||
|
/**
|
||||||
|
* The node order given by the model does not change to produce a better layout. E.g. if node A is before node B in the model this is not changed during crossing minimization. This assumes that the node model order is already respected before crossing minimization. This can be achieved by setting considerModelOrder.strategy to NODES_AND_EDGES.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
forceNodeModelOrder?: boolean;
|
||||||
|
/**
|
||||||
|
* Preserves the order of nodes and edges in the model file if this does not lead to additional edge crossings. Depending on the strategy this is not always possible since the node and edge order might be conflicting.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
considerModelOrder?: 'NONE' | 'NODES_AND_EDGES' | 'PREFER_EDGES' | 'PREFER_NODES';
|
||||||
};
|
};
|
||||||
darkMode?: boolean;
|
darkMode?: boolean;
|
||||||
htmlLabels?: boolean;
|
htmlLabels?: boolean;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { select } from 'd3';
|
import { select } from 'd3';
|
||||||
import { log } from '../logger.js';
|
|
||||||
import { getConfig } from '../diagram-api/diagramAPI.js';
|
import { getConfig } from '../diagram-api/diagramAPI.js';
|
||||||
import { evaluate } from '../diagrams/common/common.js';
|
import { evaluate, sanitizeText } from '../diagrams/common/common.js';
|
||||||
import { decodeEntities } from '../utils.js';
|
import { log } from '../logger.js';
|
||||||
import { replaceIconSubstring } from '../rendering-util/createText.js';
|
import { replaceIconSubstring } from '../rendering-util/createText.js';
|
||||||
|
import { decodeEntities } from '../utils.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param dom
|
* @param dom
|
||||||
@@ -19,14 +19,14 @@ function applyStyle(dom, styleFn) {
|
|||||||
* @param {any} node
|
* @param {any} node
|
||||||
* @returns {SVGForeignObjectElement} Node
|
* @returns {SVGForeignObjectElement} Node
|
||||||
*/
|
*/
|
||||||
function addHtmlLabel(node) {
|
function addHtmlLabel(node, config) {
|
||||||
const fo = select(document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject'));
|
const fo = select(document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject'));
|
||||||
const div = fo.append('xhtml:div');
|
const div = fo.append('xhtml:div');
|
||||||
|
|
||||||
const label = node.label;
|
const label = node.label;
|
||||||
const labelClass = node.isNode ? 'nodeLabel' : 'edgeLabel';
|
const labelClass = node.isNode ? 'nodeLabel' : 'edgeLabel';
|
||||||
const span = div.append('span');
|
const span = div.append('span');
|
||||||
span.html(label);
|
span.html(sanitizeText(label, config));
|
||||||
applyStyle(span, node.labelStyle);
|
applyStyle(span, node.labelStyle);
|
||||||
span.attr('class', labelClass);
|
span.attr('class', labelClass);
|
||||||
|
|
||||||
@@ -49,7 +49,8 @@ const createLabel = async (_vertexText, style, isTitle, isNode) => {
|
|||||||
if (typeof vertexText === 'object') {
|
if (typeof vertexText === 'object') {
|
||||||
vertexText = vertexText[0];
|
vertexText = vertexText[0];
|
||||||
}
|
}
|
||||||
if (evaluate(getConfig().flowchart.htmlLabels)) {
|
const config = getConfig();
|
||||||
|
if (evaluate(config.flowchart.htmlLabels)) {
|
||||||
// TODO: addHtmlLabel accepts a labelStyle. Do we possibly have that?
|
// TODO: addHtmlLabel accepts a labelStyle. Do we possibly have that?
|
||||||
vertexText = vertexText.replace(/\\n|\n/g, '<br />');
|
vertexText = vertexText.replace(/\\n|\n/g, '<br />');
|
||||||
log.debug('vertexText' + vertexText);
|
log.debug('vertexText' + vertexText);
|
||||||
@@ -59,7 +60,7 @@ const createLabel = async (_vertexText, style, isTitle, isNode) => {
|
|||||||
label,
|
label,
|
||||||
labelStyle: style.replace('fill:', 'color:'),
|
labelStyle: style.replace('fill:', 'color:'),
|
||||||
};
|
};
|
||||||
let vertexNode = addHtmlLabel(node);
|
let vertexNode = addHtmlLabel(node, config);
|
||||||
// vertexNode.parentNode.removeChild(vertexNode);
|
// vertexNode.parentNode.removeChild(vertexNode);
|
||||||
return vertexNode;
|
return vertexNode;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ const config: RequiredDeep<MermaidConfig> = {
|
|||||||
// mergeEdges is needed here to be considered
|
// mergeEdges is needed here to be considered
|
||||||
mergeEdges: false,
|
mergeEdges: false,
|
||||||
nodePlacementStrategy: 'BRANDES_KOEPF',
|
nodePlacementStrategy: 'BRANDES_KOEPF',
|
||||||
|
forceNodeModelOrder: false,
|
||||||
|
considerModelOrder: 'NODES_AND_EDGES',
|
||||||
},
|
},
|
||||||
themeCSS: undefined,
|
themeCSS: undefined,
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { getConfig } from '../../diagram-api/diagramAPI.js';
|
|||||||
import { createText } from '../../rendering-util/createText.js';
|
import { createText } from '../../rendering-util/createText.js';
|
||||||
import { getIconSVG } from '../../rendering-util/icons.js';
|
import { getIconSVG } from '../../rendering-util/icons.js';
|
||||||
import type { D3Element } from '../../types.js';
|
import type { D3Element } from '../../types.js';
|
||||||
|
import { sanitizeText } from '../common/common.js';
|
||||||
import type { ArchitectureDB } from './architectureDb.js';
|
import type { ArchitectureDB } from './architectureDb.js';
|
||||||
import { architectureIcons } from './architectureIcons.js';
|
import { architectureIcons } from './architectureIcons.js';
|
||||||
import {
|
import {
|
||||||
@@ -271,6 +272,7 @@ export const drawServices = async function (
|
|||||||
elem: D3Element,
|
elem: D3Element,
|
||||||
services: ArchitectureService[]
|
services: ArchitectureService[]
|
||||||
): Promise<number> {
|
): Promise<number> {
|
||||||
|
const config = getConfig();
|
||||||
for (const service of services) {
|
for (const service of services) {
|
||||||
const serviceElem = elem.append('g');
|
const serviceElem = elem.append('g');
|
||||||
const iconSize = db.getConfigField('iconSize');
|
const iconSize = db.getConfigField('iconSize');
|
||||||
@@ -285,7 +287,7 @@ export const drawServices = async function (
|
|||||||
width: iconSize * 1.5,
|
width: iconSize * 1.5,
|
||||||
classes: 'architecture-service-label',
|
classes: 'architecture-service-label',
|
||||||
},
|
},
|
||||||
getConfig()
|
config
|
||||||
);
|
);
|
||||||
|
|
||||||
textElem
|
textElem
|
||||||
@@ -320,7 +322,7 @@ export const drawServices = async function (
|
|||||||
.attr('class', 'node-icon-text')
|
.attr('class', 'node-icon-text')
|
||||||
.attr('style', `height: ${iconSize}px;`)
|
.attr('style', `height: ${iconSize}px;`)
|
||||||
.append('div')
|
.append('div')
|
||||||
.html(service.iconText);
|
.html(sanitizeText(service.iconText, config));
|
||||||
const fontSize =
|
const fontSize =
|
||||||
parseInt(
|
parseInt(
|
||||||
window
|
window
|
||||||
|
|||||||
@@ -238,13 +238,15 @@ export function edgeTypeStr2Type(typeStr: string): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function edgeStrToEdgeData(typeStr: string): string {
|
export function edgeStrToEdgeData(typeStr: string): string {
|
||||||
switch (typeStr.trim()) {
|
switch (typeStr.replace(/^[\s-]+|[\s-]+$/g, '')) {
|
||||||
case '--x':
|
case 'x':
|
||||||
return 'arrow_cross';
|
return 'arrow_cross';
|
||||||
case '--o':
|
case 'o':
|
||||||
return 'arrow_circle';
|
return 'arrow_circle';
|
||||||
default:
|
case '>':
|
||||||
return 'arrow_point';
|
return 'arrow_point';
|
||||||
|
default:
|
||||||
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-a
|
|||||||
const id = 'block';
|
const id = 'block';
|
||||||
|
|
||||||
const detector: DiagramDetector = (txt) => {
|
const detector: DiagramDetector = (txt) => {
|
||||||
return /^\s*block-beta/.test(txt);
|
return /^\s*block(-beta)?/.test(txt);
|
||||||
};
|
};
|
||||||
|
|
||||||
const loader = async () => {
|
const loader = async () => {
|
||||||
|
|||||||
@@ -36,10 +36,10 @@ CRLF \u000D\u000A
|
|||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
"block-beta" { return 'BLOCK_DIAGRAM_KEY'; }
|
"block-beta" { yy.getLogger().debug('Found block-beta'); return 'BLOCK_DIAGRAM_KEY'; }
|
||||||
"block"\s+ { yy.getLogger().debug('Found space-block'); return 'block';}
|
"block:" { yy.getLogger().debug('Found id-block'); return 'id-block'; }
|
||||||
"block"\n+ { yy.getLogger().debug('Found nl-block'); return 'block';}
|
"block" { yy.getLogger().debug('Found block'); return 'BLOCK_DIAGRAM_KEY'; }
|
||||||
"block:" { yy.getLogger().debug('Found space-block'); return 'id-block';}
|
|
||||||
// \s*\%\%.* { yy.getLogger().debug('Found comment',yytext); }
|
// \s*\%\%.* { yy.getLogger().debug('Found comment',yytext); }
|
||||||
[\s]+ { yy.getLogger().debug('.', yytext); /* skip all whitespace */ }
|
[\s]+ { yy.getLogger().debug('.', yytext); /* skip all whitespace */ }
|
||||||
[\n]+ {yy.getLogger().debug('_', yytext); /* skip all whitespace */ }
|
[\n]+ {yy.getLogger().debug('_', yytext); /* skip all whitespace */ }
|
||||||
@@ -240,7 +240,7 @@ columnsStatement
|
|||||||
|
|
||||||
blockStatement
|
blockStatement
|
||||||
: id-block nodeStatement document end { yy.getLogger().debug('Rule: id-block statement : ', $2, $3); const id2 = yy.generateId(); $$ = { ...$2, type:'composite', children: $3 }; }
|
: id-block nodeStatement document end { yy.getLogger().debug('Rule: id-block statement : ', $2, $3); const id2 = yy.generateId(); $$ = { ...$2, type:'composite', children: $3 }; }
|
||||||
| block document end { yy.getLogger().debug('Rule: blockStatement : ', $1, $2, $3); const id = yy.generateId(); $$ = { id, type:'composite', label:'', children: $2 }; }
|
| BLOCK_DIAGRAM_KEY document end { yy.getLogger().debug('Rule: blockStatement : ', $1, $2, $3); const id = yy.generateId(); $$ = { id, type:'composite', label:'', children: $2 }; }
|
||||||
;
|
;
|
||||||
|
|
||||||
node
|
node
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ describe('Block diagram', function () {
|
|||||||
expect(blocks[0].label).toBe('id');
|
expect(blocks[0].label).toBe('id');
|
||||||
});
|
});
|
||||||
it('a node with a square shape and a label', () => {
|
it('a node with a square shape and a label', () => {
|
||||||
const str = `block-beta
|
const str = `block
|
||||||
id["A label"]
|
id["A label"]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ describe('Block diagram', function () {
|
|||||||
expect(blocks[0].type).toBe('square');
|
expect(blocks[0].type).toBe('square');
|
||||||
});
|
});
|
||||||
it('a diagram with multiple nodes', () => {
|
it('a diagram with multiple nodes', () => {
|
||||||
const str = `block-beta
|
const str = `block
|
||||||
id1
|
id1
|
||||||
id2
|
id2
|
||||||
`;
|
`;
|
||||||
@@ -51,7 +51,7 @@ describe('Block diagram', function () {
|
|||||||
expect(blocks[1].type).toBe('na');
|
expect(blocks[1].type).toBe('na');
|
||||||
});
|
});
|
||||||
it('a diagram with multiple nodes', () => {
|
it('a diagram with multiple nodes', () => {
|
||||||
const str = `block-beta
|
const str = `block
|
||||||
id1
|
id1
|
||||||
id2
|
id2
|
||||||
id3
|
id3
|
||||||
@@ -72,7 +72,7 @@ describe('Block diagram', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('a node with a square shape and a label', () => {
|
it('a node with a square shape and a label', () => {
|
||||||
const str = `block-beta
|
const str = `block
|
||||||
id["A label"]
|
id["A label"]
|
||||||
id2`;
|
id2`;
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ describe('Block diagram', function () {
|
|||||||
expect(blocks[1].type).toBe('na');
|
expect(blocks[1].type).toBe('na');
|
||||||
});
|
});
|
||||||
it('a diagram with multiple nodes with edges abc123', () => {
|
it('a diagram with multiple nodes with edges abc123', () => {
|
||||||
const str = `block-beta
|
const str = `block
|
||||||
id1["first"] --> id2["second"]
|
id1["first"] --> id2["second"]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -101,7 +101,7 @@ describe('Block diagram', function () {
|
|||||||
expect(edges[0].arrowTypeEnd).toBe('arrow_point');
|
expect(edges[0].arrowTypeEnd).toBe('arrow_point');
|
||||||
});
|
});
|
||||||
it('a diagram with multiple nodes with edges abc123', () => {
|
it('a diagram with multiple nodes with edges abc123', () => {
|
||||||
const str = `block-beta
|
const str = `block
|
||||||
id1["first"] -- "a label" --> id2["second"]
|
id1["first"] -- "a label" --> id2["second"]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -116,7 +116,7 @@ describe('Block diagram', function () {
|
|||||||
expect(edges[0].label).toBe('a label');
|
expect(edges[0].label).toBe('a label');
|
||||||
});
|
});
|
||||||
it('a diagram with column statements', () => {
|
it('a diagram with column statements', () => {
|
||||||
const str = `block-beta
|
const str = `block
|
||||||
columns 2
|
columns 2
|
||||||
block1["Block 1"]
|
block1["Block 1"]
|
||||||
`;
|
`;
|
||||||
@@ -127,7 +127,7 @@ describe('Block diagram', function () {
|
|||||||
expect(blocks.length).toBe(1);
|
expect(blocks.length).toBe(1);
|
||||||
});
|
});
|
||||||
it('a diagram without column statements', () => {
|
it('a diagram without column statements', () => {
|
||||||
const str = `block-beta
|
const str = `block
|
||||||
block1["Block 1"]
|
block1["Block 1"]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -137,7 +137,7 @@ describe('Block diagram', function () {
|
|||||||
expect(blocks.length).toBe(1);
|
expect(blocks.length).toBe(1);
|
||||||
});
|
});
|
||||||
it('a diagram with auto column statements', () => {
|
it('a diagram with auto column statements', () => {
|
||||||
const str = `block-beta
|
const str = `block
|
||||||
columns auto
|
columns auto
|
||||||
block1["Block 1"]
|
block1["Block 1"]
|
||||||
`;
|
`;
|
||||||
@@ -149,7 +149,7 @@ describe('Block diagram', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('blocks next to each other', () => {
|
it('blocks next to each other', () => {
|
||||||
const str = `block-beta
|
const str = `block
|
||||||
columns 2
|
columns 2
|
||||||
block1["Block 1"]
|
block1["Block 1"]
|
||||||
block2["Block 2"]
|
block2["Block 2"]
|
||||||
@@ -163,7 +163,7 @@ describe('Block diagram', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('blocks on top of each other', () => {
|
it('blocks on top of each other', () => {
|
||||||
const str = `block-beta
|
const str = `block
|
||||||
columns 1
|
columns 1
|
||||||
block1["Block 1"]
|
block1["Block 1"]
|
||||||
block2["Block 2"]
|
block2["Block 2"]
|
||||||
@@ -177,7 +177,7 @@ describe('Block diagram', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('compound blocks 2', () => {
|
it('compound blocks 2', () => {
|
||||||
const str = `block-beta
|
const str = `block
|
||||||
block
|
block
|
||||||
aBlock["ABlock"]
|
aBlock["ABlock"]
|
||||||
bBlock["BBlock"]
|
bBlock["BBlock"]
|
||||||
@@ -205,7 +205,7 @@ describe('Block diagram', function () {
|
|||||||
expect(bBlock.type).toBe('square');
|
expect(bBlock.type).toBe('square');
|
||||||
});
|
});
|
||||||
it('compound blocks of compound blocks', () => {
|
it('compound blocks of compound blocks', () => {
|
||||||
const str = `block-beta
|
const str = `block
|
||||||
block
|
block
|
||||||
aBlock["ABlock"]
|
aBlock["ABlock"]
|
||||||
block
|
block
|
||||||
@@ -240,7 +240,7 @@ describe('Block diagram', function () {
|
|||||||
expect(bBlock.type).toBe('square');
|
expect(bBlock.type).toBe('square');
|
||||||
});
|
});
|
||||||
it('compound blocks with title', () => {
|
it('compound blocks with title', () => {
|
||||||
const str = `block-beta
|
const str = `block
|
||||||
block:compoundBlock["Compound block"]
|
block:compoundBlock["Compound block"]
|
||||||
columns 1
|
columns 1
|
||||||
block2["Block 2"]
|
block2["Block 2"]
|
||||||
@@ -265,7 +265,7 @@ describe('Block diagram', function () {
|
|||||||
expect(block2.type).toBe('square');
|
expect(block2.type).toBe('square');
|
||||||
});
|
});
|
||||||
it('blocks mixed with compound blocks', () => {
|
it('blocks mixed with compound blocks', () => {
|
||||||
const str = `block-beta
|
const str = `block
|
||||||
columns 1
|
columns 1
|
||||||
block1["Block 1"]
|
block1["Block 1"]
|
||||||
|
|
||||||
@@ -292,7 +292,7 @@ describe('Block diagram', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('Arrow blocks', () => {
|
it('Arrow blocks', () => {
|
||||||
const str = `block-beta
|
const str = `block
|
||||||
columns 3
|
columns 3
|
||||||
block1["Block 1"]
|
block1["Block 1"]
|
||||||
blockArrow<[" "]>(right)
|
blockArrow<[" "]>(right)
|
||||||
@@ -316,7 +316,7 @@ describe('Block diagram', function () {
|
|||||||
expect(blockArrow.directions).toContain('right');
|
expect(blockArrow.directions).toContain('right');
|
||||||
});
|
});
|
||||||
it('Arrow blocks with multiple points', () => {
|
it('Arrow blocks with multiple points', () => {
|
||||||
const str = `block-beta
|
const str = `block
|
||||||
columns 1
|
columns 1
|
||||||
A
|
A
|
||||||
blockArrow<[" "]>(up, down)
|
blockArrow<[" "]>(up, down)
|
||||||
@@ -339,7 +339,7 @@ describe('Block diagram', function () {
|
|||||||
expect(blockArrow.directions).not.toContain('right');
|
expect(blockArrow.directions).not.toContain('right');
|
||||||
});
|
});
|
||||||
it('blocks with different widths', () => {
|
it('blocks with different widths', () => {
|
||||||
const str = `block-beta
|
const str = `block
|
||||||
columns 3
|
columns 3
|
||||||
one["One Slot"]
|
one["One Slot"]
|
||||||
two["Two slots"]:2
|
two["Two slots"]:2
|
||||||
@@ -354,7 +354,7 @@ describe('Block diagram', function () {
|
|||||||
expect(two.widthInColumns).toBe(2);
|
expect(two.widthInColumns).toBe(2);
|
||||||
});
|
});
|
||||||
it('empty blocks', () => {
|
it('empty blocks', () => {
|
||||||
const str = `block-beta
|
const str = `block
|
||||||
columns 3
|
columns 3
|
||||||
space
|
space
|
||||||
middle["In the middle"]
|
middle["In the middle"]
|
||||||
@@ -373,7 +373,7 @@ describe('Block diagram', function () {
|
|||||||
expect(middle.label).toBe('In the middle');
|
expect(middle.label).toBe('In the middle');
|
||||||
});
|
});
|
||||||
it('classDef statements applied to a block', () => {
|
it('classDef statements applied to a block', () => {
|
||||||
const str = `block-beta
|
const str = `block
|
||||||
classDef black color:#ffffff, fill:#000000;
|
classDef black color:#ffffff, fill:#000000;
|
||||||
|
|
||||||
mc["Memcache"]
|
mc["Memcache"]
|
||||||
@@ -391,7 +391,7 @@ describe('Block diagram', function () {
|
|||||||
expect(black.styles[0]).toEqual('color:#ffffff');
|
expect(black.styles[0]).toEqual('color:#ffffff');
|
||||||
});
|
});
|
||||||
it('style statements applied to a block', () => {
|
it('style statements applied to a block', () => {
|
||||||
const str = `block-beta
|
const str = `block
|
||||||
columns 1
|
columns 1
|
||||||
B["A wide one in the middle"]
|
B["A wide one in the middle"]
|
||||||
style B fill:#f9F,stroke:#333,stroke-width:4px
|
style B fill:#f9F,stroke:#333,stroke-width:4px
|
||||||
@@ -426,9 +426,9 @@ columns 1
|
|||||||
|
|
||||||
describe('prototype properties', function () {
|
describe('prototype properties', function () {
|
||||||
function validateProperty(prop: string) {
|
function validateProperty(prop: string) {
|
||||||
expect(() => block.parse(`block-beta\n${prop}`)).not.toThrow();
|
expect(() => block.parse(`block\n${prop}`)).not.toThrow();
|
||||||
expect(() =>
|
expect(() =>
|
||||||
block.parse(`block-beta\nA; classDef ${prop} color:#ffffff,fill:#000000; class A ${prop}`)
|
block.parse(`block\nA; classDef ${prop} color:#ffffff,fill:#000000; class A ${prop}`)
|
||||||
).not.toThrow();
|
).not.toThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,13 +33,13 @@ function setupDompurifyHooks() {
|
|||||||
const TEMPORARY_ATTRIBUTE = 'data-temp-href-target';
|
const TEMPORARY_ATTRIBUTE = 'data-temp-href-target';
|
||||||
|
|
||||||
DOMPurify.addHook('beforeSanitizeAttributes', (node) => {
|
DOMPurify.addHook('beforeSanitizeAttributes', (node) => {
|
||||||
if (node instanceof Element && node.tagName === 'A' && node.hasAttribute('target')) {
|
if (node.tagName === 'A' && node.hasAttribute('target')) {
|
||||||
node.setAttribute(TEMPORARY_ATTRIBUTE, node.getAttribute('target') ?? '');
|
node.setAttribute(TEMPORARY_ATTRIBUTE, node.getAttribute('target') ?? '');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
DOMPurify.addHook('afterSanitizeAttributes', (node) => {
|
DOMPurify.addHook('afterSanitizeAttributes', (node) => {
|
||||||
if (node instanceof Element && node.tagName === 'A' && node.hasAttribute(TEMPORARY_ATTRIBUTE)) {
|
if (node.tagName === 'A' && node.hasAttribute(TEMPORARY_ATTRIBUTE)) {
|
||||||
node.setAttribute('target', node.getAttribute(TEMPORARY_ATTRIBUTE) ?? '');
|
node.setAttribute('target', node.getAttribute(TEMPORARY_ATTRIBUTE) ?? '');
|
||||||
node.removeAttribute(TEMPORARY_ATTRIBUTE);
|
node.removeAttribute(TEMPORARY_ATTRIBUTE);
|
||||||
if (node.getAttribute('target') === '_blank') {
|
if (node.getAttribute('target') === '_blank') {
|
||||||
@@ -311,9 +311,8 @@ export const hasKatex = (text: string): boolean => (text.match(katexRegex)?.leng
|
|||||||
* @returns Object containing \{width, height\}
|
* @returns Object containing \{width, height\}
|
||||||
*/
|
*/
|
||||||
export const calculateMathMLDimensions = async (text: string, config: MermaidConfig) => {
|
export const calculateMathMLDimensions = async (text: string, config: MermaidConfig) => {
|
||||||
text = await renderKatex(text, config);
|
|
||||||
const divElem = document.createElement('div');
|
const divElem = document.createElement('div');
|
||||||
divElem.innerHTML = text;
|
divElem.innerHTML = await renderKatexSanitized(text, config);
|
||||||
divElem.id = 'katex-temp';
|
divElem.id = 'katex-temp';
|
||||||
divElem.style.visibility = 'hidden';
|
divElem.style.visibility = 'hidden';
|
||||||
divElem.style.position = 'absolute';
|
divElem.style.position = 'absolute';
|
||||||
@@ -325,14 +324,7 @@ export const calculateMathMLDimensions = async (text: string, config: MermaidCon
|
|||||||
return dim;
|
return dim;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
const renderKatexUnsanitized = async (text: string, config: MermaidConfig): Promise<string> => {
|
||||||
* Attempts to render and return the KaTeX portion of a string with MathML
|
|
||||||
*
|
|
||||||
* @param text - The text to test
|
|
||||||
* @param config - Configuration for Mermaid
|
|
||||||
* @returns String containing MathML if KaTeX is supported, or an error message if it is not and stylesheets aren't present
|
|
||||||
*/
|
|
||||||
export const renderKatex = async (text: string, config: MermaidConfig): Promise<string> => {
|
|
||||||
if (!hasKatex(text)) {
|
if (!hasKatex(text)) {
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
@@ -373,6 +365,20 @@ export const renderKatex = async (text: string, config: MermaidConfig): Promise<
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to render and return the KaTeX portion of a string with MathML
|
||||||
|
*
|
||||||
|
* @param text - The text to test
|
||||||
|
* @param config - Configuration for Mermaid
|
||||||
|
* @returns String containing MathML if KaTeX is supported, or an error message if it is not and stylesheets aren't present
|
||||||
|
*/
|
||||||
|
export const renderKatexSanitized = async (
|
||||||
|
text: string,
|
||||||
|
config: MermaidConfig
|
||||||
|
): Promise<string> => {
|
||||||
|
return sanitizeText(await renderKatexUnsanitized(text, config), config);
|
||||||
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
getRows,
|
getRows,
|
||||||
sanitizeText,
|
sanitizeText,
|
||||||
|
|||||||
@@ -167,7 +167,10 @@ export const getTasks = function () {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const isInvalidDate = function (date, dateFormat, excludes, includes) {
|
export const isInvalidDate = function (date, dateFormat, excludes, includes) {
|
||||||
if (includes.includes(date.format(dateFormat.trim()))) {
|
const formattedDate = date.format(dateFormat.trim());
|
||||||
|
const dateOnly = date.format('YYYY-MM-DD');
|
||||||
|
|
||||||
|
if (includes.includes(formattedDate) || includes.includes(dateOnly)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
@@ -180,7 +183,7 @@ export const isInvalidDate = function (date, dateFormat, excludes, includes) {
|
|||||||
if (excludes.includes(date.format('dddd').toLowerCase())) {
|
if (excludes.includes(date.format('dddd').toLowerCase())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return excludes.includes(date.format(dateFormat.trim()));
|
return excludes.includes(formattedDate) || excludes.includes(dateOnly);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const setWeekday = function (txt) {
|
export const setWeekday = function (txt) {
|
||||||
|
|||||||
@@ -581,17 +581,11 @@ export const draw = function (text, id, version, diagObj) {
|
|||||||
|
|
||||||
rectangles
|
rectangles
|
||||||
.append('rect')
|
.append('rect')
|
||||||
.attr('id', function (d) {
|
.attr('id', (d) => 'exclude-' + d.start.format('YYYY-MM-DD'))
|
||||||
return 'exclude-' + d.start.format('YYYY-MM-DD');
|
.attr('x', (d) => timeScale(d.start.startOf('day')) + theSidePad)
|
||||||
})
|
|
||||||
.attr('x', function (d) {
|
|
||||||
return timeScale(d.start) + theSidePad;
|
|
||||||
})
|
|
||||||
.attr('y', conf.gridLineStartPadding)
|
.attr('y', conf.gridLineStartPadding)
|
||||||
.attr('width', function (d) {
|
.attr('width', (d) => timeScale(d.end.endOf('day')) - timeScale(d.start.startOf('day')))
|
||||||
const renderEnd = d.end.add(1, 'day');
|
|
||||||
return timeScale(renderEnd) - timeScale(d.start);
|
|
||||||
})
|
|
||||||
.attr('height', h - theTopPad - conf.gridLineStartPadding)
|
.attr('height', h - theTopPad - conf.gridLineStartPadding)
|
||||||
.attr('transform-origin', function (d, i) {
|
.attr('transform-origin', function (d, i) {
|
||||||
return (
|
return (
|
||||||
@@ -615,9 +609,20 @@ export const draw = function (text, id, version, diagObj) {
|
|||||||
* @param h
|
* @param h
|
||||||
*/
|
*/
|
||||||
function makeGrid(theSidePad, theTopPad, w, h) {
|
function makeGrid(theSidePad, theTopPad, w, h) {
|
||||||
|
const dateFormat = diagObj.db.getDateFormat();
|
||||||
|
const userAxisFormat = diagObj.db.getAxisFormat();
|
||||||
|
let axisFormat;
|
||||||
|
if (userAxisFormat) {
|
||||||
|
axisFormat = userAxisFormat;
|
||||||
|
} else if (dateFormat === 'D') {
|
||||||
|
axisFormat = '%d';
|
||||||
|
} else {
|
||||||
|
axisFormat = conf.axisFormat ?? '%Y-%m-%d';
|
||||||
|
}
|
||||||
|
|
||||||
let bottomXAxis = axisBottom(timeScale)
|
let bottomXAxis = axisBottom(timeScale)
|
||||||
.tickSize(-h + theTopPad + conf.gridLineStartPadding)
|
.tickSize(-h + theTopPad + conf.gridLineStartPadding)
|
||||||
.tickFormat(timeFormat(diagObj.db.getAxisFormat() || conf.axisFormat || '%Y-%m-%d'));
|
.tickFormat(timeFormat(axisFormat));
|
||||||
|
|
||||||
const reTickInterval = /^([1-9]\d*)(millisecond|second|minute|hour|day|week|month)$/;
|
const reTickInterval = /^([1-9]\d*)(millisecond|second|minute|hour|day|week|month)$/;
|
||||||
const resultTickInterval = reTickInterval.exec(
|
const resultTickInterval = reTickInterval.exec(
|
||||||
@@ -669,7 +674,7 @@ export const draw = function (text, id, version, diagObj) {
|
|||||||
if (diagObj.db.topAxisEnabled() || conf.topAxis) {
|
if (diagObj.db.topAxisEnabled() || conf.topAxis) {
|
||||||
let topXAxis = axisTop(timeScale)
|
let topXAxis = axisTop(timeScale)
|
||||||
.tickSize(-h + theTopPad + conf.gridLineStartPadding)
|
.tickSize(-h + theTopPad + conf.gridLineStartPadding)
|
||||||
.tickFormat(timeFormat(diagObj.db.getAxisFormat() || conf.axisFormat || '%Y-%m-%d'));
|
.tickFormat(timeFormat(axisFormat));
|
||||||
|
|
||||||
if (resultTickInterval !== null) {
|
if (resultTickInterval !== null) {
|
||||||
const every = resultTickInterval[1];
|
const every = resultTickInterval[1];
|
||||||
|
|||||||
@@ -139,6 +139,32 @@ describe('pie', () => {
|
|||||||
}).rejects.toThrowError();
|
}).rejects.toThrowError();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should handle simple pie with zero slice value', async () => {
|
||||||
|
await parser.parse(`pie title Default text position: Animal adoption
|
||||||
|
accTitle: simple pie char demo
|
||||||
|
accDescr: pie chart with 3 sections: dogs, cats, rats. Most are dogs.
|
||||||
|
"dogs" : 0
|
||||||
|
"rats" : 40.12
|
||||||
|
`);
|
||||||
|
|
||||||
|
const sections = db.getSections();
|
||||||
|
expect(sections.get('dogs')).toBe(0);
|
||||||
|
expect(sections.get('rats')).toBe(40.12);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle simple pie with negative slice value', async () => {
|
||||||
|
await expect(async () => {
|
||||||
|
await parser.parse(`pie title Default text position: Animal adoption
|
||||||
|
accTitle: simple pie char demo
|
||||||
|
accDescr: pie chart with 3 sections: dogs, cats, rats. Most are dogs.
|
||||||
|
"dogs" : -60.67
|
||||||
|
"rats" : 40.12
|
||||||
|
`);
|
||||||
|
}).rejects.toThrowError(
|
||||||
|
'"dogs" has invalid value: -60.67. Negative values are not allowed in pie charts. All slice values must be >= 0.'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('should handle unsafe properties', async () => {
|
it('should handle unsafe properties', async () => {
|
||||||
await expect(
|
await expect(
|
||||||
parser.parse(`pie title Unsafe props test
|
parser.parse(`pie title Unsafe props test
|
||||||
|
|||||||
@@ -34,6 +34,11 @@ const clear = (): void => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const addSection = ({ label, value }: D3Section): void => {
|
const addSection = ({ label, value }: D3Section): void => {
|
||||||
|
if (value < 0) {
|
||||||
|
throw new Error(
|
||||||
|
`"${label}" has invalid value: ${value}. Negative values are not allowed in pie charts. All slice values must be >= 0.`
|
||||||
|
);
|
||||||
|
}
|
||||||
if (!sections.has(label)) {
|
if (!sections.has(label)) {
|
||||||
sections.set(label, value);
|
sections.set(label, value);
|
||||||
log.debug(`added new section: ${label}, with value: ${value}`);
|
log.debug(`added new section: ${label}, with value: ${value}`);
|
||||||
|
|||||||
@@ -10,20 +10,14 @@ import { cleanAndMerge, parseFontSize } from '../../utils.js';
|
|||||||
import type { D3Section, PieDB, Sections } from './pieTypes.js';
|
import type { D3Section, PieDB, Sections } from './pieTypes.js';
|
||||||
|
|
||||||
const createPieArcs = (sections: Sections): d3.PieArcDatum<D3Section>[] => {
|
const createPieArcs = (sections: Sections): d3.PieArcDatum<D3Section>[] => {
|
||||||
// Compute the position of each group on the pie:
|
const sum = [...sections.values()].reduce((acc, val) => acc + val, 0);
|
||||||
|
|
||||||
const pieData: D3Section[] = [...sections.entries()]
|
const pieData: D3Section[] = [...sections.entries()]
|
||||||
.map((element: [string, number]): D3Section => {
|
.map(([label, value]) => ({ label, value }))
|
||||||
return {
|
.filter((d) => (d.value / sum) * 100 >= 1) // Remove values < 1%
|
||||||
label: element[0],
|
.sort((a, b) => b.value - a.value);
|
||||||
value: element[1],
|
|
||||||
};
|
const pie: d3.Pie<unknown, D3Section> = d3pie<D3Section>().value((d) => d.value);
|
||||||
})
|
|
||||||
.sort((a: D3Section, b: D3Section): number => {
|
|
||||||
return b.value - a.value;
|
|
||||||
});
|
|
||||||
const pie: d3.Pie<unknown, D3Section> = d3pie<D3Section>().value(
|
|
||||||
(d3Section: D3Section): number => d3Section.value
|
|
||||||
);
|
|
||||||
return pie(pieData);
|
return pie(pieData);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -89,13 +83,21 @@ export const draw: DrawDefinition = (text, id, _version, diagObj) => {
|
|||||||
themeVariables.pie11,
|
themeVariables.pie11,
|
||||||
themeVariables.pie12,
|
themeVariables.pie12,
|
||||||
];
|
];
|
||||||
|
let sum = 0;
|
||||||
|
sections.forEach((section) => {
|
||||||
|
sum += section;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Filter out arcs that would render as 0%
|
||||||
|
const filteredArcs = arcs.filter((datum) => ((datum.data.value / sum) * 100).toFixed(0) !== '0');
|
||||||
|
|
||||||
// Set the color scale
|
// Set the color scale
|
||||||
const color: d3.ScaleOrdinal<string, 12, never> = scaleOrdinal(myGeneratedColors);
|
const color: d3.ScaleOrdinal<string, 12, never> = scaleOrdinal(myGeneratedColors);
|
||||||
|
|
||||||
// Build the pie chart: each part of the pie is a path that we build using the arc function.
|
// Build the pie chart: each part of the pie is a path that we build using the arc function.
|
||||||
group
|
group
|
||||||
.selectAll('mySlices')
|
.selectAll('mySlices')
|
||||||
.data(arcs)
|
.data(filteredArcs)
|
||||||
.enter()
|
.enter()
|
||||||
.append('path')
|
.append('path')
|
||||||
.attr('d', arcGenerator)
|
.attr('d', arcGenerator)
|
||||||
@@ -104,15 +106,11 @@ export const draw: DrawDefinition = (text, id, _version, diagObj) => {
|
|||||||
})
|
})
|
||||||
.attr('class', 'pieCircle');
|
.attr('class', 'pieCircle');
|
||||||
|
|
||||||
let sum = 0;
|
|
||||||
sections.forEach((section) => {
|
|
||||||
sum += section;
|
|
||||||
});
|
|
||||||
// Now add the percentage.
|
// Now add the percentage.
|
||||||
// Use the centroid method to get the best coordinates.
|
// Use the centroid method to get the best coordinates.
|
||||||
group
|
group
|
||||||
.selectAll('mySlices')
|
.selectAll('mySlices')
|
||||||
.data(arcs)
|
.data(filteredArcs)
|
||||||
.enter()
|
.enter()
|
||||||
.append('text')
|
.append('text')
|
||||||
.text((datum: d3.PieArcDatum<D3Section>): string => {
|
.text((datum: d3.PieArcDatum<D3Section>): string => {
|
||||||
@@ -133,15 +131,20 @@ export const draw: DrawDefinition = (text, id, _version, diagObj) => {
|
|||||||
.attr('class', 'pieTitleText');
|
.attr('class', 'pieTitleText');
|
||||||
|
|
||||||
// Add the legends/annotations for each section
|
// Add the legends/annotations for each section
|
||||||
|
const allSectionData: D3Section[] = [...sections.entries()].map(([label, value]) => ({
|
||||||
|
label,
|
||||||
|
value,
|
||||||
|
}));
|
||||||
|
|
||||||
const legend = group
|
const legend = group
|
||||||
.selectAll('.legend')
|
.selectAll('.legend')
|
||||||
.data(color.domain())
|
.data(allSectionData)
|
||||||
.enter()
|
.enter()
|
||||||
.append('g')
|
.append('g')
|
||||||
.attr('class', 'legend')
|
.attr('class', 'legend')
|
||||||
.attr('transform', (_datum, index: number): string => {
|
.attr('transform', (_datum, index: number): string => {
|
||||||
const height = LEGEND_RECT_SIZE + LEGEND_SPACING;
|
const height = LEGEND_RECT_SIZE + LEGEND_SPACING;
|
||||||
const offset = (height * color.domain().length) / 2;
|
const offset = (height * allSectionData.length) / 2;
|
||||||
const horizontal = 12 * LEGEND_RECT_SIZE;
|
const horizontal = 12 * LEGEND_RECT_SIZE;
|
||||||
const vertical = index * height - offset;
|
const vertical = index * height - offset;
|
||||||
return 'translate(' + horizontal + ',' + vertical + ')';
|
return 'translate(' + horizontal + ',' + vertical + ')';
|
||||||
@@ -151,20 +154,18 @@ export const draw: DrawDefinition = (text, id, _version, diagObj) => {
|
|||||||
.append('rect')
|
.append('rect')
|
||||||
.attr('width', LEGEND_RECT_SIZE)
|
.attr('width', LEGEND_RECT_SIZE)
|
||||||
.attr('height', LEGEND_RECT_SIZE)
|
.attr('height', LEGEND_RECT_SIZE)
|
||||||
.style('fill', color)
|
.style('fill', (d) => color(d.label))
|
||||||
.style('stroke', color);
|
.style('stroke', (d) => color(d.label));
|
||||||
|
|
||||||
legend
|
legend
|
||||||
.data(arcs)
|
|
||||||
.append('text')
|
.append('text')
|
||||||
.attr('x', LEGEND_RECT_SIZE + LEGEND_SPACING)
|
.attr('x', LEGEND_RECT_SIZE + LEGEND_SPACING)
|
||||||
.attr('y', LEGEND_RECT_SIZE - LEGEND_SPACING)
|
.attr('y', LEGEND_RECT_SIZE - LEGEND_SPACING)
|
||||||
.text((datum: d3.PieArcDatum<D3Section>): string => {
|
.text((d) => {
|
||||||
const { label, value } = datum.data;
|
|
||||||
if (db.getShowData()) {
|
if (db.getShowData()) {
|
||||||
return `${label} [${value}]`;
|
return `${d.label} [${d.value}]`;
|
||||||
}
|
}
|
||||||
return label;
|
return d.label;
|
||||||
});
|
});
|
||||||
|
|
||||||
const longestTextWidth = Math.max(
|
const longestTextWidth = Math.max(
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ TEXTDATA [\u0020-\u0021\u0023-\u002B\u002D-\u007E]
|
|||||||
%%
|
%%
|
||||||
|
|
||||||
<INITIAL>"sankey-beta" { this.pushState('csv'); return 'SANKEY'; }
|
<INITIAL>"sankey-beta" { this.pushState('csv'); return 'SANKEY'; }
|
||||||
|
<INITIAL>"sankey" { this.pushState('csv'); return 'SANKEY'; }
|
||||||
<INITIAL,csv><<EOF>> { return 'EOF' } // match end of file
|
<INITIAL,csv><<EOF>> { return 'EOF' } // match end of file
|
||||||
<INITIAL,csv>({CRLF}|{LF}) { return 'NEWLINE' }
|
<INITIAL,csv>({CRLF}|{LF}) { return 'NEWLINE' }
|
||||||
<INITIAL,csv>{COMMA} { return 'COMMA' }
|
<INITIAL,csv>{COMMA} { return 'COMMA' }
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ describe('Sankey diagram', function () {
|
|||||||
sankey.parser.yy.clear();
|
sankey.parser.yy.clear();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('parses csv', () => {
|
it('parses csv with sankey-beta syntax', () => {
|
||||||
const csv = path.resolve(__dirname, './energy.csv');
|
const csv = path.resolve(__dirname, './energy.csv');
|
||||||
const data = fs.readFileSync(csv, 'utf8');
|
const data = fs.readFileSync(csv, 'utf8');
|
||||||
const graphDefinition = prepareTextForParsing(cleanupComments('sankey-beta\n\n ' + data));
|
const graphDefinition = prepareTextForParsing(cleanupComments('sankey-beta\n\n ' + data));
|
||||||
@@ -21,7 +21,15 @@ describe('Sankey diagram', function () {
|
|||||||
sankey.parser.parse(graphDefinition);
|
sankey.parser.parse(graphDefinition);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows __proto__ as id', function () {
|
it('parses csv with sankey syntax', () => {
|
||||||
|
const csv = path.resolve(__dirname, './energy.csv');
|
||||||
|
const data = fs.readFileSync(csv, 'utf8');
|
||||||
|
const graphDefinition = prepareTextForParsing(cleanupComments('sankey\n\n ' + data));
|
||||||
|
|
||||||
|
sankey.parser.parse(graphDefinition);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('allows __proto__ as id with sankey-beta syntax', function () {
|
||||||
sankey.parser.parse(
|
sankey.parser.parse(
|
||||||
prepareTextForParsing(`sankey-beta
|
prepareTextForParsing(`sankey-beta
|
||||||
__proto__,A,0.597
|
__proto__,A,0.597
|
||||||
@@ -29,5 +37,14 @@ describe('Sankey diagram', function () {
|
|||||||
`)
|
`)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('allows __proto__ as id with sankey syntax', function () {
|
||||||
|
sankey.parser.parse(
|
||||||
|
prepareTextForParsing(`sankey
|
||||||
|
__proto__,A,0.597
|
||||||
|
A,__proto__,0.403
|
||||||
|
`)
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-a
|
|||||||
const id = 'sankey';
|
const id = 'sankey';
|
||||||
|
|
||||||
const detector: DiagramDetector = (txt) => {
|
const detector: DiagramDetector = (txt) => {
|
||||||
return /^\s*sankey-beta/.test(txt);
|
return /^\s*sankey(-beta)?/.test(txt);
|
||||||
};
|
};
|
||||||
|
|
||||||
const loader = async () => {
|
const loader = async () => {
|
||||||
|
|||||||
@@ -12,10 +12,9 @@
|
|||||||
|
|
||||||
%options case-insensitive
|
%options case-insensitive
|
||||||
|
|
||||||
|
|
||||||
// Special states for recognizing aliases
|
// Special states for recognizing aliases
|
||||||
// A special state for grabbing text up to the first comment/newline
|
// A special state for grabbing text up to the first comment/newline
|
||||||
%x ID ALIAS LINE
|
%x ID ALIAS LINE CONFIG CONFIG_DATA
|
||||||
|
|
||||||
%x acc_title
|
%x acc_title
|
||||||
%x acc_descr
|
%x acc_descr
|
||||||
@@ -29,18 +28,17 @@
|
|||||||
\%%(?!\{)[^\n]* /* skip comments */
|
\%%(?!\{)[^\n]* /* skip comments */
|
||||||
[^\}]\%\%[^\n]* /* skip comments */
|
[^\}]\%\%[^\n]* /* skip comments */
|
||||||
[0-9]+(?=[ \n]+) return 'NUM';
|
[0-9]+(?=[ \n]+) return 'NUM';
|
||||||
|
<ID>\@\{ { this.begin('CONFIG'); return 'CONFIG_START'; }
|
||||||
|
<CONFIG>[^\}]+ { return 'CONFIG_CONTENT'; }
|
||||||
|
<CONFIG>\} { this.popState(); this.popState(); return 'CONFIG_END'; }
|
||||||
|
<ID>[^\<->\->:\n,;@\s]+(?=\@\{) { yytext = yytext.trim(); return 'ACTOR'; }
|
||||||
|
<ID>[^\<->\->:\n,;@]+?([\-]*[^\<->\->:\n,;@]+?)*?(?=((?!\n)\s)+"as"(?!\n)\s|[#\n;]|$) { yytext = yytext.trim(); this.begin('ALIAS'); return 'ACTOR'; }
|
||||||
"box" { this.begin('LINE'); return 'box'; }
|
"box" { this.begin('LINE'); return 'box'; }
|
||||||
"participant" { this.begin('ID'); return 'participant'; }
|
"participant" { this.begin('ID'); return 'participant'; }
|
||||||
"actor" { this.begin('ID'); return 'participant_actor'; }
|
"actor" { this.begin('ID'); return 'participant_actor'; }
|
||||||
"boundary" { return yy.matchAsActorOrParticipant('boundary', 'participant_boundary', this._input, this); }
|
|
||||||
"control" { return yy.matchAsActorOrParticipant('control', 'participant_control', this._input, this); }
|
|
||||||
"entity" { return yy.matchAsActorOrParticipant('entity', 'participant_entity', this._input, this); }
|
|
||||||
"database" { return yy.matchAsActorOrParticipant('database', 'participant_database', this._input, this); }
|
|
||||||
"collections" { return yy.matchAsActorOrParticipant('collections', 'participant_collections', this._input, this); }
|
|
||||||
"queue" { return yy.matchAsActorOrParticipant('queue', 'participant_queue', this._input, this); }
|
|
||||||
"create" return 'create';
|
"create" return 'create';
|
||||||
"destroy" { this.begin('ID'); return 'destroy'; }
|
"destroy" { this.begin('ID'); return 'destroy'; }
|
||||||
<ID>[^\<->\->:\n,;]+?([\-]*[^\<->\->:\n,;]+?)*?(?=((?!\n)\s)+"as"(?!\n)\s|[#\n;]|$) { yytext = yytext.trim(); this.begin('ALIAS'); return 'ACTOR'; }
|
<ID>[^<\->\->:\n,;]+?([\-]*[^<\->\->:\n,;]+?)*?(?=((?!\n)\s)+"as"(?!\n)\s|[#\n;]|$) { yytext = yytext.trim(); this.begin('ALIAS'); return 'ACTOR'; }
|
||||||
<ALIAS>"as" { this.popState(); this.popState(); this.begin('LINE'); return 'AS'; }
|
<ALIAS>"as" { this.popState(); this.popState(); this.begin('LINE'); return 'AS'; }
|
||||||
<ALIAS>(?:) { this.popState(); this.popState(); return 'NEWLINE'; }
|
<ALIAS>(?:) { this.popState(); this.popState(); return 'NEWLINE'; }
|
||||||
"loop" { this.begin('LINE'); return 'loop'; }
|
"loop" { this.begin('LINE'); return 'loop'; }
|
||||||
@@ -80,7 +78,7 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multili
|
|||||||
"off" return 'off';
|
"off" return 'off';
|
||||||
"," return ',';
|
"," return ',';
|
||||||
";" return 'NEWLINE';
|
";" return 'NEWLINE';
|
||||||
[^\+\<->\->:\n,;]+((?!(\-x|\-\-x|\-\)|\-\-\)))[\-]*[^\+\<->\->:\n,;]+)* { yytext = yytext.trim(); return 'ACTOR'; }
|
[^+<\->\->:\n,;]+((?!(\-x|\-\-x|\-\)|\-\-\)))[\-]*[^\+<\->\->:\n,;]+)* { yytext = yytext.trim(); return 'ACTOR'; }
|
||||||
"->>" return 'SOLID_ARROW';
|
"->>" return 'SOLID_ARROW';
|
||||||
"<<->>" return 'BIDIRECTIONAL_SOLID_ARROW';
|
"<<->>" return 'BIDIRECTIONAL_SOLID_ARROW';
|
||||||
"-->>" return 'DOTTED_ARROW';
|
"-->>" return 'DOTTED_ARROW';
|
||||||
@@ -238,24 +236,7 @@ participant_statement
|
|||||||
| 'participant_actor' actor 'AS' restOfLine 'NEWLINE' {$2.draw='actor'; $2.type='addParticipant';$2.description=yy.parseMessage($4); $$=$2;}
|
| 'participant_actor' actor 'AS' restOfLine 'NEWLINE' {$2.draw='actor'; $2.type='addParticipant';$2.description=yy.parseMessage($4); $$=$2;}
|
||||||
| 'participant_actor' actor 'NEWLINE' {$2.draw='actor'; $2.type='addParticipant'; $$=$2;}
|
| 'participant_actor' actor 'NEWLINE' {$2.draw='actor'; $2.type='addParticipant'; $$=$2;}
|
||||||
| 'destroy' actor 'NEWLINE' {$2.type='destroyParticipant'; $$=$2;}
|
| 'destroy' actor 'NEWLINE' {$2.type='destroyParticipant'; $$=$2;}
|
||||||
|
| 'participant' actor_with_config 'NEWLINE' {$2.draw='participant'; $2.type='addParticipant'; $$=$2;}
|
||||||
| 'participant_boundary' actor 'AS' restOfLine 'NEWLINE' {$2.draw='boundary'; $2.type='addParticipant';$2.description=yy.parseMessage($4); $$=$2;}
|
|
||||||
| 'participant_boundary' actor 'NEWLINE' {$2.draw='boundary'; $2.type='addParticipant'; $$=$2;}
|
|
||||||
|
|
||||||
| 'participant_control' actor 'AS' restOfLine 'NEWLINE' {$2.draw='control'; $2.type='addParticipant';$2.description=yy.parseMessage($4); $$=$2;}
|
|
||||||
| 'participant_control' actor 'NEWLINE' {$2.draw='control'; $2.type='addParticipant'; $$=$2;}
|
|
||||||
|
|
||||||
| 'participant_entity' actor 'AS' restOfLine 'NEWLINE' {$2.draw='entity'; $2.type='addParticipant';$2.description=yy.parseMessage($4); $$=$2;}
|
|
||||||
| 'participant_entity' actor 'NEWLINE' {$2.draw='entity'; $2.type='addParticipant'; $$=$2;}
|
|
||||||
|
|
||||||
| 'participant_database' actor 'AS' restOfLine 'NEWLINE' {$2.draw='database'; $2.type='addParticipant';$2.description=yy.parseMessage($4); $$=$2;}
|
|
||||||
| 'participant_database' actor 'NEWLINE' {$2.draw='database'; $2.type='addParticipant'; $$=$2;}
|
|
||||||
|
|
||||||
| 'participant_collections' actor 'AS' restOfLine 'NEWLINE' {$2.draw='collections'; $2.type='addParticipant';$2.description=yy.parseMessage($4); $$=$2;}
|
|
||||||
| 'participant_collections' actor 'NEWLINE' {$2.draw='collections'; $2.type='addParticipant'; $$=$2;}
|
|
||||||
|
|
||||||
| 'participant_queue' actor 'AS' restOfLine 'NEWLINE' {$2.draw='queue'; $2.type='addParticipant';$2.description=yy.parseMessage($4); $$=$2;}
|
|
||||||
| 'participant_queue' actor 'NEWLINE' {$2.draw='queue'; $2.type='addParticipant'; $$=$2;}
|
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -327,6 +308,23 @@ signal
|
|||||||
{ $$ = [$1,$3,{type: 'addMessage', from:$1.actor, to:$3.actor, signalType:$2, msg:$4}]}
|
{ $$ = [$1,$3,{type: 'addMessage', from:$1.actor, to:$3.actor, signalType:$2, msg:$4}]}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
actor_with_config
|
||||||
|
: ACTOR config_object
|
||||||
|
{
|
||||||
|
$$ = {
|
||||||
|
type: 'addParticipant',
|
||||||
|
actor: $1,
|
||||||
|
config: $2
|
||||||
|
};
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
config_object
|
||||||
|
: CONFIG_START CONFIG_CONTENT CONFIG_END
|
||||||
|
{
|
||||||
|
$$ = $2.trim();
|
||||||
|
}
|
||||||
|
;
|
||||||
// actor
|
// actor
|
||||||
// : actor_participant
|
// : actor_participant
|
||||||
// | actor_actor
|
// | actor_actor
|
||||||
@@ -339,7 +337,7 @@ signaltype
|
|||||||
: SOLID_OPEN_ARROW { $$ = yy.LINETYPE.SOLID_OPEN; }
|
: SOLID_OPEN_ARROW { $$ = yy.LINETYPE.SOLID_OPEN; }
|
||||||
| DOTTED_OPEN_ARROW { $$ = yy.LINETYPE.DOTTED_OPEN; }
|
| DOTTED_OPEN_ARROW { $$ = yy.LINETYPE.DOTTED_OPEN; }
|
||||||
| SOLID_ARROW { $$ = yy.LINETYPE.SOLID; }
|
| SOLID_ARROW { $$ = yy.LINETYPE.SOLID; }
|
||||||
| BIDIRECTIONAL_SOLID_ARROW { $$ = yy.LINETYPE.BIDIRECTIONAL_SOLID; }
|
| BIDIRECTIONAL_SOLID_ARROW { $$ = yy.LINETYPE.BIDIRECTIONAL_SOLID; }
|
||||||
| DOTTED_ARROW { $$ = yy.LINETYPE.DOTTED; }
|
| DOTTED_ARROW { $$ = yy.LINETYPE.DOTTED; }
|
||||||
| BIDIRECTIONAL_DOTTED_ARROW { $$ = yy.LINETYPE.BIDIRECTIONAL_DOTTED; }
|
| BIDIRECTIONAL_DOTTED_ARROW { $$ = yy.LINETYPE.BIDIRECTIONAL_DOTTED; }
|
||||||
| SOLID_CROSS { $$ = yy.LINETYPE.SOLID_CROSS; }
|
| SOLID_CROSS { $$ = yy.LINETYPE.SOLID_CROSS; }
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { getConfig } from '../../diagram-api/diagramAPI.js';
|
import { getConfig } from '../../diagram-api/diagramAPI.js';
|
||||||
|
import * as yaml from 'js-yaml';
|
||||||
import type { DiagramDB } from '../../diagram-api/types.js';
|
import type { DiagramDB } from '../../diagram-api/types.js';
|
||||||
import { log } from '../../logger.js';
|
import { log } from '../../logger.js';
|
||||||
import { ImperativeState } from '../../utils/imperativeState.js';
|
import { ImperativeState } from '../../utils/imperativeState.js';
|
||||||
@@ -13,6 +14,7 @@ import {
|
|||||||
setDiagramTitle,
|
setDiagramTitle,
|
||||||
} from '../common/commonDb.js';
|
} from '../common/commonDb.js';
|
||||||
import type { Actor, AddMessageParams, Box, Message, Note } from './types.js';
|
import type { Actor, AddMessageParams, Box, Message, Note } from './types.js';
|
||||||
|
import type { ParticipantMetaData } from '../../types.js';
|
||||||
|
|
||||||
interface SequenceState {
|
interface SequenceState {
|
||||||
prevActor?: string;
|
prevActor?: string;
|
||||||
@@ -107,7 +109,6 @@ export class SequenceDB implements DiagramDB {
|
|||||||
this.apply = this.apply.bind(this);
|
this.apply = this.apply.bind(this);
|
||||||
this.parseBoxData = this.parseBoxData.bind(this);
|
this.parseBoxData = this.parseBoxData.bind(this);
|
||||||
this.parseMessage = this.parseMessage.bind(this);
|
this.parseMessage = this.parseMessage.bind(this);
|
||||||
this.matchAsActorOrParticipant = this.matchAsActorOrParticipant.bind(this);
|
|
||||||
|
|
||||||
this.clear();
|
this.clear();
|
||||||
|
|
||||||
@@ -131,9 +132,22 @@ export class SequenceDB implements DiagramDB {
|
|||||||
id: string,
|
id: string,
|
||||||
name: string,
|
name: string,
|
||||||
description: { text: string; wrap?: boolean | null; type: string },
|
description: { text: string; wrap?: boolean | null; type: string },
|
||||||
type: string
|
type: string,
|
||||||
|
metadata?: any
|
||||||
) {
|
) {
|
||||||
let assignedBox = this.state.records.currentBox;
|
let assignedBox = this.state.records.currentBox;
|
||||||
|
let doc;
|
||||||
|
if (metadata !== undefined) {
|
||||||
|
let yamlData;
|
||||||
|
// detect if shapeData contains a newline character
|
||||||
|
if (!metadata.includes('\n')) {
|
||||||
|
yamlData = '{\n' + metadata + '\n}';
|
||||||
|
} else {
|
||||||
|
yamlData = metadata + '\n';
|
||||||
|
}
|
||||||
|
doc = yaml.load(yamlData, { schema: yaml.JSON_SCHEMA }) as ParticipantMetaData;
|
||||||
|
}
|
||||||
|
type = doc?.type ?? type;
|
||||||
const old = this.state.records.actors.get(id);
|
const old = this.state.records.actors.get(id);
|
||||||
if (old) {
|
if (old) {
|
||||||
// If already set and trying to set to a new one throw error
|
// If already set and trying to set to a new one throw error
|
||||||
@@ -342,22 +356,6 @@ export class SequenceDB implements DiagramDB {
|
|||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public matchAsActorOrParticipant(
|
|
||||||
tokenName: string,
|
|
||||||
tokenType: string,
|
|
||||||
inputRemainder: string,
|
|
||||||
lexer: any
|
|
||||||
): string {
|
|
||||||
const arrowLike = /^\s*(->>|-->>|->|-->|<<->>|<<-->>|-x|--x|-\))/;
|
|
||||||
const colonLike = /^\s*:/;
|
|
||||||
|
|
||||||
if (arrowLike.test(inputRemainder) || colonLike.test(inputRemainder)) {
|
|
||||||
return 'ACTOR';
|
|
||||||
}
|
|
||||||
lexer.begin('ID'); // used the passed lexer
|
|
||||||
return tokenType;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We expect the box statement to be color first then description
|
// We expect the box statement to be color first then description
|
||||||
// The color can be rgb,rgba,hsl,hsla, or css code names #hex codes are not supported for now because of the way the char # is handled
|
// The color can be rgb,rgba,hsl,hsla, or css code names #hex codes are not supported for now because of the way the char # is handled
|
||||||
// We extract first segment as color, the rest of the line is considered as text
|
// We extract first segment as color, the rest of the line is considered as text
|
||||||
@@ -546,7 +544,7 @@ export class SequenceDB implements DiagramDB {
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 'addParticipant':
|
case 'addParticipant':
|
||||||
this.addActor(param.actor, param.actor, param.description, param.draw);
|
this.addActor(param.actor, param.actor, param.description, param.draw, param.config);
|
||||||
break;
|
break;
|
||||||
case 'createParticipant':
|
case 'createParticipant':
|
||||||
if (this.state.records.actors.has(param.actor)) {
|
if (this.state.records.actors.has(param.actor)) {
|
||||||
@@ -555,7 +553,7 @@ export class SequenceDB implements DiagramDB {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
this.state.records.lastCreated = param.actor;
|
this.state.records.lastCreated = param.actor;
|
||||||
this.addActor(param.actor, param.actor, param.description, param.draw);
|
this.addActor(param.actor, param.actor, param.description, param.draw, param.config);
|
||||||
this.state.records.createdActors.set(param.actor, this.state.records.messages.length);
|
this.state.records.createdActors.set(param.actor, this.state.records.messages.length);
|
||||||
break;
|
break;
|
||||||
case 'destroyParticipant':
|
case 'destroyParticipant':
|
||||||
|
|||||||
@@ -350,6 +350,26 @@ Bob-->Alice-in-Wonderland:I am good thanks!`);
|
|||||||
expect(messages[1].from).toBe('Bob');
|
expect(messages[1].from).toBe('Bob');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should handle equals in participant names', async () => {
|
||||||
|
const diagram = await Diagram.fromText(`
|
||||||
|
sequenceDiagram
|
||||||
|
participant Alice=Wonderland
|
||||||
|
participant Bob
|
||||||
|
Alice=Wonderland->Bob:Hello Bob, how are - you?
|
||||||
|
Bob-->Alice=Wonderland:I am good thanks!`);
|
||||||
|
|
||||||
|
const actors = diagram.db.getActors();
|
||||||
|
expect([...actors.keys()]).toEqual(['Alice=Wonderland', 'Bob']);
|
||||||
|
expect(actors.get('Alice=Wonderland').description).toBe('Alice=Wonderland');
|
||||||
|
expect(actors.get('Bob').description).toBe('Bob');
|
||||||
|
|
||||||
|
const messages = diagram.db.getMessages();
|
||||||
|
|
||||||
|
expect(messages.length).toBe(2);
|
||||||
|
expect(messages[0].from).toBe('Alice=Wonderland');
|
||||||
|
expect(messages[1].from).toBe('Bob');
|
||||||
|
});
|
||||||
|
|
||||||
it('should alias participants', async () => {
|
it('should alias participants', async () => {
|
||||||
const diagram = await Diagram.fromText(`
|
const diagram = await Diagram.fromText(`
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
@@ -2038,99 +2058,213 @@ Bob->>Alice:Got it!
|
|||||||
expect(messages[0].from).toBe('Alice');
|
expect(messages[0].from).toBe('Alice');
|
||||||
expect(messages[0].to).toBe('Bob');
|
expect(messages[0].to).toBe('Bob');
|
||||||
});
|
});
|
||||||
describe('when newly parsing messages ', () => {
|
describe('when parsing extended participant syntax', () => {
|
||||||
it('should parse a message', async () => {
|
it('should parse participants with different quote styles and whitespace', async () => {
|
||||||
const actor1 = 'database';
|
|
||||||
const diagram = await Diagram.fromText(`
|
const diagram = await Diagram.fromText(`
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
database Alice
|
participant Alice@{ "type" : "database" }
|
||||||
database Bob
|
participant Bob@{ "type" : "database" }
|
||||||
Bob->>+Alice: Hi Alice
|
participant Carl@{ type: "database" }
|
||||||
Alice->>+Bob: Hi Bob
|
participant David@{ "type" : 'database' }
|
||||||
`);
|
participant Eve@{ type: 'database' }
|
||||||
|
participant Favela@{ "type" : "database" }
|
||||||
|
Bob->>+Alice: Hi Alice
|
||||||
|
Alice->>+Bob: Hi Bob
|
||||||
|
`);
|
||||||
|
|
||||||
|
const actors = diagram.db.getActors();
|
||||||
|
|
||||||
|
expect(actors.get('Alice').type).toBe('database');
|
||||||
|
expect(actors.get('Alice').description).toBe('Alice');
|
||||||
|
|
||||||
|
expect(actors.get('Bob').type).toBe('database');
|
||||||
|
expect(actors.get('Bob').description).toBe('Bob');
|
||||||
|
|
||||||
|
expect(actors.get('Carl').type).toBe('database');
|
||||||
|
expect(actors.get('Carl').description).toBe('Carl');
|
||||||
|
|
||||||
|
expect(actors.get('David').type).toBe('database');
|
||||||
|
expect(actors.get('David').description).toBe('David');
|
||||||
|
|
||||||
|
expect(actors.get('Eve').type).toBe('database');
|
||||||
|
expect(actors.get('Eve').description).toBe('Eve');
|
||||||
|
|
||||||
|
expect(actors.get('Favela').type).toBe('database');
|
||||||
|
expect(actors.get('Favela').description).toBe('Favela');
|
||||||
|
|
||||||
|
// Verify messages were parsed correctly
|
||||||
const messages = diagram.db.getMessages();
|
const messages = diagram.db.getMessages();
|
||||||
|
expect(messages.length).toBe(4); // 2 messages + 2 activation messages
|
||||||
|
expect(messages[0].from).toBe('Bob');
|
||||||
|
expect(messages[0].to).toBe('Alice');
|
||||||
|
expect(messages[0].message).toBe('Hi Alice');
|
||||||
|
expect(messages[2].from).toBe('Alice'); // Second message (index 2 due to activation)
|
||||||
|
expect(messages[2].to).toBe('Bob');
|
||||||
|
expect(messages[2].message).toBe('Hi Bob');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should parse a message', async () => {
|
it('should parse mixed participant types with extended syntax', async () => {
|
||||||
const actor1 = 'database';
|
|
||||||
const diagram = await Diagram.fromText(`
|
const diagram = await Diagram.fromText(`
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
participant lead
|
participant lead
|
||||||
queue dsa
|
participant dsa@{ "type" : "queue" }
|
||||||
API->>+Database: getUserb
|
API->>+Database: getUserb
|
||||||
Database-->>-API: userb
|
Database-->>-API: userb
|
||||||
queue --> Database: hello
|
dsa --> Database: hello
|
||||||
`);
|
`);
|
||||||
|
|
||||||
|
// Verify actors were created
|
||||||
|
const actors = diagram.db.getActors();
|
||||||
|
|
||||||
|
expect(actors.get('lead').type).toBe('participant');
|
||||||
|
expect(actors.get('lead').description).toBe('lead');
|
||||||
|
|
||||||
|
// Participant with extended syntax
|
||||||
|
expect(actors.get('dsa').type).toBe('queue');
|
||||||
|
expect(actors.get('dsa').description).toBe('dsa');
|
||||||
|
|
||||||
|
// Implicitly created actors (from messages)
|
||||||
|
expect(actors.get('API').type).toBe('participant');
|
||||||
|
expect(actors.get('API').description).toBe('API');
|
||||||
|
|
||||||
|
expect(actors.get('Database').type).toBe('participant');
|
||||||
|
expect(actors.get('Database').description).toBe('Database');
|
||||||
|
|
||||||
|
// Verify messages were parsed correctly
|
||||||
const messages = diagram.db.getMessages();
|
const messages = diagram.db.getMessages();
|
||||||
|
expect(messages.length).toBe(5); // 3 messages + 2 activation messages
|
||||||
|
|
||||||
|
// First message with activation
|
||||||
|
expect(messages[0].from).toBe('API');
|
||||||
|
expect(messages[0].to).toBe('Database');
|
||||||
|
expect(messages[0].message).toBe('getUserb');
|
||||||
|
expect(messages[0].activate).toBe(true);
|
||||||
|
|
||||||
|
// Second message with deactivation
|
||||||
|
expect(messages[2].from).toBe('Database');
|
||||||
|
expect(messages[2].to).toBe('API');
|
||||||
|
expect(messages[2].message).toBe('userb');
|
||||||
|
|
||||||
|
// Third message
|
||||||
|
expect(messages[4].from).toBe('dsa');
|
||||||
|
expect(messages[4].to).toBe('Database');
|
||||||
|
expect(messages[4].message).toBe('hello');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fail for malformed JSON in participant definition', async () => {
|
||||||
|
const invalidDiagram = `
|
||||||
|
sequenceDiagram
|
||||||
|
participant D@{ "type: "entity" }
|
||||||
|
participant E@{ "type": "dat
|
||||||
|
abase }
|
||||||
|
`;
|
||||||
|
|
||||||
|
let error = false;
|
||||||
|
try {
|
||||||
|
await mermaidAPI.parse(invalidDiagram);
|
||||||
|
} catch (e) {
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
expect(error).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fail for missing colon separator', async () => {
|
||||||
|
const invalidDiagram = `
|
||||||
|
sequenceDiagram
|
||||||
|
participant C@{ "type" "control" }
|
||||||
|
C ->> C: action
|
||||||
|
`;
|
||||||
|
|
||||||
|
let error = false;
|
||||||
|
try {
|
||||||
|
await mermaidAPI.parse(invalidDiagram);
|
||||||
|
} catch (e) {
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
expect(error).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fail for missing closing brace', async () => {
|
||||||
|
const invalidDiagram = `
|
||||||
|
sequenceDiagram
|
||||||
|
participant E@{ "type": "entity"
|
||||||
|
E ->> E: process
|
||||||
|
`;
|
||||||
|
|
||||||
|
let error = false;
|
||||||
|
try {
|
||||||
|
await mermaidAPI.parse(invalidDiagram);
|
||||||
|
} catch (e) {
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
expect(error).toBe(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('participant type parsing', () => {
|
describe('participant type parsing', () => {
|
||||||
it('should parse boundary participant', async () => {
|
it('should parse boundary participant', async () => {
|
||||||
const diagram = await Diagram.fromText(`
|
const diagram = await Diagram.fromText(`
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
boundary B as Boundary Box
|
participant boundary@{ "type" : "boundary" }
|
||||||
B->B: test
|
boundary->boundary: test
|
||||||
`);
|
`);
|
||||||
const actors = diagram.db.getActors();
|
const actors = diagram.db.getActors();
|
||||||
expect(actors.get('B').type).toBe('boundary');
|
expect(actors.get('boundary').type).toBe('boundary');
|
||||||
expect(actors.get('B').description).toBe('Boundary Box');
|
expect(actors.get('boundary').description).toBe('boundary');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should parse control participant', async () => {
|
it('should parse control participant', async () => {
|
||||||
const diagram = await Diagram.fromText(`
|
const diagram = await Diagram.fromText(`
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
control C as Controller
|
participant C@{ "type" : "control" }
|
||||||
C->C: test
|
C->C: test
|
||||||
`);
|
`);
|
||||||
const actors = diagram.db.getActors();
|
const actors = diagram.db.getActors();
|
||||||
expect(actors.get('C').type).toBe('control');
|
expect(actors.get('C').type).toBe('control');
|
||||||
expect(actors.get('C').description).toBe('Controller');
|
expect(actors.get('C').description).toBe('C');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should parse entity participant', async () => {
|
it('should parse entity participant', async () => {
|
||||||
const diagram = await Diagram.fromText(`
|
const diagram = await Diagram.fromText(`
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
entity E as Entity
|
participant E@{ "type" : "entity" }
|
||||||
E->E: test
|
E->E: test
|
||||||
`);
|
`);
|
||||||
const actors = diagram.db.getActors();
|
const actors = diagram.db.getActors();
|
||||||
expect(actors.get('E').type).toBe('entity');
|
expect(actors.get('E').type).toBe('entity');
|
||||||
expect(actors.get('E').description).toBe('Entity');
|
expect(actors.get('E').description).toBe('E');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should parse database participant', async () => {
|
it('should parse database participant', async () => {
|
||||||
const diagram = await Diagram.fromText(`
|
const diagram = await Diagram.fromText(`
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
database D as Database
|
participant D@{ "type" : "database" }
|
||||||
D->D: test
|
D->D: test
|
||||||
`);
|
`);
|
||||||
const actors = diagram.db.getActors();
|
const actors = diagram.db.getActors();
|
||||||
expect(actors.get('D').type).toBe('database');
|
expect(actors.get('D').type).toBe('database');
|
||||||
expect(actors.get('D').description).toBe('Database');
|
expect(actors.get('D').description).toBe('D');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should parse collections participant', async () => {
|
it('should parse collections participant', async () => {
|
||||||
const diagram = await Diagram.fromText(`
|
const diagram = await Diagram.fromText(`
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
collections L as List
|
participant L@{ "type" : "collections" }
|
||||||
L->L: test
|
L->L: test
|
||||||
`);
|
`);
|
||||||
const actors = diagram.db.getActors();
|
const actors = diagram.db.getActors();
|
||||||
expect(actors.get('L').type).toBe('collections');
|
expect(actors.get('L').type).toBe('collections');
|
||||||
expect(actors.get('L').description).toBe('List');
|
expect(actors.get('L').description).toBe('L');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should parse queue participant', async () => {
|
it('should parse queue participant', async () => {
|
||||||
const diagram = await Diagram.fromText(`
|
const diagram = await Diagram.fromText(`
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
queue Q as Jobs
|
participant Q@{ "type" : "queue" }
|
||||||
Q->Q: test
|
Q->Q: test
|
||||||
`);
|
`);
|
||||||
const actors = diagram.db.getActors();
|
const actors = diagram.db.getActors();
|
||||||
expect(actors.get('Q').type).toBe('queue');
|
expect(actors.get('Q').type).toBe('queue');
|
||||||
expect(actors.get('Q').description).toBe('Jobs');
|
expect(actors.get('Q').description).toBe('Q');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -2138,89 +2272,58 @@ Bob->>Alice:Got it!
|
|||||||
it('should parse actor participant', async () => {
|
it('should parse actor participant', async () => {
|
||||||
const diagram = await Diagram.fromText(`
|
const diagram = await Diagram.fromText(`
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
queue A as ActorName
|
participant A@{ "type" : "queue" }
|
||||||
A->A: test
|
A->A: test
|
||||||
`);
|
`);
|
||||||
const actors = diagram.db.getActors();
|
const actors = diagram.db.getActors();
|
||||||
expect(actors.get('A').type).toBe('queue');
|
expect(actors.get('A').type).toBe('queue');
|
||||||
expect(actors.get('A').description).toBe('ActorName');
|
expect(actors.get('A').description).toBe('A');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should parse participant participant', async () => {
|
it('should parse participant participant', async () => {
|
||||||
const diagram = await Diagram.fromText(`
|
const diagram = await Diagram.fromText(`
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
database P as PartName
|
participant P@{ "type" : "database" }
|
||||||
P->P: test
|
P->P: test
|
||||||
`);
|
`);
|
||||||
const actors = diagram.db.getActors();
|
const actors = diagram.db.getActors();
|
||||||
expect(actors.get('P').type).toBe('database');
|
expect(actors.get('P').type).toBe('database');
|
||||||
expect(actors.get('P').description).toBe('PartName');
|
expect(actors.get('P').description).toBe('P');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should parse boundary using actor keyword', async () => {
|
it('should parse boundary using actor keyword', async () => {
|
||||||
const diagram = await Diagram.fromText(`
|
const diagram = await Diagram.fromText(`
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
collections B as Boundary
|
participant Alice@{ "type" : "collections" }
|
||||||
B->B: test
|
participant Bob@{ "type" : "control" }
|
||||||
|
Alice->>Bob: Hello Bob, how are you?
|
||||||
`);
|
`);
|
||||||
const actors = diagram.db.getActors();
|
const actors = diagram.db.getActors();
|
||||||
expect(actors.get('B').type).toBe('collections');
|
expect(actors.get('Alice').type).toBe('collections');
|
||||||
expect(actors.get('B').description).toBe('Boundary');
|
expect(actors.get('Bob').type).toBe('control');
|
||||||
|
expect(actors.get('Bob').description).toBe('Bob');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should parse control using participant keyword', async () => {
|
it('should parse control using participant keyword', async () => {
|
||||||
const diagram = await Diagram.fromText(`
|
const diagram = await Diagram.fromText(`
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
control C as Controller
|
participant C@{ "type" : "control" }
|
||||||
C->C: test
|
C->C: test
|
||||||
`);
|
`);
|
||||||
const actors = diagram.db.getActors();
|
const actors = diagram.db.getActors();
|
||||||
expect(actors.get('C').type).toBe('control');
|
expect(actors.get('C').type).toBe('control');
|
||||||
expect(actors.get('C').description).toBe('Controller');
|
expect(actors.get('C').description).toBe('C');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should parse entity using actor keyword', async () => {
|
it('should parse entity using actor keyword', async () => {
|
||||||
const diagram = await Diagram.fromText(`
|
const diagram = await Diagram.fromText(`
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
entity E as Entity
|
participant E@{ "type" : "entity" }
|
||||||
E->E: test
|
E->E: test
|
||||||
`);
|
`);
|
||||||
const actors = diagram.db.getActors();
|
const actors = diagram.db.getActors();
|
||||||
expect(actors.get('E').type).toBe('entity');
|
expect(actors.get('E').type).toBe('entity');
|
||||||
expect(actors.get('E').description).toBe('Entity');
|
expect(actors.get('E').description).toBe('E');
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse database using participant keyword', async () => {
|
|
||||||
const diagram = await Diagram.fromText(`
|
|
||||||
sequenceDiagram
|
|
||||||
participant D as Database
|
|
||||||
D->D: test
|
|
||||||
`);
|
|
||||||
const actors = diagram.db.getActors();
|
|
||||||
expect(actors.get('D').type).toBe('participant');
|
|
||||||
expect(actors.get('D').description).toBe('Database');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse collections using actor keyword', async () => {
|
|
||||||
const diagram = await Diagram.fromText(`
|
|
||||||
sequenceDiagram
|
|
||||||
actor L as List
|
|
||||||
L->L: test
|
|
||||||
`);
|
|
||||||
const actors = diagram.db.getActors();
|
|
||||||
expect(actors.get('L').type).toBe('actor');
|
|
||||||
expect(actors.get('L').description).toBe('List');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse queue using participant keyword', async () => {
|
|
||||||
const diagram = await Diagram.fromText(`
|
|
||||||
sequenceDiagram
|
|
||||||
participant Q as Jobs
|
|
||||||
Q->Q: test
|
|
||||||
`);
|
|
||||||
const actors = diagram.db.getActors();
|
|
||||||
expect(actors.get('Q').type).toBe('participant');
|
|
||||||
expect(actors.get('Q').description).toBe('Jobs');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -477,7 +477,29 @@ const drawMessage = async function (diagram, msgModel, lineStartY: number, diagO
|
|||||||
|
|
||||||
// add node number
|
// add node number
|
||||||
if (sequenceVisible || conf.showSequenceNumbers) {
|
if (sequenceVisible || conf.showSequenceNumbers) {
|
||||||
line.attr('marker-start', 'url(' + url + '#sequencenumber)');
|
const isBidirectional =
|
||||||
|
type === diagObj.db.LINETYPE.BIDIRECTIONAL_SOLID ||
|
||||||
|
type === diagObj.db.LINETYPE.BIDIRECTIONAL_DOTTED;
|
||||||
|
|
||||||
|
if (isBidirectional) {
|
||||||
|
const SEQUENCE_NUMBER_RADIUS = 6;
|
||||||
|
|
||||||
|
if (startx < stopx) {
|
||||||
|
line.attr('x1', startx + 2 * SEQUENCE_NUMBER_RADIUS);
|
||||||
|
} else {
|
||||||
|
line.attr('x1', startx + SEQUENCE_NUMBER_RADIUS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diagram
|
||||||
|
.append('line')
|
||||||
|
.attr('x1', startx)
|
||||||
|
.attr('y1', lineStartY)
|
||||||
|
.attr('x2', startx)
|
||||||
|
.attr('y2', lineStartY)
|
||||||
|
.attr('stroke-width', 0)
|
||||||
|
.attr('marker-start', 'url(' + url + '#sequencenumber)');
|
||||||
|
|
||||||
diagram
|
diagram
|
||||||
.append('text')
|
.append('text')
|
||||||
.attr('x', startx)
|
.attr('x', startx)
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
import common, { calculateMathMLDimensions, hasKatex, renderKatex } from '../common/common.js';
|
|
||||||
import * as svgDrawCommon from '../common/svgDrawCommon.js';
|
|
||||||
import { ZERO_WIDTH_SPACE, parseFontSize } from '../../utils.js';
|
|
||||||
import { sanitizeUrl } from '@braintree/sanitize-url';
|
import { sanitizeUrl } from '@braintree/sanitize-url';
|
||||||
import * as configApi from '../../config.js';
|
import * as configApi from '../../config.js';
|
||||||
|
import { ZERO_WIDTH_SPACE, parseFontSize } from '../../utils.js';
|
||||||
|
import common, {
|
||||||
|
calculateMathMLDimensions,
|
||||||
|
hasKatex,
|
||||||
|
renderKatexSanitized,
|
||||||
|
} from '../common/common.js';
|
||||||
|
import * as svgDrawCommon from '../common/svgDrawCommon.js';
|
||||||
|
|
||||||
export const ACTOR_TYPE_WIDTH = 18 * 2;
|
export const ACTOR_TYPE_WIDTH = 18 * 2;
|
||||||
const TOP_ACTOR_CLASS = 'actor-top';
|
const TOP_ACTOR_CLASS = 'actor-top';
|
||||||
@@ -87,13 +91,13 @@ const popupMenuToggle = function (popId) {
|
|||||||
|
|
||||||
export const drawKatex = async function (elem, textData, msgModel = null) {
|
export const drawKatex = async function (elem, textData, msgModel = null) {
|
||||||
let textElem = elem.append('foreignObject');
|
let textElem = elem.append('foreignObject');
|
||||||
const lines = await renderKatex(textData.text, configApi.getConfig());
|
const linesSanitized = await renderKatexSanitized(textData.text, configApi.getConfig());
|
||||||
|
|
||||||
const divElem = textElem
|
const divElem = textElem
|
||||||
.append('xhtml:div')
|
.append('xhtml:div')
|
||||||
.attr('style', 'width: fit-content;')
|
.attr('style', 'width: fit-content;')
|
||||||
.attr('xmlns', 'http://www.w3.org/1999/xhtml')
|
.attr('xmlns', 'http://www.w3.org/1999/xhtml')
|
||||||
.html(lines);
|
.html(linesSanitized);
|
||||||
const dim = divElem.node().getBoundingClientRect();
|
const dim = divElem.node().getBoundingClientRect();
|
||||||
|
|
||||||
textElem.attr('height', Math.round(dim.height)).attr('width', Math.round(dim.width));
|
textElem.attr('height', Math.round(dim.height)).attr('width', Math.round(dim.width));
|
||||||
@@ -468,20 +472,18 @@ const drawActorTypeCollections = function (elem, actor, conf, isFooter) {
|
|||||||
rect.width = actor.width;
|
rect.width = actor.width;
|
||||||
rect.height = actor.height;
|
rect.height = actor.height;
|
||||||
rect.class = cssclass;
|
rect.class = cssclass;
|
||||||
// rect.rx = 3;
|
|
||||||
// rect.ry = 3;
|
|
||||||
rect.name = actor.name;
|
rect.name = actor.name;
|
||||||
|
|
||||||
// 🔹 DRAW STACKED RECTANGLES
|
// DRAW STACKED RECTANGLES
|
||||||
const offset = 6;
|
const offset = 6;
|
||||||
const shadowRect = {
|
const shadowRect = {
|
||||||
...rect,
|
...rect,
|
||||||
x: rect.x + offset,
|
x: rect.x + (isFooter ? -offset : -offset),
|
||||||
y: rect.y + (isFooter ? +offset : -offset),
|
y: rect.y + (isFooter ? +offset : +offset),
|
||||||
class: 'actor',
|
class: 'actor',
|
||||||
};
|
};
|
||||||
drawRect(g, shadowRect);
|
|
||||||
const rectElem = drawRect(g, rect); // draw main rectangle on top
|
const rectElem = drawRect(g, rect); // draw main rectangle on top
|
||||||
|
drawRect(g, shadowRect);
|
||||||
actor.rectData = rect;
|
actor.rectData = rect;
|
||||||
|
|
||||||
if (actor.properties?.icon) {
|
if (actor.properties?.icon) {
|
||||||
@@ -496,8 +498,8 @@ const drawActorTypeCollections = function (elem, actor, conf, isFooter) {
|
|||||||
_drawTextCandidateFunc(conf, hasKatex(actor.description))(
|
_drawTextCandidateFunc(conf, hasKatex(actor.description))(
|
||||||
actor.description,
|
actor.description,
|
||||||
g,
|
g,
|
||||||
rect.x,
|
rect.x - offset,
|
||||||
rect.y,
|
rect.y + offset,
|
||||||
rect.width,
|
rect.width,
|
||||||
rect.height,
|
rect.height,
|
||||||
{ class: `actor ${ACTOR_BOX_CLASS}` },
|
{ class: `actor ${ACTOR_BOX_CLASS}` },
|
||||||
@@ -686,13 +688,13 @@ const drawActorTypeControl = function (elem, actor, conf, isFooter) {
|
|||||||
.append('defs')
|
.append('defs')
|
||||||
.append('marker')
|
.append('marker')
|
||||||
.attr('id', 'filled-head-control')
|
.attr('id', 'filled-head-control')
|
||||||
.attr('refX', 15.5)
|
.attr('refX', 11)
|
||||||
.attr('refY', 7)
|
.attr('refY', 5.8)
|
||||||
.attr('markerWidth', 20)
|
.attr('markerWidth', 20)
|
||||||
.attr('markerHeight', 28)
|
.attr('markerHeight', 28)
|
||||||
.attr('orient', '180')
|
.attr('orient', '172.5')
|
||||||
.append('path')
|
.append('path')
|
||||||
.attr('d', 'M 18,7 L9,13 L14,7 L9,1 Z');
|
.attr('d', 'M 14.4 5.6 L 7.2 10.4 L 8.8 5.6 L 7.2 0.8 Z');
|
||||||
|
|
||||||
// Draw the base circle
|
// Draw the base circle
|
||||||
actElem
|
actElem
|
||||||
@@ -706,10 +708,9 @@ const drawActorTypeControl = function (elem, actor, conf, isFooter) {
|
|||||||
|
|
||||||
// Draw looping arrow as arc path
|
// Draw looping arrow as arc path
|
||||||
actElem
|
actElem
|
||||||
.append('path')
|
.append('line')
|
||||||
.attr('d', `M ${cx},${cy - r}`)
|
.attr('marker-end', 'url(#filled-head-control)')
|
||||||
.attr('stroke-width', 1.5)
|
.attr('transform', `translate(${cx}, ${cy - r})`);
|
||||||
.attr('marker-end', 'url(#filled-head-control)');
|
|
||||||
|
|
||||||
const bounds = actElem.node().getBBox();
|
const bounds = actElem.node().getBBox();
|
||||||
actor.height = bounds.height + 2 * (conf?.sequence?.labelBoxHeight ?? 0);
|
actor.height = bounds.height + 2 * (conf?.sequence?.labelBoxHeight ?? 0);
|
||||||
@@ -718,7 +719,7 @@ const drawActorTypeControl = function (elem, actor, conf, isFooter) {
|
|||||||
actor.description,
|
actor.description,
|
||||||
actElem,
|
actElem,
|
||||||
rect.x,
|
rect.x,
|
||||||
rect.y + 30,
|
rect.y + r + (isFooter ? 5 : 10),
|
||||||
rect.width,
|
rect.width,
|
||||||
rect.height,
|
rect.height,
|
||||||
{ class: `actor ${ACTOR_MAN_FIGURE_CLASS}` },
|
{ class: `actor ${ACTOR_MAN_FIGURE_CLASS}` },
|
||||||
@@ -754,7 +755,7 @@ const drawActorTypeEntity = function (elem, actor, conf, isFooter) {
|
|||||||
rect.class = 'actor';
|
rect.class = 'actor';
|
||||||
|
|
||||||
const cx = actor.x + actor.width / 2;
|
const cx = actor.x + actor.width / 2;
|
||||||
const cy = actorY + 25;
|
const cy = actorY + (!isFooter ? 25 : 10);
|
||||||
const r = 18;
|
const r = 18;
|
||||||
|
|
||||||
actElem
|
actElem
|
||||||
@@ -775,7 +776,7 @@ const drawActorTypeEntity = function (elem, actor, conf, isFooter) {
|
|||||||
.attr('stroke-width', 2);
|
.attr('stroke-width', 2);
|
||||||
|
|
||||||
const bounds = actElem.node().getBBox();
|
const bounds = actElem.node().getBBox();
|
||||||
actor.height = bounds.height + (conf.sequence.labelBoxHeight ?? 0);
|
actor.height = bounds.height + (conf?.sequence?.labelBoxHeight ?? 0);
|
||||||
|
|
||||||
if (!isFooter) {
|
if (!isFooter) {
|
||||||
actorCnt++;
|
actorCnt++;
|
||||||
@@ -798,7 +799,7 @@ const drawActorTypeEntity = function (elem, actor, conf, isFooter) {
|
|||||||
actor.description,
|
actor.description,
|
||||||
actElem,
|
actElem,
|
||||||
rect.x,
|
rect.x,
|
||||||
rect.y + (!isFooter ? (cy + r - actorY) / 2 : (cy - actorY) / 2 + r + 2),
|
rect.y + (!isFooter ? (cy + r - actorY) / 2 : (cy - actorY + r - 5) / 2),
|
||||||
rect.width,
|
rect.width,
|
||||||
rect.height,
|
rect.height,
|
||||||
{ class: `actor ${ACTOR_MAN_FIGURE_CLASS}` },
|
{ class: `actor ${ACTOR_MAN_FIGURE_CLASS}` },
|
||||||
@@ -872,7 +873,7 @@ const drawActorTypeDatabase = function (elem, actor, conf, isFooter) {
|
|||||||
rect.x = actor.x;
|
rect.x = actor.x;
|
||||||
rect.y = actorY;
|
rect.y = actorY;
|
||||||
const w = rect.width / 4;
|
const w = rect.width / 4;
|
||||||
const h = rect.height * 0.8;
|
const h = rect.width / 4;
|
||||||
const rx = w / 2;
|
const rx = w / 2;
|
||||||
const ry = rx / (2.5 + w / 50);
|
const ry = rx / (2.5 + w / 50);
|
||||||
|
|
||||||
@@ -897,7 +898,7 @@ const drawActorTypeDatabase = function (elem, actor, conf, isFooter) {
|
|||||||
.attr('class', cssclass);
|
.attr('class', cssclass);
|
||||||
|
|
||||||
if (!isFooter) {
|
if (!isFooter) {
|
||||||
cylinderGroup.attr('transform', `translate(${w * 1.5}, ${rect.height / 4 - 2 * ry})`);
|
cylinderGroup.attr('transform', `translate(${w * 1.5}, ${(rect.height + ry) / 4})`);
|
||||||
} else {
|
} else {
|
||||||
cylinderGroup.attr('transform', `translate(${w * 1.5}, ${rect.height / 4 - 2 * ry})`);
|
cylinderGroup.attr('transform', `translate(${w * 1.5}, ${rect.height / 4 - 2 * ry})`);
|
||||||
}
|
}
|
||||||
@@ -906,7 +907,7 @@ const drawActorTypeDatabase = function (elem, actor, conf, isFooter) {
|
|||||||
actor.description,
|
actor.description,
|
||||||
g,
|
g,
|
||||||
rect.x,
|
rect.x,
|
||||||
rect.y + (!isFooter ? rect.height / 2 : h / 2 + ry),
|
rect.y + (!isFooter ? (rect.height + ry) / 2 : (rect.height + h) / 4),
|
||||||
rect.width,
|
rect.width,
|
||||||
rect.height,
|
rect.height,
|
||||||
{ class: `actor ${ACTOR_BOX_CLASS}` },
|
{ class: `actor ${ACTOR_BOX_CLASS}` },
|
||||||
@@ -962,8 +963,6 @@ const drawActorTypeBoundary = function (elem, actor, conf, isFooter) {
|
|||||||
rect.width = actor.width;
|
rect.width = actor.width;
|
||||||
rect.height = actor.height;
|
rect.height = actor.height;
|
||||||
rect.class = 'actor';
|
rect.class = 'actor';
|
||||||
rect.rx = 3;
|
|
||||||
rect.ry = 3;
|
|
||||||
|
|
||||||
actElem
|
actElem
|
||||||
.append('line')
|
.append('line')
|
||||||
@@ -985,8 +984,7 @@ const drawActorTypeBoundary = function (elem, actor, conf, isFooter) {
|
|||||||
.append('circle')
|
.append('circle')
|
||||||
.attr('cx', actor.x + actor.width / 2)
|
.attr('cx', actor.x + actor.width / 2)
|
||||||
.attr('cy', actorY + 10)
|
.attr('cy', actorY + 10)
|
||||||
.attr('r', radius)
|
.attr('r', radius);
|
||||||
.attr('width', actor.width);
|
|
||||||
|
|
||||||
const bounds = actElem.node().getBBox();
|
const bounds = actElem.node().getBBox();
|
||||||
actor.height = bounds.height + (conf.sequence.labelBoxHeight ?? 0);
|
actor.height = bounds.height + (conf.sequence.labelBoxHeight ?? 0);
|
||||||
@@ -995,7 +993,7 @@ const drawActorTypeBoundary = function (elem, actor, conf, isFooter) {
|
|||||||
actor.description,
|
actor.description,
|
||||||
actElem,
|
actElem,
|
||||||
rect.x,
|
rect.x,
|
||||||
rect.y + (!isFooter ? radius / 2 : radius / 2),
|
rect.y + (!isFooter ? radius / 2 + 3 : radius / 2 - 4),
|
||||||
rect.width,
|
rect.width,
|
||||||
rect.height,
|
rect.height,
|
||||||
{ class: `actor ${ACTOR_MAN_FIGURE_CLASS}` },
|
{ class: `actor ${ACTOR_MAN_FIGURE_CLASS}` },
|
||||||
@@ -1008,8 +1006,6 @@ const drawActorTypeBoundary = function (elem, actor, conf, isFooter) {
|
|||||||
actElem.attr('transform', `translate(0,${radius / 2 + 7})`);
|
actElem.attr('transform', `translate(0,${radius / 2 + 7})`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// actElem.attr('transform', `translate(${rect.width / 2}, ${actorY + rect.height / 2})`);
|
|
||||||
|
|
||||||
return actor.height;
|
return actor.height;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1579,7 +1575,7 @@ const _drawTextCandidateFunc = (function () {
|
|||||||
.append('div')
|
.append('div')
|
||||||
.style('text-align', 'center')
|
.style('text-align', 'center')
|
||||||
.style('vertical-align', 'middle')
|
.style('vertical-align', 'middle')
|
||||||
.html(await renderKatex(content, configApi.getConfig()));
|
.html(await renderKatexSanitized(content, configApi.getConfig()));
|
||||||
|
|
||||||
byTspan(content, s, x, y, width, height, textAttrs, conf);
|
byTspan(content, s, x, y, width, height, textAttrs, conf);
|
||||||
_setTextAttrs(text, textAttrs);
|
_setTextAttrs(text, textAttrs);
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
<acc_descr_multiline>[^\}]* { return "acc_descr_multiline_value"; }
|
<acc_descr_multiline>[^\}]* { return "acc_descr_multiline_value"; }
|
||||||
|
|
||||||
"xychart-beta" {return 'XYCHART';}
|
"xychart-beta" {return 'XYCHART';}
|
||||||
|
"xychart" {return 'XYCHART';}
|
||||||
(?:"vertical"|"horizontal") {return 'CHART_ORIENTATION'}
|
(?:"vertical"|"horizontal") {return 'CHART_ORIENTATION'}
|
||||||
|
|
||||||
"x-axis" { this.pushState("axis_data"); return "X_AXIS"; }
|
"x-axis" { this.pushState("axis_data"); return "X_AXIS"; }
|
||||||
|
|||||||
@@ -33,44 +33,44 @@ describe('Testing xychart jison file', () => {
|
|||||||
clearMocks();
|
clearMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw error if xychart-beta text is not there', () => {
|
it('should throw error if xychart text is not there', () => {
|
||||||
const str = 'xychart-beta-1';
|
const str = 'xychart-1';
|
||||||
expect(parserFnConstructor(str)).toThrow();
|
expect(parserFnConstructor(str)).toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not throw error if only xychart is there', () => {
|
it('should not throw error if only xychart is there', () => {
|
||||||
const str = 'xychart-beta';
|
const str = 'xychart';
|
||||||
expect(parserFnConstructor(str)).not.toThrow();
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('parse title of the chart within "', () => {
|
it('parse title of the chart within "', () => {
|
||||||
const str = 'xychart-beta \n title "This is a title"';
|
const str = 'xychart \n title "This is a title"';
|
||||||
expect(parserFnConstructor(str)).not.toThrow();
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
expect(mockDB.setDiagramTitle).toHaveBeenCalledWith('This is a title');
|
expect(mockDB.setDiagramTitle).toHaveBeenCalledWith('This is a title');
|
||||||
});
|
});
|
||||||
it('parse title of the chart without "', () => {
|
it('parse title of the chart without "', () => {
|
||||||
const str = 'xychart-beta \n title oneLinertitle';
|
const str = 'xychart \n title oneLinertitle';
|
||||||
expect(parserFnConstructor(str)).not.toThrow();
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
expect(mockDB.setDiagramTitle).toHaveBeenCalledWith('oneLinertitle');
|
expect(mockDB.setDiagramTitle).toHaveBeenCalledWith('oneLinertitle');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('parse chart orientation', () => {
|
it('parse chart orientation', () => {
|
||||||
const str = 'xychart-beta vertical';
|
const str = 'xychart vertical';
|
||||||
expect(parserFnConstructor(str)).not.toThrow();
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
expect(mockDB.setOrientation).toHaveBeenCalledWith('vertical');
|
expect(mockDB.setOrientation).toHaveBeenCalledWith('vertical');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('parse chart orientation with spaces', () => {
|
it('parse chart orientation with spaces', () => {
|
||||||
let str = 'xychart-beta horizontal ';
|
let str = 'xychart horizontal ';
|
||||||
expect(parserFnConstructor(str)).not.toThrow();
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
expect(mockDB.setOrientation).toHaveBeenCalledWith('horizontal');
|
expect(mockDB.setOrientation).toHaveBeenCalledWith('horizontal');
|
||||||
|
|
||||||
str = 'xychart-beta abc';
|
str = 'xychart abc';
|
||||||
expect(parserFnConstructor(str)).toThrow();
|
expect(parserFnConstructor(str)).toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('parse x-axis', () => {
|
it('parse x-axis', () => {
|
||||||
const str = 'xychart-beta \nx-axis xAxisName\n';
|
const str = 'xychart \nx-axis xAxisName\n';
|
||||||
expect(parserFnConstructor(str)).not.toThrow();
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
|
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
|
||||||
text: 'xAxisName',
|
text: 'xAxisName',
|
||||||
@@ -79,7 +79,7 @@ describe('Testing xychart jison file', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('parse x-axis with axis name without "', () => {
|
it('parse x-axis with axis name without "', () => {
|
||||||
const str = 'xychart-beta \nx-axis xAxisName \n';
|
const str = 'xychart \nx-axis xAxisName \n';
|
||||||
expect(parserFnConstructor(str)).not.toThrow();
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
|
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
|
||||||
text: 'xAxisName',
|
text: 'xAxisName',
|
||||||
@@ -88,7 +88,7 @@ describe('Testing xychart jison file', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('parse x-axis with axis name with "', () => {
|
it('parse x-axis with axis name with "', () => {
|
||||||
const str = 'xychart-beta \n x-axis "xAxisName has space"\n';
|
const str = 'xychart \n x-axis "xAxisName has space"\n';
|
||||||
expect(parserFnConstructor(str)).not.toThrow();
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
|
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
|
||||||
text: 'xAxisName has space',
|
text: 'xAxisName has space',
|
||||||
@@ -97,7 +97,7 @@ describe('Testing xychart jison file', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('parse x-axis with axis name with " with spaces', () => {
|
it('parse x-axis with axis name with " with spaces', () => {
|
||||||
const str = 'xychart-beta \n x-axis " xAxisName has space " \n';
|
const str = 'xychart \n x-axis " xAxisName has space " \n';
|
||||||
expect(parserFnConstructor(str)).not.toThrow();
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
|
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
|
||||||
text: ' xAxisName has space ',
|
text: ' xAxisName has space ',
|
||||||
@@ -106,7 +106,7 @@ describe('Testing xychart jison file', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('parse x-axis with axis name and range data', () => {
|
it('parse x-axis with axis name and range data', () => {
|
||||||
const str = 'xychart-beta \nx-axis xAxisName 45.5 --> 33 \n';
|
const str = 'xychart \nx-axis xAxisName 45.5 --> 33 \n';
|
||||||
expect(parserFnConstructor(str)).not.toThrow();
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
|
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
|
||||||
text: 'xAxisName',
|
text: 'xAxisName',
|
||||||
@@ -115,11 +115,11 @@ describe('Testing xychart jison file', () => {
|
|||||||
expect(mockDB.setXAxisRangeData).toHaveBeenCalledWith(45.5, 33);
|
expect(mockDB.setXAxisRangeData).toHaveBeenCalledWith(45.5, 33);
|
||||||
});
|
});
|
||||||
it('parse x-axis throw error for invalid range data', () => {
|
it('parse x-axis throw error for invalid range data', () => {
|
||||||
const str = 'xychart-beta \nx-axis xAxisName aaa --> 33 \n';
|
const str = 'xychart \nx-axis xAxisName aaa --> 33 \n';
|
||||||
expect(parserFnConstructor(str)).toThrow();
|
expect(parserFnConstructor(str)).toThrow();
|
||||||
});
|
});
|
||||||
it('parse x-axis with axis name and range data with only decimal part', () => {
|
it('parse x-axis with axis name and range data with only decimal part', () => {
|
||||||
const str = 'xychart-beta \nx-axis xAxisName 45.5 --> .34 \n';
|
const str = 'xychart \nx-axis xAxisName 45.5 --> .34 \n';
|
||||||
expect(parserFnConstructor(str)).not.toThrow();
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
|
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
|
||||||
text: 'xAxisName',
|
text: 'xAxisName',
|
||||||
@@ -129,7 +129,7 @@ describe('Testing xychart jison file', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('parse x-axis without axis name and range data', () => {
|
it('parse x-axis without axis name and range data', () => {
|
||||||
const str = 'xychart-beta \nx-axis 45.5 --> 1.34 \n';
|
const str = 'xychart \nx-axis 45.5 --> 1.34 \n';
|
||||||
expect(parserFnConstructor(str)).not.toThrow();
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
|
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
|
||||||
text: '',
|
text: '',
|
||||||
@@ -139,7 +139,7 @@ describe('Testing xychart jison file', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('parse x-axis with axis name and category data', () => {
|
it('parse x-axis with axis name and category data', () => {
|
||||||
const str = 'xychart-beta \nx-axis xAxisName [ "cat1" , cat2a ] \n ';
|
const str = 'xychart \nx-axis xAxisName [ "cat1" , cat2a ] \n ';
|
||||||
expect(parserFnConstructor(str)).not.toThrow();
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
|
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
|
||||||
text: 'xAxisName',
|
text: 'xAxisName',
|
||||||
@@ -155,7 +155,7 @@ describe('Testing xychart jison file', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('parse x-axis without axis name and category data', () => {
|
it('parse x-axis without axis name and category data', () => {
|
||||||
const str = 'xychart-beta \nx-axis [ "cat1" , cat2a ] \n ';
|
const str = 'xychart \nx-axis [ "cat1" , cat2a ] \n ';
|
||||||
expect(parserFnConstructor(str)).not.toThrow();
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
|
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({
|
||||||
text: '',
|
text: '',
|
||||||
@@ -171,14 +171,14 @@ describe('Testing xychart jison file', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('parse x-axis throw error if unbalanced bracket', () => {
|
it('parse x-axis throw error if unbalanced bracket', () => {
|
||||||
let str = 'xychart-beta \nx-axis xAxisName [ "cat1" [ cat2a ] \n ';
|
let str = 'xychart \nx-axis xAxisName [ "cat1" [ cat2a ] \n ';
|
||||||
expect(parserFnConstructor(str)).toThrow();
|
expect(parserFnConstructor(str)).toThrow();
|
||||||
str = 'xychart-beta \nx-axis xAxisName [ "cat1" , cat2a ] ] \n ';
|
str = 'xychart \nx-axis xAxisName [ "cat1" , cat2a ] ] \n ';
|
||||||
expect(parserFnConstructor(str)).toThrow();
|
expect(parserFnConstructor(str)).toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('parse x-axis complete variant 1', () => {
|
it('parse x-axis complete variant 1', () => {
|
||||||
const str = `xychart-beta \n x-axis "this is x axis" [category1, "category 2", category3]\n`;
|
const str = `xychart \n x-axis "this is x axis" [category1, "category 2", category3]\n`;
|
||||||
expect(parserFnConstructor(str)).not.toThrow();
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'this is x axis', type: 'text' });
|
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'this is x axis', type: 'text' });
|
||||||
expect(mockDB.setXAxisBand).toHaveBeenCalledWith([
|
expect(mockDB.setXAxisBand).toHaveBeenCalledWith([
|
||||||
@@ -189,8 +189,7 @@ describe('Testing xychart jison file', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('parse x-axis complete variant 2', () => {
|
it('parse x-axis complete variant 2', () => {
|
||||||
const str =
|
const str = 'xychart \nx-axis xAxisName [ "cat1 with space" , cat2 , cat3] \n ';
|
||||||
'xychart-beta \nx-axis xAxisName [ "cat1 with space" , cat2 , cat3] \n ';
|
|
||||||
expect(parserFnConstructor(str)).not.toThrow();
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
|
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
|
||||||
expect(mockDB.setXAxisBand).toHaveBeenCalledWith([
|
expect(mockDB.setXAxisBand).toHaveBeenCalledWith([
|
||||||
@@ -202,7 +201,7 @@ describe('Testing xychart jison file', () => {
|
|||||||
|
|
||||||
it('parse x-axis complete variant 3', () => {
|
it('parse x-axis complete variant 3', () => {
|
||||||
const str =
|
const str =
|
||||||
'xychart-beta \nx-axis xAxisName [ "cat1 with space" , cat2 asdf , cat3] \n ';
|
'xychart \nx-axis xAxisName [ "cat1 with space" , cat2 asdf , cat3] \n ';
|
||||||
expect(parserFnConstructor(str)).not.toThrow();
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
|
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
|
||||||
expect(mockDB.setXAxisBand).toHaveBeenCalledWith([
|
expect(mockDB.setXAxisBand).toHaveBeenCalledWith([
|
||||||
@@ -213,17 +212,17 @@ describe('Testing xychart jison file', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('parse y-axis with axis name', () => {
|
it('parse y-axis with axis name', () => {
|
||||||
const str = 'xychart-beta \ny-axis yAxisName\n';
|
const str = 'xychart \ny-axis yAxisName\n';
|
||||||
expect(parserFnConstructor(str)).not.toThrow();
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
|
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
|
||||||
});
|
});
|
||||||
it('parse y-axis with axis name with spaces', () => {
|
it('parse y-axis with axis name with spaces', () => {
|
||||||
const str = 'xychart-beta \ny-axis yAxisName \n';
|
const str = 'xychart \ny-axis yAxisName \n';
|
||||||
expect(parserFnConstructor(str)).not.toThrow();
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
|
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
|
||||||
});
|
});
|
||||||
it('parse y-axis with axis name with "', () => {
|
it('parse y-axis with axis name with "', () => {
|
||||||
const str = 'xychart-beta \n y-axis "yAxisName has space"\n';
|
const str = 'xychart \n y-axis "yAxisName has space"\n';
|
||||||
expect(parserFnConstructor(str)).not.toThrow();
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({
|
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({
|
||||||
text: 'yAxisName has space',
|
text: 'yAxisName has space',
|
||||||
@@ -231,7 +230,7 @@ describe('Testing xychart jison file', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('parse y-axis with axis name with " and spaces', () => {
|
it('parse y-axis with axis name with " and spaces', () => {
|
||||||
const str = 'xychart-beta \n y-axis " yAxisName has space " \n';
|
const str = 'xychart \n y-axis " yAxisName has space " \n';
|
||||||
expect(parserFnConstructor(str)).not.toThrow();
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({
|
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({
|
||||||
text: ' yAxisName has space ',
|
text: ' yAxisName has space ',
|
||||||
@@ -239,39 +238,39 @@ describe('Testing xychart jison file', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('parse y-axis with axis name with range data', () => {
|
it('parse y-axis with axis name with range data', () => {
|
||||||
const str = 'xychart-beta \ny-axis yAxisName 45.5 --> 33 \n';
|
const str = 'xychart \ny-axis yAxisName 45.5 --> 33 \n';
|
||||||
expect(parserFnConstructor(str)).not.toThrow();
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
|
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
|
||||||
expect(mockDB.setYAxisRangeData).toHaveBeenCalledWith(45.5, 33);
|
expect(mockDB.setYAxisRangeData).toHaveBeenCalledWith(45.5, 33);
|
||||||
});
|
});
|
||||||
it('parse y-axis without axis name with range data', () => {
|
it('parse y-axis without axis name with range data', () => {
|
||||||
const str = 'xychart-beta \ny-axis 45.5 --> 33 \n';
|
const str = 'xychart \ny-axis 45.5 --> 33 \n';
|
||||||
expect(parserFnConstructor(str)).not.toThrow();
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: '', type: 'text' });
|
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: '', type: 'text' });
|
||||||
expect(mockDB.setYAxisRangeData).toHaveBeenCalledWith(45.5, 33);
|
expect(mockDB.setYAxisRangeData).toHaveBeenCalledWith(45.5, 33);
|
||||||
});
|
});
|
||||||
it('parse y-axis with axis name with range data with only decimal part', () => {
|
it('parse y-axis with axis name with range data with only decimal part', () => {
|
||||||
const str = 'xychart-beta \ny-axis yAxisName 45.5 --> .33 \n';
|
const str = 'xychart \ny-axis yAxisName 45.5 --> .33 \n';
|
||||||
expect(parserFnConstructor(str)).not.toThrow();
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
|
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
|
||||||
expect(mockDB.setYAxisRangeData).toHaveBeenCalledWith(45.5, 0.33);
|
expect(mockDB.setYAxisRangeData).toHaveBeenCalledWith(45.5, 0.33);
|
||||||
});
|
});
|
||||||
it('parse y-axis throw error for invalid number in range data', () => {
|
it('parse y-axis throw error for invalid number in range data', () => {
|
||||||
const str = 'xychart-beta \ny-axis yAxisName 45.5 --> abc \n';
|
const str = 'xychart \ny-axis yAxisName 45.5 --> abc \n';
|
||||||
expect(parserFnConstructor(str)).toThrow();
|
expect(parserFnConstructor(str)).toThrow();
|
||||||
});
|
});
|
||||||
it('parse y-axis throws error if range data is passed', () => {
|
it('parse y-axis throws error if range data is passed', () => {
|
||||||
const str = 'xychart-beta \ny-axis yAxisName [ 45.3, 33 ] \n';
|
const str = 'xychart \ny-axis yAxisName [ 45.3, 33 ] \n';
|
||||||
expect(parserFnConstructor(str)).toThrow();
|
expect(parserFnConstructor(str)).toThrow();
|
||||||
});
|
});
|
||||||
it('parse both axis at once', () => {
|
it('parse both axis at once', () => {
|
||||||
const str = 'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n';
|
const str = 'xychart\nx-axis xAxisName\ny-axis yAxisName\n';
|
||||||
expect(parserFnConstructor(str)).not.toThrow();
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
|
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
|
||||||
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
|
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
|
||||||
});
|
});
|
||||||
it('parse line Data', () => {
|
it('parse line Data', () => {
|
||||||
const str = 'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line lineTitle [23, 45, 56.6]';
|
const str = 'xychart\nx-axis xAxisName\ny-axis yAxisName\n line lineTitle [23, 45, 56.6]';
|
||||||
expect(parserFnConstructor(str)).not.toThrow();
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
expect(mockDB.setLineData).toHaveBeenCalledWith(
|
expect(mockDB.setLineData).toHaveBeenCalledWith(
|
||||||
{ text: 'lineTitle', type: 'text' },
|
{ text: 'lineTitle', type: 'text' },
|
||||||
@@ -282,7 +281,7 @@ describe('Testing xychart jison file', () => {
|
|||||||
});
|
});
|
||||||
it('parse line Data with spaces and +,- symbols', () => {
|
it('parse line Data with spaces and +,- symbols', () => {
|
||||||
const str =
|
const str =
|
||||||
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ +23 , -45 , 56.6 ] ';
|
'xychart\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ +23 , -45 , 56.6 ] ';
|
||||||
expect(parserFnConstructor(str)).not.toThrow();
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
|
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
|
||||||
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
|
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
|
||||||
@@ -292,8 +291,7 @@ describe('Testing xychart jison file', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('parse line Data without title', () => {
|
it('parse line Data without title', () => {
|
||||||
const str =
|
const str = 'xychart\nx-axis xAxisName\ny-axis yAxisName\n line [ +23 , -45 , 56.6 , .33] ';
|
||||||
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line [ +23 , -45 , 56.6 , .33] ';
|
|
||||||
expect(parserFnConstructor(str)).not.toThrow();
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
|
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
|
||||||
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
|
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
|
||||||
@@ -304,34 +302,32 @@ describe('Testing xychart jison file', () => {
|
|||||||
});
|
});
|
||||||
it('parse line Data throws error unbalanced brackets', () => {
|
it('parse line Data throws error unbalanced brackets', () => {
|
||||||
let str =
|
let str =
|
||||||
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ +23 [ -45 , 56.6 ] ';
|
'xychart\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ +23 [ -45 , 56.6 ] ';
|
||||||
expect(parserFnConstructor(str)).toThrow();
|
expect(parserFnConstructor(str)).toThrow();
|
||||||
str =
|
str =
|
||||||
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ +23 , -45 ] 56.6 ] ';
|
'xychart\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ +23 , -45 ] 56.6 ] ';
|
||||||
expect(parserFnConstructor(str)).toThrow();
|
expect(parserFnConstructor(str)).toThrow();
|
||||||
});
|
});
|
||||||
it('parse line Data throws error if data is not provided', () => {
|
it('parse line Data throws error if data is not provided', () => {
|
||||||
const str = 'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" ';
|
const str = 'xychart\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" ';
|
||||||
expect(parserFnConstructor(str)).toThrow();
|
expect(parserFnConstructor(str)).toThrow();
|
||||||
});
|
});
|
||||||
it('parse line Data throws error if data is empty', () => {
|
it('parse line Data throws error if data is empty', () => {
|
||||||
const str =
|
const str = 'xychart\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ ] ';
|
||||||
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ ] ';
|
|
||||||
expect(parserFnConstructor(str)).toThrow();
|
expect(parserFnConstructor(str)).toThrow();
|
||||||
});
|
});
|
||||||
it('parse line Data throws error if , is not in proper', () => {
|
it('parse line Data throws error if , is not in proper', () => {
|
||||||
const str =
|
const str =
|
||||||
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ +23 , , -45 , 56.6 ] ';
|
'xychart\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ +23 , , -45 , 56.6 ] ';
|
||||||
expect(parserFnConstructor(str)).toThrow();
|
expect(parserFnConstructor(str)).toThrow();
|
||||||
});
|
});
|
||||||
it('parse line Data throws error if not number', () => {
|
it('parse line Data throws error if not number', () => {
|
||||||
const str =
|
const str =
|
||||||
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ +23 , -4aa5 , 56.6 ] ';
|
'xychart\nx-axis xAxisName\ny-axis yAxisName\n line "lineTitle with space" [ +23 , -4aa5 , 56.6 ] ';
|
||||||
expect(parserFnConstructor(str)).toThrow();
|
expect(parserFnConstructor(str)).toThrow();
|
||||||
});
|
});
|
||||||
it('parse bar Data', () => {
|
it('parse bar Data', () => {
|
||||||
const str =
|
const str = 'xychart\nx-axis xAxisName\ny-axis yAxisName\n bar barTitle [23, 45, 56.6, .22]';
|
||||||
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar barTitle [23, 45, 56.6, .22]';
|
|
||||||
expect(parserFnConstructor(str)).not.toThrow();
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
|
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
|
||||||
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
|
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
|
||||||
@@ -342,7 +338,7 @@ describe('Testing xychart jison file', () => {
|
|||||||
});
|
});
|
||||||
it('parse bar Data spaces and +,- symbol', () => {
|
it('parse bar Data spaces and +,- symbol', () => {
|
||||||
const str =
|
const str =
|
||||||
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ +23 , -45 , 56.6 ] ';
|
'xychart\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ +23 , -45 , 56.6 ] ';
|
||||||
expect(parserFnConstructor(str)).not.toThrow();
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
|
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
|
||||||
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
|
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
|
||||||
@@ -352,8 +348,7 @@ describe('Testing xychart jison file', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('parse bar Data without plot title', () => {
|
it('parse bar Data without plot title', () => {
|
||||||
const str =
|
const str = 'xychart\nx-axis xAxisName\ny-axis yAxisName\n bar [ +23 , -45 , 56.6 ] ';
|
||||||
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar [ +23 , -45 , 56.6 ] ';
|
|
||||||
expect(parserFnConstructor(str)).not.toThrow();
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
|
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
|
||||||
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
|
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
|
||||||
@@ -361,34 +356,34 @@ describe('Testing xychart jison file', () => {
|
|||||||
});
|
});
|
||||||
it('parse bar should throw for unbalanced brackets', () => {
|
it('parse bar should throw for unbalanced brackets', () => {
|
||||||
let str =
|
let str =
|
||||||
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ +23 [ -45 , 56.6 ] ';
|
'xychart\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ +23 [ -45 , 56.6 ] ';
|
||||||
expect(parserFnConstructor(str)).toThrow();
|
expect(parserFnConstructor(str)).toThrow();
|
||||||
str =
|
str =
|
||||||
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ +23 , -45 ] 56.6 ] ';
|
'xychart\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ +23 , -45 ] 56.6 ] ';
|
||||||
expect(parserFnConstructor(str)).toThrow();
|
expect(parserFnConstructor(str)).toThrow();
|
||||||
});
|
});
|
||||||
it('parse bar should throw error if data is not provided', () => {
|
it('parse bar should throw error if data is not provided', () => {
|
||||||
const str = 'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" ';
|
const str = 'xychart\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" ';
|
||||||
expect(parserFnConstructor(str)).toThrow();
|
expect(parserFnConstructor(str)).toThrow();
|
||||||
});
|
});
|
||||||
it('parse bar should throw error if data is empty', () => {
|
it('parse bar should throw error if data is empty', () => {
|
||||||
const str =
|
const str =
|
||||||
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ ] ';
|
'xychart\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ ] ';
|
||||||
expect(parserFnConstructor(str)).toThrow();
|
expect(parserFnConstructor(str)).toThrow();
|
||||||
});
|
});
|
||||||
it('parse bar should throw error if comma is not proper', () => {
|
it('parse bar should throw error if comma is not proper', () => {
|
||||||
const str =
|
const str =
|
||||||
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ +23 , , -45 , 56.6 ] ';
|
'xychart\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ +23 , , -45 , 56.6 ] ';
|
||||||
expect(parserFnConstructor(str)).toThrow();
|
expect(parserFnConstructor(str)).toThrow();
|
||||||
});
|
});
|
||||||
it('parse bar should throw error if number is not passed', () => {
|
it('parse bar should throw error if number is not passed', () => {
|
||||||
const str =
|
const str =
|
||||||
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ +23 , -4aa5 , 56.6 ] ';
|
'xychart\nx-axis xAxisName\ny-axis yAxisName\n bar "barTitle with space" [ +23 , -4aa5 , 56.6 ] ';
|
||||||
expect(parserFnConstructor(str)).toThrow();
|
expect(parserFnConstructor(str)).toThrow();
|
||||||
});
|
});
|
||||||
it('parse multiple bar and line variant 1', () => {
|
it('parse multiple bar and line variant 1', () => {
|
||||||
const str =
|
const str =
|
||||||
'xychart-beta\nx-axis xAxisName\ny-axis yAxisName\n bar barTitle1 [23, 45, 56.6] \n line lineTitle1 [11, 45.5, 67, 23] \n bar barTitle2 [13, 42, 56.89] \n line lineTitle2 [45, 99, 012]';
|
'xychart\nx-axis xAxisName\ny-axis yAxisName\n bar barTitle1 [23, 45, 56.6] \n line lineTitle1 [11, 45.5, 67, 23] \n bar barTitle2 [13, 42, 56.89] \n line lineTitle2 [45, 99, 012]';
|
||||||
expect(parserFnConstructor(str)).not.toThrow();
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
|
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith({ text: 'yAxisName', type: 'text' });
|
||||||
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
|
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith({ text: 'xAxisName', type: 'text' });
|
||||||
@@ -411,8 +406,8 @@ describe('Testing xychart jison file', () => {
|
|||||||
});
|
});
|
||||||
it('parse multiple bar and line variant 2', () => {
|
it('parse multiple bar and line variant 2', () => {
|
||||||
const str = `
|
const str = `
|
||||||
xychart-beta horizontal
|
xychart horizontal
|
||||||
title Basic xychart
|
title "Basic xychart"
|
||||||
x-axis "this is x axis" [category1, "category 2", category3]
|
x-axis "this is x axis" [category1, "category 2", category3]
|
||||||
y-axis yaxisText 10 --> 150
|
y-axis yaxisText 10 --> 150
|
||||||
bar barTitle1 [23, 45, 56.6]
|
bar barTitle1 [23, 45, 56.6]
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import type {
|
|||||||
const id = 'xychart';
|
const id = 'xychart';
|
||||||
|
|
||||||
const detector: DiagramDetector = (txt) => {
|
const detector: DiagramDetector = (txt) => {
|
||||||
return /^\s*xychart-beta/.test(txt);
|
return /^\s*xychart(-beta)?/.test(txt);
|
||||||
};
|
};
|
||||||
|
|
||||||
const loader: DiagramLoader = async () => {
|
const loader: DiagramLoader = async () => {
|
||||||
|
|||||||
@@ -9,56 +9,136 @@ interface Feature {
|
|||||||
interface EditorColumn {
|
interface EditorColumn {
|
||||||
title: string;
|
title: string;
|
||||||
description: string;
|
description: string;
|
||||||
redirectUrl: string;
|
redBarText?: string;
|
||||||
|
redirectUrl?: string;
|
||||||
|
buttonText?: string;
|
||||||
highlighted?: boolean;
|
highlighted?: boolean;
|
||||||
|
proTrialUrl?: string;
|
||||||
|
proTrialButtonText?: string;
|
||||||
features: Feature[];
|
features: Feature[];
|
||||||
|
isButtonMargined?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const editorColumns: EditorColumn[] = [
|
const mermaidChartFeatures: Feature[] = [
|
||||||
{
|
{ iconUrl: '/icons/folder.svg', featureName: 'Storage' },
|
||||||
title: 'Playground',
|
{ iconUrl: '/icons/terminal.svg', featureName: 'Code editor' },
|
||||||
description: 'Basic features, no login',
|
{ iconUrl: '/icons/ai-diagram.svg', featureName: 'AI diagram generator' },
|
||||||
redirectUrl:
|
{ iconUrl: '/icons/whiteboard.svg', featureName: 'Whiteboard' },
|
||||||
'https://www.mermaidchart.com/play?utm_source=mermaid_js&utm_medium=editor_selection&utm_campaign=playground',
|
{ iconUrl: '/icons/group.svg', featureName: 'Teams' },
|
||||||
features: [
|
{ iconUrl: '/icons/groups.svg', featureName: 'Multi-user editing' },
|
||||||
{ iconUrl: '/icons/public.svg', featureName: 'Diagram stored in URL' },
|
{ iconUrl: '/icons/ai-repair.svg', featureName: 'AI diagram repair' },
|
||||||
{ iconUrl: '/icons/terminal.svg', featureName: 'Code editor' },
|
{ iconUrl: '/icons/version-history.svg', featureName: 'Version history' },
|
||||||
{ iconUrl: '/icons/whiteboard.svg', featureName: 'Whiteboard' },
|
{ iconUrl: '/icons/comment.svg', featureName: 'Comments' },
|
||||||
],
|
{ iconUrl: '/icons/presentation.svg', featureName: 'Presentations' },
|
||||||
},
|
{ iconUrl: '/icons/plugins.svg', featureName: 'Advanced plugins' },
|
||||||
{
|
|
||||||
title: 'Free',
|
|
||||||
description: 'Advanced features, free account',
|
|
||||||
redirectUrl:
|
|
||||||
'https://www.mermaidchart.com/app/sign-up?utm_source=mermaid_js&utm_medium=editor_selection&utm_campaign=mermaid_chart&redirect=%2Fapp%2Fdiagrams%2Fnew',
|
|
||||||
highlighted: true,
|
|
||||||
features: [
|
|
||||||
{ iconUrl: '/icons/folder.svg', featureName: 'Storage' },
|
|
||||||
{ iconUrl: '/icons/terminal.svg', featureName: 'Code editor' },
|
|
||||||
{ iconUrl: '/icons/ai-diagram.svg', featureName: 'AI diagram generator' },
|
|
||||||
{ iconUrl: '/icons/whiteboard.svg', featureName: 'Whiteboard' },
|
|
||||||
{ iconUrl: '/icons/group.svg', featureName: 'Teams' },
|
|
||||||
{ iconUrl: '/icons/groups.svg', featureName: 'Multi-user editing' },
|
|
||||||
{ iconUrl: '/icons/ai-repair.svg', featureName: 'AI diagram repair' },
|
|
||||||
{ iconUrl: '/icons/version-history.svg', featureName: 'Version history' },
|
|
||||||
{ iconUrl: '/icons/comment.svg', featureName: 'Comments' },
|
|
||||||
{ iconUrl: '/icons/presentation.svg', featureName: 'Presentations' },
|
|
||||||
{ iconUrl: '/icons/plugins.svg', featureName: 'Advanced Plugins' },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Open Source',
|
|
||||||
description: 'Code only, no login',
|
|
||||||
redirectUrl: 'https://mermaid.live/edit',
|
|
||||||
features: [
|
|
||||||
{ iconUrl: '/icons/public.svg', featureName: 'Diagram stored in URL' },
|
|
||||||
{ iconUrl: '/icons/terminal.svg', featureName: 'Code editor' },
|
|
||||||
{ iconUrl: '/icons/open-source.svg', featureName: 'Open source' },
|
|
||||||
{ iconUrl: '/icons/version-history.svg', featureName: 'Version history' },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const openSourceFeatures: Feature[] = [
|
||||||
|
{ iconUrl: '/icons/public.svg', featureName: 'Diagram stored in URL' },
|
||||||
|
{ iconUrl: '/icons/terminal.svg', featureName: 'Code editor' },
|
||||||
|
{ iconUrl: '/icons/open-source.svg', featureName: 'Open source' },
|
||||||
|
{ iconUrl: '/icons/version-history.svg', featureName: 'Version history' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const playgroundFeatures: Feature[] = [
|
||||||
|
{ iconUrl: '/icons/public.svg', featureName: 'Diagram stored in URL' },
|
||||||
|
{ iconUrl: '/icons/terminal.svg', featureName: 'Code editor' },
|
||||||
|
{ iconUrl: '/icons/whiteboard.svg', featureName: 'Whiteboard' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const editorColumnVariants: EditorColumn[][] = [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
title: 'Playground',
|
||||||
|
description: 'Basic features, no login',
|
||||||
|
redirectUrl:
|
||||||
|
'https://www.mermaidchart.com/app/sign-up?utm_source=mermaid_js&utm_medium=3_editor_selection_A&utm_campaign=start_playground',
|
||||||
|
buttonText: 'Start free',
|
||||||
|
features: playgroundFeatures,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Free or Pro',
|
||||||
|
description: 'Advanced features, Free or Pro account',
|
||||||
|
proTrialUrl:
|
||||||
|
'https://www.mermaidchart.com/app/sign-up?utm_source=mermaid_js&utm_medium=3_editor_selection_A&utm_campaign=start_free',
|
||||||
|
proTrialButtonText: 'Start free',
|
||||||
|
highlighted: true,
|
||||||
|
redBarText: 'Best for collaboration',
|
||||||
|
features: mermaidChartFeatures,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Open Source',
|
||||||
|
description: 'Code only, no login',
|
||||||
|
redirectUrl: 'https://mermaid.live/edit',
|
||||||
|
buttonText: 'Start free',
|
||||||
|
features: openSourceFeatures,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
title: 'Mermaid Pro',
|
||||||
|
description: 'Unlock AI and real-time collaboration',
|
||||||
|
redirectUrl:
|
||||||
|
'https://www.mermaidchart.com/app/sign-up?utm_source=mermaid_js&utm_medium=editor_selection_B&utm_campaign=start_free',
|
||||||
|
buttonText: 'Start Free',
|
||||||
|
highlighted: true,
|
||||||
|
redBarText: 'Recommended',
|
||||||
|
proTrialButtonText: 'Start Pro trial',
|
||||||
|
proTrialUrl:
|
||||||
|
'https://www.mermaidchart.com/app/sign-up?utm_source=mermaid_js&utm_medium=editor_selection_B&utm_campaign=start_trial&redirect=%2Fapp%2Fuser%2Fbilling%2Fcheckout%3FisFromMermaid%3Dtrue',
|
||||||
|
features: mermaidChartFeatures,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Open Source',
|
||||||
|
description: 'Code only, no login',
|
||||||
|
buttonText: 'Start free',
|
||||||
|
redirectUrl: 'https://mermaid.live/edit',
|
||||||
|
isButtonMargined: true,
|
||||||
|
features: openSourceFeatures,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
title: 'Mermaid Pro',
|
||||||
|
description: 'Unlock AI and real-time collaboration',
|
||||||
|
highlighted: true,
|
||||||
|
redBarText: 'Recommended',
|
||||||
|
proTrialButtonText: 'Start free trial',
|
||||||
|
proTrialUrl:
|
||||||
|
'https://www.mermaidchart.com/app/sign-up?utm_source=mermaid_js&utm_medium=editor_selection_C&utm_campaign=start_trial&redirect=%2Fapp%2Fuser%2Fbilling%2Fcheckout%3FisFromMermaid%3Dtrue',
|
||||||
|
features: mermaidChartFeatures,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Open Source',
|
||||||
|
description: 'Code only, no login',
|
||||||
|
buttonText: 'Start free',
|
||||||
|
redirectUrl: 'https://mermaid.live/edit',
|
||||||
|
features: openSourceFeatures,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
title: 'Mermaid Pro',
|
||||||
|
description: 'Unlock AI and real-time collaboration',
|
||||||
|
highlighted: true,
|
||||||
|
redBarText: 'Recommended',
|
||||||
|
proTrialButtonText: 'Start free',
|
||||||
|
proTrialUrl:
|
||||||
|
'https://www.mermaidchart.com/app/sign-up?utm_source=mermaid_js&utm_medium=editor_selection_D&utm_campaign=start_free',
|
||||||
|
features: mermaidChartFeatures,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Open Source',
|
||||||
|
description: 'Code only, no login',
|
||||||
|
redirectUrl: 'https://mermaid.live/edit',
|
||||||
|
buttonText: 'Start free',
|
||||||
|
features: openSourceFeatures,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
const editorColumns = editorColumnVariants[Math.floor(Math.random() * editorColumnVariants.length)];
|
||||||
|
|
||||||
const isVisible = ref(false);
|
const isVisible = ref(false);
|
||||||
|
|
||||||
const handleMouseDown = (e: MouseEvent) => {
|
const handleMouseDown = (e: MouseEvent) => {
|
||||||
@@ -84,44 +164,53 @@ onUnmounted(() => {
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
v-if="isVisible"
|
v-if="isVisible"
|
||||||
class="fixed top-0 left-0 z-50 flex h-screen w-screen backdrop-blur-sm items-center justify-center"
|
class="fixed top-0 left-0 z-50 flex h-screen w-screen backdrop-blur-sm items-center justify-center bg-[#8585A4]/40 plausible-event-name=editorSelectionModalOpen"
|
||||||
@click.self="isVisible = false"
|
@click.self="isVisible = false"
|
||||||
>
|
>
|
||||||
<div class="flex flex-row rounded-3xl shadow relative gap-5 pt-20 pb-10 px-10 bg-[#F1F8FA]">
|
<div
|
||||||
|
class="flex flex-col sm:flex-row rounded-3xl shadow relative gap-5 pt-10 sm:pt-20 pb-10 px-4 sm:px-10 bg-[#F1F8FA] overflow-y-auto max-h-full"
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
v-for="column in editorColumns"
|
v-for="column in editorColumns"
|
||||||
class="w-80 flex relative flex-col justify-start items-center bg-[#dceef1] p-8 text-gray-800 shadow"
|
:key="column.title"
|
||||||
|
class="sm:w-96 flex relative flex-col justify-start items-center p-6 sm:p-8 text-gray-800 shadow w-full"
|
||||||
:class="
|
:class="
|
||||||
column.highlighted ? 'bg-white rounded-b-3xl shadow-xl' : 'bg-[#DCEEF1] rounded-3xl'
|
column.highlighted ? 'bg-white rounded-b-3xl mt-10 sm:mt-0' : 'bg-[#DCEEF1] rounded-3xl'
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
v-if="column.highlighted"
|
v-if="column.highlighted"
|
||||||
class="absolute -top-10 w-full rounded-t-3xl bg-[#E0095F] py-2 flex justify-center"
|
class="absolute -top-10 w-full rounded-t-3xl bg-[#E0095F] py-2 flex justify-center"
|
||||||
>
|
>
|
||||||
<p class="text-lg font-semibold text-white">Best for collaboration</p>
|
<p class="text-lg font-semibold text-white">{{ column.redBarText }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<header class="mb-6 w-full text-start space-y-1">
|
<header class="mb-6 w-full text-start space-y-1">
|
||||||
<p class="text-2xl font-medium capitalize text-[#1E1A2E]">
|
<p class="text-2xl font-medium text-[#1E1A2E]">{{ column.title }}</p>
|
||||||
{{ column.title }}
|
<p class="text-sm text-gray-600">{{ column.description }}</p>
|
||||||
</p>
|
|
||||||
<p class="text-sm text-gray-600">
|
|
||||||
{{ column.description }}
|
|
||||||
</p>
|
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<a
|
<a
|
||||||
|
v-if="column.redirectUrl"
|
||||||
:href="column.redirectUrl"
|
:href="column.redirectUrl"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
class="mb-6 flex h-10 w-full items-center justify-center rounded-xl hover:bg-[#272040] hover:text-white hover:shadow-md"
|
class="flex h-10 w-full bg-[#BEDDE3] hover:bg-[#5CA3B4] text-[#1E1A2E] items-center justify-center rounded-xl hover:text-white hover:shadow-md"
|
||||||
:class="
|
:class="column.isButtonMargined ? 'mb-[88px]' : ' mb-6'"
|
||||||
column.highlighted
|
|
||||||
? 'bg-[#1e1a2e] text-[#BEDDE3] hover:text-[#5CA3B4]'
|
|
||||||
: 'bg-[#BEDDE3] hover:bg-[#5CA3B4] text-[#1E1A2E]'
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
Start free
|
{{ column.buttonText }}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
<a
|
||||||
|
v-if="column.proTrialUrl"
|
||||||
|
:href="column.proTrialUrl"
|
||||||
|
target="_blank"
|
||||||
|
class="mb-6 flex h-10 w-full text-white items-center justify-center rounded-xl bg-[#E0095F] hover:bg-[#B0134A]"
|
||||||
|
>
|
||||||
|
{{ column.proTrialButtonText || 'Start Pro trial' }}
|
||||||
|
</a>
|
||||||
|
|
||||||
<div class="h-px w-full bg-[#bedde3] mb-6"></div>
|
<div class="h-px w-full bg-[#bedde3] mb-6"></div>
|
||||||
|
|
||||||
<ul class="w-full space-y-2">
|
<ul class="w-full space-y-2">
|
||||||
<li
|
<li
|
||||||
v-for="{ iconUrl, featureName } in column.features"
|
v-for="{ iconUrl, featureName } in column.features"
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import type { MarkdownOptions } from 'vitepress';
|
import type { MarkdownOptions } from 'vitepress';
|
||||||
import { defineConfig } from 'vitepress';
|
import { defineConfig } from 'vitepress';
|
||||||
import packageJson from '../../../package.json' assert { type: 'json' };
|
import packageJson from '../../../package.json' assert { type: 'json' };
|
||||||
import MermaidExample from './mermaid-markdown-all.js';
|
|
||||||
import { addCanonicalUrls } from './canonical-urls.js';
|
import { addCanonicalUrls } from './canonical-urls.js';
|
||||||
|
import MermaidExample from './mermaid-markdown-all.js';
|
||||||
|
|
||||||
const allMarkdownTransformers: MarkdownOptions = {
|
const allMarkdownTransformers: MarkdownOptions = {
|
||||||
// the shiki theme to highlight code blocks
|
// the shiki theme to highlight code blocks
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export default {
|
|||||||
'home-hero-before': () => h(TopBar),
|
'home-hero-before': () => h(TopBar),
|
||||||
'doc-before': () => h(TopBar),
|
'doc-before': () => h(TopBar),
|
||||||
'layout-bottom': () => h(Tooltip),
|
'layout-bottom': () => h(Tooltip),
|
||||||
'home-hero-after': () => h(EditorSelectionModal),
|
'layout-top': () => h(EditorSelectionModal),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
enhanceApp({ app, router }: EnhanceAppContext) {
|
enhanceApp({ app, router }: EnhanceAppContext) {
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ To add an integration to this list, see the [Integrations - create page](./integ
|
|||||||
- [Obsidian](https://help.obsidian.md/Editing+and+formatting/Advanced+formatting+syntax#Diagram) ✅
|
- [Obsidian](https://help.obsidian.md/Editing+and+formatting/Advanced+formatting+syntax#Diagram) ✅
|
||||||
- [Outline](https://docs.getoutline.com/s/guide/doc/diagrams-KQiKoT4wzK) ✅
|
- [Outline](https://docs.getoutline.com/s/guide/doc/diagrams-KQiKoT4wzK) ✅
|
||||||
- [Redmine](https://redmine.org)
|
- [Redmine](https://redmine.org)
|
||||||
- [Mermaid Macro](https://www.redmine.org/plugins/redmine_mermaid_macro)
|
- [Mermaid Macro](https://redmine.org/plugins/redmine_mermaid_macro)
|
||||||
- [Markdown for mermaid plugin](https://github.com/jamieh-mongolian/markdown-for-mermaid-plugin)
|
- [Markdown for mermaid plugin](https://github.com/jamieh-mongolian/markdown-for-mermaid-plugin)
|
||||||
- [redmine-mermaid](https://github.com/styz/redmine_mermaid)
|
- [redmine-mermaid](https://github.com/styz/redmine_mermaid)
|
||||||
- Visual Studio Code [Polyglot Interactive Notebooks](https://github.com/dotnet/interactive#net-interactive)
|
- Visual Studio Code [Polyglot Interactive Notebooks](https://github.com/dotnet/interactive#net-interactive)
|
||||||
@@ -112,7 +112,7 @@ Content Management Systems/Enterprise Content Management
|
|||||||
- [Grav CMS](https://getgrav.org/)
|
- [Grav CMS](https://getgrav.org/)
|
||||||
- [Mermaid Diagrams Plugin](https://github.com/DanielFlaum/grav-plugin-mermaid-diagrams)
|
- [Mermaid Diagrams Plugin](https://github.com/DanielFlaum/grav-plugin-mermaid-diagrams)
|
||||||
- [GitLab Markdown Adapter](https://github.com/Goutte/grav-plugin-gitlab-markdown-adapter)
|
- [GitLab Markdown Adapter](https://github.com/Goutte/grav-plugin-gitlab-markdown-adapter)
|
||||||
- [Tiki](https://tiki.org)
|
- [Tiki Wiki CMS Groupware](https://tiki.org)
|
||||||
- [Tracker Entity Relationship Diagram](https://doc.tiki.org/Tracker-Entity-Relationship-Diagram)
|
- [Tracker Entity Relationship Diagram](https://doc.tiki.org/Tracker-Entity-Relationship-Diagram)
|
||||||
- [VitePress](https://vitepress.vuejs.org/)
|
- [VitePress](https://vitepress.vuejs.org/)
|
||||||
- [Plugin for Mermaid.js](https://emersonbottero.github.io/vitepress-plugin-mermaid/)
|
- [Plugin for Mermaid.js](https://emersonbottero.github.io/vitepress-plugin-mermaid/)
|
||||||
|
|||||||
@@ -1,5 +1,65 @@
|
|||||||
# Blog
|
# Blog
|
||||||
|
|
||||||
|
## [Mermaid introduces the Visual Editor for Entity Relationship diagrams](https://docs.mermaidchart.com/blog/posts/mermaid-introduces-the-visual-editor-for-entity-relationship-diagrams)
|
||||||
|
|
||||||
|
7/15/2025 • 7 mins
|
||||||
|
|
||||||
|
Mermaid just introduced a Visual Editor for Entity Relationship diagrams, letting anyone map database structures through a simple point-and-click interface instead of code. This no-code ER builder now sits alongside Mermaid’s editors for flowcharts, sequence, and class diagrams, enabling teams to craft and share polished data models for apps, AI, and business processes.
|
||||||
|
|
||||||
|
## [Mermaid supports Treemap Diagrams now!!!](https://docs.mermaidchart.com/blog/posts/mermaid-have-treemap-diagrams-now)
|
||||||
|
|
||||||
|
7/3/2025 • 4 mins
|
||||||
|
|
||||||
|
Mermaid has introduced Treemap diagrams, currently in beta, enhancing hierarchical data visualization. Treemap diagrams use nested rectangles to represent data relationships, focusing on size and proportions. They offer various applications, including budget visualization and market analysis. With simple syntax and customization options, users can effectively present complex data hierarchies.
|
||||||
|
|
||||||
|
## [AI Diagram Generators and Data Visualization: Best Practices](https://docs.mermaidchart.com/blog/posts/ai-diagram-generators-and-data-visualization-best-practices)
|
||||||
|
|
||||||
|
7/2/2025 • 6 mins
|
||||||
|
|
||||||
|
AI diagram generators transform complex data into clear, interactive visuals – enabling faster analysis, better decisions, and stronger collaboration across teams. By combining automation with manual refinement, these tools empower anyone to communicate insights effectively, regardless of technical skill level.
|
||||||
|
|
||||||
|
## [How to Choose the Best AI Diagram Generator for Your Needs (2025)](https://docs.mermaidchart.com/blog/posts/how-to-choose-the-best-ai-diagram-generator-for-your-needs-2025)
|
||||||
|
|
||||||
|
6/26/2025 • 14 mins
|
||||||
|
|
||||||
|
AI diagram generators are transforming how developers visualize and communicate complex systems, reducing hours of manual work into minutes. With tools like Mermaid AI, users benefit from both code-based and visual editing, enabling seamless collaboration and precision. Whether you’re diagramming workflows, software architecture, or data relationships, the right AI tool can significantly boost productivity and streamline communication.
|
||||||
|
|
||||||
|
## [5 Time-Saving Tips for Using Mermaid’s AI Diagram Generator Effectively](https://docs.mermaidchart.com/blog/posts/5-time-saving-tips-for-using-mermaids-ai-diagram-generator-effectively)
|
||||||
|
|
||||||
|
6/11/2025 • 10 mins
|
||||||
|
|
||||||
|
See how developers can save time and boost productivity using Mermaid Chart’s AI diagram generator. Learn five practical tips that help turn plain language into powerful, professional diagrams.
|
||||||
|
|
||||||
|
## [Enhancing Team Collaboration with AI-Powered Diagrams](https://docs.mermaidchart.com/blog/posts/enhancing-team-collaboration-with-ai-powered-diagrams)
|
||||||
|
|
||||||
|
5/27/2025 • 6 mins
|
||||||
|
|
||||||
|
Software teams move fast, but old-school diagramming tools can’t keep up. Mermaid Chart replaces static slides and whiteboards with real-time, AI-generated visuals that evolve with your code and ideas. Just describe a process in plain English, and watch it come to life.
|
||||||
|
|
||||||
|
## [What is an AI Diagram Generator? Benefits and Use Cases](https://docs.mermaidchart.com/blog/posts/what-is-an-ai-diagram-generator-benefits-and-use-cases)
|
||||||
|
|
||||||
|
5/22/2025 • 6 mins
|
||||||
|
|
||||||
|
Discover how AI diagram generators like Mermaid Chart transform developer workflows. Instantly turn text into flowcharts, ERDs, and system diagrams, no manual drag-and-drop needed. Learn how it works, key benefits, and real-world use cases.
|
||||||
|
|
||||||
|
## [How to Use Mermaid Chart as an AI Diagram Generator for Developers](https://docs.mermaidchart.com/blog/posts/how-to-use-mermaid-chart-as-an-ai-diagram-generator)
|
||||||
|
|
||||||
|
5/21/2025 • 9 mins
|
||||||
|
|
||||||
|
Would an AI diagram generator make your life easier? We think it would!
|
||||||
|
|
||||||
|
## [Mermaid Chart VS Code Plugin: Create and Edit Mermaid.js Diagrams in Visual Studio Code](https://docs.mermaidchart.com/blog/posts/mermaid-chart-vs-code-plugin-create-and-edit-mermaid-js-diagrams-in-visual-studio-code)
|
||||||
|
|
||||||
|
3/21/2025 • 5 mins
|
||||||
|
|
||||||
|
The Mermaid Chart VS Code Plugin is a powerful developer diagramming tool that brings Mermaid.js diagramming directly into your Visual Studio Code environment. Whether you’re visualizing software architecture, documenting API flows, fixing bad documentation, or managing flowcharts and sequence diagrams, this plugin integrates seamlessly into your workflow. Key Features of the Mermaid Chart VS Code […]
|
||||||
|
|
||||||
|
## [Mermaid Chart: The Evolution of Mermaid](https://docs.mermaidchart.com/blog/posts/mermaid-chart-the-evolution-of-mermaid)
|
||||||
|
|
||||||
|
1/30/2025 • 3 mins
|
||||||
|
|
||||||
|
Mermaid revolutionized diagramming with its simple, markdown-style syntax, empowering millions of developers worldwide. Now, Mermaid Chart takes it further with AI-powered visuals, a GUI for seamless editing, real-time collaboration, and advanced design tools. Experience the next generation of diagramming—faster, smarter, and built for modern teams. Try Mermaid Chart today!
|
||||||
|
|
||||||
## [GUI for editing Mermaid Class Diagrams](https://docs.mermaidchart.com/blog/posts/gui-for-editing-mermaid-class-diagrams)
|
## [GUI for editing Mermaid Class Diagrams](https://docs.mermaidchart.com/blog/posts/gui-for-editing-mermaid-class-diagrams)
|
||||||
|
|
||||||
1/17/2025 • 5 mins
|
1/17/2025 • 5 mins
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
"fast-glob": "^3.3.3",
|
"fast-glob": "^3.3.3",
|
||||||
"https-localhost": "^4.7.1",
|
"https-localhost": "^4.7.1",
|
||||||
"pathe": "^2.0.3",
|
"pathe": "^2.0.3",
|
||||||
"unocss": "^66.0.0",
|
"unocss": "^66.4.2",
|
||||||
"unplugin-vue-components": "^28.4.0",
|
"unplugin-vue-components": "^28.4.0",
|
||||||
"vite": "^6.1.1",
|
"vite": "^6.1.1",
|
||||||
"vite-plugin-pwa": "^1.0.0",
|
"vite-plugin-pwa": "^1.0.0",
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ outline: 'deep' # shows all h3 headings in outline in Vitepress
|
|||||||
## Introduction to Block Diagrams
|
## Introduction to Block Diagrams
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
columns 1
|
columns 1
|
||||||
db(("DB"))
|
db(("DB"))
|
||||||
blockArrowId6<[" "]>(down)
|
blockArrowId6<[" "]>(down)
|
||||||
@@ -62,7 +62,7 @@ At its core, a block diagram consists of blocks representing different entities
|
|||||||
To create a simple block diagram with three blocks labeled 'a', 'b', and 'c', the syntax is as follows:
|
To create a simple block diagram with three blocks labeled 'a', 'b', and 'c', the syntax is as follows:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
a b c
|
a b c
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ While simple block diagrams are linear and straightforward, more complex systems
|
|||||||
In scenarios where you need to distribute blocks across multiple columns, you can specify the number of columns and arrange the blocks accordingly. Here's how to create a block diagram with three columns and four blocks, where the fourth block appears in a second row:
|
In scenarios where you need to distribute blocks across multiple columns, you can specify the number of columns and arrange the blocks accordingly. Here's how to create a block diagram with three columns and four blocks, where the fourth block appears in a second row:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
columns 3
|
columns 3
|
||||||
a b c d
|
a b c d
|
||||||
```
|
```
|
||||||
@@ -101,7 +101,7 @@ In more complex diagrams, you may need blocks that span multiple columns to emph
|
|||||||
To create a block diagram where one block spans across two columns, you can specify the desired width for each block:
|
To create a block diagram where one block spans across two columns, you can specify the desired width for each block:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
columns 3
|
columns 3
|
||||||
a["A label"] b:2 c:2 d
|
a["A label"] b:2 c:2 d
|
||||||
```
|
```
|
||||||
@@ -118,7 +118,7 @@ Composite blocks, or blocks within blocks, are an advanced feature in Mermaid's
|
|||||||
Creating a composite block involves defining a parent block and then nesting other blocks within it. Here's how to define a composite block with nested elements:
|
Creating a composite block involves defining a parent block and then nesting other blocks within it. Here's how to define a composite block with nested elements:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
block
|
block
|
||||||
D
|
D
|
||||||
end
|
end
|
||||||
@@ -137,7 +137,7 @@ Mermaid also allows for dynamic adjustment of column widths based on the content
|
|||||||
In diagrams with varying block sizes, Mermaid automatically adjusts the column widths to fit the largest block in each column. Here's an example:
|
In diagrams with varying block sizes, Mermaid automatically adjusts the column widths to fit the largest block in each column. Here's an example:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
columns 3
|
columns 3
|
||||||
a:3
|
a:3
|
||||||
block:group1:2
|
block:group1:2
|
||||||
@@ -157,7 +157,7 @@ This example demonstrates how Mermaid dynamically adjusts the width of the colum
|
|||||||
In scenarios where you need to stack blocks horizontally, you can use column width to accomplish the task. Blocks can be arranged vertically by putting them in a single column. Here is how you can create a block diagram in which 4 blocks are stacked on top of each other:
|
In scenarios where you need to stack blocks horizontally, you can use column width to accomplish the task. Blocks can be arranged vertically by putting them in a single column. Here is how you can create a block diagram in which 4 blocks are stacked on top of each other:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
block
|
block
|
||||||
columns 1
|
columns 1
|
||||||
a["A label"] b c d
|
a["A label"] b c d
|
||||||
@@ -181,7 +181,7 @@ Mermaid supports a range of block shapes to suit different diagramming needs, fr
|
|||||||
To create a block with round edges, which can be used to represent a softer or more flexible component:
|
To create a block with round edges, which can be used to represent a softer or more flexible component:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
id1("This is the text in the box")
|
id1("This is the text in the box")
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -190,7 +190,7 @@ block-beta
|
|||||||
A stadium-shaped block, resembling an elongated circle, can be used for components that are process-oriented:
|
A stadium-shaped block, resembling an elongated circle, can be used for components that are process-oriented:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
id1(["This is the text in the box"])
|
id1(["This is the text in the box"])
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -199,7 +199,7 @@ block-beta
|
|||||||
For representing subroutines or contained processes, a block with double vertical lines is useful:
|
For representing subroutines or contained processes, a block with double vertical lines is useful:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
id1[["This is the text in the box"]]
|
id1[["This is the text in the box"]]
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -208,7 +208,7 @@ block-beta
|
|||||||
The cylindrical shape is ideal for representing databases or storage components:
|
The cylindrical shape is ideal for representing databases or storage components:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
id1[("Database")]
|
id1[("Database")]
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -217,7 +217,7 @@ block-beta
|
|||||||
A circle can be used for centralized or pivotal components:
|
A circle can be used for centralized or pivotal components:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
id1(("This is the text in the circle"))
|
id1(("This is the text in the circle"))
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -228,21 +228,21 @@ For decision points, use a rhombus, and for unique or specialized processes, asy
|
|||||||
**Asymmetric**
|
**Asymmetric**
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
id1>"This is the text in the box"]
|
id1>"This is the text in the box"]
|
||||||
```
|
```
|
||||||
|
|
||||||
**Rhombus**
|
**Rhombus**
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
id1{"This is the text in the box"}
|
id1{"This is the text in the box"}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Hexagon**
|
**Hexagon**
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
id1{{"This is the text in the box"}}
|
id1{{"This is the text in the box"}}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -251,7 +251,7 @@ block-beta
|
|||||||
Parallelogram and trapezoid shapes are perfect for inputs/outputs and transitional processes:
|
Parallelogram and trapezoid shapes are perfect for inputs/outputs and transitional processes:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
id1[/"This is the text in the box"/]
|
id1[/"This is the text in the box"/]
|
||||||
id2[\"This is the text in the box"\]
|
id2[\"This is the text in the box"\]
|
||||||
A[/"Christmas"\]
|
A[/"Christmas"\]
|
||||||
@@ -263,7 +263,7 @@ block-beta
|
|||||||
For highlighting critical or high-priority components, a double circle can be effective:
|
For highlighting critical or high-priority components, a double circle can be effective:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
id1((("This is the text in the circle")))
|
id1((("This is the text in the circle")))
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -276,7 +276,7 @@ Mermaid also offers unique shapes like block arrows and space blocks for directi
|
|||||||
Block arrows can visually indicate direction or flow within a process:
|
Block arrows can visually indicate direction or flow within a process:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
blockArrowId<["Label"]>(right)
|
blockArrowId<["Label"]>(right)
|
||||||
blockArrowId2<["Label"]>(left)
|
blockArrowId2<["Label"]>(left)
|
||||||
blockArrowId3<["Label"]>(up)
|
blockArrowId3<["Label"]>(up)
|
||||||
@@ -291,7 +291,7 @@ block-beta
|
|||||||
Space blocks can be used to create intentional empty spaces in the diagram, which is useful for layout and readability:
|
Space blocks can be used to create intentional empty spaces in the diagram, which is useful for layout and readability:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
columns 3
|
columns 3
|
||||||
a space b
|
a space b
|
||||||
c d e
|
c d e
|
||||||
@@ -300,7 +300,7 @@ block-beta
|
|||||||
or
|
or
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
ida space:3 idb idc
|
ida space:3 idb idc
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -325,7 +325,7 @@ The most fundamental aspect of connecting blocks is the use of arrows or links.
|
|||||||
A simple link with an arrow can be created to show direction or flow from one block to another:
|
A simple link with an arrow can be created to show direction or flow from one block to another:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
A space B
|
A space B
|
||||||
A-->B
|
A-->B
|
||||||
```
|
```
|
||||||
@@ -342,7 +342,7 @@ Example - Text with Links
|
|||||||
To add text to a link, the syntax includes the text within the link definition:
|
To add text to a link, the syntax includes the text within the link definition:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
A space:2 B
|
A space:2 B
|
||||||
A-- "X" -->B
|
A-- "X" -->B
|
||||||
```
|
```
|
||||||
@@ -352,7 +352,7 @@ This example show how to add descriptive text to the links, enhancing the inform
|
|||||||
Example - Edges and Styles:
|
Example - Edges and Styles:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
columns 1
|
columns 1
|
||||||
db(("DB"))
|
db(("DB"))
|
||||||
blockArrowId6<[" "]>(down)
|
blockArrowId6<[" "]>(down)
|
||||||
@@ -381,7 +381,7 @@ Mermaid enables detailed styling of individual blocks, allowing you to apply var
|
|||||||
To apply custom styles to a block, you can use the `style` keyword followed by the block identifier and the desired CSS properties:
|
To apply custom styles to a block, you can use the `style` keyword followed by the block identifier and the desired CSS properties:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
id1 space id2
|
id1 space id2
|
||||||
id1("Start")-->id2("Stop")
|
id1("Start")-->id2("Stop")
|
||||||
style id1 fill:#636,stroke:#333,stroke-width:4px
|
style id1 fill:#636,stroke:#333,stroke-width:4px
|
||||||
@@ -395,7 +395,7 @@ Mermaid enables applying styling to classes, which could make styling easier if
|
|||||||
#### Example - Styling a Single Class
|
#### Example - Styling a Single Class
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
A space B
|
A space B
|
||||||
A-->B
|
A-->B
|
||||||
classDef blue fill:#6e6ce6,stroke:#333,stroke-width:4px;
|
classDef blue fill:#6e6ce6,stroke:#333,stroke-width:4px;
|
||||||
@@ -420,7 +420,7 @@ Combining the elements of structure, linking, and styling, we can create compreh
|
|||||||
Illustrating a simple software system architecture with interconnected components:
|
Illustrating a simple software system architecture with interconnected components:
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
block-beta
|
block
|
||||||
columns 3
|
columns 3
|
||||||
Frontend blockArrowId6<[" "]>(right) Backend
|
Frontend blockArrowId6<[" "]>(right) Backend
|
||||||
space:2 down<[" "]>(down)
|
space:2 down<[" "]>(down)
|
||||||
@@ -439,7 +439,7 @@ This example shows a basic architecture with a frontend, backend, and database.
|
|||||||
Representing a business process flow with decision points and multiple stages:
|
Representing a business process flow with decision points and multiple stages:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
columns 3
|
columns 3
|
||||||
Start(("Start")) space:2
|
Start(("Start")) space:2
|
||||||
down<[" "]>(down) space:2
|
down<[" "]>(down) space:2
|
||||||
@@ -468,7 +468,7 @@ Understanding and avoiding common syntax errors is key to a smooth experience wi
|
|||||||
A common mistake is incorrect linking syntax, which can lead to unexpected results or broken diagrams:
|
A common mistake is incorrect linking syntax, which can lead to unexpected results or broken diagrams:
|
||||||
|
|
||||||
```
|
```
|
||||||
block-beta
|
block
|
||||||
A - B
|
A - B
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -476,7 +476,7 @@ block-beta
|
|||||||
Ensure that links between blocks are correctly specified with arrows (--> or ---) to define the direction and type of connection. Also remember that one of the fundamentals for block diagram is to give the author full control of where the boxes are positioned so in the example you need to add a space between the boxes:
|
Ensure that links between blocks are correctly specified with arrows (--> or ---) to define the direction and type of connection. Also remember that one of the fundamentals for block diagram is to give the author full control of where the boxes are positioned so in the example you need to add a space between the boxes:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
A space B
|
A space B
|
||||||
A --> B
|
A --> B
|
||||||
```
|
```
|
||||||
@@ -486,7 +486,7 @@ block-beta
|
|||||||
Applying styles in the wrong context or with incorrect syntax can lead to blocks not being styled as intended:
|
Applying styles in the wrong context or with incorrect syntax can lead to blocks not being styled as intended:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
A
|
A
|
||||||
style A fill#969;
|
style A fill#969;
|
||||||
```
|
```
|
||||||
@@ -495,7 +495,7 @@ Applying styles in the wrong context or with incorrect syntax can lead to blocks
|
|||||||
Correct the syntax by ensuring proper separation of style properties with commas and using the correct CSS property format:
|
Correct the syntax by ensuring proper separation of style properties with commas and using the correct CSS property format:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
block-beta
|
block
|
||||||
A
|
A
|
||||||
style A fill:#969,stroke:#333;
|
style A fill:#969,stroke:#333;
|
||||||
|
|
||||||
|
|||||||
@@ -590,11 +590,17 @@ flowchart TD
|
|||||||
- `b`
|
- `b`
|
||||||
- **w**: The width of the image. If not defined, this will default to the natural width of the image.
|
- **w**: The width of the image. If not defined, this will default to the natural width of the image.
|
||||||
- **h**: The height of the image. If not defined, this will default to the natural height of the image.
|
- **h**: The height of the image. If not defined, this will default to the natural height of the image.
|
||||||
- **constraint**: Determines if the image should constrain the node size. This setting also ensures the image maintains its original aspect ratio, adjusting the height (`h`) accordingly to the width (`w`). If not defined, this will default to `off` Possible values are:
|
- **constraint**: Determines if the image should constrain the node size. This setting also ensures the image maintains its original aspect ratio, adjusting the width (`w`) accordingly to the height (`h`). If not defined, this will default to `off` Possible values are:
|
||||||
- `on`
|
- `on`
|
||||||
- `off`
|
- `off`
|
||||||
|
|
||||||
These new shapes provide additional flexibility and visual appeal to your flowcharts, making them more informative and engaging.
|
If you want to resize an image, but keep the same aspect ratio, set `h`, and set `constraint: on` to constrain the aspect ratio. E.g.
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
%% My image with a constrained aspect ratio
|
||||||
|
A@{ img: "https://mermaid.js.org/favicon.svg", label: "My example image label", pos: "t", h: 60, constraint: "on" }
|
||||||
|
```
|
||||||
|
|
||||||
## Links between nodes
|
## Links between nodes
|
||||||
|
|
||||||
@@ -1156,7 +1162,7 @@ config:
|
|||||||
graph LR
|
graph LR
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Edge level curve style using Edge IDs (v<MERMAID_RELEASE_VERSION>+)
|
#### Edge level curve style using Edge IDs (v11.10.0+)
|
||||||
|
|
||||||
You can assign IDs to [edges](#attaching-an-id-to-edges). After assigning an ID you can modify the line style by modifying the edge's `curve` property using the following syntax:
|
You can assign IDs to [edges](#attaching-an-id-to-edges). After assigning an ID you can modify the line style by modifying the edge's `curve` property using the following syntax:
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,11 @@ Drawing a pie chart is really simple in mermaid.
|
|||||||
- Followed by `:` colon as separator
|
- Followed by `:` colon as separator
|
||||||
- Followed by `positive numeric value` (supported up to two decimal places)
|
- Followed by `positive numeric value` (supported up to two decimal places)
|
||||||
|
|
||||||
|
**Note:**
|
||||||
|
|
||||||
|
> Pie chart values must be **positive numbers greater than zero**.
|
||||||
|
> **Negative values are not allowed** and will result in an error.
|
||||||
|
|
||||||
[pie] [showData] (OPTIONAL)
|
[pie] [showData] (OPTIONAL)
|
||||||
[title] [titlevalue] (OPTIONAL)
|
[title] [titlevalue] (OPTIONAL)
|
||||||
"[datakey1]" : [dataValue1]
|
"[datakey1]" : [dataValue1]
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ config:
|
|||||||
sankey:
|
sankey:
|
||||||
showValues: false
|
showValues: false
|
||||||
---
|
---
|
||||||
sankey-beta
|
sankey
|
||||||
|
|
||||||
Agricultural 'waste',Bio-conversion,124.729
|
Agricultural 'waste',Bio-conversion,124.729
|
||||||
Bio-conversion,Liquid,0.597
|
Bio-conversion,Liquid,0.597
|
||||||
@@ -92,7 +92,7 @@ Wind,Electricity grid,289.366
|
|||||||
|
|
||||||
## Syntax
|
## Syntax
|
||||||
|
|
||||||
The idea behind syntax is that a user types `sankey-beta` keyword first, then pastes raw CSV below and get the result.
|
The idea behind syntax is that a user types `sankey` keyword first, then pastes raw CSV below and get the result.
|
||||||
|
|
||||||
It implements CSV standard as [described here](https://www.ietf.org/rfc/rfc4180.txt) with subtle **differences**:
|
It implements CSV standard as [described here](https://www.ietf.org/rfc/rfc4180.txt) with subtle **differences**:
|
||||||
|
|
||||||
@@ -104,7 +104,7 @@ It implements CSV standard as [described here](https://www.ietf.org/rfc/rfc4180.
|
|||||||
It is implied that 3 columns inside CSV should represent `source`, `target` and `value` accordingly:
|
It is implied that 3 columns inside CSV should represent `source`, `target` and `value` accordingly:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
sankey-beta
|
sankey
|
||||||
|
|
||||||
%% source,target,value
|
%% source,target,value
|
||||||
Electricity grid,Over generation / exports,104.453
|
Electricity grid,Over generation / exports,104.453
|
||||||
@@ -117,7 +117,7 @@ Electricity grid,H2 conversion,27.14
|
|||||||
CSV does not support empty lines without comma delimiters by default. But you can add them if needed:
|
CSV does not support empty lines without comma delimiters by default. But you can add them if needed:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
sankey-beta
|
sankey
|
||||||
|
|
||||||
Bio-conversion,Losses,26.862
|
Bio-conversion,Losses,26.862
|
||||||
|
|
||||||
@@ -131,7 +131,7 @@ Bio-conversion,Gas,81.144
|
|||||||
If you need to have a comma, wrap it in double quotes:
|
If you need to have a comma, wrap it in double quotes:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
sankey-beta
|
sankey
|
||||||
|
|
||||||
Pumped heat,"Heating and cooling, homes",193.026
|
Pumped heat,"Heating and cooling, homes",193.026
|
||||||
Pumped heat,"Heating and cooling, commercial",70.672
|
Pumped heat,"Heating and cooling, commercial",70.672
|
||||||
@@ -142,7 +142,7 @@ Pumped heat,"Heating and cooling, commercial",70.672
|
|||||||
If you need to have double quote, put a pair of them inside quoted string:
|
If you need to have double quote, put a pair of them inside quoted string:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
sankey-beta
|
sankey
|
||||||
|
|
||||||
Pumped heat,"Heating and cooling, ""homes""",193.026
|
Pumped heat,"Heating and cooling, ""homes""",193.026
|
||||||
Pumped heat,"Heating and cooling, ""commercial""",70.672
|
Pumped heat,"Heating and cooling, ""commercial""",70.672
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user