mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-12-26 06:06:22 +01:00
Compare commits
140 Commits
testE2E
...
feat/confi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8b0399ed26 | ||
|
|
80c20a72b2 | ||
|
|
78f1631c8f | ||
|
|
ff6988e875 | ||
|
|
95dcd30324 | ||
|
|
c84c7f52f9 | ||
|
|
cd8e354234 | ||
|
|
d797365802 | ||
|
|
73293efcf3 | ||
|
|
91ae282808 | ||
|
|
4c551b2aca | ||
|
|
d21461fba0 | ||
|
|
b51d8ff7ba | ||
|
|
75ec719257 | ||
|
|
13e052ff81 | ||
|
|
bde6a9ff4f | ||
|
|
23d843b6d3 | ||
|
|
cffac848ea | ||
|
|
9651d0c2da | ||
|
|
e1a23f10df | ||
|
|
d346a77e3c | ||
|
|
f069de5487 | ||
|
|
ba0bddf417 | ||
|
|
f30c26485e | ||
|
|
b71f4c7e54 | ||
|
|
e046da10c2 | ||
|
|
12dc3d8373 | ||
|
|
c5272d5279 | ||
|
|
7ca990d762 | ||
|
|
91907fe0eb | ||
|
|
6bf5571f96 | ||
|
|
8619a53a9c | ||
|
|
9bedfa2033 | ||
|
|
59264a33d7 | ||
|
|
0b0f988180 | ||
|
|
1c200ee5bc | ||
|
|
6939cf52e6 | ||
|
|
ec79ac200c | ||
|
|
de03a017db | ||
|
|
42ad1f4fe4 | ||
|
|
a01be16d27 | ||
|
|
5c6c8d1135 | ||
|
|
493f238319 | ||
|
|
17066aab97 | ||
|
|
21c9397ec1 | ||
|
|
427bcaa3f6 | ||
|
|
8fad1f55e2 | ||
|
|
05e17c0bf0 | ||
|
|
1612d3fabd | ||
|
|
679f77dea5 | ||
|
|
1bad612c51 | ||
|
|
81825f22f5 | ||
|
|
e668698b5c | ||
|
|
7b624667fa | ||
|
|
e7c52bbf59 | ||
|
|
3e87412e97 | ||
|
|
2401f334ec | ||
|
|
4f60a27472 | ||
|
|
2bbdd15031 | ||
|
|
c226358f65 | ||
|
|
8fd268d59b | ||
|
|
b91624cb63 | ||
|
|
54f2452406 | ||
|
|
84a18a1858 | ||
|
|
5b2a10e592 | ||
|
|
8820c7baf1 | ||
|
|
1e70b3817e | ||
|
|
1f37b6c91b | ||
|
|
c080522102 | ||
|
|
d95fdfee94 | ||
|
|
d74025bd80 | ||
|
|
d0224b23b0 | ||
|
|
6334516639 | ||
|
|
aadf32ab3e | ||
|
|
6424f823b2 | ||
|
|
8bfb269b37 | ||
|
|
3935f6b389 | ||
|
|
f5dd24bce4 | ||
|
|
279e31bc55 | ||
|
|
f1fc874da8 | ||
|
|
a871a68f3c | ||
|
|
a964af67ec | ||
|
|
6f205f89b2 | ||
|
|
35b3192c2b | ||
|
|
be4721b24d | ||
|
|
a9a8a208a6 | ||
|
|
f58a86d747 | ||
|
|
4ce5d07125 | ||
|
|
658af081ee | ||
|
|
fdfa917cdb | ||
|
|
46552faa2e | ||
|
|
1285e59080 | ||
|
|
cb0ee5aa41 | ||
|
|
95ebb4aaec | ||
|
|
3852117581 | ||
|
|
bf55d940b6 | ||
|
|
e0ee9b1bc0 | ||
|
|
51aea90e9a | ||
|
|
7918f96f94 | ||
|
|
be8faae68c | ||
|
|
04ebf0ddc9 | ||
|
|
223c8c92cb | ||
|
|
7a8a1315c0 | ||
|
|
9213afbacd | ||
|
|
c77a6e156c | ||
|
|
02246f64d2 | ||
|
|
bf1edd99f9 | ||
|
|
6f09bc7dc7 | ||
|
|
3fb6acbf8f | ||
|
|
cbeee51108 | ||
|
|
c50a82a60e | ||
|
|
f5ef0b600e | ||
|
|
41f3f9fb32 | ||
|
|
46583cf4eb | ||
|
|
eb3e924c44 | ||
|
|
222c46e7f0 | ||
|
|
00ac6ccb37 | ||
|
|
e6bd1ae9dc | ||
|
|
8e6f5bbdb1 | ||
|
|
8002d9e2eb | ||
|
|
ddd6e9ac73 | ||
|
|
31578ae72d | ||
|
|
5d70b8922d | ||
|
|
26956bf128 | ||
|
|
11aa7a7052 | ||
|
|
7e6fd1ebe2 | ||
|
|
5e1f0c620a | ||
|
|
c8f0b39075 | ||
|
|
7e1cc27c76 | ||
|
|
8bff32adab | ||
|
|
03b5c00f03 | ||
|
|
aa3a19b63c | ||
|
|
8e95cdb883 | ||
|
|
68ff352f2d | ||
|
|
f02dfe60af | ||
|
|
53b4f584db | ||
|
|
201016ccc5 | ||
|
|
aaf9fd5f03 | ||
|
|
783becebf6 | ||
|
|
3e098ab73b |
6
.github/ISSUE_TEMPLATE/config.yml
vendored
6
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -3,9 +3,9 @@ contact_links:
|
||||
- name: GitHub Discussions
|
||||
url: https://github.com/mermaid-js/mermaid/discussions
|
||||
about: Ask the Community questions or share your own graphs in our discussions.
|
||||
- name: Slack
|
||||
url: https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE
|
||||
about: Join our Community on Slack for Help and a casual chat.
|
||||
- name: Discord
|
||||
url: https://discord.gg/wwtabKgp8y
|
||||
about: Join our Community on Discord for Help and a casual chat.
|
||||
- name: Documentation
|
||||
url: https://mermaid.js.org
|
||||
about: Read our documentation for all that Mermaid.js can offer.
|
||||
|
||||
4
.github/lychee.toml
vendored
4
.github/lychee.toml
vendored
@@ -34,8 +34,8 @@ exclude = [
|
||||
# Don't check files that are generated during the build via `pnpm docs:code`
|
||||
'packages/mermaid/src/docs/config/setup/*',
|
||||
|
||||
# Ignore slack invite
|
||||
"https://join.slack.com/"
|
||||
# Ignore Discord invite
|
||||
"https://discord.gg"
|
||||
]
|
||||
|
||||
# Exclude all private IPs from checking.
|
||||
|
||||
10
.github/workflows/build.yml
vendored
10
.github/workflows/build.yml
vendored
@@ -12,23 +12,23 @@ on:
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
node-version: 18.x
|
||||
|
||||
jobs:
|
||||
build-mermaid:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [18.x]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: pnpm/action-setup@v2
|
||||
# uses version from "packageManager" field in package.json
|
||||
|
||||
- name: Setup Node.js ${{ matrix.node-version }}
|
||||
- name: Setup Node.js ${{ env.node-version }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: pnpm
|
||||
node-version: ${{ matrix.node-version }}
|
||||
node-version: ${{ env.node-version }}
|
||||
|
||||
- name: Install Packages
|
||||
run: |
|
||||
|
||||
78
.github/workflows/e2e.yml
vendored
78
.github/workflows/e2e.yml
vendored
@@ -1,13 +1,26 @@
|
||||
# We use github cache to save snapshots between runs.
|
||||
# For PRs and MergeQueues, the target commit is used, and for push events, github.event.previous is used.
|
||||
# If a snapshot for a given Hash is not found, we checkout that commit, run the tests and cache the snapshots.
|
||||
# These are then downloaded before running the E2E, providing the reference snapshots.
|
||||
# If there are any errors, the diff image is uploaded to artifacts, and the user is notified.
|
||||
|
||||
name: E2E
|
||||
|
||||
on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- 'gh-readonly-queue/**'
|
||||
pull_request:
|
||||
merge_group:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
node-version: 18.x
|
||||
# For PRs and MergeQueues, the target commit is used, and for push events, github.event.previous is used.
|
||||
targetHash: ${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha || (github.event.before == '0000000000000000000000000000000000000000' && 'develop' || github.event.before) }}
|
||||
|
||||
jobs:
|
||||
cache:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -18,20 +31,20 @@ jobs:
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18.x
|
||||
|
||||
- name: Cache snapshots
|
||||
id: cache-snapshot
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
save-always: true
|
||||
path: ./cypress/snapshots
|
||||
key: ${{ runner.os }}-snapshots
|
||||
key: ${{ runner.os }}-snapshots-${{ env.targetHash }}
|
||||
|
||||
# If a snapshot for a given Hash is not found, we checkout that commit, run the tests and cache the snapshots.
|
||||
- name: Switch to base branch
|
||||
if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' }}
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event_name == 'merge_group' && github.event.merge_group.base.sha || 'develop' }}
|
||||
ref: ${{ env.targetHash }}
|
||||
|
||||
- name: Cypress run
|
||||
uses: cypress-io/github-action@v4
|
||||
@@ -48,7 +61,6 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node-version: [18.x]
|
||||
containers: [1, 2, 3, 4]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@@ -56,17 +68,18 @@ jobs:
|
||||
- uses: pnpm/action-setup@v2
|
||||
# uses version from "packageManager" field in package.json
|
||||
|
||||
- name: Setup Node.js ${{ matrix.node-version }}
|
||||
- name: Setup Node.js ${{ env.node-version }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
node-version: ${{ env.node-version }}
|
||||
|
||||
# These cached snapshots are downloaded, providing the reference snapshots.
|
||||
- name: Cache snapshots
|
||||
id: cache-snapshot
|
||||
uses: actions/cache/restore@v3
|
||||
with:
|
||||
path: ./cypress/snapshots
|
||||
key: ${{ runner.os }}-snapshots
|
||||
key: ${{ runner.os }}-snapshots-${{ env.targetHash }}
|
||||
|
||||
# Install NPM dependencies, cache them correctly
|
||||
# and run all Cypress tests
|
||||
@@ -101,9 +114,54 @@ jobs:
|
||||
verbose: true
|
||||
token: 6845cc80-77ee-4e17-85a1-026cd95e0766
|
||||
|
||||
# We upload the artifacts into numbered archives to prevent overwriting
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
if: ${{ failure() && steps.cypress.conclusion == 'failure' }}
|
||||
uses: actions/upload-artifact@v4
|
||||
if: ${{ always() }}
|
||||
with:
|
||||
name: snapshots-${{ matrix.containers }}
|
||||
retention-days: 1
|
||||
path: ./cypress/snapshots
|
||||
|
||||
combineArtifacts:
|
||||
needs: e2e
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ always() }}
|
||||
steps:
|
||||
# Download all snapshot artifacts and merge them into a single folder
|
||||
- name: Download All Artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: snapshots
|
||||
pattern: snapshots-*
|
||||
merge-multiple: true
|
||||
|
||||
# For successful push events, we save the snapshots cache
|
||||
- name: Save snapshots cache
|
||||
id: cache-upload
|
||||
if: ${{ github.event_name == 'push' && needs.e2e.result != 'failure' }}
|
||||
uses: actions/cache/save@v3
|
||||
with:
|
||||
path: ./snapshots
|
||||
key: ${{ runner.os }}-snapshots-${{ github.event.after }}
|
||||
|
||||
- name: Flatten images to a folder
|
||||
if: ${{ needs.e2e.result == 'failure' }}
|
||||
run: |
|
||||
mkdir errors
|
||||
cd snapshots
|
||||
find . -mindepth 2 -type d -name "*__diff_output__*" -exec sh -c 'mv "$0"/*.png ../errors/' {} \;
|
||||
|
||||
- name: Upload Error snapshots
|
||||
if: ${{ needs.e2e.result == 'failure' }}
|
||||
uses: actions/upload-artifact@v4
|
||||
id: upload-artifacts
|
||||
with:
|
||||
name: error-snapshots
|
||||
path: cypress/snapshots/**/__diff_output__/*
|
||||
retention-days: 10
|
||||
path: errors/
|
||||
|
||||
- name: Notify Users
|
||||
if: ${{ needs.e2e.result == 'failure' }}
|
||||
run: |
|
||||
echo "::error title=Visual tests failed::You can view images that failed by downloading the error-snapshots artifact: ${{ steps.upload-artifacts.outputs.artifact-url }}"
|
||||
|
||||
10
.github/workflows/lint.yml
vendored
10
.github/workflows/lint.yml
vendored
@@ -13,23 +13,23 @@ on:
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
env:
|
||||
node-version: 18.x
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [18.x]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: pnpm/action-setup@v2
|
||||
# uses version from "packageManager" field in package.json
|
||||
|
||||
- name: Setup Node.js ${{ matrix.node-version }}
|
||||
- name: Setup Node.js ${{ env.node-version }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: pnpm
|
||||
node-version: ${{ matrix.node-version }}
|
||||
node-version: ${{ env.node-version }}
|
||||
|
||||
- name: Install Packages
|
||||
run: |
|
||||
|
||||
10
.github/workflows/test.yml
vendored
10
.github/workflows/test.yml
vendored
@@ -5,23 +5,23 @@ on: [push, pull_request, merge_group]
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
node-version: 18.x
|
||||
|
||||
jobs:
|
||||
unit-test:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [18.x]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: pnpm/action-setup@v2
|
||||
# uses version from "packageManager" field in package.json
|
||||
|
||||
- name: Setup Node.js ${{ matrix.node-version }}
|
||||
- name: Setup Node.js ${{ env.node-version }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: pnpm
|
||||
node-version: ${{ matrix.node-version }}
|
||||
node-version: ${{ env.node-version }}
|
||||
|
||||
- name: Install Packages
|
||||
run: |
|
||||
|
||||
9
.github/workflows/update-browserlist.yml
vendored
9
.github/workflows/update-browserlist.yml
vendored
@@ -9,10 +9,17 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: npx browserslist@latest --update-db
|
||||
- uses: pnpm/action-setup@v2
|
||||
- run: npx update-browserslist-db@latest
|
||||
- name: Commit changes
|
||||
uses: EndBug/add-and-commit@v9
|
||||
with:
|
||||
author_name: ${{ github.actor }}
|
||||
author_email: ${{ github.actor }}@users.noreply.github.com
|
||||
message: 'chore: update browsers list'
|
||||
push: false
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v5
|
||||
with:
|
||||
branch: update-browserslist
|
||||
title: Update Browserslist
|
||||
|
||||
@@ -15,7 +15,7 @@ Generate diagrams from markdown-like text.
|
||||
<a href="https://mermaid.live/"><b>Live Editor!</b></a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://mermaid.js.org">📖 Documentation</a> | <a href="https://mermaid.js.org/intro/">🚀 Getting Started</a> | <a href="https://www.jsdelivr.com/package/npm/mermaid">🌐 CDN</a> | <a href="https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE" title="Slack invite">🙌 Join Us</a>
|
||||
<a href="https://mermaid.js.org">📖 Documentation</a> | <a href="https://mermaid.js.org/intro/">🚀 Getting Started</a> | <a href="https://www.jsdelivr.com/package/npm/mermaid">🌐 CDN</a> | <a href="https://discord.gg/wwtabKgp8y" title="Discord invite">🙌 Join Us</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="./README.zh-CN.md">简体中文</a>
|
||||
@@ -33,7 +33,7 @@ Try Live Editor previews of future releases: <a href="https://develop.git.mermai
|
||||
[](https://app.codecov.io/github/mermaid-js/mermaid/tree/develop)
|
||||
[](https://www.jsdelivr.com/package/npm/mermaid)
|
||||
[](https://www.npmjs.com/package/mermaid)
|
||||
[](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE)
|
||||
[](https://discord.gg/wwtabKgp8y)
|
||||
[](https://twitter.com/mermaidjs_)
|
||||
|
||||
<img src="./img/header.png" alt="" />
|
||||
|
||||
@@ -15,7 +15,7 @@ Mermaid
|
||||
<a href="https://mermaid.live/"><b>实时编辑器!</b></a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://mermaid.js.org">📖 文档</a> | <a href="https://mermaid.js.org/intro/">🚀 入门</a> | <a href="https://www.jsdelivr.com/package/npm/mermaid">🌐 CDN</a> | <a href="https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE" title="Slack invite">🙌 加入我们</a>
|
||||
<a href="https://mermaid.js.org">📖 文档</a> | <a href="https://mermaid.js.org/intro/">🚀 入门</a> | <a href="https://www.jsdelivr.com/package/npm/mermaid">🌐 CDN</a> | <a href="https://discord.gg/wwtabKgp8y" title="Discord invite">🙌 加入我们</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="./README.md">English</a>
|
||||
@@ -34,7 +34,7 @@ Mermaid
|
||||
[](https://app.codecov.io/github/mermaid-js/mermaid/tree/develop)
|
||||
[](https://www.jsdelivr.com/package/npm/mermaid)
|
||||
[](https://www.npmjs.com/package/mermaid)
|
||||
[](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE)
|
||||
[](https://discord.gg/wwtabKgp8y)
|
||||
[](https://twitter.com/mermaidjs_)
|
||||
|
||||
<img src="./img/header.png" alt="" />
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const { defineConfig } = require('cypress');
|
||||
|
||||
module.exports = defineConfig({
|
||||
testConcurrency: 1,
|
||||
browser: [
|
||||
// Add browsers with different viewports
|
||||
// { width: 800, height: 600, name: 'chrome' },
|
||||
// { width: 700, height: 500, name: 'firefox' },
|
||||
// { width: 1600, height: 1200, name: 'ie11' },
|
||||
// { width: 1024, height: 768, name: 'edgechromium' },
|
||||
// { width: 800, height: 600, name: 'safari' },
|
||||
// // Add mobile emulation devices in Portrait mode
|
||||
// { deviceName: 'iPhone X', screenOrientation: 'portrait' },
|
||||
// { deviceName: 'Pixel 2', screenOrientation: 'portrait' },
|
||||
],
|
||||
// set batch name to the configuration
|
||||
// batchName: `Mermaid ${process.env.APPLI_BRANCH ?? "'no APPLI_BRANCH set'"}`,
|
||||
});
|
||||
@@ -102,6 +102,7 @@
|
||||
"pathe",
|
||||
"pbrolin",
|
||||
"phpbb",
|
||||
"pixelmatch",
|
||||
"plantuml",
|
||||
"playfair",
|
||||
"pnpm",
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
|
||||
const { defineConfig } = require('cypress');
|
||||
const { addMatchImageSnapshotPlugin } = require('cypress-image-snapshot/plugin');
|
||||
const coverage = require('@cypress/code-coverage/task');
|
||||
|
||||
module.exports = defineConfig({
|
||||
projectId: 'n2sma2',
|
||||
viewportWidth: 1440,
|
||||
viewportHeight: 1024,
|
||||
e2e: {
|
||||
specPattern: 'cypress/integration/**/*.{js,ts}',
|
||||
setupNodeEvents(on, config) {
|
||||
coverage(on, config);
|
||||
on('before:browser:launch', (browser = {}, launchOptions) => {
|
||||
if (browser.name === 'chrome' && browser.isHeadless) {
|
||||
launchOptions.args.push('--window-size=1440,1024', '--force-device-scale-factor=1');
|
||||
}
|
||||
return launchOptions;
|
||||
});
|
||||
addMatchImageSnapshotPlugin(on, config);
|
||||
// copy any needed variables from process.env to config.env
|
||||
config.env.useAppli = process.env.USE_APPLI ? true : false;
|
||||
|
||||
// do not forget to return the changed config object!
|
||||
return config;
|
||||
},
|
||||
},
|
||||
video: false,
|
||||
});
|
||||
|
||||
require('@applitools/eyes-cypress')(module);
|
||||
30
cypress.config.ts
Normal file
30
cypress.config.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { defineConfig } from 'cypress';
|
||||
import { addMatchImageSnapshotPlugin } from 'cypress-image-snapshot/plugin';
|
||||
import coverage from '@cypress/code-coverage/task';
|
||||
import eyesPlugin from '@applitools/eyes-cypress';
|
||||
export default eyesPlugin(
|
||||
defineConfig({
|
||||
projectId: 'n2sma2',
|
||||
viewportWidth: 1440,
|
||||
viewportHeight: 1024,
|
||||
e2e: {
|
||||
specPattern: 'cypress/integration/**/*.{js,ts}',
|
||||
setupNodeEvents(on, config) {
|
||||
coverage(on, config);
|
||||
on('before:browser:launch', (browser, launchOptions) => {
|
||||
if (browser.name === 'chrome' && browser.isHeadless) {
|
||||
launchOptions.args.push('--window-size=1440,1024', '--force-device-scale-factor=1');
|
||||
}
|
||||
return launchOptions;
|
||||
});
|
||||
addMatchImageSnapshotPlugin(on, config);
|
||||
// copy any needed variables from process.env to config.env
|
||||
config.env.useAppli = process.env.USE_APPLI ? true : false;
|
||||
|
||||
// do not forget to return the changed config object!
|
||||
return config;
|
||||
},
|
||||
},
|
||||
video: false,
|
||||
})
|
||||
);
|
||||
@@ -1,12 +0,0 @@
|
||||
import { imgSnapshotTest } from '../../helpers/util.ts';
|
||||
|
||||
describe('Flowchart', () => {
|
||||
it('34: testing the label width in percy', () => {
|
||||
imgSnapshotTest(
|
||||
`graph TD
|
||||
A[Christmas]
|
||||
`,
|
||||
{ theme: 'forest', fontFamily: '"Noto Sans SC", sans-serif' }
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -741,6 +741,25 @@ A ~~~ B
|
||||
);
|
||||
});
|
||||
|
||||
it('5059: Should render when subgraph contains only subgraphs, has link to outside and itself is part of a link', () => {
|
||||
imgSnapshotTest(
|
||||
`flowchart
|
||||
|
||||
subgraph Main
|
||||
subgraph Child1
|
||||
Node1
|
||||
Node2
|
||||
end
|
||||
subgraph Child2
|
||||
Node3
|
||||
Node4
|
||||
end
|
||||
end
|
||||
Main --> Out1
|
||||
Child2 --> Out2`
|
||||
);
|
||||
});
|
||||
|
||||
describe('Markdown strings flowchart (#4220)', () => {
|
||||
describe('html labels', () => {
|
||||
it('With styling and classes', () => {
|
||||
|
||||
@@ -583,4 +583,106 @@ describe('Gantt diagram', () => {
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it("should render when there's a semicolon in the title", () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
gantt
|
||||
title ;Gantt With a Semicolon in the Title
|
||||
dateFormat YYYY-MM-DD
|
||||
section Section
|
||||
A task :a1, 2014-01-01, 30d
|
||||
Another task :after a1 , 20d
|
||||
section Another
|
||||
Task in sec :2014-01-12 , 12d
|
||||
another task : 24d
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it("should render when there's a semicolon in a section is true", () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
gantt
|
||||
title Gantt Digram
|
||||
dateFormat YYYY-MM-DD
|
||||
section ;Section With a Semicolon
|
||||
A task :a1, 2014-01-01, 30d
|
||||
Another task :after a1 , 20d
|
||||
section Another
|
||||
Task in sec :2014-01-12 , 12d
|
||||
another task : 24d
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it("should render when there's a semicolon in the task data", () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
gantt
|
||||
title Gantt Digram
|
||||
dateFormat YYYY-MM-DD
|
||||
section Section
|
||||
;A task with a semiclon :a1, 2014-01-01, 30d
|
||||
Another task :after a1 , 20d
|
||||
section Another
|
||||
Task in sec :2014-01-12 , 12d
|
||||
another task : 24d
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it("should render when there's a hashtag in the title", () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
gantt
|
||||
title #Gantt With a Hashtag in the Title
|
||||
dateFormat YYYY-MM-DD
|
||||
section Section
|
||||
A task :a1, 2014-01-01, 30d
|
||||
Another task :after a1 , 20d
|
||||
section Another
|
||||
Task in sec :2014-01-12 , 12d
|
||||
another task : 24d
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it("should render when there's a hashtag in a section is true", () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
gantt
|
||||
title Gantt Digram
|
||||
dateFormat YYYY-MM-DD
|
||||
section #Section With a Hashtag
|
||||
A task :a1, 2014-01-01, 30d
|
||||
Another task :after a1 , 20d
|
||||
section Another
|
||||
Task in sec :2014-01-12 , 12d
|
||||
another task : 24d
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it("should render when there's a hashtag in the task data", () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
gantt
|
||||
title Gantt Digram
|
||||
dateFormat YYYY-MM-DD
|
||||
section Section
|
||||
#A task with a hashtag :a1, 2014-01-01, 30d
|
||||
Another task :after a1 , 20d
|
||||
section Another
|
||||
Task in sec :2014-01-12 , 12d
|
||||
another task : 24d
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -826,4 +826,121 @@ gitGraph TB:
|
||||
cherry-pick id: "M" parent:"B"`
|
||||
);
|
||||
});
|
||||
it('41: should render default GitGraph with parallelCommits set to false', () => {
|
||||
imgSnapshotTest(
|
||||
`gitGraph
|
||||
commit id:"1-abcdefg"
|
||||
commit id:"2-abcdefg"
|
||||
branch develop
|
||||
commit id:"3-abcdefg"
|
||||
commit id:"4-abcdefg"
|
||||
checkout main
|
||||
branch feature
|
||||
commit id:"5-abcdefg"
|
||||
commit id:"6-abcdefg"
|
||||
checkout main
|
||||
commit id:"7-abcdefg"
|
||||
commit id:"8-abcdefg"
|
||||
`,
|
||||
{ gitGraph: { parallelCommits: false } }
|
||||
);
|
||||
});
|
||||
it('42: should render GitGraph with parallel commits', () => {
|
||||
imgSnapshotTest(
|
||||
`gitGraph
|
||||
commit id:"1-abcdefg"
|
||||
commit id:"2-abcdefg"
|
||||
branch develop
|
||||
commit id:"3-abcdefg"
|
||||
commit id:"4-abcdefg"
|
||||
checkout main
|
||||
branch feature
|
||||
commit id:"5-abcdefg"
|
||||
commit id:"6-abcdefg"
|
||||
checkout main
|
||||
commit id:"7-abcdefg"
|
||||
commit id:"8-abcdefg"
|
||||
`,
|
||||
{ gitGraph: { parallelCommits: true } }
|
||||
);
|
||||
});
|
||||
it('43: should render GitGraph with parallel commits | Vertical Branch', () => {
|
||||
imgSnapshotTest(
|
||||
`gitGraph TB:
|
||||
commit id:"1-abcdefg"
|
||||
commit id:"2-abcdefg"
|
||||
branch develop
|
||||
commit id:"3-abcdefg"
|
||||
commit id:"4-abcdefg"
|
||||
checkout main
|
||||
branch feature
|
||||
commit id:"5-abcdefg"
|
||||
commit id:"6-abcdefg"
|
||||
checkout main
|
||||
commit id:"7-abcdefg"
|
||||
commit id:"8-abcdefg"
|
||||
`,
|
||||
{ gitGraph: { parallelCommits: true } }
|
||||
);
|
||||
});
|
||||
it('44: should render GitGraph with unconnected branches and no parallel commits', () => {
|
||||
imgSnapshotTest(
|
||||
`gitGraph
|
||||
branch dev
|
||||
branch v2
|
||||
branch feat
|
||||
commit id:"1-abcdefg"
|
||||
commit id:"2-abcdefg"
|
||||
checkout main
|
||||
commit id:"3-abcdefg"
|
||||
checkout dev
|
||||
commit id:"4-abcdefg"
|
||||
checkout v2
|
||||
commit id:"5-abcdefg"
|
||||
checkout main
|
||||
commit id:"6-abcdefg"
|
||||
`,
|
||||
{ gitGraph: { parallelCommits: false } }
|
||||
);
|
||||
});
|
||||
it('45: should render GitGraph with unconnected branches and parallel commits', () => {
|
||||
imgSnapshotTest(
|
||||
`gitGraph
|
||||
branch dev
|
||||
branch v2
|
||||
branch feat
|
||||
commit id:"1-abcdefg"
|
||||
commit id:"2-abcdefg"
|
||||
checkout main
|
||||
commit id:"3-abcdefg"
|
||||
checkout dev
|
||||
commit id:"4-abcdefg"
|
||||
checkout v2
|
||||
commit id:"5-abcdefg"
|
||||
checkout main
|
||||
commit id:"6-abcdefg"
|
||||
`,
|
||||
{ gitGraph: { parallelCommits: true } }
|
||||
);
|
||||
});
|
||||
it('46: should render GitGraph with unconnected branches and parallel commits | Vertical Branch', () => {
|
||||
imgSnapshotTest(
|
||||
`gitGraph TB:
|
||||
branch dev
|
||||
branch v2
|
||||
branch feat
|
||||
commit id:"1-abcdefg"
|
||||
commit id:"2-abcdefg"
|
||||
checkout main
|
||||
commit id:"3-abcdefg"
|
||||
checkout dev
|
||||
commit id:"4-abcdefg"
|
||||
checkout v2
|
||||
commit id:"5-abcdefg"
|
||||
checkout main
|
||||
commit id:"6-abcdefg"
|
||||
`,
|
||||
{ gitGraph: { parallelCommits: true } }
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -792,6 +792,34 @@ context('Sequence diagram', () => {
|
||||
});
|
||||
});
|
||||
context('links', () => {
|
||||
it('should support actor links', () => {
|
||||
renderGraph(
|
||||
`
|
||||
sequenceDiagram
|
||||
link Alice: Dashboard @ https://dashboard.contoso.com/alice
|
||||
link Alice: Wiki @ https://wiki.contoso.com/alice
|
||||
link John: Dashboard @ https://dashboard.contoso.com/john
|
||||
link John: Wiki @ https://wiki.contoso.com/john
|
||||
Alice->>John: Hello John<br/>
|
||||
John-->>Alice: Great<br/><br/>day!
|
||||
`,
|
||||
{ securityLevel: 'loose' }
|
||||
);
|
||||
cy.get('#actor0_popup').should((popupMenu) => {
|
||||
const style = popupMenu.attr('style');
|
||||
expect(style).to.undefined;
|
||||
});
|
||||
cy.get('#root-0').click();
|
||||
cy.get('#actor0_popup').should((popupMenu) => {
|
||||
const style = popupMenu.attr('style');
|
||||
expect(style).to.match(/^display: block;$/);
|
||||
});
|
||||
cy.get('#root-0').click();
|
||||
cy.get('#actor0_popup').should((popupMenu) => {
|
||||
const style = popupMenu.attr('style');
|
||||
expect(style).to.match(/^display: none;$/);
|
||||
});
|
||||
});
|
||||
it('should support actor links and properties EXPERIMENTAL: USE WITH CAUTION', () => {
|
||||
//Be aware that the syntax for "properties" is likely to be changed.
|
||||
imgSnapshotTest(
|
||||
|
||||
@@ -26,12 +26,16 @@
|
||||
|
||||
import { addMatchImageSnapshotCommand } from 'cypress-image-snapshot/command';
|
||||
|
||||
addMatchImageSnapshotCommand({
|
||||
comparisonMethod: 'ssim',
|
||||
failureThreshold: 0.01,
|
||||
failureThresholdType: 'percent',
|
||||
customDiffConfig: {
|
||||
ssim: 'fast',
|
||||
},
|
||||
blur: 1,
|
||||
});
|
||||
// The SSIM comparison method can be used if the pixelmatch is throwing lots of false positives.
|
||||
// SSIM actually does not catch minute changes in the image, so it is not as accurate as pixelmatch.
|
||||
// addMatchImageSnapshotCommand({
|
||||
// comparisonMethod: 'ssim',
|
||||
// failureThreshold: 0.01,
|
||||
// failureThresholdType: 'percent',
|
||||
// customDiffConfig: {
|
||||
// ssim: 'fast',
|
||||
// },
|
||||
// blur: 1,
|
||||
// });
|
||||
|
||||
addMatchImageSnapshotCommand();
|
||||
|
||||
@@ -30,6 +30,21 @@
|
||||
</pre>
|
||||
<hr />
|
||||
|
||||
<pre class="mermaid">
|
||||
gantt
|
||||
title #; Gantt Diagrams Allow Semicolons and Hashtags #;!
|
||||
accTitle: A simple sample gantt diagram
|
||||
accDescr: 2 sections with 2 tasks each, from 2014
|
||||
dateFormat YYYY-MM-DD
|
||||
section #;Section
|
||||
#;A task :a1, 2014-01-01, 30d
|
||||
#;Another task :after a1 , 20d
|
||||
section #;Another
|
||||
Task in sec :2014-01-12 , 12d
|
||||
another task : 24d
|
||||
</pre>
|
||||
<hr />
|
||||
|
||||
<pre class="mermaid">
|
||||
gantt
|
||||
title Airworks roadmap
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<body>
|
||||
<h1>Pie chart demos</h1>
|
||||
<pre class="mermaid">
|
||||
pie title Pets adopted by volunteers
|
||||
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": 386
|
||||
@@ -27,7 +27,7 @@
|
||||
<pre class="mermaid">
|
||||
%%{init: {"pie": {"textPosition": 0.9}, "themeVariables": {"pieOuterStrokeWidth": "5px"}}}%%
|
||||
pie
|
||||
title Key elements in Product X
|
||||
title Offset labels close to border: Product X
|
||||
accTitle: Key elements in Product X
|
||||
accDescr: This is a pie chart showing the key elements in Product X.
|
||||
"Calcium": 42.96
|
||||
@@ -36,6 +36,19 @@
|
||||
"Iron": 5
|
||||
</pre>
|
||||
|
||||
<pre class="mermaid">
|
||||
%%{init: {"pie": {"textPosition": 0.45}, "themeVariables": {"pieOuterStrokeWidth": "5px"}}}%%
|
||||
pie
|
||||
title Centralized labels: Languages
|
||||
accTitle: Key elements in Product X
|
||||
accDescr: This is a pie chart showing the key elements in Product X.
|
||||
"JavaScript": 30
|
||||
"Python": 25
|
||||
"Java": 20
|
||||
"C#": 15
|
||||
"Others": 10
|
||||
</pre>
|
||||
|
||||
<script type="module">
|
||||
import mermaid from './mermaid.esm.mjs';
|
||||
mermaid.initialize({
|
||||
|
||||
@@ -23,6 +23,10 @@
|
||||
participant Alice
|
||||
participant Bob
|
||||
participant John as John<br />Second Line
|
||||
link Alice: Dashboard @ https://dashboard.contoso.com/alice
|
||||
link Alice: Wiki @ https://wiki.contoso.com/alice
|
||||
link John: Dashboard @ https://dashboard.contoso.com/john
|
||||
link John: Wiki @ https://wiki.contoso.com/john
|
||||
autonumber 10 10
|
||||
rect rgb(200, 220, 100)
|
||||
rect rgb(200, 255, 200)
|
||||
@@ -62,6 +66,26 @@
|
||||
</pre>
|
||||
<hr />
|
||||
<pre class="mermaid">
|
||||
---
|
||||
title: With forced menus
|
||||
config:
|
||||
sequence:
|
||||
forceMenus: true
|
||||
---
|
||||
sequenceDiagram
|
||||
participant Alice
|
||||
participant John
|
||||
link Alice: Dashboard @ https://dashboard.contoso.com/alice
|
||||
link Alice: Wiki @ https://wiki.contoso.com/alice
|
||||
link John: Dashboard @ https://dashboard.contoso.com/john
|
||||
link John: Wiki @ https://wiki.contoso.com/john
|
||||
Alice->>John: Hello John, how are you?
|
||||
John-->>Alice: Great!
|
||||
Alice-)John: See you later!
|
||||
</pre
|
||||
>
|
||||
<hr />
|
||||
<pre class="mermaid">
|
||||
sequenceDiagram
|
||||
accTitle: Sequence diagram title is here
|
||||
accDescr: Hello friends
|
||||
|
||||
@@ -16,7 +16,7 @@ We aim to reply within three working days, probably much sooner.
|
||||
|
||||
You should expect a close collaboration as we work to resolve the issue you have reported. Please reach out to <security@mermaid.live> again if you do not receive prompt attention and regular updates.
|
||||
|
||||
You may also reach out to the team via our public Slack chat channels; however, please make sure to e-mail <security@mermaid.live> when reporting an issue, and avoid revealing information about vulnerabilities in public as that could that could put users at risk.
|
||||
You may also reach out to the team via our public Discord chat channels; however, please make sure to e-mail <security@mermaid.live> when reporting an issue, and avoid revealing information about vulnerabilities in public as that could that could put users at risk.
|
||||
|
||||
## Best practices
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -31,7 +31,7 @@ Renames and re-exports [mermaidAPI](mermaidAPI.md#mermaidapi)
|
||||
|
||||
### mermaidAPI
|
||||
|
||||
• `Const` **mermaidAPI**: `Readonly`<{ `defaultConfig`: `MermaidConfig` = configApi.defaultConfig; `getConfig`: () => `MermaidConfig` = configApi.getConfig; `getDiagramFromText`: (`text`: `string`, `metadata`: `Pick`<`DiagramMetadata`, `"title"`>) => `Promise`<`Diagram`> ; `getSiteConfig`: () => `MermaidConfig` = configApi.getSiteConfig; `globalReset`: () => `void` ; `initialize`: (`options`: `MermaidConfig`) => `void` ; `parse`: (`text`: `string`, `parseOptions?`: [`ParseOptions`](../interfaces/mermaidAPI.ParseOptions.md)) => `Promise`<`boolean`> ; `render`: (`id`: `string`, `text`: `string`, `svgContainingElement?`: `Element`) => `Promise`<[`RenderResult`](../interfaces/mermaidAPI.RenderResult.md)> ; `reset`: () => `void` ; `setConfig`: (`conf`: `MermaidConfig`) => `MermaidConfig` = configApi.setConfig; `updateSiteConfig`: (`conf`: `MermaidConfig`) => `MermaidConfig` = configApi.updateSiteConfig }>
|
||||
• `Const` **mermaidAPI**: `Readonly`<{ `defaultConfig`: `RequiredObjectDeep`<`MermaidConfig`> = configApi.defaultConfig; `getConfig`: () => `MermaidConfig` = configApi.getConfig; `getDiagramFromText`: (`text`: `string`, `metadata`: `Pick`<`DiagramMetadata`, `"title"`>) => `Promise`<`Diagram`> ; `getSiteConfig`: () => `MermaidConfig` = configApi.getSiteConfig; `globalReset`: () => `void` ; `initialize`: (`options`: `MermaidConfig`) => `void` ; `parse`: (`text`: `string`, `parseOptions?`: [`ParseOptions`](../interfaces/mermaidAPI.ParseOptions.md)) => `Promise`<`boolean`> ; `render`: (`id`: `string`, `text`: `string`, `svgContainingElement?`: `Element`) => `Promise`<[`RenderResult`](../interfaces/mermaidAPI.RenderResult.md)> ; `reset`: () => `void` ; `setConfig`: (`conf`: `MermaidConfig`) => `MermaidConfig` = configApi.setConfig; `updateSiteConfig`: (`conf`: `MermaidConfig`) => `MermaidConfig` = configApi.updateSiteConfig }>
|
||||
|
||||
## mermaidAPI configuration defaults
|
||||
|
||||
|
||||
@@ -27,50 +27,49 @@ To add an integration to this list, see the [Integrations - create page](./integ
|
||||
|
||||
### Productivity tools
|
||||
|
||||
- [GitHub](https://github.com) ✅
|
||||
- [Using code blocks](https://github.blog/2022-02-14-include-diagrams-markdown-files-mermaid/) ✅
|
||||
- [GitHub action: Compile mermaid to image](https://github.com/neenjaw/compile-mermaid-markdown-action)
|
||||
- [svg-generator](https://github.com/SimonKenyonShepard/mermaidjs-github-svg-generator)
|
||||
- [GitHub Writer](https://github.com/ckeditor/github-writer)
|
||||
- [GitLab](https://docs.gitlab.com/ee/user/markdown.html#diagrams-and-flowcharts) ✅
|
||||
- [Gitea](https://gitea.io) ✅
|
||||
- [Azure Devops](https://docs.microsoft.com/en-us/azure/devops/project/wiki/wiki-markdown-guidance?view=azure-devops#add-mermaid-diagrams-to-a-wiki-page) ✅
|
||||
- [Tuleap](https://docs.tuleap.org/user-guide/writing-in-tuleap.html#graphs) ✅
|
||||
- [Mermaid Flow Visual Editor](https://www.mermaidflow.app) ✅
|
||||
- [Deepdwn](https://billiam.itch.io/deepdwn) ✅
|
||||
- [Joplin](https://joplinapp.org) ✅
|
||||
- [Slab](https://slab.com) ✅
|
||||
- [Swimm](https://swimm.io) ✅
|
||||
- [Notion](https://notion.so) ✅
|
||||
- [Observable](https://observablehq.com/@observablehq/mermaid) ✅
|
||||
- [Obsidian](https://help.obsidian.md/Editing+and+formatting/Advanced+formatting+syntax#Diagram) ✅
|
||||
- [NotesHub](https://noteshub.app) ✅
|
||||
- [GitBook](https://gitbook.com)
|
||||
- [Mermaid Plugin](https://github.com/JozoVilcek/gitbook-plugin-mermaid)
|
||||
- [Markdown with Mermaid CLI](https://github.com/miao1007/gitbook-plugin-mermaid-cli)
|
||||
- [Mermaid plugin for GitBook](https://github.com/wwformat/gitbook-plugin-mermaid-pdf)
|
||||
- [LiveBook](https://livebook.dev) ✅
|
||||
- [Atlassian Products](https://www.atlassian.com)
|
||||
- [Mermaid for Confluence](https://marketplace.atlassian.com/apps/1224722/mermaid-for-confluence?hosting=cloud&tab=overview)
|
||||
- [Mermaid Integration for Confluence](https://marketplace.atlassian.com/apps/1222792/mermaid-integration-for-confluence?hosting=cloud&tab=overview)
|
||||
- [Mermaid Diagrams for Confluence](https://marketplace.atlassian.com/apps/1226945/mermaid-diagrams-for-confluence?hosting=cloud&tab=overview)
|
||||
- [Mermaid Macro for Confluence](https://marketplace.atlassian.com/apps/1231150/mermaid-macro-for-confluence?hosting=cloud&tab=overview)
|
||||
- [EliteSoft Mermaid Charts and Diagrams](https://marketplace.atlassian.com/apps/1227286/elitesoft-mermaid-charts-and-diagrams?hosting=cloud&tab=overview)
|
||||
- [Mermaid for Jira Cloud - Draw UML diagrams easily](https://marketplace.atlassian.com/apps/1223053/mermaid-for-jira-cloud-draw-uml-diagrams-easily?hosting=cloud&tab=overview)
|
||||
- [Mermaid Charts & Diagrams for Confluence](https://marketplace.atlassian.com/apps/1222572/)
|
||||
- [Mermaid Charts & Diagrams for Jira](https://marketplace.atlassian.com/apps/1224537/)
|
||||
- [Mermaid Diagrams for Confluence](https://marketplace.atlassian.com/apps/1226945/mermaid-diagrams-for-confluence?hosting=cloud&tab=overview)
|
||||
- [Mermaid Live Editor for Confluence Cloud](https://marketplace.atlassian.com/apps/1231571/mermaid-live-editor-for-confluence?hosting=cloud&tab=overview)
|
||||
- [Mermaid Macro for Confluence](https://marketplace.atlassian.com/apps/1231150/mermaid-macro-for-confluence?hosting=cloud&tab=overview)
|
||||
- [Mermaid Plugin for Confluence](https://marketplace.atlassian.com/apps/1214124/mermaid-plugin-for-confluence?hosting=server&tab=overview)
|
||||
- [CloudScript.io Addon](https://marketplace.atlassian.com/apps/1219878/cloudscript-io-mermaid-addon?hosting=cloud&tab=overview)
|
||||
- [EliteSoft Mermaid Charts and Diagrams](https://marketplace.atlassian.com/apps/1227286/elitesoft-mermaid-charts-and-diagrams?hosting=cloud&tab=overview)
|
||||
- [Auto convert diagrams in Jira](https://github.com/coddingtonbear/jirafs-mermaid)
|
||||
- [Mermaid Charts & Diagrams for Jira](https://marketplace.atlassian.com/apps/1224537/)
|
||||
- [Mermaid for Jira Cloud - Draw UML diagrams easily](https://marketplace.atlassian.com/apps/1223053/mermaid-for-jira-cloud-draw-uml-diagrams-easily?hosting=cloud&tab=overview)
|
||||
- [CloudScript.io Mermaid Addon](https://marketplace.atlassian.com/apps/1219878/cloudscript-io-mermaid-addon?hosting=cloud&tab=overview)
|
||||
- [Azure Devops](https://learn.microsoft.com/en-us/azure/devops/project/wiki/markdown-guidance?view=azure-devops#add-mermaid-diagrams-to-a-wiki-page) ✅
|
||||
- [Deepdwn](https://billiam.itch.io/deepdwn) ✅
|
||||
- [GitBook](https://gitbook.com)
|
||||
- [Mermaid Plugin](https://github.com/JozoVilcek/gitbook-plugin-mermaid)
|
||||
- [Mermaid plugin for GitBook](https://github.com/wwformat/gitbook-plugin-mermaid-pdf)
|
||||
- [Markdown with Mermaid CLI](https://github.com/miao1007/gitbook-plugin-mermaid-cli)
|
||||
- [Gitea](https://gitea.io) ✅
|
||||
- [GitHub](https://github.com) ✅
|
||||
- [Using code blocks](https://github.blog/2022-02-14-include-diagrams-markdown-files-mermaid/) ✅
|
||||
- [GitHub action: Compile mermaid to image](https://github.com/neenjaw/compile-mermaid-markdown-action)
|
||||
- [GitHub Writer](https://github.com/ckeditor/github-writer)
|
||||
- [SVG diagram generator](https://github.com/SimonKenyonShepard/mermaidjs-github-svg-generator)
|
||||
- [GitLab](https://docs.gitlab.com/ee/user/markdown.html#diagrams-and-flowcharts) ✅
|
||||
- [Mermaid Plugin for JetBrains IDEs](https://plugins.jetbrains.com/plugin/20146-mermaid)
|
||||
- [Joplin](https://joplinapp.org) ✅
|
||||
- [LiveBook](https://livebook.dev) ✅
|
||||
- [Tuleap](https://docs.tuleap.org/user-guide/writing-in-tuleap.html#graphs) ✅
|
||||
- [Mermaid Flow Visual Editor](https://www.mermaidflow.app) ✅
|
||||
- [Mermerd](https://github.com/KarnerTh/mermerd)
|
||||
- [Slab](https://slab.com) ✅
|
||||
- [Swimm](https://docs.swimm.io/features/diagrams-and-charts/#mermaid--swimm--up-to-date-diagrams-) ✅
|
||||
- [NotesHub](https://noteshub.app) ✅
|
||||
- [Notion](https://notion.so) ✅
|
||||
- [Observable](https://observablehq.com/@observablehq/mermaid) ✅
|
||||
- [Obsidian](https://help.obsidian.md/Editing+and+formatting/Advanced+formatting+syntax#Diagram) ✅
|
||||
- [Redmine](https://redmine.org)
|
||||
- [Mermaid Macro](https://www.redmine.org/plugins/redmine_mermaid_macro)
|
||||
- [Markdown for mermaid plugin](https://github.com/jamieh-mongolian/markdown-for-mermaid-plugin)
|
||||
- [redmine-mermaid](https://github.com/styz/redmine_mermaid)
|
||||
- [markdown-for-mermaid-plugin](https://github.com/jamieh-mongolian/markdown-for-mermaid-plugin)
|
||||
- [Mermaid Plugin for JetBrains IDEs](https://plugins.jetbrains.com/plugin/20146-mermaid)
|
||||
- [mermerd](https://github.com/KarnerTh/mermerd)
|
||||
- Visual Studio Code [Polyglot Interactive Notebooks](https://github.com/dotnet/interactive#net-interactive)
|
||||
- Codemia [a tool to practice system design problems](https://codemia.io)
|
||||
|
||||
### CRM/ERP
|
||||
|
||||
@@ -82,139 +81,137 @@ Customer Relationship Management/Enterprise Resource Planning
|
||||
|
||||
Blogging frameworks and platforms
|
||||
|
||||
- [WordPress](https://wordpress.org)
|
||||
- [WordPress Markdown Editor](https://wordpress.org/plugins/wp-githuber-md)
|
||||
- [WP-ReliableMD](https://wordpress.org/plugins/wp-reliablemd/)
|
||||
- [Hexo](https://hexo.io)
|
||||
- [hexo-filter-mermaid-diagrams](https://github.com/webappdevelp/hexo-filter-mermaid-diagrams)
|
||||
- [hexo-tag-mermaid](https://github.com/JameChou/hexo-tag-mermaid)
|
||||
- [hexo-mermaid-diagrams](https://github.com/mslxl/hexo-mermaid-diagrams)
|
||||
- [Nextra](https://nextra.site/)
|
||||
- [Mermaid](https://nextra.site/docs/guide/mermaid)
|
||||
- [WordPress](https://wordpress.org)
|
||||
- [WordPress Markdown Editor](https://wordpress.org/plugins/wp-githuber-md)
|
||||
- [WP-ReliableMD](https://wordpress.org/plugins/wp-reliablemd/)
|
||||
|
||||
### CMS/ECM
|
||||
|
||||
Content Management Systems/Enterprise Content Management
|
||||
|
||||
- [Grav CMS](https://getgrav.org/)
|
||||
- [Mermaid Diagrams Plugin](https://github.com/DanielFlaum/grav-plugin-mermaid-diagrams)
|
||||
- [GitLab Markdown Adapter](https://github.com/Goutte/grav-plugin-gitlab-markdown-adapter)
|
||||
- [VitePress](https://vitepress.vuejs.org/)
|
||||
- [Plugin for Mermaid.js](https://emersonbottero.github.io/vitepress-plugin-mermaid/)
|
||||
- [VuePress](https://vuepress.vuejs.org/)
|
||||
- [Plugin for Mermaid.js](https://github.com/eFrane/vuepress-plugin-mermaidjs)
|
||||
- [Grav CMS](https://getgrav.org/)
|
||||
- [Mermaid Diagrams](https://github.com/DanielFlaum/grav-plugin-mermaid-diagrams)
|
||||
- [GitLab Markdown Adapter](https://github.com/Goutte/grav-plugin-gitlab-markdown-adapter)
|
||||
|
||||
### Communication
|
||||
|
||||
Communication tools and platforms
|
||||
|
||||
- [Discourse](https://discourse.org)
|
||||
- [Mermaid Plugin](https://github.com/pnewell/discourse-mermaid), [And](https://github.com/unfoldingWord-dev/discourse-mermaid)
|
||||
- [Mermaid Plugin](https://github.com/pnewell/discourse-mermaid)
|
||||
- [Mattermost](https://mattermost.com/)
|
||||
- [Mermaid Plugin](https://github.com/SpikeTings/Mermaid)
|
||||
- [NodeBB](https://nodebb.org)
|
||||
- [Mermaid Parser Plugin](https://www.npmjs.com/package/nodebb-plugin-mermaid)
|
||||
- [phpBB](https://phpbb.com)
|
||||
- [phpbb-ext-mermaid](https://github.com/AlfredoRamos/phpbb-ext-mermaid)
|
||||
- [NodeBB](https://nodebb.org)
|
||||
- [Mermaid Plugin](https://www.npmjs.com/package/nodebb-plugin-mermaid)
|
||||
- [Slack](https://slack.com)
|
||||
- [Mermaid for Slack](https://github.com/JackuB/mermaid-for-slack)
|
||||
- [Mermaid Preview](https://github.com/JackuB/mermaid-for-slack)
|
||||
|
||||
### Wikis
|
||||
|
||||
- [PmWiki](https://www.pmwiki.org)
|
||||
- [MermaidJs Cookbook recipe](https://www.pmwiki.org/wiki/Cookbook/MermaidJs)
|
||||
- [MediaWiki](https://www.mediawiki.org)
|
||||
- [Mermaid Extension](https://www.mediawiki.org/wiki/Extension:Mermaid)
|
||||
- [Flex Diagrams Extension](https://www.mediawiki.org/wiki/Extension:Flex_Diagrams)
|
||||
- [Semantic Media Wiki](https://semantic-mediawiki.org)
|
||||
- [Mermaid Plugin](https://github.com/SemanticMediaWiki/Mermaid)
|
||||
- [DokuWiki](https://dokuwiki.org)
|
||||
- [ComboStrap](https://combostrap.com/mermaid)
|
||||
- [Mermaid Plugin](https://www.dokuwiki.org/plugin:mermaid)
|
||||
- [Foswiki](https://foswiki.org)
|
||||
- [Mermaid Plugin](https://foswiki.org/Extensions/MermaidPlugin)
|
||||
- [DokuWiki](https://dokuwiki.org)
|
||||
- [Mermaid Plugin](https://www.dokuwiki.org/plugin:mermaid)
|
||||
- [ComboStrap](https://combostrap.com/mermaid)
|
||||
- [MediaWiki](https://www.mediawiki.org)
|
||||
- [Flex Diagrams Extension](https://www.mediawiki.org/wiki/Extension:Flex_Diagrams)
|
||||
- [Mermaid Extension](https://www.mediawiki.org/wiki/Extension:Mermaid)
|
||||
- [PmWiki](https://www.pmwiki.org)
|
||||
- [MermaidJs Cookbook recipe](https://www.pmwiki.org/wiki/Cookbook/MermaidJs)
|
||||
- [Semantic Media Wiki](https://semantic-mediawiki.org)
|
||||
- [Mermaid Plugin](https://github.com/SemanticMediaWiki/Mermaid)
|
||||
- [TiddlyWiki](https://tiddlywiki.com/)
|
||||
- [mermaid-tw5: full js library](https://github.com/efurlanm/mermaid-tw5)
|
||||
- [tw5-mermaid: wrapper for Mermaid Live](https://github.com/jasonmhoule/tw5-mermaid)
|
||||
- [mermaid-tw5: wrapper for Mermaid Live](https://github.com/efurlanm/mermaid-tw5)
|
||||
- [tw5-mermaid: plugin for managing Mermaid.js tiddlers](https://github.com/jasonmhoule/tw5-mermaid)
|
||||
|
||||
### Editor Plugins
|
||||
|
||||
- [VS Code](https://code.visualstudio.com/)
|
||||
- [Markdown Preview Mermaid Support](https://marketplace.visualstudio.com/items?itemName=bierner.markdown-mermaid)
|
||||
- [Mermaid Preview](https://marketplace.visualstudio.com/items?itemName=vstirbu.vscode-mermaid-preview)
|
||||
- [Markdown Preview Enhanced](https://marketplace.visualstudio.com/items?itemName=shd101wyy.markdown-preview-enhanced)
|
||||
- [Mermaid Markdown Syntax Highlighting](https://marketplace.visualstudio.com/items?itemName=bpruitt-goddard.mermaid-markdown-syntax-highlighting)
|
||||
- [Mermaid Editor](https://marketplace.visualstudio.com/items?itemName=tomoyukim.vscode-mermaid-editor)
|
||||
- [Mermaid Export](https://marketplace.visualstudio.com/items?itemName=Gruntfuggly.mermaid-export)
|
||||
- [Markdown PDF](https://marketplace.visualstudio.com/items?itemName=yzane.markdown-pdf)
|
||||
- [Preview](https://marketplace.visualstudio.com/items?itemName=searKing.preview-vscode)
|
||||
- [Preview Sequence Diagrams](https://marketplace.visualstudio.com/items?itemName=arichika.previewseqdiag-vscode)
|
||||
- Atom _(Atom has been [archived.](https://github.blog/2022-06-08-sunsetting-atom/))_
|
||||
- [Markdown Preview Enhanced](https://github.com/shd101wyy/markdown-preview-enhanced)
|
||||
- [Atom Mermaid](https://github.com/y-takey/atom-mermaid)
|
||||
- [Language Mermaid Syntax Highlighter](https://github.com/ytisf/language-mermaid)
|
||||
- [Astah](https://astah.net)
|
||||
- [Export to Mermaid](https://github.com/Avens666/Astah_Jude_UML_export_to_Markdown-mermaid-Plantuml-)
|
||||
- [Brackets](https://brackets.io/)
|
||||
- [Mermaid Preview](https://github.com/AlanHohn/mermaid-preview)
|
||||
- [CKEditor](https://github.com/ckeditor/ckeditor5)
|
||||
- [CKEditor 5 Mermaid plugin](https://github.com/ckeditor/ckeditor5-mermaid)
|
||||
- [Draw.io](https://draw.io)
|
||||
- [Mermaid Plugin](https://github.com/nopeslide/drawio_mermaid_plugin)
|
||||
- [GNU Emacs](https://www.gnu.org/software/emacs/)
|
||||
- [Major mode for .mmd files](https://github.com/abrochard/mermaid-mode)
|
||||
- [Org-Mode integration](https://github.com/arnm/ob-mermaid)
|
||||
- [GNU Nano](https://www.nano-editor.org/)
|
||||
- [Nano Mermaid](https://github.com/Yash-Singh1/nano-mermaid)
|
||||
- [Google docs](https://docs.google.com/)
|
||||
- [Mermaid plugin for google docs](https://workspace.google.com/marketplace/app/mermaid/636321283856)
|
||||
- [Inkdrop](https://www.inkdrop.app)
|
||||
- [Mermaid Plugin](https://github.com/inkdropapp/inkdrop-mermaid)
|
||||
- [Light Table](http://lighttable.com/)
|
||||
- [Mermaid Plugin](https://github.com/cldwalker/Mermaid)
|
||||
- [Markdown-It](https://github.com/markdown-it/markdown-it)
|
||||
- [Textual UML Parser](https://github.com/manastalukdar/markdown-it-textual-uml)
|
||||
- [Mermaid Plugin](https://github.com/tylingsoft/markdown-it-mermaid)
|
||||
- [md-it-mermaid](https://github.com/iamcco/md-it-mermaid)
|
||||
- [markdown-it-mermaid-less](https://github.com/searKing/markdown-it-mermaid-less)
|
||||
- Atom _(Atom has been [archived.](https://github.blog/2022-06-08-sunsetting-atom/))_
|
||||
- [Markdown Preview Enhanced](https://github.com/shd101wyy/markdown-preview-enhanced)
|
||||
- [Atom Mermaid](https://github.com/y-takey/atom-mermaid)
|
||||
- [Language Mermaid Syntax Highlighter](https://github.com/ytisf/language-mermaid)
|
||||
- [Podlite](https://github.com/zag/podlite-desktop)
|
||||
- [=Diagram block](https://github.com/zag/podlite/tree/main/packages/podlite-diagrams)
|
||||
- [Standard Notes](https://standardnotes.com/)
|
||||
- [Mermaid Extension](https://github.com/nienow/sn-mermaid)
|
||||
- [Sublime Text 3](https://sublimetext.com)
|
||||
- [Mermaid Package](https://packagecontrol.io/packages/Mermaid)
|
||||
- [Astah](https://astah.net)
|
||||
- [Export to Mermaid](https://github.com/Avens666/Astah_Jude_UML_export_to_Markdown-mermaid-Plantuml-)
|
||||
- [Light Table](http://lighttable.com/)
|
||||
- [Mermaid Plugin](https://github.com/cldwalker/Mermaid)
|
||||
- [Draw.io](https://draw.io) - [Plugin](https://github.com/nopeslide/drawio_mermaid_plugin)
|
||||
- [Inkdrop](https://www.inkdrop.app) - [Plugin](https://github.com/inkdropapp/inkdrop-mermaid)
|
||||
- [VS Code](https://code.visualstudio.com/)
|
||||
- [Mermaid Editor](https://marketplace.visualstudio.com/items?itemName=tomoyukim.vscode-mermaid-editor)
|
||||
- [Mermaid Export](https://marketplace.visualstudio.com/items?itemName=Gruntfuggly.mermaid-export)
|
||||
- [Markdown PDF](https://marketplace.visualstudio.com/items?itemName=yzane.markdown-pdf)
|
||||
- [Markdown Preview Mermaid Support](https://marketplace.visualstudio.com/items?itemName=bierner.markdown-mermaid)
|
||||
- [Markdown Preview Enhanced](https://marketplace.visualstudio.com/items?itemName=shd101wyy.markdown-preview-enhanced)
|
||||
- [Mermaid Preview](https://marketplace.visualstudio.com/items?itemName=vstirbu.vscode-mermaid-preview)
|
||||
- [Preview](https://marketplace.visualstudio.com/items?itemName=searKing.preview-vscode)
|
||||
- [Preview Sequence Diagrams](https://marketplace.visualstudio.com/items?itemName=arichika.previewseqdiag-vscode)
|
||||
- [Mermaid Markdown Syntax Highlighting](https://marketplace.visualstudio.com/items?itemName=bpruitt-goddard.mermaid-markdown-syntax-highlighting)
|
||||
- [Vim](https://www.vim.org)
|
||||
- [Official Vim Syntax and ftplugin](https://github.com/craigmac/vim-mermaid)
|
||||
- [Vim Diagram Syntax](https://github.com/zhaozg/vim-diagram)
|
||||
- [GNU Emacs](https://www.gnu.org/software/emacs/)
|
||||
- [Major mode for .mmd files](https://github.com/abrochard/mermaid-mode)
|
||||
- [Org-Mode integration](https://github.com/arnm/ob-mermaid)
|
||||
- [Brackets](https://brackets.io/)
|
||||
- [Mermaid Preview](https://github.com/AlanHohn/mermaid-preview)
|
||||
- [Iodide](https://github.com/iodide-project/iodide)
|
||||
- [iodide-mermaid-plugin](https://github.com/iodide-project/iodide-mermaid-plugin)
|
||||
- [Google docs](https://docs.google.com/)
|
||||
- [Mermaid plugin for google docs](https://workspace.google.com/marketplace/app/mermaid/636321283856)
|
||||
- [Podlite](https://github.com/zag/podlite-desktop)
|
||||
- [Named block =Diagram](https://github.com/zag/podlite/tree/main/packages/podlite-diagrams)
|
||||
- [GNU Nano](https://www.nano-editor.org/)
|
||||
- [Nano Mermaid](https://github.com/Yash-Singh1/nano-mermaid)
|
||||
- [CKEditor](https://github.com/ckeditor/ckeditor5)
|
||||
- [CKEditor 5 Mermaid plugin](https://github.com/ckeditor/ckeditor5-mermaid)
|
||||
- [Standard Notes](https://standardnotes.com/)
|
||||
- [sn-mermaid](https://github.com/nienow/sn-mermaid)
|
||||
- [Official Vim Syntax and ft plugin](https://github.com/craigmac/vim-mermaid)
|
||||
|
||||
### Document Generation
|
||||
|
||||
- [Codedoc](https://codedoc.cc/)
|
||||
- [codedoc-mermaid-plugin](https://www.npmjs.com/package/codedoc-mermaid-plugin)
|
||||
- [Docsy Hugo Theme](https://www.docsy.dev/docs/adding-content/lookandfeel/#diagrams-with-mermaid) ✅
|
||||
- [Docusaurus](https://docusaurus.io/docs/markdown-features/diagrams) ✅
|
||||
- [Unison programming language](https://www.unison-lang.org/docs/usage-topics/documentation/) ✅
|
||||
- [Swimm - Up-to-date diagrams with Swimm, the knowledge management tool for code](https://docs.swimm.io/features/diagrams-and-charts/#mermaid--swimm--up-to-date-diagrams-)
|
||||
- [Sphinx](https://www.sphinx-doc.org/en/master/)
|
||||
- [sphinxcontrib-mermaid](https://github.com/mgaitan/sphinxcontrib-mermaid)
|
||||
- [remark](https://remark.js.org/)
|
||||
- [remark-mermaidjs](https://github.com/remcohaszing/remark-mermaidjs)
|
||||
- [rehype](https://github.com/rehypejs/rehype)
|
||||
- [rehype-mermaid](https://github.com/remcohaszing/rehype-mermaid)
|
||||
- [Gatsby](https://www.gatsbyjs.com/)
|
||||
- [gatsby-remark-mermaid](https://github.com/remcohaszing/gatsby-remark-mermaid)
|
||||
- [JSDoc](https://jsdoc.app/)
|
||||
- [jsdoc-mermaid](https://github.com/Jellyvision/jsdoc-mermaid)
|
||||
- [mdBook](https://rust-lang.github.io/mdBook/index.html)
|
||||
- [mdbook-mermaid](https://github.com/badboy/mdbook-mermaid)
|
||||
- [MkDocs](https://www.mkdocs.org)
|
||||
- [mkdocs-mermaid2-plugin](https://github.com/fralau/mkdocs-mermaid2-plugin)
|
||||
- [mkdocs-material](https://github.com/squidfunk/mkdocs-material), check the [docs](https://squidfunk.github.io/mkdocs-material/reference/diagrams/)
|
||||
- [Quarto](https://quarto.org/)
|
||||
- [rehype](https://github.com/rehypejs/rehype)
|
||||
- [rehype-mermaid](https://github.com/remcohaszing/rehype-mermaid)
|
||||
- [remark](https://remark.js.org/)
|
||||
- [remark-mermaidjs](https://github.com/remcohaszing/remark-mermaidjs)
|
||||
- [Sphinx](https://www.sphinx-doc.org/en/master/)
|
||||
- [sphinxcontrib-mermaid](https://github.com/mgaitan/sphinxcontrib-mermaid)
|
||||
- [Type Doc](https://typedoc.org/)
|
||||
- [typedoc-plugin-mermaid](https://www.npmjs.com/package/typedoc-plugin-mermaid)
|
||||
- [Docsy Hugo Theme](https://www.docsy.dev/docs/adding-content/lookandfeel/#diagrams-with-mermaid) ✅
|
||||
- [Codedoc](https://codedoc.cc/)
|
||||
- [codedoc-mermaid-plugin](https://www.npmjs.com/package/codedoc-mermaid-plugin)
|
||||
- [mdbook](https://rust-lang.github.io/mdBook/index.html)
|
||||
- [mdbook-mermaid](https://github.com/badboy/mdbook-mermaid)
|
||||
- [Quarto](https://quarto.org/)
|
||||
- [Typora](https://typora.io/) ✅
|
||||
- [See docs](https://support.typora.io/Draw-Diagrams-With-Markdown/#mermaid)
|
||||
- [Typora](https://support.typora.io/Draw-Diagrams-With-Markdown/#mermaid) ✅
|
||||
- [Unison programming language](https://www.unison-lang.org/docs/usage-topics/documentation/) ✅
|
||||
|
||||
### Browser Extensions
|
||||
|
||||
@@ -225,7 +222,7 @@ Communication tools and platforms
|
||||
| Diagram Tab | - | - | - | - | [🐙🔗](https://github.com/khafast/diagramtab) |
|
||||
| Markdown Diagrams | [🎡🔗](https://chrome.google.com/webstore/detail/markdown-diagrams/pmoglnmodacnbbofbgcagndelmgaclel/) | [🦊🔗](https://addons.mozilla.org/en-US/firefox/addon/markdown-diagrams/) | [🔴🔗](https://addons.opera.com/en/extensions/details/markdown-diagrams/) | [🌀🔗](https://microsoftedge.microsoft.com/addons/detail/markdown-diagrams/hceenoomhhdkjjijnmlclkpenkapfihe) | [🐙🔗](https://github.com/marcozaccari/markdown-diagrams-browser-extension/tree/master/doc/examples) |
|
||||
| Markdown Viewer | - | [🦊🔗](https://addons.mozilla.org/en-US/firefox/addon/markdown-viewer-chrome/) | - | - | [🐙🔗](https://github.com/simov/markdown-viewer) |
|
||||
| Extensions for Mermaid | - | [🦊🔗](https://addons.mozilla.org/en-US/firefox/addon/markdown-viewer-chrome/) | [🔴🔗](https://addons.opera.com/en/extensions/details/extensions-for-mermaid/) | - | [🐙🔗](https://github.com/Stefan-S/mermaid-extension) |
|
||||
| Extensions for Mermaid | - | - | [🔴🔗](https://addons.opera.com/en/extensions/details/extensions-for-mermaid/) | - | [🐙🔗](https://github.com/Stefan-S/mermaid-extension) |
|
||||
| Chrome Diagrammer | [🎡🔗](https://chrome.google.com/webstore/detail/chrome-diagrammer/bkpbgjmkomfoakfklcjeoegkklgjnnpk) | - | - | - | - |
|
||||
| Mermaid Diagrams | [🎡🔗](https://chrome.google.com/webstore/detail/mermaid-diagrams/phfcghedmopjadpojhmmaffjmfiakfil) | - | - | - | - |
|
||||
| Monkeys | [🎡🔗](https://chrome.google.com/webstore/detail/monkeys-mermaid-for-githu/cplfdpoajbclbgphaphphcldamfkjlgi) | - | - | - | - |
|
||||
@@ -233,19 +230,23 @@ Communication tools and platforms
|
||||
|
||||
### Other
|
||||
|
||||
- [Bisheng](https://www.npmjs.com/package/bisheng)
|
||||
- [bisheng-plugin-mermaid](https://github.com/yct21/bisheng-plugin-mermaid)
|
||||
- [Codemia: A tool to practice system design problems](https://codemia.io) ✅
|
||||
- [ExDoc](https://github.com/elixir-lang/ex_doc)
|
||||
- [Rendering Mermaid graphs](https://github.com/elixir-lang/ex_doc#rendering-mermaid-graphs)
|
||||
- [Jekyll](https://jekyllrb.com/)
|
||||
- [jekyll-mermaid](https://rubygems.org/gems/jekyll-mermaid)
|
||||
- [jekyll-mermaid-diagrams](https://github.com/fuzhibo/jekyll-mermaid-diagrams)
|
||||
- [mermaid-isomorphic](https://github.com/remcohaszing/mermaid-isomorphic)
|
||||
- [mermaid-server: Generate diagrams using a HTTP request](https://github.com/TomWright/mermaid-server)
|
||||
- [NiceGUI: Let any browser be the frontend of your Python code](https://nicegui.io) ✅
|
||||
- [ui.mermaid(...)](https://nicegui.io/documentation/mermaid)
|
||||
- [Reveal.js](https://github.com/hakimel/reveal.js)
|
||||
- [reveal.js-mermaid-plugin](https://github.com/ludwick/reveal.js-mermaid-plugin)
|
||||
- [Bisheng](https://www.npmjs.com/package/bisheng)
|
||||
- [bisheng-plugin-mermaid](https://github.com/yct21/bisheng-plugin-mermaid)
|
||||
- [Reveal CK](https://github.com/jedcn/reveal-ck)
|
||||
- [reveal-ck-mermaid-plugin](https://github.com/tmtm/reveal-ck-mermaid-plugin)
|
||||
- [mermaid-isomorphic](https://github.com/remcohaszing/mermaid-isomorphic)
|
||||
- [mermaid-server: Generate diagrams using a HTTP request](https://github.com/TomWright/mermaid-server)
|
||||
- [ExDoc](https://github.com/elixir-lang/ex_doc)
|
||||
- [Rendering Mermaid graphs](https://github.com/elixir-lang/ex_doc#rendering-mermaid-graphs)
|
||||
- [NiceGUI: Let any browser be the frontend of your Python code](https://nicegui.io) ✅
|
||||
- [ui.mermaid(...)](https://nicegui.io/documentation/section_text_elements#markdown_element)
|
||||
- [ui.markdown(..., extras=\['mermaid'\])](https://nicegui.io/documentation/section_text_elements#mermaid_diagrams)
|
||||
|
||||
@@ -22,9 +22,9 @@ Currently pending [IANA](https://www.iana.org/) recognition.
|
||||
|
||||
## Showcase
|
||||
|
||||
### Mermaid Slack workspace
|
||||
### Mermaid Discord workspace
|
||||
|
||||
We would love to see what you create with Mermaid. Please share your creations with us in our [Slack](https://join.slack.com/t/mermaid-talk/shared_invite/zt-22p2r8p9y-qiyP1H38GjFQ6S6jbBkOxQ) workspace [#community-showcase](https://mermaid-talk.slack.com/archives/C05NK37LT40) channel.
|
||||
We would love to see what you create with Mermaid. Please share your creations with us in our [Discord](https://discord.gg/wwtabKgp8y) server [#showcase](https://discord.com/channels/1079455296289788015/1079502635054399649) channel.
|
||||
|
||||
### Add to Mermaid Ecosystem
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ It is a JavaScript based diagramming and charting tool that renders Markdown-ins
|
||||
[](https://coveralls.io/github/mermaid-js/mermaid?branch=master)
|
||||
[](https://www.jsdelivr.com/package/npm/mermaid)
|
||||
[](https://www.npmjs.com/package/mermaid)
|
||||
[](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE)
|
||||
[](https://discord.gg/wwtabKgp8y)
|
||||
[](https://twitter.com/mermaidjs_)
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1134,7 +1134,19 @@ flowchart TD
|
||||
B-->E(A fa:fa-camera-retro perhaps?)
|
||||
```
|
||||
|
||||
Mermaid is compatible with Font Awesome up to version 5, Free icons only. Check that the icons you use are from the [supported set of icons](https://fontawesome.com/v5/search?o=r&m=free).
|
||||
Mermaid supports Font Awesome if the CSS is included on the website.
|
||||
Mermaid does not have any restriction on the version of Font Awesome that can be used.
|
||||
|
||||
Please refer the [Official Font Awesome Documentation](https://fontawesome.com/start) on how to include it in your website.
|
||||
|
||||
Adding this snippet in the `<head>` would add support for Font Awesome v6.5.1
|
||||
|
||||
```html
|
||||
<link
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
```
|
||||
|
||||
## Graph declarations with spaces between vertices and link and without semicolon
|
||||
|
||||
|
||||
@@ -114,7 +114,30 @@ gantt
|
||||
Add another diagram to demo page :48h
|
||||
```
|
||||
|
||||
It is possible to set multiple dependencies separated by space:
|
||||
Tasks are by default sequential. A task start date defaults to the end date of the preceding task.
|
||||
|
||||
A colon, `:`, separates the task title from its metadata.
|
||||
Metadata items are separated by a comma, `,`. Valid tags are `active`, `done`, `crit`, and `milestone`. Tags are optional, but if used, they must be specified first.
|
||||
After processing the tags, the remaining metadata items are interpreted as follows:
|
||||
|
||||
1. If a single item is specified, it determines when the task ends. It can either be a specific date/time or a duration. If a duration is specified, it is added to the start date of the task to determine the end date of the task, taking into account any exclusions.
|
||||
2. If two items are specified, the last item is interpreted as in the previous case. The first item can either specify an explicit start date/time (in the format specified by `dateFormat`) or reference another task using `after <otherTaskID> [[otherTaskID2 [otherTaskID3]]...]`. In the latter case, the start date of the task will be set according to the latest end date of any referenced task.
|
||||
3. If three items are specified, the last two will be interpreted as in the previous case. The first item will denote the ID of the task, which can be referenced using the `later <taskID>` syntax.
|
||||
|
||||
| Metadata syntax | Start date | End date | ID |
|
||||
| ------------------------------------------ | --------------------------------------------------- | ------------------------------------------- | -------- |
|
||||
| `<taskID>, <startDate>, <endDate>` | `startdate` as interpreted using `dateformat` | `endDate` as interpreted using `dateformat` | `taskID` |
|
||||
| `<taskID>, <startDate>, <length>` | `startdate` as interpreted using `dateformat` | Start date + `length` | `taskID` |
|
||||
| `<taskID>, after <otherTaskId>, <endDate>` | End date of previously specified task `otherTaskID` | `endDate` as interpreted using `dateformat` | `taskID` |
|
||||
| `<taskID>, after <otherTaskId>, <length>` | End date of previously specified task `otherTaskID` | Start date + `length` | `taskID` |
|
||||
| `<startDate>, <endDate>` | `startdate` as interpreted using `dateformat` | `enddate` as interpreted using `dateformat` | n/a |
|
||||
| `<startDate>, <length>` | `startdate` as interpreted using `dateformat` | Start date + `length` | n/a |
|
||||
| `after <otherTaskID>, <endDate>` | End date of previously specified task `otherTaskID` | `enddate` as interpreted using `dateformat` | n/a |
|
||||
| `after <otherTaskID>, <length>` | End date of previously specified task `otherTaskID` | Start date + `length` | n/a |
|
||||
| `<endDate>` | End date of preceding task | `enddate` as interpreted using `dateformat` | n/a |
|
||||
| `<length>` | End date of preceding task | Start date + `length` | n/a |
|
||||
|
||||
For simplicity, the table does not show the use of multiple tasks listed with the `after` keyword. Here is an example of how to use it and how it's interpreted:
|
||||
|
||||
```mermaid-example
|
||||
gantt
|
||||
|
||||
@@ -163,11 +163,11 @@ timeline
|
||||
timeline
|
||||
title MermaidChart 2023 Timeline
|
||||
section 2023 Q1 <br> Release Personal Tier
|
||||
Buttet 1 : sub-point 1a : sub-point 1b
|
||||
Bullet 1 : sub-point 1a : sub-point 1b
|
||||
: sub-point 1c
|
||||
Bullet 2 : sub-point 2a : sub-point 2b
|
||||
section 2023 Q2 <br> Release XYZ Tier
|
||||
Buttet 3 : sub-point <br> 3a : sub-point 3b
|
||||
Bullet 3 : sub-point <br> 3a : sub-point 3b
|
||||
: sub-point 3c
|
||||
Bullet 4 : sub-point 4a : sub-point 4b
|
||||
```
|
||||
@@ -176,11 +176,11 @@ timeline
|
||||
timeline
|
||||
title MermaidChart 2023 Timeline
|
||||
section 2023 Q1 <br> Release Personal Tier
|
||||
Buttet 1 : sub-point 1a : sub-point 1b
|
||||
Bullet 1 : sub-point 1a : sub-point 1b
|
||||
: sub-point 1c
|
||||
Bullet 2 : sub-point 2a : sub-point 2b
|
||||
section 2023 Q2 <br> Release XYZ Tier
|
||||
Buttet 3 : sub-point <br> 3a : sub-point 3b
|
||||
Bullet 3 : sub-point <br> 3a : sub-point 3b
|
||||
: sub-point 3c
|
||||
Bullet 4 : sub-point 4a : sub-point 4b
|
||||
```
|
||||
|
||||
11
package.json
11
package.json
@@ -61,11 +61,11 @@
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@applitools/eyes-cypress": "^3.33.1",
|
||||
"@applitools/eyes-cypress": "^3.40.6",
|
||||
"@commitlint/cli": "^17.6.1",
|
||||
"@commitlint/config-conventional": "^17.6.1",
|
||||
"@cspell/eslint-plugin": "^6.31.1",
|
||||
"@cypress/code-coverage": "^3.10.7",
|
||||
"@cypress/code-coverage": "^3.12.18",
|
||||
"@rollup/plugin-typescript": "^11.1.1",
|
||||
"@types/cors": "^2.8.13",
|
||||
"@types/eslint": "^8.37.0",
|
||||
@@ -85,7 +85,7 @@
|
||||
"ajv": "^8.12.0",
|
||||
"concurrently": "^8.0.1",
|
||||
"cors": "^2.8.5",
|
||||
"cypress": "^12.10.0",
|
||||
"cypress": "^12.17.4",
|
||||
"cypress-image-snapshot": "^4.0.1",
|
||||
"esbuild": "^0.19.0",
|
||||
"eslint": "^8.47.0",
|
||||
@@ -127,5 +127,10 @@
|
||||
},
|
||||
"nyc": {
|
||||
"report-dir": "coverage/cypress"
|
||||
},
|
||||
"pnpm": {
|
||||
"patchedDependencies": {
|
||||
"cytoscape@3.28.1": "patches/cytoscape@3.28.1.patch"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,15 +39,10 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@braintree/sanitize-url": "^6.0.1",
|
||||
"cytoscape": "^3.23.0",
|
||||
"cytoscape-cose-bilkent": "^4.1.0",
|
||||
"cytoscape-fcose": "^2.1.0",
|
||||
"d3": "^7.0.0",
|
||||
"khroma": "^2.0.0",
|
||||
"non-layered-tidy-tree-layout": "^2.0.2"
|
||||
"khroma": "^2.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/cytoscape": "^3.19.9",
|
||||
"concurrently": "^8.0.0",
|
||||
"rimraf": "^5.0.0",
|
||||
"mermaid": "workspace:*"
|
||||
|
||||
@@ -62,9 +62,8 @@
|
||||
"@braintree/sanitize-url": "^6.0.1",
|
||||
"@types/d3-scale": "^4.0.3",
|
||||
"@types/d3-scale-chromatic": "^3.0.0",
|
||||
"cytoscape": "^3.23.0",
|
||||
"cytoscape": "^3.28.1",
|
||||
"cytoscape-cose-bilkent": "^4.1.0",
|
||||
"cytoscape-fcose": "^2.1.0",
|
||||
"d3": "^7.4.0",
|
||||
"d3-sankey": "^0.12.3",
|
||||
"dagre-d3-es": "7.0.10",
|
||||
@@ -116,7 +115,7 @@
|
||||
"remark-gfm": "^3.0.1",
|
||||
"rimraf": "^5.0.0",
|
||||
"start-server-and-test": "^2.0.0",
|
||||
"type-fest": "^4.1.0",
|
||||
"type-fest": "^4.10.1",
|
||||
"typedoc": "^0.25.0",
|
||||
"typedoc-plugin-markdown": "^3.15.2",
|
||||
"typescript": "^5.0.4",
|
||||
|
||||
@@ -4,8 +4,10 @@ import theme from './themes/index.js';
|
||||
import config from './defaultConfig.js';
|
||||
import type { MermaidConfig } from './config.type.js';
|
||||
import { sanitizeDirective } from './utils/sanitizeDirective.js';
|
||||
import lodashGet from 'lodash-es/get.js';
|
||||
import type { RequiredDeep, Get, Paths } from 'type-fest';
|
||||
|
||||
export const defaultConfig: MermaidConfig = Object.freeze(config);
|
||||
export const defaultConfig: RequiredDeep<MermaidConfig> = Object.freeze(config);
|
||||
|
||||
let siteConfig: MermaidConfig = assignWithDepth({}, defaultConfig);
|
||||
let configFromInitialize: MermaidConfig;
|
||||
@@ -245,3 +247,20 @@ const checkConfig = (config: MermaidConfig) => {
|
||||
issueWarning('LAZY_LOAD_DEPRECATED');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a value from the provided config, or the default config if it doesn't exist
|
||||
* @param config - Mermaid Config
|
||||
* @param path - Path of the value to get
|
||||
* @returns Value from provided config if it exists, otherwise from default config
|
||||
*/
|
||||
export const getConfigValue = <Path extends Paths<RequiredDeep<MermaidConfig>>>(
|
||||
config: MermaidConfig,
|
||||
path: Path
|
||||
): Get<RequiredDeep<MermaidConfig>, Path> => {
|
||||
let value = lodashGet(config, path) as Get<RequiredDeep<MermaidConfig>, Path>;
|
||||
if (!value) {
|
||||
value = lodashGet(defaultConfig, path) as Get<RequiredDeep<MermaidConfig>, Path>;
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
@@ -576,6 +576,7 @@ export interface GitGraphDiagramConfig extends BaseDiagramConfig {
|
||||
showCommitLabel?: boolean;
|
||||
showBranches?: boolean;
|
||||
rotateCommitLabel?: boolean;
|
||||
parallelCommits?: boolean;
|
||||
/**
|
||||
* Controls whether or arrow markers in html code are absolute paths or anchors.
|
||||
* This matters if you are using base tag settings.
|
||||
|
||||
@@ -254,6 +254,16 @@ export const adjustClustersAndEdges = (graph, depth) => {
|
||||
}
|
||||
});
|
||||
|
||||
for (let id of Object.keys(clusterDb)) {
|
||||
const nonClusterChild = clusterDb[id].id;
|
||||
const parent = graph.parent(nonClusterChild);
|
||||
|
||||
// Change replacement node of id to parent of current replacement node if valid
|
||||
if (parent !== id && clusterDb[parent] && !clusterDb[parent].externalConnections) {
|
||||
clusterDb[id].id = parent;
|
||||
}
|
||||
}
|
||||
|
||||
// For clusters with incoming and/or outgoing edges translate those edges to a real node
|
||||
// in the cluster in order to fake the edge
|
||||
graph.edges().forEach(function (e) {
|
||||
@@ -307,9 +317,13 @@ export const adjustClustersAndEdges = (graph, depth) => {
|
||||
w = getAnchorId(e.w);
|
||||
graph.removeEdge(e.v, e.w, e.name);
|
||||
if (v !== e.v) {
|
||||
const parent = graph.parent(v);
|
||||
clusterDb[parent].externalConnections = true;
|
||||
edge.fromCluster = e.v;
|
||||
}
|
||||
if (w !== e.w) {
|
||||
const parent = graph.parent(w);
|
||||
clusterDb[parent].externalConnections = true;
|
||||
edge.toCluster = e.w;
|
||||
}
|
||||
log.warn('Fix Replacing with XXX', v, w, e.name);
|
||||
|
||||
@@ -18,13 +18,18 @@ export const getRows = (s?: string): string[] => {
|
||||
return str.split('#br#');
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes script tags from a text
|
||||
*
|
||||
* @param txt - The text to sanitize
|
||||
* @returns The safer text
|
||||
*/
|
||||
export const removeScript = (txt: string): string => {
|
||||
const setupDompurifyHooksIfNotSetup = (() => {
|
||||
let setup = false;
|
||||
|
||||
return () => {
|
||||
if (!setup) {
|
||||
setupDompurifyHooks();
|
||||
setup = true;
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
function setupDompurifyHooks() {
|
||||
const TEMPORARY_ATTRIBUTE = 'data-temp-href-target';
|
||||
|
||||
DOMPurify.addHook('beforeSanitizeAttributes', (node: Element) => {
|
||||
@@ -33,8 +38,6 @@ export const removeScript = (txt: string): string => {
|
||||
}
|
||||
});
|
||||
|
||||
const sanitizedText = DOMPurify.sanitize(txt);
|
||||
|
||||
DOMPurify.addHook('afterSanitizeAttributes', (node: Element) => {
|
||||
if (node.tagName === 'A' && node.hasAttribute(TEMPORARY_ATTRIBUTE)) {
|
||||
node.setAttribute('target', node.getAttribute(TEMPORARY_ATTRIBUTE) || '');
|
||||
@@ -44,6 +47,18 @@ export const removeScript = (txt: string): string => {
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes script tags from a text
|
||||
*
|
||||
* @param txt - The text to sanitize
|
||||
* @returns The safer text
|
||||
*/
|
||||
export const removeScript = (txt: string): string => {
|
||||
setupDompurifyHooksIfNotSetup();
|
||||
|
||||
const sanitizedText = DOMPurify.sanitize(txt);
|
||||
|
||||
return sanitizedText;
|
||||
};
|
||||
|
||||
@@ -27,11 +27,10 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multili
|
||||
|
||||
\%\%(?!\{)*[^\n]* /* skip comments */
|
||||
[^\}]\%\%*[^\n]* /* skip comments */
|
||||
\%\%*[^\n]*[\n]* /* do nothing */
|
||||
\%\%*[^\n]*[\n]* /* do nothing */
|
||||
|
||||
[\n]+ return 'NL';
|
||||
\s+ /* skip whitespace */
|
||||
\#[^\n]* /* skip comments */
|
||||
\%%[^\n]* /* skip comments */
|
||||
|
||||
/*
|
||||
@@ -86,10 +85,10 @@ weekday\s+friday return 'weekday_friday'
|
||||
weekday\s+saturday return 'weekday_saturday'
|
||||
weekday\s+sunday return 'weekday_sunday'
|
||||
\d\d\d\d"-"\d\d"-"\d\d return 'date';
|
||||
"title"\s[^#\n;]+ return 'title';
|
||||
"title"\s[^\n]+ return 'title';
|
||||
"accDescription"\s[^#\n;]+ return 'accDescription'
|
||||
"section"\s[^#:\n;]+ return 'section';
|
||||
[^#:\n;]+ return 'taskTxt';
|
||||
"section"\s[^\n]+ return 'section';
|
||||
[^:\n]+ return 'taskTxt';
|
||||
":"[^#\n;]+ return 'taskData';
|
||||
":" return ':';
|
||||
<<EOF>> return 'EOF';
|
||||
|
||||
@@ -28,8 +28,12 @@ describe('when parsing a gantt diagram it', function () {
|
||||
});
|
||||
it('should handle a title definition', function () {
|
||||
const str = 'gantt\ndateFormat yyyy-mm-dd\ntitle Adding gantt diagram functionality to mermaid';
|
||||
const semi = 'gantt\ndateFormat yyyy-mm-dd\ntitle ;Gantt diagram titles support semicolons';
|
||||
const hash = 'gantt\ndateFormat yyyy-mm-dd\ntitle #Gantt diagram titles support hashtags';
|
||||
|
||||
expect(parserFnConstructor(str)).not.toThrow();
|
||||
expect(parserFnConstructor(semi)).not.toThrow();
|
||||
expect(parserFnConstructor(hash)).not.toThrow();
|
||||
});
|
||||
it('should handle an excludes definition', function () {
|
||||
const str =
|
||||
@@ -53,7 +57,23 @@ describe('when parsing a gantt diagram it', function () {
|
||||
'excludes weekdays 2019-02-01\n' +
|
||||
'section Documentation';
|
||||
|
||||
const semi =
|
||||
'gantt\n' +
|
||||
'dateFormat yyyy-mm-dd\n' +
|
||||
'title Adding gantt diagram functionality to mermaid\n' +
|
||||
'excludes weekdays 2019-02-01\n' +
|
||||
'section ;Documentation';
|
||||
|
||||
const hash =
|
||||
'gantt\n' +
|
||||
'dateFormat yyyy-mm-dd\n' +
|
||||
'title Adding gantt diagram functionality to mermaid\n' +
|
||||
'excludes weekdays 2019-02-01\n' +
|
||||
'section #Documentation';
|
||||
|
||||
expect(parserFnConstructor(str)).not.toThrow();
|
||||
expect(parserFnConstructor(semi)).not.toThrow();
|
||||
expect(parserFnConstructor(hash)).not.toThrow();
|
||||
});
|
||||
it('should handle multiline section titles with different line breaks', function () {
|
||||
const str =
|
||||
@@ -73,7 +93,23 @@ describe('when parsing a gantt diagram it', function () {
|
||||
'section Documentation\n' +
|
||||
'Design jison grammar:des1, 2014-01-01, 2014-01-04';
|
||||
|
||||
const semi =
|
||||
'gantt\n' +
|
||||
'dateFormat YYYY-MM-DD\n' +
|
||||
'title Adding gantt diagram functionality to mermaid\n' +
|
||||
'section Documentation\n' +
|
||||
';Design jison grammar:des1, 2014-01-01, 2014-01-04';
|
||||
|
||||
const hash =
|
||||
'gantt\n' +
|
||||
'dateFormat YYYY-MM-DD\n' +
|
||||
'title Adding gantt diagram functionality to mermaid\n' +
|
||||
'section Documentation\n' +
|
||||
'#Design jison grammar:des1, 2014-01-01, 2014-01-04';
|
||||
|
||||
expect(parserFnConstructor(str)).not.toThrow();
|
||||
expect(parserFnConstructor(semi)).not.toThrow();
|
||||
expect(parserFnConstructor(hash)).not.toThrow();
|
||||
|
||||
const tasks = parser.yy.getTasks();
|
||||
|
||||
|
||||
@@ -64,6 +64,29 @@ const drawText = (txt) => {
|
||||
return svgLabel;
|
||||
};
|
||||
|
||||
/**
|
||||
* Searches for the closest parent from the parents list passed as argument.
|
||||
* The parents list comes from an individual commit. The closest parent is actually
|
||||
* the one farther down the graph, since that means it is closer to its child.
|
||||
*
|
||||
* @param {string[]} parents
|
||||
* @returns {string | undefined}
|
||||
*/
|
||||
const findClosestParent = (parents) => {
|
||||
let closestParent = '';
|
||||
let maxPosition = 0;
|
||||
|
||||
parents.forEach((parent) => {
|
||||
const parentPosition = dir === 'TB' ? commitPos[parent].y : commitPos[parent].x;
|
||||
if (parentPosition >= maxPosition) {
|
||||
closestParent = parent;
|
||||
maxPosition = parentPosition;
|
||||
}
|
||||
});
|
||||
|
||||
return closestParent || undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* Draws the commits with its symbol and labels. The function has two modes, one which only
|
||||
* calculates the positions and one that does the actual drawing. This for a simple way getting the
|
||||
@@ -87,11 +110,31 @@ const drawCommits = (svg, commits, modifyGraph) => {
|
||||
const sortedKeys = keys.sort((a, b) => {
|
||||
return commits[a].seq - commits[b].seq;
|
||||
});
|
||||
|
||||
const isParallelCommits = gitGraphConfig.parallelCommits;
|
||||
const layoutOffset = 10;
|
||||
const commitStep = 40;
|
||||
sortedKeys.forEach((key) => {
|
||||
const commit = commits[key];
|
||||
|
||||
const y = dir === 'TB' ? pos + 10 : branchPos[commit.branch].pos;
|
||||
const x = dir === 'TB' ? branchPos[commit.branch].pos : pos + 10;
|
||||
if (isParallelCommits) {
|
||||
if (commit.parents.length) {
|
||||
const closestParent = findClosestParent(commit.parents);
|
||||
pos =
|
||||
dir === 'TB'
|
||||
? commitPos[closestParent].y + commitStep
|
||||
: commitPos[closestParent].x + commitStep;
|
||||
} else {
|
||||
pos = 0;
|
||||
if (dir === 'TB') {
|
||||
pos = 30;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const posWithOffset = pos + layoutOffset;
|
||||
const y = dir === 'TB' ? posWithOffset : branchPos[commit.branch].pos;
|
||||
const x = dir === 'TB' ? branchPos[commit.branch].pos : posWithOffset;
|
||||
|
||||
// Don't draw the commits now but calculate the positioning which is used by the branch lines etc.
|
||||
if (modifyGraph) {
|
||||
@@ -216,9 +259,9 @@ const drawCommits = (svg, commits, modifyGraph) => {
|
||||
}
|
||||
}
|
||||
if (dir === 'TB') {
|
||||
commitPos[commit.id] = { x: x, y: pos + 10 };
|
||||
commitPos[commit.id] = { x: x, y: posWithOffset };
|
||||
} else {
|
||||
commitPos[commit.id] = { x: pos + 10, y: y };
|
||||
commitPos[commit.id] = { x: posWithOffset, y: y };
|
||||
}
|
||||
|
||||
// The first iteration over the commits are for positioning purposes, this
|
||||
@@ -247,7 +290,7 @@ const drawCommits = (svg, commits, modifyGraph) => {
|
||||
|
||||
// Now we have the label, lets position the background
|
||||
labelBkg
|
||||
.attr('x', pos + 10 - bbox.width / 2 - py)
|
||||
.attr('x', posWithOffset - bbox.width / 2 - py)
|
||||
.attr('y', y + 13.5)
|
||||
.attr('width', bbox.width + 2 * py)
|
||||
.attr('height', bbox.height + 2 * py);
|
||||
@@ -258,7 +301,7 @@ const drawCommits = (svg, commits, modifyGraph) => {
|
||||
}
|
||||
|
||||
if (dir !== 'TB') {
|
||||
text.attr('x', pos + 10 - bbox.width / 2);
|
||||
text.attr('x', posWithOffset - bbox.width / 2);
|
||||
}
|
||||
if (gitGraphConfig.rotateCommitLabel) {
|
||||
if (dir === 'TB') {
|
||||
@@ -284,7 +327,7 @@ const drawCommits = (svg, commits, modifyGraph) => {
|
||||
.attr('class', 'tag-label')
|
||||
.text(commit.tag);
|
||||
let tagBbox = tag.node().getBBox();
|
||||
tag.attr('x', pos + 10 - tagBbox.width / 2);
|
||||
tag.attr('x', posWithOffset - tagBbox.width / 2);
|
||||
|
||||
const h2 = tagBbox.height / 2;
|
||||
const ly = y - 19.2;
|
||||
@@ -293,10 +336,10 @@ const drawCommits = (svg, commits, modifyGraph) => {
|
||||
`
|
||||
${pos - tagBbox.width / 2 - px / 2},${ly + py}
|
||||
${pos - tagBbox.width / 2 - px / 2},${ly - py}
|
||||
${pos + 10 - tagBbox.width / 2 - px},${ly - h2 - py}
|
||||
${pos + 10 + tagBbox.width / 2 + px},${ly - h2 - py}
|
||||
${pos + 10 + tagBbox.width / 2 + px},${ly + h2 + py}
|
||||
${pos + 10 - tagBbox.width / 2 - px},${ly + h2 + py}`
|
||||
${posWithOffset - tagBbox.width / 2 - px},${ly - h2 - py}
|
||||
${posWithOffset + tagBbox.width / 2 + px},${ly - h2 - py}
|
||||
${posWithOffset + tagBbox.width / 2 + px},${ly + h2 + py}
|
||||
${posWithOffset - tagBbox.width / 2 - px},${ly + h2 + py}`
|
||||
);
|
||||
|
||||
hole
|
||||
@@ -313,10 +356,10 @@ const drawCommits = (svg, commits, modifyGraph) => {
|
||||
`
|
||||
${x},${pos + py}
|
||||
${x},${pos - py}
|
||||
${x + 10},${pos - h2 - py}
|
||||
${x + 10 + tagBbox.width + px},${pos - h2 - py}
|
||||
${x + 10 + tagBbox.width + px},${pos + h2 + py}
|
||||
${x + 10},${pos + h2 + py}`
|
||||
${x + layoutOffset},${pos - h2 - py}
|
||||
${x + layoutOffset + tagBbox.width + px},${pos - h2 - py}
|
||||
${x + layoutOffset + tagBbox.width + px},${pos + h2 + py}
|
||||
${x + layoutOffset},${pos + h2 + py}`
|
||||
)
|
||||
.attr('transform', 'translate(12,12) rotate(45, ' + x + ',' + pos + ')');
|
||||
hole
|
||||
@@ -330,7 +373,7 @@ const drawCommits = (svg, commits, modifyGraph) => {
|
||||
}
|
||||
}
|
||||
}
|
||||
pos += 50;
|
||||
pos += commitStep + layoutOffset;
|
||||
if (pos > maxPos) {
|
||||
maxPos = pos;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
// @ts-ignore: JISON doesn't support types
|
||||
import mindmapParser from './parser/mindmap.jison';
|
||||
import * as mindmapDb from './mindmapDb.js';
|
||||
import mindmapRenderer from './mindmapRenderer.js';
|
||||
import mindmapStyles from './styles.js';
|
||||
import parser from './parser/mindmap.jison';
|
||||
import db from './mindmapDb.js';
|
||||
import renderer from './mindmapRenderer.js';
|
||||
import styles from './styles.js';
|
||||
import type { DiagramDefinition } from '../../diagram-api/types.js';
|
||||
|
||||
export const diagram = {
|
||||
db: mindmapDb,
|
||||
renderer: mindmapRenderer,
|
||||
parser: mindmapParser,
|
||||
styles: mindmapStyles,
|
||||
export const diagram: DiagramDefinition = {
|
||||
db,
|
||||
renderer,
|
||||
parser,
|
||||
styles,
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// @ts-expect-error No types available for JISON
|
||||
import { parser as mindmap } from './parser/mindmap.jison';
|
||||
import * as mindmapDB from './mindmapDb.js';
|
||||
import mindmapDB from './mindmapDb.js';
|
||||
// Todo fix utils functions for tests
|
||||
import { setLogLevel } from '../../diagram-api/diagramAPI.js';
|
||||
|
||||
@@ -11,7 +12,7 @@ describe('when parsing a mindmap ', function () {
|
||||
});
|
||||
describe('hiearchy', function () {
|
||||
it('MMP-1 should handle a simple root definition abc122', function () {
|
||||
let str = `mindmap
|
||||
const str = `mindmap
|
||||
root`;
|
||||
|
||||
mindmap.parse(str);
|
||||
@@ -19,7 +20,7 @@ describe('when parsing a mindmap ', function () {
|
||||
expect(mindmap.yy.getMindmap().descr).toEqual('root');
|
||||
});
|
||||
it('MMP-2 should handle a hierachial mindmap definition', function () {
|
||||
let str = `mindmap
|
||||
const str = `mindmap
|
||||
root
|
||||
child1
|
||||
child2
|
||||
@@ -34,7 +35,7 @@ describe('when parsing a mindmap ', function () {
|
||||
});
|
||||
|
||||
it('3 should handle a simple root definition with a shape and without an id abc123', function () {
|
||||
let str = `mindmap
|
||||
const str = `mindmap
|
||||
(root)`;
|
||||
|
||||
mindmap.parse(str);
|
||||
@@ -43,7 +44,7 @@ describe('when parsing a mindmap ', function () {
|
||||
});
|
||||
|
||||
it('MMP-4 should handle a deeper hierachial mindmap definition', function () {
|
||||
let str = `mindmap
|
||||
const str = `mindmap
|
||||
root
|
||||
child1
|
||||
leaf1
|
||||
@@ -58,40 +59,27 @@ describe('when parsing a mindmap ', function () {
|
||||
expect(mm.children[1].descr).toEqual('child2');
|
||||
});
|
||||
it('5 Multiple roots are illegal', function () {
|
||||
let str = `mindmap
|
||||
const str = `mindmap
|
||||
root
|
||||
fakeRoot`;
|
||||
|
||||
try {
|
||||
mindmap.parse(str);
|
||||
// Fail test if above expression doesn't throw anything.
|
||||
expect(true).toBe(false);
|
||||
} catch (e) {
|
||||
expect(e.message).toBe(
|
||||
'There can be only one root. No parent could be found for ("fakeRoot")'
|
||||
);
|
||||
}
|
||||
expect(() => mindmap.parse(str)).toThrow(
|
||||
'There can be only one root. No parent could be found for ("fakeRoot")'
|
||||
);
|
||||
});
|
||||
it('MMP-6 real root in wrong place', function () {
|
||||
let str = `mindmap
|
||||
const str = `mindmap
|
||||
root
|
||||
fakeRoot
|
||||
realRootWrongPlace`;
|
||||
|
||||
try {
|
||||
mindmap.parse(str);
|
||||
// Fail test if above expression doesn't throw anything.
|
||||
expect(true).toBe(false);
|
||||
} catch (e) {
|
||||
expect(e.message).toBe(
|
||||
'There can be only one root. No parent could be found for ("fakeRoot")'
|
||||
);
|
||||
}
|
||||
expect(() => mindmap.parse(str)).toThrow(
|
||||
'There can be only one root. No parent could be found for ("fakeRoot")'
|
||||
);
|
||||
});
|
||||
});
|
||||
describe('nodes', function () {
|
||||
it('MMP-7 should handle an id and type for a node definition', function () {
|
||||
let str = `mindmap
|
||||
const str = `mindmap
|
||||
root[The root]
|
||||
`;
|
||||
|
||||
@@ -102,7 +90,7 @@ describe('when parsing a mindmap ', function () {
|
||||
expect(mm.type).toEqual(mindmap.yy.nodeType.RECT);
|
||||
});
|
||||
it('MMP-8 should handle an id and type for a node definition', function () {
|
||||
let str = `mindmap
|
||||
const str = `mindmap
|
||||
root
|
||||
theId(child1)`;
|
||||
|
||||
@@ -116,7 +104,7 @@ describe('when parsing a mindmap ', function () {
|
||||
expect(child.type).toEqual(mindmap.yy.nodeType.ROUNDED_RECT);
|
||||
});
|
||||
it('MMP-9 should handle an id and type for a node definition', function () {
|
||||
let str = `mindmap
|
||||
const str = `mindmap
|
||||
root
|
||||
theId(child1)`;
|
||||
|
||||
@@ -130,7 +118,7 @@ root
|
||||
expect(child.type).toEqual(mindmap.yy.nodeType.ROUNDED_RECT);
|
||||
});
|
||||
it('MMP-10 multiple types (circle)', function () {
|
||||
let str = `mindmap
|
||||
const str = `mindmap
|
||||
root((the root))
|
||||
`;
|
||||
|
||||
@@ -142,7 +130,7 @@ root
|
||||
});
|
||||
|
||||
it('MMP-11 multiple types (cloud)', function () {
|
||||
let str = `mindmap
|
||||
const str = `mindmap
|
||||
root)the root(
|
||||
`;
|
||||
|
||||
@@ -153,7 +141,7 @@ root
|
||||
expect(mm.type).toEqual(mindmap.yy.nodeType.CLOUD);
|
||||
});
|
||||
it('MMP-12 multiple types (bang)', function () {
|
||||
let str = `mindmap
|
||||
const str = `mindmap
|
||||
root))the root((
|
||||
`;
|
||||
|
||||
@@ -165,7 +153,7 @@ root
|
||||
});
|
||||
|
||||
it('MMP-12-a multiple types (hexagon)', function () {
|
||||
let str = `mindmap
|
||||
const str = `mindmap
|
||||
root{{the root}}
|
||||
`;
|
||||
|
||||
@@ -178,7 +166,7 @@ root
|
||||
});
|
||||
describe('decorations', function () {
|
||||
it('MMP-13 should be possible to set an icon for the node', function () {
|
||||
let str = `mindmap
|
||||
const str = `mindmap
|
||||
root[The root]
|
||||
::icon(bomb)
|
||||
`;
|
||||
@@ -192,7 +180,7 @@ root
|
||||
expect(mm.icon).toEqual('bomb');
|
||||
});
|
||||
it('MMP-14 should be possible to set classes for the node', function () {
|
||||
let str = `mindmap
|
||||
const str = `mindmap
|
||||
root[The root]
|
||||
:::m-4 p-8
|
||||
`;
|
||||
@@ -206,7 +194,7 @@ root
|
||||
expect(mm.class).toEqual('m-4 p-8');
|
||||
});
|
||||
it('MMP-15 should be possible to set both classes and icon for the node', function () {
|
||||
let str = `mindmap
|
||||
const str = `mindmap
|
||||
root[The root]
|
||||
:::m-4 p-8
|
||||
::icon(bomb)
|
||||
@@ -222,7 +210,7 @@ root
|
||||
expect(mm.icon).toEqual('bomb');
|
||||
});
|
||||
it('MMP-16 should be possible to set both classes and icon for the node', function () {
|
||||
let str = `mindmap
|
||||
const str = `mindmap
|
||||
root[The root]
|
||||
::icon(bomb)
|
||||
:::m-4 p-8
|
||||
@@ -240,7 +228,7 @@ root
|
||||
});
|
||||
describe('descriptions', function () {
|
||||
it('MMP-17 should be possible to use node syntax in the descriptions', function () {
|
||||
let str = `mindmap
|
||||
const str = `mindmap
|
||||
root["String containing []"]
|
||||
`;
|
||||
mindmap.parse(str);
|
||||
@@ -249,7 +237,7 @@ root
|
||||
expect(mm.descr).toEqual('String containing []');
|
||||
});
|
||||
it('MMP-18 should be possible to use node syntax in the descriptions in children', function () {
|
||||
let str = `mindmap
|
||||
const str = `mindmap
|
||||
root["String containing []"]
|
||||
child1["String containing ()"]
|
||||
`;
|
||||
@@ -261,7 +249,7 @@ root
|
||||
expect(mm.children[0].descr).toEqual('String containing ()');
|
||||
});
|
||||
it('MMP-19 should be possible to have a child after a class assignment', function () {
|
||||
let str = `mindmap
|
||||
const str = `mindmap
|
||||
root(Root)
|
||||
Child(Child)
|
||||
:::hot
|
||||
@@ -281,7 +269,7 @@ root
|
||||
});
|
||||
});
|
||||
it('MMP-20 should be possible to have meaningless empty rows in a mindmap abc124', function () {
|
||||
let str = `mindmap
|
||||
const str = `mindmap
|
||||
root(Root)
|
||||
Child(Child)
|
||||
a(a)
|
||||
@@ -300,7 +288,7 @@ root
|
||||
expect(child.children[1].nodeId).toEqual('b');
|
||||
});
|
||||
it('MMP-21 should be possible to have comments in a mindmap', function () {
|
||||
let str = `mindmap
|
||||
const str = `mindmap
|
||||
root(Root)
|
||||
Child(Child)
|
||||
a(a)
|
||||
@@ -321,7 +309,7 @@ root
|
||||
});
|
||||
|
||||
it('MMP-22 should be possible to have comments at the end of a line', function () {
|
||||
let str = `mindmap
|
||||
const str = `mindmap
|
||||
root(Root)
|
||||
Child(Child)
|
||||
a(a) %% This is a comment
|
||||
@@ -339,7 +327,7 @@ root
|
||||
expect(child.children[1].nodeId).toEqual('b');
|
||||
});
|
||||
it('MMP-23 Rows with only spaces should not interfere', function () {
|
||||
let str = 'mindmap\nroot\n A\n \n\n B';
|
||||
const str = 'mindmap\nroot\n A\n \n\n B';
|
||||
mindmap.parse(str);
|
||||
const mm = mindmap.yy.getMindmap();
|
||||
expect(mm.nodeId).toEqual('root');
|
||||
@@ -351,7 +339,7 @@ root
|
||||
expect(child2.nodeId).toEqual('B');
|
||||
});
|
||||
it('MMP-24 Handle rows above the mindmap declarations', function () {
|
||||
let str = '\n \nmindmap\nroot\n A\n \n\n B';
|
||||
const str = '\n \nmindmap\nroot\n A\n \n\n B';
|
||||
mindmap.parse(str);
|
||||
const mm = mindmap.yy.getMindmap();
|
||||
expect(mm.nodeId).toEqual('root');
|
||||
@@ -363,7 +351,7 @@ root
|
||||
expect(child2.nodeId).toEqual('B');
|
||||
});
|
||||
it('MMP-25 Handle rows above the mindmap declarations, no space', function () {
|
||||
let str = '\n\n\nmindmap\nroot\n A\n \n\n B';
|
||||
const str = '\n\n\nmindmap\nroot\n A\n \n\n B';
|
||||
mindmap.parse(str);
|
||||
const mm = mindmap.yy.getMindmap();
|
||||
expect(mm.nodeId).toEqual('root');
|
||||
@@ -1,19 +1,21 @@
|
||||
import { getConfig } from '../../diagram-api/diagramAPI.js';
|
||||
import { sanitizeText as _sanitizeText } from '../../diagrams/common/common.js';
|
||||
import type { D3Element } from '../../mermaidAPI.js';
|
||||
import { sanitizeText } from '../../diagrams/common/common.js';
|
||||
import { log } from '../../logger.js';
|
||||
import type { MindmapNode } from './mindmapTypes.js';
|
||||
import { getConfigValue } from '../../config.js';
|
||||
|
||||
export const sanitizeText = (text) => _sanitizeText(text, getConfig());
|
||||
|
||||
let nodes = [];
|
||||
let nodes: MindmapNode[] = [];
|
||||
let cnt = 0;
|
||||
let elements = {};
|
||||
export const clear = () => {
|
||||
let elements: Record<number, D3Element> = {};
|
||||
|
||||
const clear = () => {
|
||||
nodes = [];
|
||||
cnt = 0;
|
||||
elements = {};
|
||||
};
|
||||
|
||||
const getParent = function (level) {
|
||||
const getParent = function (level: number) {
|
||||
for (let i = nodes.length - 1; i >= 0; i--) {
|
||||
if (nodes[i].level < level) {
|
||||
return nodes[i];
|
||||
@@ -23,34 +25,32 @@ const getParent = function (level) {
|
||||
return null;
|
||||
};
|
||||
|
||||
export const getMindmap = () => {
|
||||
const getMindmap = () => {
|
||||
return nodes.length > 0 ? nodes[0] : null;
|
||||
};
|
||||
export const addNode = (level, id, descr, type) => {
|
||||
|
||||
const addNode = (level: number, id: string, descr: string, type: number) => {
|
||||
log.info('addNode', level, id, descr, type);
|
||||
const conf = getConfig();
|
||||
let padding: number = getConfigValue(conf, 'mindmap.padding');
|
||||
switch (type) {
|
||||
case nodeType.ROUNDED_RECT:
|
||||
case nodeType.RECT:
|
||||
case nodeType.HEXAGON:
|
||||
padding *= 2;
|
||||
}
|
||||
|
||||
const node = {
|
||||
id: cnt++,
|
||||
nodeId: sanitizeText(id),
|
||||
nodeId: sanitizeText(id, conf),
|
||||
level,
|
||||
descr: sanitizeText(descr),
|
||||
descr: sanitizeText(descr, conf),
|
||||
type,
|
||||
children: [],
|
||||
width: getConfig().mindmap.maxNodeWidth,
|
||||
};
|
||||
switch (node.type) {
|
||||
case nodeType.ROUNDED_RECT:
|
||||
node.padding = 2 * conf.mindmap.padding;
|
||||
break;
|
||||
case nodeType.RECT:
|
||||
node.padding = 2 * conf.mindmap.padding;
|
||||
break;
|
||||
case nodeType.HEXAGON:
|
||||
node.padding = 2 * conf.mindmap.padding;
|
||||
break;
|
||||
default:
|
||||
node.padding = conf.mindmap.padding;
|
||||
}
|
||||
width: getConfigValue(conf, 'mindmap.maxNodeWidth'),
|
||||
padding,
|
||||
} satisfies MindmapNode;
|
||||
|
||||
const parent = getParent(level);
|
||||
if (parent) {
|
||||
parent.children.push(node);
|
||||
@@ -62,22 +62,14 @@ export const addNode = (level, id, descr, type) => {
|
||||
nodes.push(node);
|
||||
} else {
|
||||
// Syntax error ... there can only bee one root
|
||||
let error = new Error(
|
||||
throw new Error(
|
||||
'There can be only one root. No parent could be found for ("' + node.descr + '")'
|
||||
);
|
||||
error.hash = {
|
||||
text: 'branch ' + name,
|
||||
token: 'branch ' + name,
|
||||
line: '1',
|
||||
loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 },
|
||||
expected: ['"checkout ' + name + '"'],
|
||||
};
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const nodeType = {
|
||||
const nodeType = {
|
||||
DEFAULT: 0,
|
||||
NO_BORDER: 0,
|
||||
ROUNDED_RECT: 1,
|
||||
@@ -88,7 +80,7 @@ export const nodeType = {
|
||||
HEXAGON: 6,
|
||||
};
|
||||
|
||||
export const getType = (startStr, endStr) => {
|
||||
const getType = (startStr: string, endStr: string): number => {
|
||||
log.debug('In get type', startStr, endStr);
|
||||
switch (startStr) {
|
||||
case '[':
|
||||
@@ -108,21 +100,25 @@ export const getType = (startStr, endStr) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const setElementForId = (id, element) => {
|
||||
const setElementForId = (id: number, element: D3Element) => {
|
||||
elements[id] = element;
|
||||
};
|
||||
|
||||
export const decorateNode = (decoration) => {
|
||||
const node = nodes[nodes.length - 1];
|
||||
if (decoration && decoration.icon) {
|
||||
node.icon = sanitizeText(decoration.icon);
|
||||
const decorateNode = (decoration?: { class?: string; icon?: string }) => {
|
||||
if (!decoration) {
|
||||
return;
|
||||
}
|
||||
if (decoration && decoration.class) {
|
||||
node.class = sanitizeText(decoration.class);
|
||||
const config = getConfig();
|
||||
const node = nodes[nodes.length - 1];
|
||||
if (decoration.icon) {
|
||||
node.icon = sanitizeText(decoration.icon, config);
|
||||
}
|
||||
if (decoration.class) {
|
||||
node.class = sanitizeText(decoration.class, config);
|
||||
}
|
||||
};
|
||||
|
||||
export const type2Str = (type) => {
|
||||
const type2Str = (type: number) => {
|
||||
switch (type) {
|
||||
case nodeType.DEFAULT:
|
||||
return 'no-border';
|
||||
@@ -143,13 +139,21 @@ export const type2Str = (type) => {
|
||||
}
|
||||
};
|
||||
|
||||
export let parseError;
|
||||
export const setErrorHandler = (handler) => {
|
||||
parseError = handler;
|
||||
};
|
||||
|
||||
// Expose logger to grammar
|
||||
export const getLogger = () => log;
|
||||
const getLogger = () => log;
|
||||
const getElementById = (id: number) => elements[id];
|
||||
|
||||
export const getNodeById = (id) => nodes[id];
|
||||
export const getElementById = (id) => elements[id];
|
||||
const db = {
|
||||
clear,
|
||||
addNode,
|
||||
getMindmap,
|
||||
nodeType,
|
||||
getType,
|
||||
setElementForId,
|
||||
decorateNode,
|
||||
type2Str,
|
||||
getLogger,
|
||||
getElementById,
|
||||
} as const;
|
||||
|
||||
export default db;
|
||||
@@ -1,36 +1,52 @@
|
||||
/** Created by knut on 14-12-11. */
|
||||
import { select } from 'd3';
|
||||
import { log } from '../../logger.js';
|
||||
import { getConfig } from '../../diagram-api/diagramAPI.js';
|
||||
import { setupGraphViewbox } from '../../setupGraphViewbox.js';
|
||||
import svgDraw from './svgDraw.js';
|
||||
import cytoscape from 'cytoscape/dist/cytoscape.umd.js';
|
||||
import cytoscape from 'cytoscape';
|
||||
// @ts-expect-error No types available
|
||||
import coseBilkent from 'cytoscape-cose-bilkent';
|
||||
import * as db from './mindmapDb.js';
|
||||
import { select } from 'd3';
|
||||
import type { MermaidConfig } from '../../config.type.js';
|
||||
import type { DrawDefinition } from '../../diagram-api/types.js';
|
||||
import { log } from '../../logger.js';
|
||||
import type { D3Element } from '../../mermaidAPI.js';
|
||||
import { selectSvgElement } from '../../rendering-util/selectSvgElement.js';
|
||||
import { setupGraphViewbox } from '../../setupGraphViewbox.js';
|
||||
import type { FilledMindMapNode, MindmapDB, MindmapNode } from './mindmapTypes.js';
|
||||
import { drawNode, positionNode } from './svgDraw.js';
|
||||
import { getConfig, getConfigValue } from '../../config.js';
|
||||
|
||||
// Inject the layout algorithm into cytoscape
|
||||
cytoscape.use(coseBilkent);
|
||||
|
||||
/**
|
||||
* @param {any} svg The svg element to draw the diagram onto
|
||||
* @param {object} mindmap The mindmap data and hierarchy
|
||||
* @param section
|
||||
* @param {object} conf The configuration object
|
||||
*/
|
||||
function drawNodes(svg, mindmap, section, conf) {
|
||||
svgDraw.drawNode(svg, mindmap, section, conf);
|
||||
function drawNodes(
|
||||
db: MindmapDB,
|
||||
svg: D3Element,
|
||||
mindmap: FilledMindMapNode,
|
||||
section: number,
|
||||
conf: MermaidConfig
|
||||
) {
|
||||
drawNode(db, svg, mindmap, section, conf);
|
||||
if (mindmap.children) {
|
||||
mindmap.children.forEach((child, index) => {
|
||||
drawNodes(svg, child, section < 0 ? index : section, conf);
|
||||
drawNodes(db, svg, child, section < 0 ? index : section, conf);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param edgesEl
|
||||
* @param cy
|
||||
*/
|
||||
function drawEdges(edgesEl, cy) {
|
||||
declare module 'cytoscape' {
|
||||
interface EdgeSingular {
|
||||
_private: {
|
||||
bodyBounds: unknown;
|
||||
rscratch: {
|
||||
startX: number;
|
||||
startY: number;
|
||||
midX: number;
|
||||
midY: number;
|
||||
endX: number;
|
||||
endY: number;
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function drawEdges(edgesEl: D3Element, cy: cytoscape.Core) {
|
||||
cy.edges().map((edge, id) => {
|
||||
const data = edge.data();
|
||||
if (edge[0]._private.bodyBounds) {
|
||||
@@ -47,17 +63,11 @@ function drawEdges(edgesEl, cy) {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mindmap The mindmap data and hierarchy
|
||||
* @param cy
|
||||
* @param conf The configuration object
|
||||
* @param level
|
||||
*/
|
||||
function addNodes(mindmap, cy, conf, level) {
|
||||
function addNodes(mindmap: MindmapNode, cy: cytoscape.Core, conf: MermaidConfig, level: number) {
|
||||
cy.add({
|
||||
group: 'nodes',
|
||||
data: {
|
||||
id: mindmap.id,
|
||||
id: mindmap.id.toString(),
|
||||
labelText: mindmap.descr,
|
||||
height: mindmap.height,
|
||||
width: mindmap.width,
|
||||
@@ -67,8 +77,8 @@ function addNodes(mindmap, cy, conf, level) {
|
||||
type: mindmap.type,
|
||||
},
|
||||
position: {
|
||||
x: mindmap.x,
|
||||
y: mindmap.y,
|
||||
x: mindmap.x!,
|
||||
y: mindmap.y!,
|
||||
},
|
||||
});
|
||||
if (mindmap.children) {
|
||||
@@ -88,12 +98,7 @@ function addNodes(mindmap, cy, conf, level) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* @param conf
|
||||
* @param cy
|
||||
*/
|
||||
function layoutMindmap(node, conf) {
|
||||
function layoutMindmap(node: MindmapNode, conf: MermaidConfig): Promise<cytoscape.Core> {
|
||||
return new Promise((resolve) => {
|
||||
// Add temporary render element
|
||||
const renderEl = select('body').append('div').attr('id', 'cy').attr('style', 'display:none');
|
||||
@@ -122,8 +127,8 @@ function layoutMindmap(node, conf) {
|
||||
|
||||
cy.layout({
|
||||
name: 'cose-bilkent',
|
||||
// @ts-ignore Types for cose-bilkent are not correct?
|
||||
quality: 'proof',
|
||||
// headless: true,
|
||||
styleEnabled: false,
|
||||
animate: false,
|
||||
}).run();
|
||||
@@ -133,18 +138,13 @@ function layoutMindmap(node, conf) {
|
||||
});
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @param node
|
||||
* @param cy
|
||||
* @param positionedMindmap
|
||||
* @param conf
|
||||
*/
|
||||
function positionNodes(cy) {
|
||||
|
||||
function positionNodes(db: MindmapDB, cy: cytoscape.Core) {
|
||||
cy.nodes().map((node, id) => {
|
||||
const data = node.data();
|
||||
data.x = node.position().x;
|
||||
data.y = node.position().y;
|
||||
svgDraw.positionNode(data);
|
||||
positionNode(db, data);
|
||||
const el = db.getElementById(data.nodeId);
|
||||
log.info('Id:', id, 'Position: (', node.position().x, ', ', node.position().y, ')', data);
|
||||
el.attr(
|
||||
@@ -155,38 +155,19 @@ function positionNodes(cy) {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a an info picture in the tag with id: id based on the graph definition in text.
|
||||
*
|
||||
* @param {any} text
|
||||
* @param {any} id
|
||||
* @param {any} version
|
||||
* @param diagObj
|
||||
*/
|
||||
export const draw: DrawDefinition = async (text, id, _version, diagObj) => {
|
||||
log.debug('Rendering mindmap diagram\n' + text);
|
||||
|
||||
const db = diagObj.db as MindmapDB;
|
||||
const mm = db.getMindmap();
|
||||
if (!mm) {
|
||||
return;
|
||||
}
|
||||
|
||||
export const draw = async (text, id, version, diagObj) => {
|
||||
const conf = getConfig();
|
||||
|
||||
conf.htmlLabels = false;
|
||||
|
||||
log.debug('Rendering mindmap diagram\n' + text, diagObj.parser);
|
||||
|
||||
const securityLevel = getConfig().securityLevel;
|
||||
// Handle root and Document for when rendering in sandbox mode
|
||||
let sandboxElement;
|
||||
if (securityLevel === 'sandbox') {
|
||||
sandboxElement = select('#i' + id);
|
||||
}
|
||||
const root =
|
||||
securityLevel === 'sandbox'
|
||||
? select(sandboxElement.nodes()[0].contentDocument.body)
|
||||
: select('body');
|
||||
// Parse the graph definition
|
||||
|
||||
const svg = root.select('#' + id);
|
||||
|
||||
svg.append('g');
|
||||
const mm = diagObj.db.getMindmap();
|
||||
const svg = selectSvgElement(id);
|
||||
|
||||
// Draw the graph and start with drawing the nodes without proper position
|
||||
// this gives us the size of the nodes and we can set the positions later
|
||||
@@ -195,18 +176,23 @@ export const draw = async (text, id, version, diagObj) => {
|
||||
edgesElem.attr('class', 'mindmap-edges');
|
||||
const nodesElem = svg.append('g');
|
||||
nodesElem.attr('class', 'mindmap-nodes');
|
||||
drawNodes(nodesElem, mm, -1, conf);
|
||||
drawNodes(db, nodesElem, mm as FilledMindMapNode, -1, conf);
|
||||
|
||||
// Next step is to layout the mindmap, giving each node a position
|
||||
|
||||
const cy = await layoutMindmap(mm, conf);
|
||||
|
||||
// // After this we can draw, first the edges and the then nodes with the correct position
|
||||
drawEdges(edgesElem, cy, conf);
|
||||
positionNodes(cy, conf);
|
||||
// After this we can draw, first the edges and the then nodes with the correct position
|
||||
drawEdges(edgesElem, cy);
|
||||
positionNodes(db, cy);
|
||||
|
||||
// Setup the view box and size of the svg element
|
||||
setupGraphViewbox(undefined, svg, conf.mindmap.padding, conf.mindmap.useMaxWidth);
|
||||
setupGraphViewbox(
|
||||
undefined,
|
||||
svg,
|
||||
getConfigValue(conf, 'mindmap.padding'),
|
||||
getConfigValue(conf, 'mindmap.useMaxWidth')
|
||||
);
|
||||
};
|
||||
|
||||
export default {
|
||||
22
packages/mermaid/src/diagrams/mindmap/mindmapTypes.ts
Normal file
22
packages/mermaid/src/diagrams/mindmap/mindmapTypes.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import type { RequiredDeep } from 'type-fest';
|
||||
import type mindmapDb from './mindmapDb.js';
|
||||
|
||||
export interface MindmapNode {
|
||||
id: number;
|
||||
nodeId: string;
|
||||
level: number;
|
||||
descr: string;
|
||||
type: number;
|
||||
children: MindmapNode[];
|
||||
width: number;
|
||||
padding: number;
|
||||
section?: number;
|
||||
height?: number;
|
||||
class?: string;
|
||||
icon?: string;
|
||||
x?: number;
|
||||
y?: number;
|
||||
}
|
||||
|
||||
export type FilledMindMapNode = RequiredDeep<MindmapNode>;
|
||||
export type MindmapDB = typeof mindmapDb;
|
||||
@@ -1,6 +1,8 @@
|
||||
// @ts-expect-error Incorrect khroma types
|
||||
import { darken, lighten, isDark } from 'khroma';
|
||||
import type { DiagramStylesProvider } from '../../diagram-api/types.js';
|
||||
|
||||
const genSections = (options) => {
|
||||
const genSections: DiagramStylesProvider = (options) => {
|
||||
let sections = '';
|
||||
|
||||
for (let i = 0; i < options.THEME_COLOR_LIMIT; i++) {
|
||||
@@ -49,7 +51,8 @@ const genSections = (options) => {
|
||||
return sections;
|
||||
};
|
||||
|
||||
const getStyles = (options) =>
|
||||
// TODO: These options seem incorrect.
|
||||
const getStyles: DiagramStylesProvider = (options) =>
|
||||
`
|
||||
.edge {
|
||||
stroke-width: 3;
|
||||
@@ -1,55 +1,20 @@
|
||||
import { select } from 'd3';
|
||||
import * as db from './mindmapDb.js';
|
||||
import type { D3Element } from '../../mermaidAPI.js';
|
||||
import { createText } from '../../rendering-util/createText.js';
|
||||
import type { FilledMindMapNode, MindmapDB } from './mindmapTypes.js';
|
||||
import type { Point } from '../../types.js';
|
||||
import { parseFontSize } from '../../utils.js';
|
||||
import type { MermaidConfig } from '../../config.type.js';
|
||||
|
||||
const MAX_SECTIONS = 12;
|
||||
|
||||
/**
|
||||
* @param {string} text The text to be wrapped
|
||||
* @param {number} width The max width of the text
|
||||
*/
|
||||
function wrap(text, width) {
|
||||
text.each(function () {
|
||||
var text = select(this),
|
||||
words = text
|
||||
.text()
|
||||
.split(/(\s+|<br\/>)/)
|
||||
.reverse(),
|
||||
word,
|
||||
line = [],
|
||||
lineHeight = 1.1, // ems
|
||||
y = text.attr('y'),
|
||||
dy = parseFloat(text.attr('dy')),
|
||||
tspan = text
|
||||
.text(null)
|
||||
.append('tspan')
|
||||
.attr('x', 0)
|
||||
.attr('y', y)
|
||||
.attr('dy', dy + 'em');
|
||||
for (let j = 0; j < words.length; j++) {
|
||||
word = words[words.length - 1 - j];
|
||||
line.push(word);
|
||||
tspan.text(line.join(' ').trim());
|
||||
if (tspan.node().getComputedTextLength() > width || word === '<br/>') {
|
||||
line.pop();
|
||||
tspan.text(line.join(' ').trim());
|
||||
if (word === '<br/>') {
|
||||
line = [''];
|
||||
} else {
|
||||
line = [word];
|
||||
}
|
||||
type ShapeFunction = (
|
||||
db: MindmapDB,
|
||||
elem: D3Element,
|
||||
node: FilledMindMapNode,
|
||||
section?: number
|
||||
) => void;
|
||||
|
||||
tspan = text
|
||||
.append('tspan')
|
||||
.attr('x', 0)
|
||||
.attr('y', y)
|
||||
.attr('dy', lineHeight + 'em')
|
||||
.text(word);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const defaultBkg = function (elem, node, section) {
|
||||
const defaultBkg: ShapeFunction = function (db, elem, node, section) {
|
||||
const rd = 5;
|
||||
elem
|
||||
.append('path')
|
||||
@@ -71,7 +36,7 @@ const defaultBkg = function (elem, node, section) {
|
||||
.attr('y2', node.height);
|
||||
};
|
||||
|
||||
const rectBkg = function (elem, node) {
|
||||
const rectBkg: ShapeFunction = function (db, elem, node) {
|
||||
elem
|
||||
.append('rect')
|
||||
.attr('id', 'node-' + node.id)
|
||||
@@ -80,7 +45,7 @@ const rectBkg = function (elem, node) {
|
||||
.attr('width', node.width);
|
||||
};
|
||||
|
||||
const cloudBkg = function (elem, node) {
|
||||
const cloudBkg: ShapeFunction = function (db, elem, node) {
|
||||
const w = node.width;
|
||||
const h = node.height;
|
||||
const r1 = 0.15 * w;
|
||||
@@ -111,7 +76,7 @@ const cloudBkg = function (elem, node) {
|
||||
);
|
||||
};
|
||||
|
||||
const bangBkg = function (elem, node) {
|
||||
const bangBkg: ShapeFunction = function (db, elem, node) {
|
||||
const w = node.width;
|
||||
const h = node.height;
|
||||
const r = 0.15 * w;
|
||||
@@ -143,7 +108,7 @@ const bangBkg = function (elem, node) {
|
||||
);
|
||||
};
|
||||
|
||||
const circleBkg = function (elem, node) {
|
||||
const circleBkg: ShapeFunction = function (db, elem, node) {
|
||||
elem
|
||||
.append('circle')
|
||||
.attr('id', 'node-' + node.id)
|
||||
@@ -151,15 +116,13 @@ const circleBkg = function (elem, node) {
|
||||
.attr('r', node.width / 2);
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param parent
|
||||
* @param w
|
||||
* @param h
|
||||
* @param points
|
||||
* @param node
|
||||
*/
|
||||
function insertPolygonShape(parent, w, h, points, node) {
|
||||
function insertPolygonShape(
|
||||
parent: D3Element,
|
||||
w: number,
|
||||
h: number,
|
||||
points: Point[],
|
||||
node: FilledMindMapNode
|
||||
) {
|
||||
return parent
|
||||
.insert('polygon', ':first-child')
|
||||
.attr(
|
||||
@@ -173,12 +136,16 @@ function insertPolygonShape(parent, w, h, points, node) {
|
||||
.attr('transform', 'translate(' + (node.width - w) / 2 + ', ' + h + ')');
|
||||
}
|
||||
|
||||
const hexagonBkg = function (elem, node) {
|
||||
const hexagonBkg: ShapeFunction = function (
|
||||
_db: MindmapDB,
|
||||
elem: D3Element,
|
||||
node: FilledMindMapNode
|
||||
) {
|
||||
const h = node.height;
|
||||
const f = 4;
|
||||
const m = h / f;
|
||||
const w = node.width - node.padding + 2 * m;
|
||||
const points = [
|
||||
const points: Point[] = [
|
||||
{ x: m, y: 0 },
|
||||
{ x: w - m, y: 0 },
|
||||
{ x: w, y: -h / 2 },
|
||||
@@ -186,10 +153,10 @@ const hexagonBkg = function (elem, node) {
|
||||
{ x: m, y: -h },
|
||||
{ x: 0, y: -h / 2 },
|
||||
];
|
||||
const shapeSvg = insertPolygonShape(elem, w, h, points, node);
|
||||
insertPolygonShape(elem, w, h, points, node);
|
||||
};
|
||||
|
||||
const roundedRectBkg = function (elem, node) {
|
||||
const roundedRectBkg: ShapeFunction = function (db, elem, node) {
|
||||
elem
|
||||
.append('rect')
|
||||
.attr('id', 'node-' + node.id)
|
||||
@@ -201,13 +168,20 @@ const roundedRectBkg = function (elem, node) {
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {object} elem The D3 dom element in which the node is to be added
|
||||
* @param {object} node The node to be added
|
||||
* @param fullSection
|
||||
* @param {object} conf The configuration object
|
||||
* @returns {number} The height nodes dom element
|
||||
* @param db - The database
|
||||
* @param elem - The D3 dom element in which the node is to be added
|
||||
* @param node - The node to be added
|
||||
* @param fullSection - ?
|
||||
* @param conf - The configuration object
|
||||
* @returns The height nodes dom element
|
||||
*/
|
||||
export const drawNode = function (elem, node, fullSection, conf) {
|
||||
export const drawNode = function (
|
||||
db: MindmapDB,
|
||||
elem: D3Element,
|
||||
node: FilledMindMapNode,
|
||||
fullSection: number,
|
||||
conf: MermaidConfig
|
||||
): number {
|
||||
const htmlLabels = conf.htmlLabels;
|
||||
const section = fullSection % (MAX_SECTIONS - 1);
|
||||
const nodeElem = elem.append('g');
|
||||
@@ -235,10 +209,9 @@ export const drawNode = function (elem, node, fullSection, conf) {
|
||||
.attr('dominant-baseline', 'middle')
|
||||
.attr('text-anchor', 'middle');
|
||||
}
|
||||
// .call(wrap, node.width);
|
||||
const bbox = textElem.node().getBBox();
|
||||
const fontSize = conf.fontSize.replace ? conf.fontSize.replace('px', '') : conf.fontSize;
|
||||
node.height = bbox.height + fontSize * 1.1 * 0.5 + node.padding;
|
||||
const [fontSize] = parseFontSize(conf.fontSize);
|
||||
node.height = bbox.height + fontSize! * 1.1 * 0.5 + node.padding;
|
||||
node.width = bbox.width + 2 * node.padding;
|
||||
if (node.icon) {
|
||||
if (node.type === db.nodeType.CIRCLE) {
|
||||
@@ -294,60 +267,34 @@ export const drawNode = function (elem, node, fullSection, conf) {
|
||||
|
||||
switch (node.type) {
|
||||
case db.nodeType.DEFAULT:
|
||||
defaultBkg(bkgElem, node, section, conf);
|
||||
defaultBkg(db, bkgElem, node, section);
|
||||
break;
|
||||
case db.nodeType.ROUNDED_RECT:
|
||||
roundedRectBkg(bkgElem, node, section, conf);
|
||||
roundedRectBkg(db, bkgElem, node, section);
|
||||
break;
|
||||
case db.nodeType.RECT:
|
||||
rectBkg(bkgElem, node, section, conf);
|
||||
rectBkg(db, bkgElem, node, section);
|
||||
break;
|
||||
case db.nodeType.CIRCLE:
|
||||
bkgElem.attr('transform', 'translate(' + node.width / 2 + ', ' + +node.height / 2 + ')');
|
||||
circleBkg(bkgElem, node, section, conf);
|
||||
circleBkg(db, bkgElem, node, section);
|
||||
break;
|
||||
case db.nodeType.CLOUD:
|
||||
cloudBkg(bkgElem, node, section, conf);
|
||||
cloudBkg(db, bkgElem, node, section);
|
||||
break;
|
||||
case db.nodeType.BANG:
|
||||
bangBkg(bkgElem, node, section, conf);
|
||||
bangBkg(db, bkgElem, node, section);
|
||||
break;
|
||||
case db.nodeType.HEXAGON:
|
||||
hexagonBkg(bkgElem, node, section, conf);
|
||||
hexagonBkg(db, bkgElem, node, section);
|
||||
break;
|
||||
}
|
||||
|
||||
// Position the node to its coordinate
|
||||
// if (typeof node.x !== 'undefined' && typeof node.y !== 'undefined') {
|
||||
// nodeElem.attr('transform', 'translate(' + node.x + ',' + node.y + ')');
|
||||
// }
|
||||
db.setElementForId(node.id, nodeElem);
|
||||
return node.height;
|
||||
};
|
||||
|
||||
export const drawEdge = function drawEdge(edgesElem, mindmap, parent, depth, fullSection) {
|
||||
const section = fullSection % (MAX_SECTIONS - 1);
|
||||
const sx = parent.x + parent.width / 2;
|
||||
const sy = parent.y + parent.height / 2;
|
||||
const ex = mindmap.x + mindmap.width / 2;
|
||||
const ey = mindmap.y + mindmap.height / 2;
|
||||
const mx = ex > sx ? sx + Math.abs(sx - ex) / 2 : sx - Math.abs(sx - ex) / 2;
|
||||
const my = ey > sy ? sy + Math.abs(sy - ey) / 2 : sy - Math.abs(sy - ey) / 2;
|
||||
const qx = ex > sx ? Math.abs(sx - mx) / 2 + sx : -Math.abs(sx - mx) / 2 + sx;
|
||||
const qy = ey > sy ? Math.abs(sy - my) / 2 + sy : -Math.abs(sy - my) / 2 + sy;
|
||||
|
||||
edgesElem
|
||||
.append('path')
|
||||
.attr(
|
||||
'd',
|
||||
parent.direction === 'TB' || parent.direction === 'BT'
|
||||
? `M${sx},${sy} Q${sx},${qy} ${mx},${my} T${ex},${ey}`
|
||||
: `M${sx},${sy} Q${qx},${sy} ${mx},${my} T${ex},${ey}`
|
||||
)
|
||||
.attr('class', 'edge section-edge-' + section + ' edge-depth-' + depth);
|
||||
};
|
||||
|
||||
export const positionNode = function (node) {
|
||||
export const positionNode = function (db: MindmapDB, node: FilledMindMapNode) {
|
||||
const nodeElem = db.getElementById(node.id);
|
||||
|
||||
const x = node.x || 0;
|
||||
@@ -355,5 +302,3 @@ export const positionNode = function (node) {
|
||||
// Position the node to its coordinate
|
||||
nodeElem.attr('transform', 'translate(' + x + ',' + y + ')');
|
||||
};
|
||||
|
||||
export default { drawNode, positionNode, drawEdge };
|
||||
@@ -1,6 +1,5 @@
|
||||
import type { Diagram } from '../../Diagram.js';
|
||||
import { getConfig, defaultConfig } from '../../diagram-api/diagramAPI.js';
|
||||
|
||||
import {
|
||||
select as d3select,
|
||||
scaleOrdinal as d3scaleOrdinal,
|
||||
|
||||
@@ -10,22 +10,6 @@ export const drawRect = function (elem, rectData) {
|
||||
return svgDrawCommon.drawRect(elem, rectData);
|
||||
};
|
||||
|
||||
const addPopupInteraction = (id, actorCnt) => {
|
||||
addFunction(() => {
|
||||
const arr = document.querySelectorAll(id);
|
||||
// This will be the case when running in sandboxed mode
|
||||
if (arr.length === 0) {
|
||||
return;
|
||||
}
|
||||
arr[0].addEventListener('mouseover', function () {
|
||||
popupMenuUpFunc('actor' + actorCnt + '_popup');
|
||||
});
|
||||
arr[0].addEventListener('mouseout', function () {
|
||||
popupMenuDownFunc('actor' + actorCnt + '_popup');
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const drawPopup = function (elem, actor, minMenuWidth, textAttrs, forceMenus) {
|
||||
if (actor.links === undefined || actor.links === null || Object.keys(actor.links).length === 0) {
|
||||
return { height: 0, width: 0 };
|
||||
@@ -44,7 +28,6 @@ export const drawPopup = function (elem, actor, minMenuWidth, textAttrs, forceMe
|
||||
g.attr('id', 'actor' + actorCnt + '_popup');
|
||||
g.attr('class', 'actorPopupMenu');
|
||||
g.attr('display', displayValue);
|
||||
addPopupInteraction('#actor' + actorCnt + '_popup', actorCnt);
|
||||
var actorClass = '';
|
||||
if (rectData.class !== undefined) {
|
||||
actorClass = ' ' + rectData.class;
|
||||
@@ -90,36 +73,14 @@ export const drawPopup = function (elem, actor, minMenuWidth, textAttrs, forceMe
|
||||
return { height: rectData.height + linkY, width: menuWidth };
|
||||
};
|
||||
|
||||
export const popupMenu = function (popid) {
|
||||
const popupMenuToggle = function (popid) {
|
||||
return (
|
||||
"var pu = document.getElementById('" +
|
||||
popid +
|
||||
"'); if (pu != null) { pu.style.display = 'block'; }"
|
||||
"'); if (pu != null) { pu.style.display = pu.style.display == 'block' ? 'none' : 'block'; }"
|
||||
);
|
||||
};
|
||||
|
||||
export const popdownMenu = function (popid) {
|
||||
return (
|
||||
"var pu = document.getElementById('" +
|
||||
popid +
|
||||
"'); if (pu != null) { pu.style.display = 'none'; }"
|
||||
);
|
||||
};
|
||||
|
||||
const popupMenuUpFunc = function (popupId) {
|
||||
var pu = document.getElementById(popupId);
|
||||
if (pu != null) {
|
||||
pu.style.display = 'block';
|
||||
}
|
||||
};
|
||||
|
||||
const popupMenuDownFunc = function (popupId) {
|
||||
var pu = document.getElementById(popupId);
|
||||
if (pu != null) {
|
||||
pu.style.display = 'none';
|
||||
}
|
||||
};
|
||||
|
||||
export const drawText = function (elem, textData) {
|
||||
let prevTextHeight = 0;
|
||||
let textHeight = 0;
|
||||
@@ -329,6 +290,9 @@ const drawActorTypeParticipant = function (elem, actor, conf, isFooter) {
|
||||
|
||||
if (!isFooter) {
|
||||
actorCnt++;
|
||||
if (Object.keys(actor.links || {}).length && !conf.forceMenus) {
|
||||
g.attr('onclick', popupMenuToggle(`actor${actorCnt}_popup`)).attr('cursor', 'pointer');
|
||||
}
|
||||
g.append('line')
|
||||
.attr('id', 'actor' + actorCnt)
|
||||
.attr('x1', center)
|
||||
@@ -345,7 +309,6 @@ const drawActorTypeParticipant = function (elem, actor, conf, isFooter) {
|
||||
|
||||
if (actor.links != null) {
|
||||
g.attr('id', 'root-' + actorCnt);
|
||||
addPopupInteraction('#root-' + actorCnt, actorCnt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1053,8 +1016,6 @@ export default {
|
||||
insertClockIcon,
|
||||
getTextObj,
|
||||
getNoteRect,
|
||||
popupMenu,
|
||||
popdownMenu,
|
||||
fixLifeLineHeights,
|
||||
sanitizeUrl,
|
||||
};
|
||||
|
||||
@@ -16,11 +16,7 @@ import { teamMembers } from '../contributors';
|
||||
<p text-lg max-w-200 text-center leading-7>
|
||||
<Contributors />
|
||||
<br />
|
||||
<a
|
||||
href="https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE"
|
||||
rel="noopener noreferrer"
|
||||
>Join the community</a
|
||||
>
|
||||
<a href="https://discord.gg/wwtabKgp8y" rel="noopener noreferrer">Join the community</a>
|
||||
and get involved!
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -55,8 +55,8 @@ export default defineConfig({
|
||||
socialLinks: [
|
||||
{ icon: 'github', link: 'https://github.com/mermaid-js/mermaid' },
|
||||
{
|
||||
icon: 'slack',
|
||||
link: 'https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE',
|
||||
icon: 'discord',
|
||||
link: 'https://discord.gg/wwtabKgp8y',
|
||||
},
|
||||
{
|
||||
icon: {
|
||||
|
||||
@@ -10,7 +10,7 @@ We aim to reply within three working days, probably much sooner.
|
||||
|
||||
You should expect a close collaboration as we work to resolve the issue you have reported. Please reach out to <security@mermaid.live> again if you do not receive prompt attention and regular updates.
|
||||
|
||||
You may also reach out to the team via our public Slack chat channels; however, please make sure to e-mail <security@mermaid.live> when reporting an issue, and avoid revealing information about vulnerabilities in public as that could that could put users at risk.
|
||||
You may also reach out to the team via our public Discord chat channels; however, please make sure to e-mail <security@mermaid.live> when reporting an issue, and avoid revealing information about vulnerabilities in public as that could that could put users at risk.
|
||||
|
||||
## Best practices
|
||||
|
||||
|
||||
@@ -22,50 +22,49 @@ To add an integration to this list, see the [Integrations - create page](./integ
|
||||
|
||||
### Productivity tools
|
||||
|
||||
- [GitHub](https://github.com) ✅
|
||||
- [Using code blocks](https://github.blog/2022-02-14-include-diagrams-markdown-files-mermaid/) ✅
|
||||
- [GitHub action: Compile mermaid to image](https://github.com/neenjaw/compile-mermaid-markdown-action)
|
||||
- [svg-generator](https://github.com/SimonKenyonShepard/mermaidjs-github-svg-generator)
|
||||
- [GitHub Writer](https://github.com/ckeditor/github-writer)
|
||||
- [GitLab](https://docs.gitlab.com/ee/user/markdown.html#diagrams-and-flowcharts) ✅
|
||||
- [Gitea](https://gitea.io) ✅
|
||||
- [Azure Devops](https://docs.microsoft.com/en-us/azure/devops/project/wiki/wiki-markdown-guidance?view=azure-devops#add-mermaid-diagrams-to-a-wiki-page) ✅
|
||||
- [Tuleap](https://docs.tuleap.org/user-guide/writing-in-tuleap.html#graphs) ✅
|
||||
- [Mermaid Flow Visual Editor](https://www.mermaidflow.app) ✅
|
||||
- [Deepdwn](https://billiam.itch.io/deepdwn) ✅
|
||||
- [Joplin](https://joplinapp.org) ✅
|
||||
- [Slab](https://slab.com) ✅
|
||||
- [Swimm](https://swimm.io) ✅
|
||||
- [Notion](https://notion.so) ✅
|
||||
- [Observable](https://observablehq.com/@observablehq/mermaid) ✅
|
||||
- [Obsidian](https://help.obsidian.md/Editing+and+formatting/Advanced+formatting+syntax#Diagram) ✅
|
||||
- [NotesHub](https://noteshub.app) ✅
|
||||
- [GitBook](https://gitbook.com)
|
||||
- [Mermaid Plugin](https://github.com/JozoVilcek/gitbook-plugin-mermaid)
|
||||
- [Markdown with Mermaid CLI](https://github.com/miao1007/gitbook-plugin-mermaid-cli)
|
||||
- [Mermaid plugin for GitBook](https://github.com/wwformat/gitbook-plugin-mermaid-pdf)
|
||||
- [LiveBook](https://livebook.dev) ✅
|
||||
- [Atlassian Products](https://www.atlassian.com)
|
||||
- [Mermaid for Confluence](https://marketplace.atlassian.com/apps/1224722/mermaid-for-confluence?hosting=cloud&tab=overview)
|
||||
- [Mermaid Integration for Confluence](https://marketplace.atlassian.com/apps/1222792/mermaid-integration-for-confluence?hosting=cloud&tab=overview)
|
||||
- [Mermaid Diagrams for Confluence](https://marketplace.atlassian.com/apps/1226945/mermaid-diagrams-for-confluence?hosting=cloud&tab=overview)
|
||||
- [Mermaid Macro for Confluence](https://marketplace.atlassian.com/apps/1231150/mermaid-macro-for-confluence?hosting=cloud&tab=overview)
|
||||
- [EliteSoft Mermaid Charts and Diagrams](https://marketplace.atlassian.com/apps/1227286/elitesoft-mermaid-charts-and-diagrams?hosting=cloud&tab=overview)
|
||||
- [Mermaid for Jira Cloud - Draw UML diagrams easily](https://marketplace.atlassian.com/apps/1223053/mermaid-for-jira-cloud-draw-uml-diagrams-easily?hosting=cloud&tab=overview)
|
||||
- [Mermaid Charts & Diagrams for Confluence](https://marketplace.atlassian.com/apps/1222572/)
|
||||
- [Mermaid Charts & Diagrams for Jira](https://marketplace.atlassian.com/apps/1224537/)
|
||||
- [Mermaid Diagrams for Confluence](https://marketplace.atlassian.com/apps/1226945/mermaid-diagrams-for-confluence?hosting=cloud&tab=overview)
|
||||
- [Mermaid Live Editor for Confluence Cloud](https://marketplace.atlassian.com/apps/1231571/mermaid-live-editor-for-confluence?hosting=cloud&tab=overview)
|
||||
- [Mermaid Macro for Confluence](https://marketplace.atlassian.com/apps/1231150/mermaid-macro-for-confluence?hosting=cloud&tab=overview)
|
||||
- [Mermaid Plugin for Confluence](https://marketplace.atlassian.com/apps/1214124/mermaid-plugin-for-confluence?hosting=server&tab=overview)
|
||||
- [CloudScript.io Addon](https://marketplace.atlassian.com/apps/1219878/cloudscript-io-mermaid-addon?hosting=cloud&tab=overview)
|
||||
- [EliteSoft Mermaid Charts and Diagrams](https://marketplace.atlassian.com/apps/1227286/elitesoft-mermaid-charts-and-diagrams?hosting=cloud&tab=overview)
|
||||
- [Auto convert diagrams in Jira](https://github.com/coddingtonbear/jirafs-mermaid)
|
||||
- [Mermaid Charts & Diagrams for Jira](https://marketplace.atlassian.com/apps/1224537/)
|
||||
- [Mermaid for Jira Cloud - Draw UML diagrams easily](https://marketplace.atlassian.com/apps/1223053/mermaid-for-jira-cloud-draw-uml-diagrams-easily?hosting=cloud&tab=overview)
|
||||
- [CloudScript.io Mermaid Addon](https://marketplace.atlassian.com/apps/1219878/cloudscript-io-mermaid-addon?hosting=cloud&tab=overview)
|
||||
- [Azure Devops](https://learn.microsoft.com/en-us/azure/devops/project/wiki/markdown-guidance?view=azure-devops#add-mermaid-diagrams-to-a-wiki-page) ✅
|
||||
- [Deepdwn](https://billiam.itch.io/deepdwn) ✅
|
||||
- [GitBook](https://gitbook.com)
|
||||
- [Mermaid Plugin](https://github.com/JozoVilcek/gitbook-plugin-mermaid)
|
||||
- [Mermaid plugin for GitBook](https://github.com/wwformat/gitbook-plugin-mermaid-pdf)
|
||||
- [Markdown with Mermaid CLI](https://github.com/miao1007/gitbook-plugin-mermaid-cli)
|
||||
- [Gitea](https://gitea.io) ✅
|
||||
- [GitHub](https://github.com) ✅
|
||||
- [Using code blocks](https://github.blog/2022-02-14-include-diagrams-markdown-files-mermaid/) ✅
|
||||
- [GitHub action: Compile mermaid to image](https://github.com/neenjaw/compile-mermaid-markdown-action)
|
||||
- [GitHub Writer](https://github.com/ckeditor/github-writer)
|
||||
- [SVG diagram generator](https://github.com/SimonKenyonShepard/mermaidjs-github-svg-generator)
|
||||
- [GitLab](https://docs.gitlab.com/ee/user/markdown.html#diagrams-and-flowcharts) ✅
|
||||
- [Mermaid Plugin for JetBrains IDEs](https://plugins.jetbrains.com/plugin/20146-mermaid)
|
||||
- [Joplin](https://joplinapp.org) ✅
|
||||
- [LiveBook](https://livebook.dev) ✅
|
||||
- [Tuleap](https://docs.tuleap.org/user-guide/writing-in-tuleap.html#graphs) ✅
|
||||
- [Mermaid Flow Visual Editor](https://www.mermaidflow.app) ✅
|
||||
- [Mermerd](https://github.com/KarnerTh/mermerd)
|
||||
- [Slab](https://slab.com) ✅
|
||||
- [Swimm](https://docs.swimm.io/features/diagrams-and-charts/#mermaid--swimm--up-to-date-diagrams-) ✅
|
||||
- [NotesHub](https://noteshub.app) ✅
|
||||
- [Notion](https://notion.so) ✅
|
||||
- [Observable](https://observablehq.com/@observablehq/mermaid) ✅
|
||||
- [Obsidian](https://help.obsidian.md/Editing+and+formatting/Advanced+formatting+syntax#Diagram) ✅
|
||||
- [Redmine](https://redmine.org)
|
||||
- [Mermaid Macro](https://www.redmine.org/plugins/redmine_mermaid_macro)
|
||||
- [Markdown for mermaid plugin](https://github.com/jamieh-mongolian/markdown-for-mermaid-plugin)
|
||||
- [redmine-mermaid](https://github.com/styz/redmine_mermaid)
|
||||
- [markdown-for-mermaid-plugin](https://github.com/jamieh-mongolian/markdown-for-mermaid-plugin)
|
||||
- [Mermaid Plugin for JetBrains IDEs](https://plugins.jetbrains.com/plugin/20146-mermaid)
|
||||
- [mermerd](https://github.com/KarnerTh/mermerd)
|
||||
- Visual Studio Code [Polyglot Interactive Notebooks](https://github.com/dotnet/interactive#net-interactive)
|
||||
- Codemia [a tool to practice system design problems](https://codemia.io)
|
||||
|
||||
### CRM/ERP
|
||||
|
||||
@@ -77,139 +76,137 @@ Customer Relationship Management/Enterprise Resource Planning
|
||||
|
||||
Blogging frameworks and platforms
|
||||
|
||||
- [WordPress](https://wordpress.org)
|
||||
- [WordPress Markdown Editor](https://wordpress.org/plugins/wp-githuber-md)
|
||||
- [WP-ReliableMD](https://wordpress.org/plugins/wp-reliablemd/)
|
||||
- [Hexo](https://hexo.io)
|
||||
- [hexo-filter-mermaid-diagrams](https://github.com/webappdevelp/hexo-filter-mermaid-diagrams)
|
||||
- [hexo-tag-mermaid](https://github.com/JameChou/hexo-tag-mermaid)
|
||||
- [hexo-mermaid-diagrams](https://github.com/mslxl/hexo-mermaid-diagrams)
|
||||
- [Nextra](https://nextra.site/)
|
||||
- [Mermaid](https://nextra.site/docs/guide/mermaid)
|
||||
- [WordPress](https://wordpress.org)
|
||||
- [WordPress Markdown Editor](https://wordpress.org/plugins/wp-githuber-md)
|
||||
- [WP-ReliableMD](https://wordpress.org/plugins/wp-reliablemd/)
|
||||
|
||||
### CMS/ECM
|
||||
|
||||
Content Management Systems/Enterprise Content Management
|
||||
|
||||
- [Grav CMS](https://getgrav.org/)
|
||||
- [Mermaid Diagrams Plugin](https://github.com/DanielFlaum/grav-plugin-mermaid-diagrams)
|
||||
- [GitLab Markdown Adapter](https://github.com/Goutte/grav-plugin-gitlab-markdown-adapter)
|
||||
- [VitePress](https://vitepress.vuejs.org/)
|
||||
- [Plugin for Mermaid.js](https://emersonbottero.github.io/vitepress-plugin-mermaid/)
|
||||
- [VuePress](https://vuepress.vuejs.org/)
|
||||
- [Plugin for Mermaid.js](https://github.com/eFrane/vuepress-plugin-mermaidjs)
|
||||
- [Grav CMS](https://getgrav.org/)
|
||||
- [Mermaid Diagrams](https://github.com/DanielFlaum/grav-plugin-mermaid-diagrams)
|
||||
- [GitLab Markdown Adapter](https://github.com/Goutte/grav-plugin-gitlab-markdown-adapter)
|
||||
|
||||
### Communication
|
||||
|
||||
Communication tools and platforms
|
||||
|
||||
- [Discourse](https://discourse.org)
|
||||
- [Mermaid Plugin](https://github.com/pnewell/discourse-mermaid), [And](https://github.com/unfoldingWord-dev/discourse-mermaid)
|
||||
- [Mermaid Plugin](https://github.com/pnewell/discourse-mermaid)
|
||||
- [Mattermost](https://mattermost.com/)
|
||||
- [Mermaid Plugin](https://github.com/SpikeTings/Mermaid)
|
||||
- [NodeBB](https://nodebb.org)
|
||||
- [Mermaid Parser Plugin](https://www.npmjs.com/package/nodebb-plugin-mermaid)
|
||||
- [phpBB](https://phpbb.com)
|
||||
- [phpbb-ext-mermaid](https://github.com/AlfredoRamos/phpbb-ext-mermaid)
|
||||
- [NodeBB](https://nodebb.org)
|
||||
- [Mermaid Plugin](https://www.npmjs.com/package/nodebb-plugin-mermaid)
|
||||
- [Slack](https://slack.com)
|
||||
- [Mermaid for Slack](https://github.com/JackuB/mermaid-for-slack)
|
||||
- [Mermaid Preview](https://github.com/JackuB/mermaid-for-slack)
|
||||
|
||||
### Wikis
|
||||
|
||||
- [PmWiki](https://www.pmwiki.org)
|
||||
- [MermaidJs Cookbook recipe](https://www.pmwiki.org/wiki/Cookbook/MermaidJs)
|
||||
- [MediaWiki](https://www.mediawiki.org)
|
||||
- [Mermaid Extension](https://www.mediawiki.org/wiki/Extension:Mermaid)
|
||||
- [Flex Diagrams Extension](https://www.mediawiki.org/wiki/Extension:Flex_Diagrams)
|
||||
- [Semantic Media Wiki](https://semantic-mediawiki.org)
|
||||
- [Mermaid Plugin](https://github.com/SemanticMediaWiki/Mermaid)
|
||||
- [DokuWiki](https://dokuwiki.org)
|
||||
- [ComboStrap](https://combostrap.com/mermaid)
|
||||
- [Mermaid Plugin](https://www.dokuwiki.org/plugin:mermaid)
|
||||
- [Foswiki](https://foswiki.org)
|
||||
- [Mermaid Plugin](https://foswiki.org/Extensions/MermaidPlugin)
|
||||
- [DokuWiki](https://dokuwiki.org)
|
||||
- [Mermaid Plugin](https://www.dokuwiki.org/plugin:mermaid)
|
||||
- [ComboStrap](https://combostrap.com/mermaid)
|
||||
- [MediaWiki](https://www.mediawiki.org)
|
||||
- [Flex Diagrams Extension](https://www.mediawiki.org/wiki/Extension:Flex_Diagrams)
|
||||
- [Mermaid Extension](https://www.mediawiki.org/wiki/Extension:Mermaid)
|
||||
- [PmWiki](https://www.pmwiki.org)
|
||||
- [MermaidJs Cookbook recipe](https://www.pmwiki.org/wiki/Cookbook/MermaidJs)
|
||||
- [Semantic Media Wiki](https://semantic-mediawiki.org)
|
||||
- [Mermaid Plugin](https://github.com/SemanticMediaWiki/Mermaid)
|
||||
- [TiddlyWiki](https://tiddlywiki.com/)
|
||||
- [mermaid-tw5: full js library](https://github.com/efurlanm/mermaid-tw5)
|
||||
- [tw5-mermaid: wrapper for Mermaid Live](https://github.com/jasonmhoule/tw5-mermaid)
|
||||
- [mermaid-tw5: wrapper for Mermaid Live](https://github.com/efurlanm/mermaid-tw5)
|
||||
- [tw5-mermaid: plugin for managing Mermaid.js tiddlers](https://github.com/jasonmhoule/tw5-mermaid)
|
||||
|
||||
### Editor Plugins
|
||||
|
||||
- [VS Code](https://code.visualstudio.com/)
|
||||
- [Markdown Preview Mermaid Support](https://marketplace.visualstudio.com/items?itemName=bierner.markdown-mermaid)
|
||||
- [Mermaid Preview](https://marketplace.visualstudio.com/items?itemName=vstirbu.vscode-mermaid-preview)
|
||||
- [Markdown Preview Enhanced](https://marketplace.visualstudio.com/items?itemName=shd101wyy.markdown-preview-enhanced)
|
||||
- [Mermaid Markdown Syntax Highlighting](https://marketplace.visualstudio.com/items?itemName=bpruitt-goddard.mermaid-markdown-syntax-highlighting)
|
||||
- [Mermaid Editor](https://marketplace.visualstudio.com/items?itemName=tomoyukim.vscode-mermaid-editor)
|
||||
- [Mermaid Export](https://marketplace.visualstudio.com/items?itemName=Gruntfuggly.mermaid-export)
|
||||
- [Markdown PDF](https://marketplace.visualstudio.com/items?itemName=yzane.markdown-pdf)
|
||||
- [Preview](https://marketplace.visualstudio.com/items?itemName=searKing.preview-vscode)
|
||||
- [Preview Sequence Diagrams](https://marketplace.visualstudio.com/items?itemName=arichika.previewseqdiag-vscode)
|
||||
- Atom _(Atom has been [archived.](https://github.blog/2022-06-08-sunsetting-atom/))_
|
||||
- [Markdown Preview Enhanced](https://github.com/shd101wyy/markdown-preview-enhanced)
|
||||
- [Atom Mermaid](https://github.com/y-takey/atom-mermaid)
|
||||
- [Language Mermaid Syntax Highlighter](https://github.com/ytisf/language-mermaid)
|
||||
- [Astah](https://astah.net)
|
||||
- [Export to Mermaid](https://github.com/Avens666/Astah_Jude_UML_export_to_Markdown-mermaid-Plantuml-)
|
||||
- [Brackets](https://brackets.io/)
|
||||
- [Mermaid Preview](https://github.com/AlanHohn/mermaid-preview)
|
||||
- [CKEditor](https://github.com/ckeditor/ckeditor5)
|
||||
- [CKEditor 5 Mermaid plugin](https://github.com/ckeditor/ckeditor5-mermaid)
|
||||
- [Draw.io](https://draw.io)
|
||||
- [Mermaid Plugin](https://github.com/nopeslide/drawio_mermaid_plugin)
|
||||
- [GNU Emacs](https://www.gnu.org/software/emacs/)
|
||||
- [Major mode for .mmd files](https://github.com/abrochard/mermaid-mode)
|
||||
- [Org-Mode integration](https://github.com/arnm/ob-mermaid)
|
||||
- [GNU Nano](https://www.nano-editor.org/)
|
||||
- [Nano Mermaid](https://github.com/Yash-Singh1/nano-mermaid)
|
||||
- [Google docs](https://docs.google.com/)
|
||||
- [Mermaid plugin for google docs](https://workspace.google.com/marketplace/app/mermaid/636321283856)
|
||||
- [Inkdrop](https://www.inkdrop.app)
|
||||
- [Mermaid Plugin](https://github.com/inkdropapp/inkdrop-mermaid)
|
||||
- [Light Table](http://lighttable.com/)
|
||||
- [Mermaid Plugin](https://github.com/cldwalker/Mermaid)
|
||||
- [Markdown-It](https://github.com/markdown-it/markdown-it)
|
||||
- [Textual UML Parser](https://github.com/manastalukdar/markdown-it-textual-uml)
|
||||
- [Mermaid Plugin](https://github.com/tylingsoft/markdown-it-mermaid)
|
||||
- [md-it-mermaid](https://github.com/iamcco/md-it-mermaid)
|
||||
- [markdown-it-mermaid-less](https://github.com/searKing/markdown-it-mermaid-less)
|
||||
- Atom _(Atom has been [archived.](https://github.blog/2022-06-08-sunsetting-atom/))_
|
||||
- [Markdown Preview Enhanced](https://github.com/shd101wyy/markdown-preview-enhanced)
|
||||
- [Atom Mermaid](https://github.com/y-takey/atom-mermaid)
|
||||
- [Language Mermaid Syntax Highlighter](https://github.com/ytisf/language-mermaid)
|
||||
- [Podlite](https://github.com/zag/podlite-desktop)
|
||||
- [=Diagram block](https://github.com/zag/podlite/tree/main/packages/podlite-diagrams)
|
||||
- [Standard Notes](https://standardnotes.com/)
|
||||
- [Mermaid Extension](https://github.com/nienow/sn-mermaid)
|
||||
- [Sublime Text 3](https://sublimetext.com)
|
||||
- [Mermaid Package](https://packagecontrol.io/packages/Mermaid)
|
||||
- [Astah](https://astah.net)
|
||||
- [Export to Mermaid](https://github.com/Avens666/Astah_Jude_UML_export_to_Markdown-mermaid-Plantuml-)
|
||||
- [Light Table](http://lighttable.com/)
|
||||
- [Mermaid Plugin](https://github.com/cldwalker/Mermaid)
|
||||
- [Draw.io](https://draw.io) - [Plugin](https://github.com/nopeslide/drawio_mermaid_plugin)
|
||||
- [Inkdrop](https://www.inkdrop.app) - [Plugin](https://github.com/inkdropapp/inkdrop-mermaid)
|
||||
- [VS Code](https://code.visualstudio.com/)
|
||||
- [Mermaid Editor](https://marketplace.visualstudio.com/items?itemName=tomoyukim.vscode-mermaid-editor)
|
||||
- [Mermaid Export](https://marketplace.visualstudio.com/items?itemName=Gruntfuggly.mermaid-export)
|
||||
- [Markdown PDF](https://marketplace.visualstudio.com/items?itemName=yzane.markdown-pdf)
|
||||
- [Markdown Preview Mermaid Support](https://marketplace.visualstudio.com/items?itemName=bierner.markdown-mermaid)
|
||||
- [Markdown Preview Enhanced](https://marketplace.visualstudio.com/items?itemName=shd101wyy.markdown-preview-enhanced)
|
||||
- [Mermaid Preview](https://marketplace.visualstudio.com/items?itemName=vstirbu.vscode-mermaid-preview)
|
||||
- [Preview](https://marketplace.visualstudio.com/items?itemName=searKing.preview-vscode)
|
||||
- [Preview Sequence Diagrams](https://marketplace.visualstudio.com/items?itemName=arichika.previewseqdiag-vscode)
|
||||
- [Mermaid Markdown Syntax Highlighting](https://marketplace.visualstudio.com/items?itemName=bpruitt-goddard.mermaid-markdown-syntax-highlighting)
|
||||
- [Vim](https://www.vim.org)
|
||||
- [Official Vim Syntax and ftplugin](https://github.com/craigmac/vim-mermaid)
|
||||
- [Vim Diagram Syntax](https://github.com/zhaozg/vim-diagram)
|
||||
- [GNU Emacs](https://www.gnu.org/software/emacs/)
|
||||
- [Major mode for .mmd files](https://github.com/abrochard/mermaid-mode)
|
||||
- [Org-Mode integration](https://github.com/arnm/ob-mermaid)
|
||||
- [Brackets](https://brackets.io/)
|
||||
- [Mermaid Preview](https://github.com/AlanHohn/mermaid-preview)
|
||||
- [Iodide](https://github.com/iodide-project/iodide)
|
||||
- [iodide-mermaid-plugin](https://github.com/iodide-project/iodide-mermaid-plugin)
|
||||
- [Google docs](https://docs.google.com/)
|
||||
- [Mermaid plugin for google docs](https://workspace.google.com/marketplace/app/mermaid/636321283856)
|
||||
- [Podlite](https://github.com/zag/podlite-desktop)
|
||||
- [Named block =Diagram](https://github.com/zag/podlite/tree/main/packages/podlite-diagrams)
|
||||
- [GNU Nano](https://www.nano-editor.org/)
|
||||
- [Nano Mermaid](https://github.com/Yash-Singh1/nano-mermaid)
|
||||
- [CKEditor](https://github.com/ckeditor/ckeditor5)
|
||||
- [CKEditor 5 Mermaid plugin](https://github.com/ckeditor/ckeditor5-mermaid)
|
||||
- [Standard Notes](https://standardnotes.com/)
|
||||
- [sn-mermaid](https://github.com/nienow/sn-mermaid)
|
||||
- [Official Vim Syntax and ft plugin](https://github.com/craigmac/vim-mermaid)
|
||||
|
||||
### Document Generation
|
||||
|
||||
- [Codedoc](https://codedoc.cc/)
|
||||
- [codedoc-mermaid-plugin](https://www.npmjs.com/package/codedoc-mermaid-plugin)
|
||||
- [Docsy Hugo Theme](https://www.docsy.dev/docs/adding-content/lookandfeel/#diagrams-with-mermaid) ✅
|
||||
- [Docusaurus](https://docusaurus.io/docs/markdown-features/diagrams) ✅
|
||||
- [Unison programming language](https://www.unison-lang.org/docs/usage-topics/documentation/) ✅
|
||||
- [Swimm - Up-to-date diagrams with Swimm, the knowledge management tool for code](https://docs.swimm.io/features/diagrams-and-charts/#mermaid--swimm--up-to-date-diagrams-)
|
||||
- [Sphinx](https://www.sphinx-doc.org/en/master/)
|
||||
- [sphinxcontrib-mermaid](https://github.com/mgaitan/sphinxcontrib-mermaid)
|
||||
- [remark](https://remark.js.org/)
|
||||
- [remark-mermaidjs](https://github.com/remcohaszing/remark-mermaidjs)
|
||||
- [rehype](https://github.com/rehypejs/rehype)
|
||||
- [rehype-mermaid](https://github.com/remcohaszing/rehype-mermaid)
|
||||
- [Gatsby](https://www.gatsbyjs.com/)
|
||||
- [gatsby-remark-mermaid](https://github.com/remcohaszing/gatsby-remark-mermaid)
|
||||
- [JSDoc](https://jsdoc.app/)
|
||||
- [jsdoc-mermaid](https://github.com/Jellyvision/jsdoc-mermaid)
|
||||
- [mdBook](https://rust-lang.github.io/mdBook/index.html)
|
||||
- [mdbook-mermaid](https://github.com/badboy/mdbook-mermaid)
|
||||
- [MkDocs](https://www.mkdocs.org)
|
||||
- [mkdocs-mermaid2-plugin](https://github.com/fralau/mkdocs-mermaid2-plugin)
|
||||
- [mkdocs-material](https://github.com/squidfunk/mkdocs-material), check the [docs](https://squidfunk.github.io/mkdocs-material/reference/diagrams/)
|
||||
- [Quarto](https://quarto.org/)
|
||||
- [rehype](https://github.com/rehypejs/rehype)
|
||||
- [rehype-mermaid](https://github.com/remcohaszing/rehype-mermaid)
|
||||
- [remark](https://remark.js.org/)
|
||||
- [remark-mermaidjs](https://github.com/remcohaszing/remark-mermaidjs)
|
||||
- [Sphinx](https://www.sphinx-doc.org/en/master/)
|
||||
- [sphinxcontrib-mermaid](https://github.com/mgaitan/sphinxcontrib-mermaid)
|
||||
- [Type Doc](https://typedoc.org/)
|
||||
- [typedoc-plugin-mermaid](https://www.npmjs.com/package/typedoc-plugin-mermaid)
|
||||
- [Docsy Hugo Theme](https://www.docsy.dev/docs/adding-content/lookandfeel/#diagrams-with-mermaid) ✅
|
||||
- [Codedoc](https://codedoc.cc/)
|
||||
- [codedoc-mermaid-plugin](https://www.npmjs.com/package/codedoc-mermaid-plugin)
|
||||
- [mdbook](https://rust-lang.github.io/mdBook/index.html)
|
||||
- [mdbook-mermaid](https://github.com/badboy/mdbook-mermaid)
|
||||
- [Quarto](https://quarto.org/)
|
||||
- [Typora](https://typora.io/) ✅
|
||||
- [See docs](https://support.typora.io/Draw-Diagrams-With-Markdown/#mermaid)
|
||||
- [Typora](https://support.typora.io/Draw-Diagrams-With-Markdown/#mermaid) ✅
|
||||
- [Unison programming language](https://www.unison-lang.org/docs/usage-topics/documentation/) ✅
|
||||
|
||||
### Browser Extensions
|
||||
|
||||
@@ -220,7 +217,7 @@ Communication tools and platforms
|
||||
| Diagram Tab | - | - | - | - | [🐙🔗](https://github.com/khafast/diagramtab) |
|
||||
| Markdown Diagrams | [🎡🔗](https://chrome.google.com/webstore/detail/markdown-diagrams/pmoglnmodacnbbofbgcagndelmgaclel/) | [🦊🔗](https://addons.mozilla.org/en-US/firefox/addon/markdown-diagrams/) | [🔴🔗](https://addons.opera.com/en/extensions/details/markdown-diagrams/) | [🌀🔗](https://microsoftedge.microsoft.com/addons/detail/markdown-diagrams/hceenoomhhdkjjijnmlclkpenkapfihe) | [🐙🔗](https://github.com/marcozaccari/markdown-diagrams-browser-extension/tree/master/doc/examples) |
|
||||
| Markdown Viewer | - | [🦊🔗](https://addons.mozilla.org/en-US/firefox/addon/markdown-viewer-chrome/) | - | - | [🐙🔗](https://github.com/simov/markdown-viewer) |
|
||||
| Extensions for Mermaid | - | [🦊🔗](https://addons.mozilla.org/en-US/firefox/addon/markdown-viewer-chrome/) | [🔴🔗](https://addons.opera.com/en/extensions/details/extensions-for-mermaid/) | - | [🐙🔗](https://github.com/Stefan-S/mermaid-extension) |
|
||||
| Extensions for Mermaid | - | - | [🔴🔗](https://addons.opera.com/en/extensions/details/extensions-for-mermaid/) | - | [🐙🔗](https://github.com/Stefan-S/mermaid-extension) |
|
||||
| Chrome Diagrammer | [🎡🔗](https://chrome.google.com/webstore/detail/chrome-diagrammer/bkpbgjmkomfoakfklcjeoegkklgjnnpk) | - | - | - | - |
|
||||
| Mermaid Diagrams | [🎡🔗](https://chrome.google.com/webstore/detail/mermaid-diagrams/phfcghedmopjadpojhmmaffjmfiakfil) | - | - | - | - |
|
||||
| Monkeys | [🎡🔗](https://chrome.google.com/webstore/detail/monkeys-mermaid-for-githu/cplfdpoajbclbgphaphphcldamfkjlgi) | - | - | - | - |
|
||||
@@ -228,19 +225,23 @@ Communication tools and platforms
|
||||
|
||||
### Other
|
||||
|
||||
- [Bisheng](https://www.npmjs.com/package/bisheng)
|
||||
- [bisheng-plugin-mermaid](https://github.com/yct21/bisheng-plugin-mermaid)
|
||||
- [Codemia: A tool to practice system design problems](https://codemia.io) ✅
|
||||
- [ExDoc](https://github.com/elixir-lang/ex_doc)
|
||||
- [Rendering Mermaid graphs](https://github.com/elixir-lang/ex_doc#rendering-mermaid-graphs)
|
||||
- [Jekyll](https://jekyllrb.com/)
|
||||
- [jekyll-mermaid](https://rubygems.org/gems/jekyll-mermaid)
|
||||
- [jekyll-mermaid-diagrams](https://github.com/fuzhibo/jekyll-mermaid-diagrams)
|
||||
- [mermaid-isomorphic](https://github.com/remcohaszing/mermaid-isomorphic)
|
||||
- [mermaid-server: Generate diagrams using a HTTP request](https://github.com/TomWright/mermaid-server)
|
||||
- [NiceGUI: Let any browser be the frontend of your Python code](https://nicegui.io) ✅
|
||||
- [ui.mermaid(...)](https://nicegui.io/documentation/mermaid)
|
||||
- [Reveal.js](https://github.com/hakimel/reveal.js)
|
||||
- [reveal.js-mermaid-plugin](https://github.com/ludwick/reveal.js-mermaid-plugin)
|
||||
- [Bisheng](https://www.npmjs.com/package/bisheng)
|
||||
- [bisheng-plugin-mermaid](https://github.com/yct21/bisheng-plugin-mermaid)
|
||||
- [Reveal CK](https://github.com/jedcn/reveal-ck)
|
||||
- [reveal-ck-mermaid-plugin](https://github.com/tmtm/reveal-ck-mermaid-plugin)
|
||||
- [mermaid-isomorphic](https://github.com/remcohaszing/mermaid-isomorphic)
|
||||
- [mermaid-server: Generate diagrams using a HTTP request](https://github.com/TomWright/mermaid-server)
|
||||
- [ExDoc](https://github.com/elixir-lang/ex_doc)
|
||||
- [Rendering Mermaid graphs](https://github.com/elixir-lang/ex_doc#rendering-mermaid-graphs)
|
||||
- [NiceGUI: Let any browser be the frontend of your Python code](https://nicegui.io) ✅
|
||||
- [ui.mermaid(...)](https://nicegui.io/documentation/section_text_elements#markdown_element)
|
||||
- [ui.markdown(..., extras=['mermaid'])](https://nicegui.io/documentation/section_text_elements#mermaid_diagrams)
|
||||
|
||||
@@ -16,9 +16,9 @@ Currently pending [IANA](https://www.iana.org/) recognition.
|
||||
|
||||
## Showcase
|
||||
|
||||
### Mermaid Slack workspace
|
||||
### Mermaid Discord workspace
|
||||
|
||||
We would love to see what you create with Mermaid. Please share your creations with us in our [Slack](https://join.slack.com/t/mermaid-talk/shared_invite/zt-22p2r8p9y-qiyP1H38GjFQ6S6jbBkOxQ) workspace [#community-showcase](https://mermaid-talk.slack.com/archives/C05NK37LT40) channel.
|
||||
We would love to see what you create with Mermaid. Please share your creations with us in our [Discord](https://discord.gg/wwtabKgp8y) server [#showcase](https://discord.com/channels/1079455296289788015/1079502635054399649) channel.
|
||||
|
||||
### Add to Mermaid Ecosystem
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ It is a JavaScript based diagramming and charting tool that renders Markdown-ins
|
||||
[](https://coveralls.io/github/mermaid-js/mermaid?branch=master)
|
||||
[](https://www.jsdelivr.com/package/npm/mermaid)
|
||||
[](https://www.npmjs.com/package/mermaid)
|
||||
[](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE)
|
||||
[](https://discord.gg/wwtabKgp8y)
|
||||
[](https://twitter.com/mermaidjs_)
|
||||
|
||||
</div>
|
||||
|
||||
@@ -775,7 +775,19 @@ flowchart TD
|
||||
B-->E(A fa:fa-camera-retro perhaps?)
|
||||
```
|
||||
|
||||
Mermaid is compatible with Font Awesome up to version 5, Free icons only. Check that the icons you use are from the [supported set of icons](https://fontawesome.com/v5/search?o=r&m=free).
|
||||
Mermaid supports Font Awesome if the CSS is included on the website.
|
||||
Mermaid does not have any restriction on the version of Font Awesome that can be used.
|
||||
|
||||
Please refer the [Official Font Awesome Documentation](https://fontawesome.com/start) on how to include it in your website.
|
||||
|
||||
Adding this snippet in the `<head>` would add support for Font Awesome v6.5.1
|
||||
|
||||
```html
|
||||
<link
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
```
|
||||
|
||||
## Graph declarations with spaces between vertices and link and without semicolon
|
||||
|
||||
|
||||
@@ -63,7 +63,30 @@ gantt
|
||||
Add another diagram to demo page :48h
|
||||
```
|
||||
|
||||
It is possible to set multiple dependencies separated by space:
|
||||
Tasks are by default sequential. A task start date defaults to the end date of the preceding task.
|
||||
|
||||
A colon, `:`, separates the task title from its metadata.
|
||||
Metadata items are separated by a comma, `,`. Valid tags are `active`, `done`, `crit`, and `milestone`. Tags are optional, but if used, they must be specified first.
|
||||
After processing the tags, the remaining metadata items are interpreted as follows:
|
||||
|
||||
1. If a single item is specified, it determines when the task ends. It can either be a specific date/time or a duration. If a duration is specified, it is added to the start date of the task to determine the end date of the task, taking into account any exclusions.
|
||||
2. If two items are specified, the last item is interpreted as in the previous case. The first item can either specify an explicit start date/time (in the format specified by `dateFormat`) or reference another task using `after <otherTaskID> [[otherTaskID2 [otherTaskID3]]...]`. In the latter case, the start date of the task will be set according to the latest end date of any referenced task.
|
||||
3. If three items are specified, the last two will be interpreted as in the previous case. The first item will denote the ID of the task, which can be referenced using the `later <taskID>` syntax.
|
||||
|
||||
| Metadata syntax | Start date | End date | ID |
|
||||
| ------------------------------------------ | --------------------------------------------------- | ------------------------------------------- | -------- |
|
||||
| `<taskID>, <startDate>, <endDate>` | `startdate` as interpreted using `dateformat` | `endDate` as interpreted using `dateformat` | `taskID` |
|
||||
| `<taskID>, <startDate>, <length>` | `startdate` as interpreted using `dateformat` | Start date + `length` | `taskID` |
|
||||
| `<taskID>, after <otherTaskId>, <endDate>` | End date of previously specified task `otherTaskID` | `endDate` as interpreted using `dateformat` | `taskID` |
|
||||
| `<taskID>, after <otherTaskId>, <length>` | End date of previously specified task `otherTaskID` | Start date + `length` | `taskID` |
|
||||
| `<startDate>, <endDate>` | `startdate` as interpreted using `dateformat` | `enddate` as interpreted using `dateformat` | n/a |
|
||||
| `<startDate>, <length>` | `startdate` as interpreted using `dateformat` | Start date + `length` | n/a |
|
||||
| `after <otherTaskID>, <endDate>` | End date of previously specified task `otherTaskID` | `enddate` as interpreted using `dateformat` | n/a |
|
||||
| `after <otherTaskID>, <length>` | End date of previously specified task `otherTaskID` | Start date + `length` | n/a |
|
||||
| `<endDate>` | End date of preceding task | `enddate` as interpreted using `dateformat` | n/a |
|
||||
| `<length>` | End date of preceding task | Start date + `length` | n/a |
|
||||
|
||||
For simplicity, the table does not show the use of multiple tasks listed with the `after` keyword. Here is an example of how to use it and how it's interpreted:
|
||||
|
||||
```mermaid-example
|
||||
gantt
|
||||
|
||||
@@ -112,11 +112,11 @@ timeline
|
||||
timeline
|
||||
title MermaidChart 2023 Timeline
|
||||
section 2023 Q1 <br> Release Personal Tier
|
||||
Buttet 1 : sub-point 1a : sub-point 1b
|
||||
Bullet 1 : sub-point 1a : sub-point 1b
|
||||
: sub-point 1c
|
||||
Bullet 2 : sub-point 2a : sub-point 2b
|
||||
section 2023 Q2 <br> Release XYZ Tier
|
||||
Buttet 3 : sub-point <br> 3a : sub-point 3b
|
||||
Bullet 3 : sub-point <br> 3a : sub-point 3b
|
||||
: sub-point 3c
|
||||
Bullet 4 : sub-point 4a : sub-point 4b
|
||||
```
|
||||
|
||||
@@ -786,6 +786,9 @@ $defs: # JSON Schema definition (maybe we should move these to a separate file)
|
||||
rotateCommitLabel:
|
||||
type: boolean
|
||||
default: true
|
||||
parallelCommits:
|
||||
type: boolean
|
||||
default: false
|
||||
# YAML anchor reference, don't use $ref since ajv doesn't load defaults
|
||||
arrowMarkerAbsolute: *arrowMarkerAbsolute
|
||||
|
||||
|
||||
@@ -925,3 +925,7 @@ export const encodeEntities = function (text: string): string {
|
||||
export const decodeEntities = function (text: string): string {
|
||||
return text.replace(/fl°°/g, '&#').replace(/fl°/g, '&').replace(/¶ß/g, ';');
|
||||
};
|
||||
|
||||
export const isString = (value: unknown): value is string => {
|
||||
return typeof value === 'string';
|
||||
};
|
||||
|
||||
20
patches/cytoscape@3.28.1.patch
Normal file
20
patches/cytoscape@3.28.1.patch
Normal file
@@ -0,0 +1,20 @@
|
||||
diff --git a/package.json b/package.json
|
||||
index f2f77fa79c99382b079f4051ed51eafe8d2379c8..0bfddf55394e86f3a386eb7ab681369d410bae07 100644
|
||||
--- a/package.json
|
||||
+++ b/package.json
|
||||
@@ -30,7 +30,15 @@
|
||||
"engines": {
|
||||
"node": ">=0.10"
|
||||
},
|
||||
+ "exports": {
|
||||
+ ".": {
|
||||
+ "import": "./dist/cytoscape.umd.js",
|
||||
+ "default": "./dist/cytoscape.cjs.js"
|
||||
+ },
|
||||
+ "./*": "./*"
|
||||
+ },
|
||||
"main": "dist/cytoscape.cjs.js",
|
||||
+ "module": "dist/cytoscape.umd.js",
|
||||
"unpkg": "dist/cytoscape.min.js",
|
||||
"jsdelivr": "dist/cytoscape.min.js",
|
||||
"scripts": {
|
||||
988
pnpm-lock.yaml
generated
988
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user