Merge branch 'develop' into feature/add-point-styling-quadrant-to-charts

This commit is contained in:
Sidharth Vinod
2024-03-23 22:59:54 +05:30
committed by GitHub
142 changed files with 4303 additions and 3117 deletions

View File

@@ -1,3 +0,0 @@
{
"extends": ["@commitlint/config-conventional"]
}

View File

@@ -14,7 +14,7 @@ module.exports = {
}, },
tsconfigRootDir: __dirname, tsconfigRootDir: __dirname,
sourceType: 'module', sourceType: 'module',
ecmaVersion: 2020, ecmaVersion: 2022,
allowAutomaticSingleRunInference: true, allowAutomaticSingleRunInference: true,
project: ['./tsconfig.eslint.json', './packages/*/tsconfig.json'], project: ['./tsconfig.eslint.json', './packages/*/tsconfig.json'],
parser: '@typescript-eslint/parser', parser: '@typescript-eslint/parser',
@@ -23,7 +23,7 @@ module.exports = {
'eslint:recommended', 'eslint:recommended',
'plugin:@typescript-eslint/recommended', 'plugin:@typescript-eslint/recommended',
'plugin:json/recommended', 'plugin:json/recommended',
'plugin:markdown/recommended', 'plugin:markdown/recommended-legacy',
'plugin:@cspell/recommended', 'plugin:@cspell/recommended',
'prettier', 'prettier',
], ],

View File

@@ -17,9 +17,19 @@ permissions:
contents: read contents: read
env: env:
# For PRs and MergeQueues, the target commit is used, and for push events, github.event.previous is used. # For PRs and MergeQueues, the target commit is used, and for push events to non-develop branches, github.event.previous is used if available. Otherwise, 'develop' is used.
targetHash: ${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha || (github.event.before == '0000000000000000000000000000000000000000' && 'develop' || github.event.before) }} targetHash: >-
${{
github.event.pull_request.base.sha ||
github.event.merge_group.base_sha ||
(
(
(github.event_name == 'push' && github.ref == 'refs/heads/develop') ||
github.event.before == '0000000000000000000000000000000000000000'
) && 'develop'
) ||
github.event.before
}}
jobs: jobs:
cache: cache:
runs-on: ubuntu-latest runs-on: ubuntu-latest

View File

@@ -1,4 +0,0 @@
#!/bin/sh
# . "$(dirname "$0")/_/husky.sh"
# npx --no-install commitlint --edit $1

View File

@@ -1,4 +1,4 @@
#!/bin/sh #!/bin/sh
. "$(dirname "$0")/_/husky.sh" . "$(dirname "$0")/_/husky.sh"
pnpm run pre-commit NODE_OPTIONS="--max_old_space_size=8192" pnpm run pre-commit

View File

@@ -3,5 +3,6 @@
"printWidth": 100, "printWidth": 100,
"singleQuote": true, "singleQuote": true,
"useTabs": false, "useTabs": false,
"tabWidth": 2 "tabWidth": 2,
"trailingComma": "es5"
} }

View File

@@ -118,11 +118,53 @@ describe('Configuration', () => {
it('should not taint the initial configuration when using multiple directives', () => { it('should not taint the initial configuration when using multiple directives', () => {
const url = 'http://localhost:9000/regression/issue-1874.html'; const url = 'http://localhost:9000/regression/issue-1874.html';
cy.visit(url); cy.visit(url);
cy.window().should('have.property', 'rendered', true);
cy.get('svg'); cy.get('svg').should('be.visible');
cy.matchImageSnapshot( cy.matchImageSnapshot(
'configuration.spec-should-not-taint-initial-configuration-when-using-multiple-directives' 'configuration.spec-should-not-taint-initial-configuration-when-using-multiple-directives'
); );
}); });
}); });
describe('suppressErrorRendering', () => {
beforeEach(() => {
cy.on('uncaught:exception', (err, runnable) => {
return !err.message.includes('Parse error on line');
});
});
it('should not render error diagram if suppressErrorRendering is set', () => {
const url = 'http://localhost:9000/suppressError.html?suppressErrorRendering=true';
cy.visit(url);
cy.window().should('have.property', 'rendered', true);
cy.get('#test')
.find('svg')
.should(($svg) => {
// all failing diagrams should not appear!
expect($svg).to.have.length(2);
// none of the diagrams should be error diagrams
expect($svg).to.not.contain('Syntax error');
});
cy.matchImageSnapshot(
'configuration.spec-should-not-render-error-diagram-if-suppressErrorRendering-is-set'
);
});
it('should render error diagram if suppressErrorRendering is not set', () => {
const url = 'http://localhost:9000/suppressError.html';
cy.visit(url);
cy.window().should('have.property', 'rendered', true);
cy.get('#test')
.find('svg')
.should(($svg) => {
// all five diagrams should be rendered
expect($svg).to.have.length(5);
// some of the diagrams should be error diagrams
expect($svg).to.contain('Syntax error');
});
cy.matchImageSnapshot(
'configuration.spec-should-render-error-diagram-if-suppressErrorRendering-is-not-set'
);
});
});
}); });

View File

@@ -844,3 +844,42 @@ end
}); });
}); });
}); });
describe('Title and arrow styling #4813', () => {
it('should render a flowchart with title', () => {
const titleString = 'Test Title';
renderGraph(
`---
title: ${titleString}
---
flowchart LR
A-->B
A-->C`,
{ flowchart: { defaultRenderer: 'elk' } }
);
cy.get('svg').should((svg) => {
const title = svg[0].querySelector('text');
expect(title.textContent).to.contain(titleString);
});
});
it('Render with stylized arrows', () => {
renderGraph(
`
flowchart LR
A-->B
B-.-oC
C==xD
D ~~~ A`,
{ flowchart: { defaultRenderer: 'elk' } }
);
cy.get('svg').should((svg) => {
const edges = svg[0].querySelectorAll('.edges path');
console.log(edges);
expect(edges[0]).to.have.attr('pattern', 'solid');
expect(edges[1]).to.have.attr('pattern', 'dotted');
expect(edges[2]).to.have.css('stroke-width', '3.5px');
expect(edges[3]).to.have.css('stroke-width', '1.5px');
});
});
});

View File

@@ -760,6 +760,51 @@ A ~~~ B
); );
}); });
it('3258: Should render subgraphs with main graph nodeSpacing and rankSpacing', () => {
imgSnapshotTest(
`---
title: Subgraph nodeSpacing and rankSpacing example
---
flowchart LR
X --> Y
subgraph X
direction LR
A
C
end
subgraph Y
B
D
end
`,
{ flowchart: { nodeSpacing: 1, rankSpacing: 1 } }
);
});
it('3258: Should render subgraphs with large nodeSpacing and rankSpacing', () => {
imgSnapshotTest(
`---
title: Subgraph nodeSpacing and rankSpacing example
config:
flowchart:
nodeSpacing: 250
rankSpacing: 250
---
flowchart LR
X --> Y
subgraph X
direction LR
A
C
end
subgraph Y
B
D
end
`
);
});
describe('Markdown strings flowchart (#4220)', () => { describe('Markdown strings flowchart (#4220)', () => {
describe('html labels', () => { describe('html labels', () => {
it('With styling and classes', () => { it('With styling and classes', () => {
@@ -904,6 +949,18 @@ end
); );
}); });
}); });
it('should not auto wrap when markdownAutoWrap is false', () => {
imgSnapshotTest(
`flowchart TD
angular_velocity["\`**angular_velocity**
*angular_displacement / duration*
[rad/s, 1/s]
{vector}\`"]
frequency["frequency\n(1 / period_duration)\n[Hz, 1/s]"]`,
{ markdownAutoWrap: false }
);
});
}); });
describe('Subgraph title margins', () => { describe('Subgraph title margins', () => {
it('Should render subgraphs with title margins set (LR)', () => { it('Should render subgraphs with title margins set (LR)', () => {

View File

@@ -573,7 +573,28 @@ describe('Gantt diagram', () => {
` `
); );
}); });
it('should render a gantt diagram exculding friday and saturday', () => {
imgSnapshotTest(
`gantt
title A Gantt Diagram
dateFormat YYYY-MM-DD
excludes weekends
weekend friday
section Section1
A task :a1, 2024-02-28, 10d`
);
});
it('should render a gantt diagram exculding saturday and sunday', () => {
imgSnapshotTest(
`gantt
title A Gantt Diagram
dateFormat YYYY-MM-DD
excludes weekends
weekend saturday
section Section1
A task :a1, 2024-02-28, 10d`
);
});
it('should render when compact is true', () => { it('should render when compact is true', () => {
imgSnapshotTest( imgSnapshotTest(
` `

View File

@@ -1013,4 +1013,450 @@ gitGraph TB:
{ gitGraph: { parallelCommits: true } } { gitGraph: { parallelCommits: true } }
); );
}); });
describe('Git-Graph Bottom-to-Top Orientation Tests', () => {
it('50: should render a simple gitgraph with commit on main branch | Vertical Branch - Bottom-to-top', () => {
imgSnapshotTest(
`gitGraph BT:
commit id: "1"
commit id: "2"
commit id: "3"
`,
{}
);
});
it('51: should render a simple gitgraph with commit on main branch with Id | Vertical Branch - Bottom-to-top', () => {
imgSnapshotTest(
`gitGraph BT:
commit id: "One"
commit id: "Two"
commit id: "Three"
`,
{}
);
});
it('52: should render a simple gitgraph with different commitTypes on main branch | Vertical Branch - Bottom-to-top', () => {
imgSnapshotTest(
`gitGraph BT:
commit id: "Normal Commit"
commit id: "Reverse Commit" type: REVERSE
commit id: "Highlight Commit" type: HIGHLIGHT
`,
{}
);
});
it('53: should render a simple gitgraph with tags commitTypes on main branch | Vertical Branch - Bottom-to-top', () => {
imgSnapshotTest(
`gitGraph BT:
commit id: "Normal Commit with tag" tag: "v1.0.0"
commit id: "Reverse Commit with tag" type: REVERSE tag: "RC_1"
commit id: "Highlight Commit" type: HIGHLIGHT tag: "8.8.4"
`,
{}
);
});
it('54: should render a simple gitgraph with two branches | Vertical Branch - Bottom-to-top', () => {
imgSnapshotTest(
`gitGraph BT:
commit id: "1"
commit id: "2"
branch develop
checkout develop
commit id: "3"
commit id: "4"
checkout main
commit id: "5"
commit id: "6"
`,
{}
);
});
it('55: should render a simple gitgraph with two branches and merge commit | Vertical Branch - Bottom-to-top', () => {
imgSnapshotTest(
`gitGraph BT:
commit id: "1"
commit id: "2"
branch develop
checkout develop
commit id: "3"
commit id: "4"
checkout main
merge develop
commit id: "5"
commit id: "6"
`,
{}
);
});
it('56: should render a simple gitgraph with three branches and tagged merge commit | Vertical Branch - Bottom-to-top', () => {
imgSnapshotTest(
`gitGraph BT:
commit id: "1"
commit id: "2"
branch nice_feature
checkout nice_feature
commit id: "3"
checkout main
commit id: "4"
checkout nice_feature
branch very_nice_feature
checkout very_nice_feature
commit id: "5"
checkout main
commit id: "6"
checkout nice_feature
commit id: "7"
checkout main
merge nice_feature id: "12345" tag: "my merge commit"
checkout very_nice_feature
commit id: "8"
checkout main
commit id: "9"
`,
{}
);
});
it('57: should render a simple gitgraph with more than 8 branches & overriding variables | Vertical Branch - Bottom-to-top', () => {
imgSnapshotTest(
`%%{init: { 'logLevel': 'debug', 'theme': 'default' , 'themeVariables': {
'gitBranchLabel0': '#ffffff',
'gitBranchLabel1': '#ffffff',
'gitBranchLabel2': '#ffffff',
'gitBranchLabel3': '#ffffff',
'gitBranchLabel4': '#ffffff',
'gitBranchLabel5': '#ffffff',
'gitBranchLabel6': '#ffffff',
'gitBranchLabel7': '#ffffff',
} } }%%
gitGraph BT:
checkout main
branch branch1
branch branch2
branch branch3
branch branch4
branch branch5
branch branch6
branch branch7
branch branch8
branch branch9
checkout branch1
commit id: "1"
`,
{}
);
});
it('58: should render a simple gitgraph with rotated labels | Vertical Branch - Bottom-to-top', () => {
imgSnapshotTest(
`%%{init: { 'logLevel': 'debug', 'theme': 'default' , 'gitGraph': {
'rotateCommitLabel': true
} } }%%
gitGraph BT:
commit id: "75f7219e83b321cd3fdde7dcf83bc7c1000a6828"
commit id: "0db4784daf82736dec4569e0dc92980d328c1f2e"
commit id: "7067e9973f9eaa6cd4a4b723c506d1eab598e83e"
commit id: "66972321ad6c199013b5b31f03b3a86fa3f9817d"
`,
{}
);
});
it('59: should render a simple gitgraph with horizontal labels | Vertical Branch - Bottom-to-top', () => {
imgSnapshotTest(
`%%{init: { 'logLevel': 'debug', 'theme': 'default' , 'gitGraph': {
'rotateCommitLabel': false
} } }%%
gitGraph BT:
commit id: "Alpha"
commit id: "Beta"
commit id: "Gamma"
commit id: "Delta"
`,
{}
);
});
it('60: should render a simple gitgraph with cherry pick commit | Vertical Branch - Bottom-to-top', () => {
imgSnapshotTest(
`
gitGraph BT:
commit id: "ZERO"
branch develop
commit id:"A"
checkout main
commit id:"ONE"
checkout develop
commit id:"B"
checkout main
commit id:"TWO"
cherry-pick id:"A"
commit id:"THREE"
checkout develop
commit id:"C"
`,
{}
);
});
it('61: should render a gitgraph with cherry pick commit with custom tag | Vertical Branch - Bottom-to-top', () => {
imgSnapshotTest(
`
gitGraph BT:
commit id: "ZERO"
branch develop
commit id:"A"
checkout main
commit id:"ONE"
checkout develop
commit id:"B"
checkout main
commit id:"TWO"
cherry-pick id:"A" tag: "snapshot"
commit id:"THREE"
checkout develop
commit id:"C"
`,
{}
);
});
it('62: should render a gitgraph with cherry pick commit with no tag | Vertical Branch - Bottom-to-top', () => {
imgSnapshotTest(
`
gitGraph BT:
commit id: "ZERO"
branch develop
commit id:"A"
checkout main
commit id:"ONE"
checkout develop
commit id:"B"
checkout main
commit id:"TWO"
cherry-pick id:"A" tag: ""
commit id:"THREE"
checkout develop
commit id:"C"
`,
{}
);
});
it('63: should render a simple gitgraph with two cherry pick commit | Vertical Branch - Bottom-to-top', () => {
imgSnapshotTest(
`
gitGraph BT:
commit id: "ZERO"
branch develop
commit id:"A"
checkout main
commit id:"ONE"
checkout develop
commit id:"B"
branch featureA
commit id:"FIX"
commit id: "FIX-2"
checkout main
commit id:"TWO"
cherry-pick id:"A"
commit id:"THREE"
cherry-pick id:"FIX"
checkout develop
commit id:"C"
merge featureA
`,
{}
);
});
it('64: should render commits for more than 8 branches | Vertical Branch - Bottom-to-top', () => {
imgSnapshotTest(
`
gitGraph BT:
checkout main
%% Make sure to manually set the ID of all commits, for consistent visual tests
commit id: "1-abcdefg"
checkout main
branch branch1
commit id: "2-abcdefg"
checkout main
merge branch1
branch branch2
commit id: "3-abcdefg"
checkout main
merge branch2
branch branch3
commit id: "4-abcdefg"
checkout main
merge branch3
branch branch4
commit id: "5-abcdefg"
checkout main
merge branch4
branch branch5
commit id: "6-abcdefg"
checkout main
merge branch5
branch branch6
commit id: "7-abcdefg"
checkout main
merge branch6
branch branch7
commit id: "8-abcdefg"
checkout main
merge branch7
branch branch8
commit id: "9-abcdefg"
checkout main
merge branch8
branch branch9
commit id: "10-abcdefg"
`,
{}
);
});
it('65: should render a simple gitgraph with three branches,custom merge commit id,tag,type | Vertical Branch - Bottom-to-top', () => {
imgSnapshotTest(
`gitGraph BT:
commit id: "1"
commit id: "2"
branch nice_feature
checkout nice_feature
commit id: "3"
checkout main
commit id: "4"
checkout nice_feature
branch very_nice_feature
checkout very_nice_feature
commit id: "5"
checkout main
commit id: "6"
checkout nice_feature
commit id: "7"
checkout main
merge nice_feature id: "customID" tag: "customTag" type: REVERSE
checkout very_nice_feature
commit id: "8"
checkout main
commit id: "9"
`,
{}
);
});
it('66: should render a simple gitgraph with a title | Vertical Branch - Bottom-to-top', () => {
imgSnapshotTest(
`---
title: simple gitGraph
---
gitGraph BT:
commit id: "1-abcdefg"
`,
{}
);
});
it('67: should render a simple gitgraph overlapping commits | Vertical Branch - Bottom-to-top', () => {
imgSnapshotTest(
`gitGraph BT:
commit id:"s1"
commit id:"s2"
branch branch1
commit id:"s3"
commit id:"s4"
checkout main
commit id:"s5"
checkout branch1
commit id:"s6"
commit id:"s7"
merge main
`,
{}
);
});
it('68: should render a simple gitgraph with two branches from same commit | Vertical Branch - Bottom-to-top', () => {
imgSnapshotTest(
`gitGraph BT:
commit id:"1-abcdefg"
commit id:"2-abcdefg"
branch feature-001
commit id:"3-abcdefg"
commit id:"4-abcdefg"
checkout main
branch feature-002
commit id:"5-abcdefg"
checkout feature-001
merge feature-002
`,
{}
);
});
it('69: should render GitGraph with branch that is not used immediately | Vertical Branch - Bottom-to-top', () => {
imgSnapshotTest(
`gitGraph BT:
commit id:"1-abcdefg"
branch x
checkout main
commit id:"2-abcdefg"
checkout x
commit id:"3-abcdefg"
checkout main
merge x
`,
{}
);
});
it('70: should render GitGraph with branch and sub-branch neither of which used immediately | Vertical Branch - Bottom-to-top', () => {
imgSnapshotTest(
`gitGraph BT:
commit id:"1-abcdefg"
branch x
checkout main
commit id:"2-abcdefg"
checkout x
commit id:"3-abcdefg"
checkout main
merge x
checkout x
branch y
checkout x
commit id:"4-abcdefg"
checkout y
commit id:"5-abcdefg"
checkout x
merge y
`,
{}
);
});
it('71: should render GitGraph with parallel commits | Vertical Branch - Bottom-to-top', () => {
imgSnapshotTest(
`gitGraph BT:
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('72: should render GitGraph with unconnected branches and parallel commits | Vertical Branch - Bottom-to-top', () => {
imgSnapshotTest(
`gitGraph BT:
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 } }
);
});
});
}); });

View File

@@ -375,7 +375,7 @@ context('Sequence diagram', () => {
{} {}
); );
}); });
it('should have actor-top and actor-bottom classes on top and bottom actor box and symbol', () => { it('should have actor-top and actor-bottom classes on top and bottom actor box and symbol and actor-box and actor-man classes for text tags', () => {
imgSnapshotTest( imgSnapshotTest(
` `
sequenceDiagram sequenceDiagram
@@ -394,6 +394,9 @@ context('Sequence diagram', () => {
cy.get('.actor-man').should('have.class', 'actor-bottom'); cy.get('.actor-man').should('have.class', 'actor-bottom');
cy.get('.actor.actor-bottom').should('not.have.class', 'actor-top'); cy.get('.actor.actor-bottom').should('not.have.class', 'actor-top');
cy.get('.actor-man.actor-bottom').should('not.have.class', 'actor-top'); cy.get('.actor-man.actor-bottom').should('not.have.class', 'actor-top');
cy.get('text.actor-box').should('include.text', 'Alice');
cy.get('text.actor-man').should('include.text', 'Bob');
}); });
it('should render long notes left of actor', () => { it('should render long notes left of actor', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -807,7 +810,10 @@ context('Sequence diagram', () => {
note left of Alice: config: mirrorActors=true<br/>directive: mirrorActors=false note left of Alice: config: mirrorActors=true<br/>directive: mirrorActors=false
Bob->>Alice: Short as well Bob->>Alice: Short as well
`, `,
{ logLevel: 0, sequence: { mirrorActors: true, noteFontSize: 18, noteFontFamily: 'Arial' } } {
logLevel: 0,
sequence: { mirrorActors: true, noteFontSize: 18, noteFontFamily: 'Arial' },
}
); );
}); });
}); });
@@ -858,7 +864,10 @@ context('Sequence diagram', () => {
a->>j: Hello John, how are you? a->>j: Hello John, how are you?
j-->>a: Great! j-->>a: Great!
`, `,
{ logLevel: 0, sequence: { mirrorActors: true, noteFontSize: 18, noteFontFamily: 'Arial' } } {
logLevel: 0,
sequence: { mirrorActors: true, noteFontSize: 18, noteFontFamily: 'Arial' },
}
); );
}); });
it('should support actor links and properties when not mirrored EXPERIMENTAL: USE WITH CAUTION', () => { it('should support actor links and properties when not mirrored EXPERIMENTAL: USE WITH CAUTION', () => {

View File

@@ -33,7 +33,9 @@
background-image: radial-gradient(#fff 1%, transparent 11%), background-image: radial-gradient(#fff 1%, transparent 11%),
radial-gradient(#fff 1%, transparent 11%); radial-gradient(#fff 1%, transparent 11%);
background-size: 20px 20px; background-size: 20px 20px;
background-position: 0 0, 10px 10px; background-position:
0 0,
10px 10px;
background-repeat: repeat; background-repeat: repeat;
} }
.malware { .malware {

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html> <html>
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html> <html>
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html> <html>
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html> <html>
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html> <html>
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html> <html>
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -21,7 +21,11 @@ sequenceDiagram
mermaid.initialize({ mermaid.initialize({
theme: 'base', theme: 'base',
themeVariables: {}, themeVariables: {},
startOnLoad: true, startOnLoad: false,
}); });
await mermaid.run();
if (window.Cypress) {
window.rendered = true;
}
</script> </script>
</html> </html>

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html> <html>
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html> <html>
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html> <html>
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -0,0 +1,59 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Mermaid Quick Test Page</title>
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=" />
</head>
<body>
<div id="test">
<pre class="mermaid">
flowchart
a[This should be visible]
</pre
>
<pre class="mermaid">
flowchart
a --< b
</pre
>
<pre class="mermaid">
flowchart
a[This should be visible]
</pre
>
<pre class="mermaid">
---
config:
suppressErrorRendering: true # This should not affect anything, as suppressErrorRendering is a secure config
---
flowchart
a --< b
</pre
>
<pre class="mermaid">
---
config:
suppressErrorRendering: false # This should not affect anything, as suppressErrorRendering is a secure config
---
flowchart
a --< b
</pre
>
</div>
<script type="module">
import mermaid from './mermaid.esm.mjs';
const shouldSuppress =
new URLSearchParams(window.location.search).get('suppressErrorRendering') === 'true';
mermaid.initialize({ startOnLoad: false, suppressErrorRendering: shouldSuppress });
try {
await mermaid.run();
} catch {
if (window.Cypress) {
window.rendered = true;
}
}
</script>
</body>
</html>

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html> <html>
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -1,4 +1,5 @@
import mermaid from './mermaid.esm.mjs'; import mermaid from './mermaid.esm.mjs';
import flowchartELK from './mermaid-flowchart-elk.esm.mjs';
import externalExample from './mermaid-example-diagram.esm.mjs'; import externalExample from './mermaid-example-diagram.esm.mjs';
import zenUml from './mermaid-zenuml.esm.mjs'; import zenUml from './mermaid-zenuml.esm.mjs';
@@ -45,7 +46,7 @@ const contentLoaded = async function () {
document.getElementsByTagName('body')[0].appendChild(div); document.getElementsByTagName('body')[0].appendChild(div);
} }
await mermaid.registerExternalDiagrams([externalExample, zenUml]); await mermaid.registerExternalDiagrams([externalExample, zenUml, flowchartELK]);
mermaid.initialize(graphObj.mermaid); mermaid.initialize(graphObj.mermaid);
await mermaid.run(); await mermaid.run();
} }

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en" xmlns="http://www.w3.org/1999/html"> <html lang="en" xmlns="http://www.w3.org/1999/html">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

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

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
@@ -1591,6 +1591,33 @@
</pre> </pre>
<hr /> <hr />
<pre class="mermaid">
---
title: Subgraph nodeSpacing and rankSpacing example
config:
flowchart:
nodeSpacing: 1
rankSpacing: 1
---
flowchart LR
X --> Y
subgraph X
direction LR
A
C
end
subgraph Y
direction LR
B
D
end
</pre>
<hr />
<h1 id="link-clicked">Anchor for "link-clicked" test</h1> <h1 id="link-clicked">Anchor for "link-clicked" test</h1>
<script type="module"> <script type="module">

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
@@ -40,6 +40,19 @@
checkout main checkout main
merge newbranch merge newbranch
</pre> </pre>
<pre class="mermaid">
---
title: Simple "branch and merge" (bottom-to-top)
---
gitGraph BT:
commit
branch newbranch
checkout newbranch
commit
checkout main
merge newbranch
</pre
>
<h2>Continuous development graph</h2> <h2>Continuous development graph</h2>
<pre class="mermaid"> <pre class="mermaid">
--- ---
@@ -73,6 +86,23 @@
checkout main checkout main
merge develop merge develop
</pre> </pre>
<pre class="mermaid">
---
title: Continuous development (bottom-to-top)
---
gitGraph BT:
commit
branch develop
checkout develop
commit
checkout main
merge develop
checkout develop
commit
checkout main
merge develop
</pre
>
<h2>Merge feature to advanced main graph</h2> <h2>Merge feature to advanced main graph</h2>
<pre class="mermaid"> <pre class="mermaid">
--- ---
@@ -100,6 +130,20 @@
commit commit
merge newbranch merge newbranch
</pre> </pre>
<pre class="mermaid">
---
title: Merge feature to advanced main (bottom-to-top)
---
gitGraph BT:
commit
branch newbranch
checkout newbranch
commit
checkout main
commit
merge newbranch
</pre
>
<h2>Two-way merges</h2> <h2>Two-way merges</h2>
<pre class="mermaid"> <pre class="mermaid">
--- ---
@@ -137,6 +181,25 @@
checkout main checkout main
merge develop merge develop
</pre> </pre>
<pre class="mermaid">
---
title: Two-way merges (bottom-to-top)
---
gitGraph BT:
commit
branch develop
checkout develop
commit
checkout main
merge develop
commit
checkout develop
merge main
commit
checkout main
merge develop
</pre
>
<h2>Cherry-pick from branch graph</h2> <h2>Cherry-pick from branch graph</h2>
<pre class="mermaid"> <pre class="mermaid">
--- ---
@@ -170,6 +233,22 @@
checkout main checkout main
cherry-pick id: "Pick me" cherry-pick id: "Pick me"
</pre> </pre>
<pre class="mermaid">
---
title: Cherry-pick from branch (bottom-to-top)
---
gitGraph BT:
commit
branch newbranch
checkout newbranch
commit id: "Pick me"
checkout main
commit
checkout newbranch
commit
checkout main
cherry-pick id: "Pick me"
</pre>
<h2>Cherry-pick from main graph</h2> <h2>Cherry-pick from main graph</h2>
<pre class="mermaid"> <pre class="mermaid">
--- ---
@@ -199,6 +278,21 @@
commit commit
cherry-pick id: "A" cherry-pick id: "A"
</pre> </pre>
<pre class="mermaid">
---
title: Cherry-pick from main (bottom-to-top)
---
gitGraph BT:
commit
branch develop
commit
checkout main
commit id:"A"
checkout develop
commit
cherry-pick id: "A"
</pre
>
<h2>Cherry-pick then merge graph</h2> <h2>Cherry-pick then merge graph</h2>
<pre class="mermaid"> <pre class="mermaid">
--- ---
@@ -234,6 +328,24 @@
cherry-pick id: "Pick me" cherry-pick id: "Pick me"
merge newbranch merge newbranch
</pre> </pre>
<pre class="mermaid">
---
title: Cherry-pick then merge (bottom-to-top)
---
gitGraph BT:
commit
branch newbranch
checkout newbranch
commit id: "Pick me"
checkout main
commit
checkout newbranch
commit
checkout main
cherry-pick id: "Pick me"
merge newbranch
</pre
>
<h2>Merge from main onto undeveloped branch graph</h2> <h2>Merge from main onto undeveloped branch graph</h2>
<pre class="mermaid"> <pre class="mermaid">
--- ---
@@ -261,6 +373,20 @@
checkout develop checkout develop
merge main merge main
</pre> </pre>
<pre class="mermaid">
---
title: Merge from main onto undeveloped branch (bottom-to-top)
---
gitGraph BT:
commit
branch develop
commit
checkout main
commit
checkout develop
merge main
</pre
>
<h2>Merge from main onto developed branch graph</h2> <h2>Merge from main onto developed branch graph</h2>
<pre class="mermaid"> <pre class="mermaid">
--- ---
@@ -290,6 +416,21 @@
commit commit
merge main merge main
</pre> </pre>
<pre class="mermaid">
---
title: Merge from main onto developed branch (bottom-to-top)
---
gitGraph BT:
commit
branch develop
commit
checkout main
commit
checkout develop
commit
merge main
</pre
>
<h2>Two branches from same commit graph</h2> <h2>Two branches from same commit graph</h2>
<pre class="mermaid"> <pre class="mermaid">
--- ---
@@ -323,6 +464,23 @@
checkout feature-001 checkout feature-001
merge feature-002 merge feature-002
</pre> </pre>
<pre class="mermaid">
---
title: Two branches from same commit (bottom-to-top)
---
gitGraph BT:
commit
commit
branch feature-001
commit
commit
checkout main
branch feature-002
commit
checkout feature-001
merge feature-002
</pre
>
<h2>Three branches and a cherry-pick from each graph</h2> <h2>Three branches and a cherry-pick from each graph</h2>
<pre class="mermaid"> <pre class="mermaid">
--- ---
@@ -372,6 +530,30 @@
commit id:"C" commit id:"C"
merge featureA merge featureA
</pre> </pre>
<pre class="mermaid">
---
title: Three branches and a cherry-pick from each (bottom-to-top)
---
gitGraph BT:
commit id: "ZERO"
branch develop
commit id:"A"
checkout main
commit id:"ONE"
checkout develop
commit id:"B"
branch featureA
commit id:"FIX"
commit id: "FIX-2"
checkout main
commit id:"TWO"
cherry-pick id:"A"
commit id:"THREE"
cherry-pick id:"FIX"
checkout develop
commit id:"C"
merge featureA
</pre>
<script type="module"> <script type="module">
import mermaid from './mermaid.esm.mjs'; import mermaid from './mermaid.esm.mjs';
const ALLOWED_TAGS = [ const ALLOWED_TAGS = [

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
@@ -18,6 +18,7 @@
<p> <p>
Some of these pages have duplicates; some are slow to load because they have so many graphs. Some of these pages have duplicates; some are slow to load because they have so many graphs.
</p> </p>
<p>You can test custom code in the <a href="./dev/example.html">development page</a>.</p>
<p> <p>
If you'd like to clean up one of the pages, please feel free to If you'd like to clean up one of the pages, please feel free to
<a href="https://github.com/mermaid-js/mermaid/pulls">submit a pull request (PR).</a> <a href="https://github.com/mermaid-js/mermaid/pulls">submit a pull request (PR).</a>

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en" xmlns="http://www.w3.org/1999/html"> <html lang="en" xmlns="http://www.w3.org/1999/html">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en" xmlns="http://www.w3.org/1999/html"> <html lang="en" xmlns="http://www.w3.org/1999/html">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html> <html>
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -175,6 +175,7 @@ statement
The functions for setting title and description are provided by a common module. This is the import from flowDb.js: The functions for setting title and description are provided by a common module. This is the import from flowDb.js:
```
import { import {
setAccTitle, setAccTitle,
getAccTitle, getAccTitle,
@@ -182,6 +183,7 @@ The functions for setting title and description are provided by a common module.
setAccDescription, setAccDescription,
clear as commonClear, clear as commonClear,
} from '../../commonDb'; } from '../../commonDb';
```
The accessibility title and description are inserted into the SVG element in the `render` function in mermaidAPI. The accessibility title and description are inserted into the SVG element in the `render` function in mermaidAPI.

View File

@@ -64,6 +64,7 @@ The syntax for accessible titles and descriptions is described in [the Accessibi
The functions for setting title and description are provided by a common module. This is the import in flowDb.js: The functions for setting title and description are provided by a common module. This is the import in flowDb.js:
```
import { import {
setAccTitle, setAccTitle,
getAccTitle, getAccTitle,
@@ -71,6 +72,7 @@ The functions for setting title and description are provided by a common module.
setAccDescription, setAccDescription,
clear as commonClear, clear as commonClear,
} from '../../commonDb'; } from '../../commonDb';
```
The accessibility title and description are inserted into the SVG element in the `render` function in mermaidAPI. The accessibility title and description are inserted into the SVG element in the `render` function in mermaidAPI.

View File

@@ -47,6 +47,7 @@ Here the structure of a directive text is like a nested key-value pair map or a
The following code snippet shows the structure of a directive: The following code snippet shows the structure of a directive:
```
%%{ %%{
init: { init: {
"theme": "dark", "theme": "dark",
@@ -61,14 +62,19 @@ The following code snippet shows the structure of a directive:
} }
} }
}%% }%%
```
You can also define the directives in a single line, like this: You can also define the directives in a single line, like this:
```
%%{init: { **insert configuration options here** } }%% %%{init: { **insert configuration options here** } }%%
```
For example, the following code snippet: For example, the following code snippet:
```
%%{init: { "sequence": { "mirrorActors":false }}}%% %%{init: { "sequence": { "mirrorActors":false }}}%%
```
**Notes:** **Notes:**
The JSON object that is passed as {**argument**} must be valid key value pairs and encased in quotation marks or it will be ignored. The JSON object that is passed as {**argument**} must be valid key value pairs and encased in quotation marks or it will be ignored.

View File

@@ -61,7 +61,7 @@ By default, MathML is used for rendering mathematical expressions. If you have u
Example with legacy mode enabled (the latest version of KaTeX's stylesheet can be found on their [docs](https://katex.org/docs/browser.html)): Example with legacy mode enabled (the latest version of KaTeX's stylesheet can be found on their [docs](https://katex.org/docs/browser.html)):
```html ```html
<!DOCTYPE html> <!doctype html>
<!-- KaTeX requires the use of the HTML5 doctype. Without it, KaTeX may not render properly --> <!-- KaTeX requires the use of the HTML5 doctype. Without it, KaTeX may not render properly -->
<html lang="en"> <html lang="en">
<head> <head>

View File

@@ -50,7 +50,7 @@ Pushes in a directive to the configuration
| --------- | ------------------------- | ----------- | ------------------------------ | | --------- | ------------------------- | ----------- | ------------------------------ |
| getConfig | Obtains the currentConfig | Get Request | Any Values from current Config | | getConfig | Obtains the currentConfig | Get Request | Any Values from current Config |
**Notes**: Returns **any** the currentConfig **Notes**: Avoid calling this function repeatedly. Instead, store the result in a variable and use it, and pass it down to function calls.
#### Returns #### Returns

View File

@@ -43,6 +43,7 @@ const config = {
securityLevel: 'strict', securityLevel: 'strict',
startOnLoad: true, startOnLoad: true,
arrowMarkerAbsolute: false, arrowMarkerAbsolute: false,
suppressErrorRendering: false,
er: { er: {
diagramPadding: 20, diagramPadding: 20,
@@ -97,7 +98,7 @@ mermaid.initialize(config);
#### Defined in #### Defined in
[mermaidAPI.ts:622](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L622) [mermaidAPI.ts:635](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L635)
## Functions ## Functions

View File

@@ -73,7 +73,7 @@ Example:
## Simple full example: ## Simple full example:
```html ```html
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<body> <body>
<pre class="mermaid"> <pre class="mermaid">

View File

@@ -103,6 +103,8 @@ Content Management Systems/Enterprise Content Management
- [ApostropheCMS](https://apostrophecms.com/) - [ApostropheCMS](https://apostrophecms.com/)
- [Extension for Mermaid.js](https://github.com/BoDonkey/mermaid-extension) - [Extension for Mermaid.js](https://github.com/BoDonkey/mermaid-extension)
- [Drupal](https://drupal.org/)
- [Mermaid Diagram Field module](https://www.drupal.org/project/mermaid_diagram_field)
- [Grav CMS](https://getgrav.org/) - [Grav CMS](https://getgrav.org/)
- [Mermaid Diagrams Plugin](https://github.com/DanielFlaum/grav-plugin-mermaid-diagrams) - [Mermaid Diagrams Plugin](https://github.com/DanielFlaum/grav-plugin-mermaid-diagrams)
- [GitLab Markdown Adapter](https://github.com/Goutte/grav-plugin-gitlab-markdown-adapter) - [GitLab Markdown Adapter](https://github.com/Goutte/grav-plugin-gitlab-markdown-adapter)

View File

@@ -311,7 +311,9 @@ xychart-beta
### CDN ### CDN
```
https://cdn.jsdelivr.net/npm/mermaid@<version>/dist/ https://cdn.jsdelivr.net/npm/mermaid@<version>/dist/
```
To select a version: To select a version:

View File

@@ -6,7 +6,29 @@
# Announcements # Announcements
## 🚀 Mermaid Chart's Visual Editor for Flowcharts ## 🚀 Exciting News from Mermaid Chart! 🚀
We're thrilled to announce that Mermaid Chart has successfully raised $7.5 million in Seed funding! 🌟 This achievement marks the beginning of a new era for Mermaid and Mermaid Chart.
**Why It Matters for Mermaid Chart:**
- **Empowering Collaboration**: Our tools are designed to enable faster, more efficient team collaboration across any distance, leveraging the best of text, voice, and automation.
- **Opening New Doors**: Mermaid AI and our Visual Editor are breaking down barriers, making sophisticated diagramming accessible to everyone, not just software engineers.
- **Looking Forward**: We're not stopping here! Expect groundbreaking features like automated documentation tools, advanced AI diagramming, and high-security on-premise solutions.
**Why It Matters for Mermaid JS:**
- **Continued support from Mermaid Chart**: At Mermaid Chart, we value our still-growing Mermaid JS roots. As such, we have funneled back development and support to the project. Thanks to the successful seed round, we can continue to ramp up these efforts.
We are incredibly excited about the future and are grateful to the community, our team, and our investors for being part of this journey. Together, we're not just creating diagrams; we're designing the future of collaboration.
🌐 Learn more about our groundbreaking tools and what's next for Mermaid Chart by visiting [our website](https://www.mermaidchart.com/blog/posts/mermaid-chart-raises-7.5m-to-reinvent-visual-collaoration-for-enterprises).
Thank you for being part of our story. Here's to creating, innovating, and collaborating on a global scale!
Knut Sveidqvist 🧜‍♂️✨
## Mermaid Chart's Visual Editor for Flowcharts
The Mermaid Chart team is excited to introduce a new Visual Editor for flowcharts, enabling users of all skill levels to create diagrams easily and efficiently, with both GUI and code-based editing options. The Mermaid Chart team is excited to introduce a new Visual Editor for flowcharts, enabling users of all skill levels to create diagrams easily and efficiently, with both GUI and code-based editing options.

View File

@@ -6,6 +6,12 @@
# Blog # Blog
## [Mermaid Chart Raises $7.5M to Reinvent Visual Collaboration for Enterprises](https://www.mermaidchart.com/blog/posts/mermaid-chart-raises-7.5m-to-reinvent-visual-collaoration-for-enterprises/)
20 March 2024 · 4 mins
Mermaid Chart, the company offering text-based diagramming and workflow management tools, today announced it has raised $7.5 million in Seed funding.
## [Mermaid Chart GPT Is Now Available In the GPT Store!](https://www.mermaidchart.com/blog/posts/mermaid-chart-gpt-is-now-available-in-the-gpt-store/) ## [Mermaid Chart GPT Is Now Available In the GPT Store!](https://www.mermaidchart.com/blog/posts/mermaid-chart-gpt-is-now-available-in-the-gpt-store/)
7 March 2024 · 3 mins 7 March 2024 · 3 mins

View File

@@ -636,8 +636,10 @@ Understanding and avoiding common syntax errors is key to a smooth experience wi
A common mistake is incorrect linking syntax, which can lead to unexpected results or broken diagrams: A common mistake is incorrect linking syntax, which can lead to unexpected results or broken diagrams:
```
block-beta block-beta
A - B A - B
```
**Correction**: **Correction**:
Ensure that links between blocks are correctly specified with arrows (--> or ---) to define the direction and type of connection. Also remember that one of the fundaments for block diagram is to give the author full control of where the boxes are positioned so in the example you need to add a space between the boxes: Ensure that links between blocks are correctly specified with arrows (--> or ---) to define the direction and type of connection. Also remember that one of the fundaments for block diagram is to give the author full control of where the boxes are positioned so in the example you need to add a space between the boxes:

View File

@@ -8,7 +8,7 @@
> "In software engineering, a class diagram in the Unified Modeling Language (UML) is a type of static structure diagram that describes the structure of a system by showing the system's classes, their attributes, operations (or methods), and the relationships among objects." > "In software engineering, a class diagram in the Unified Modeling Language (UML) is a type of static structure diagram that describes the structure of a system by showing the system's classes, their attributes, operations (or methods), and the relationships among objects."
> >
> \-Wikipedia > -Wikipedia
The class diagram is the main building block of object-oriented modeling. It is used for general conceptual modeling of the structure of the application, and for detailed modeling to translate the models into programming code. Class diagrams can also be used for data modeling. The classes in a class diagram represent both the main elements, interactions in the application, and the classes to be programmed. The class diagram is the main building block of object-oriented modeling. It is used for general conceptual modeling of the structure of the application, and for detailed modeling to translate the models into programming code. Class diagrams can also be used for data modeling. The classes in a class diagram represent both the main elements, interactions in the application, and the classes to be programmed.
@@ -296,7 +296,9 @@ To describe the visibility (or encapsulation) of an attribute or method/function
A relationship is a general term covering the specific types of logical connections found on class and object diagrams. A relationship is a general term covering the specific types of logical connections found on class and object diagrams.
```
[classA][Arrow][ClassB] [classA][Arrow][ClassB]
```
There are eight different types of relations defined for classes under UML which are currently supported: There are eight different types of relations defined for classes under UML which are currently supported:
@@ -369,7 +371,9 @@ classO .. classP : Link(Dashed)
It is possible to add label text to a relation: It is possible to add label text to a relation:
```
[classA][Arrow][ClassB]:LabelText [classA][Arrow][ClassB]:LabelText
```
```mermaid-example ```mermaid-example
classDiagram classDiagram
@@ -401,7 +405,9 @@ classDiagram
Here is the syntax: Here is the syntax:
```
[Relation Type][Link][Relation Type] [Relation Type][Link][Relation Type]
```
Where `Relation Type` can be one of: Where `Relation Type` can be one of:
@@ -465,7 +471,9 @@ The different cardinality options are :
Cardinality can be easily defined by placing the text option within quotes `"` before or after a given arrow. For example: Cardinality can be easily defined by placing the text option within quotes `"` before or after a given arrow. For example:
```
[classA] "cardinality1" [Arrow] "cardinality2" [ClassB]:LabelText [classA] "cardinality1" [Arrow] "cardinality2" [ClassB]:LabelText
```
```mermaid-example ```mermaid-example
classDiagram classDiagram
@@ -618,9 +626,11 @@ It is possible to bind a click event to a node. The click can lead to either a j
You would define these actions on a separate line after all classes have been declared. You would define these actions on a separate line after all classes have been declared.
```
action className "reference" "tooltip" action className "reference" "tooltip"
click className call callback() "tooltip" click className call callback() "tooltip"
click className href "url" "tooltip" click className href "url" "tooltip"
```
- _action_ is either `link` or `callback`, depending on which type of interaction you want to have called - _action_ is either `link` or `callback`, depending on which type of interaction you want to have called
- _className_ is the id of the node that the action will be associated with - _className_ is the id of the node that the action will be associated with
@@ -803,11 +813,15 @@ should have a different look. This is done by predefining classes in css styles
Then attaching that class to a specific node: Then attaching that class to a specific node:
```
cssClass "nodeId1" styleClass; cssClass "nodeId1" styleClass;
```
It is also possible to attach a class to a list of nodes in one statement: It is also possible to attach a class to a list of nodes in one statement:
```
cssClass "nodeId1,nodeId2" styleClass; cssClass "nodeId1,nodeId2" styleClass;
```
A shorter form of adding a class is to attach the classname to the node using the `:::` operator: A shorter form of adding a class is to attach the classname to the node using the `:::` operator:

View File

@@ -86,7 +86,9 @@ When including attributes on ER diagrams, you must decide whether to include for
Mermaid syntax for ER diagrams is compatible with PlantUML, with an extension to label the relationship. Each statement consists of the following parts: Mermaid syntax for ER diagrams is compatible with PlantUML, with an extension to label the relationship. Each statement consists of the following parts:
```
<first-entity> [<relationship> <second-entity> : <relationship-label>] <first-entity> [<relationship> <second-entity> : <relationship-label>]
```
Where: Where:
@@ -97,7 +99,9 @@ Where:
For example: For example:
```
PROPERTY ||--|{ ROOM : contains PROPERTY ||--|{ ROOM : contains
```
This statement can be read as _a property contains one or more rooms, and a room is part of one and only one property_. You can see that the label here is from the first entity's perspective: a property contains a room, but a room does not contain a property. When considered from the perspective of the second entity, the equivalent label is usually very easy to infer. (Some ER diagrams label relationships from both perspectives, but this is not supported here, and is usually superfluous). This statement can be read as _a property contains one or more rooms, and a room is part of one and only one property_. You can see that the label here is from the first entity's perspective: a property contains a room, but a room does not contain a property. When considered from the perspective of the second entity, the equivalent label is usually very easy to infer. (Some ER diagrams label relationships from both perspectives, but this is not supported here, and is usually superfluous).

View File

@@ -642,9 +642,11 @@ Numbers given are base 10, so `#` can be encoded as `#35;`. It is also supported
## Subgraphs ## Subgraphs
```
subgraph title subgraph title
graph definition graph definition
end end
```
An example below: An example below:
@@ -850,6 +852,16 @@ Formatting:
This feature is applicable to node labels, edge labels, and subgraph labels. This feature is applicable to node labels, edge labels, and subgraph labels.
The auto wrapping can be disabled by using
```
---
config:
markdownAutoWrap: false
---
graph LR
```
## Interaction ## Interaction
It is possible to bind a click event to a node, the click can lead to either a javascript callback or to a link which will be opened in a new browser tab. It is possible to bind a click event to a node, the click can lead to either a javascript callback or to a link which will be opened in a new browser tab.
@@ -857,8 +869,10 @@ It is possible to bind a click event to a node, the click can lead to either a j
> **Note** > **Note**
> This functionality is disabled when using `securityLevel='strict'` and enabled when using `securityLevel='loose'`. > This functionality is disabled when using `securityLevel='strict'` and enabled when using `securityLevel='loose'`.
```
click nodeId callback click nodeId callback
click nodeId call callback() click nodeId call callback()
```
- nodeId is the id of the node - nodeId is the id of the node
- callback is the name of a javascript function defined on the page displaying the graph, the function will be called with the nodeId as parameter. - callback is the name of a javascript function defined on the page displaying the graph, the function will be called with the nodeId as parameter.
@@ -981,11 +995,15 @@ have no ids in the same way as nodes, some other way of deciding what style the
Instead of ids, the order number of when the link was defined in the graph is used, or use default to apply to all links. Instead of ids, the order number of when the link was defined in the graph is used, or use default to apply to all links.
In the example below the style defined in the linkStyle statement will belong to the fourth link in the graph: In the example below the style defined in the linkStyle statement will belong to the fourth link in the graph:
```
linkStyle 3 stroke:#ff3,stroke-width:4px,color:red; linkStyle 3 stroke:#ff3,stroke-width:4px,color:red;
```
It is also possible to add style to multiple links in a single statement, by separating link numbers with commas: It is also possible to add style to multiple links in a single statement, by separating link numbers with commas:
```
linkStyle 1,2,7 color:blue; linkStyle 1,2,7 color:blue;
```
### Styling line curves ### Styling line curves
@@ -995,8 +1013,10 @@ Available curve styles include `basis`, `bumpX`, `bumpY`, `cardinal`, `catmullRo
In this example, a left-to-right graph uses the `stepBefore` curve style: In this example, a left-to-right graph uses the `stepBefore` curve style:
```
%%{ init: { 'flowchart': { 'curve': 'stepBefore' } } }%% %%{ init: { 'flowchart': { 'curve': 'stepBefore' } } }%%
graph LR graph LR
```
For a full list of available curves, including an explanation of custom curves, refer to For a full list of available curves, including an explanation of custom curves, refer to
the [Shapes](https://github.com/d3/d3-shape/blob/main/README.md#curves) documentation in the the [Shapes](https://github.com/d3/d3-shape/blob/main/README.md#curves) documentation in the
@@ -1027,19 +1047,27 @@ should have a different look.
A class definition looks like the example below: A class definition looks like the example below:
```
classDef className fill:#f9f,stroke:#333,stroke-width:4px; classDef className fill:#f9f,stroke:#333,stroke-width:4px;
```
Also, it is possible to define style to multiple classes in one statement: Also, it is possible to define style to multiple classes in one statement:
```
classDef firstClassName,secondClassName font-size:12pt; classDef firstClassName,secondClassName font-size:12pt;
```
Attachment of a class to a node is done as per below: Attachment of a class to a node is done as per below:
```
class nodeId1 className; class nodeId1 className;
```
It is also possible to attach a class to a list of nodes in one statement: It is also possible to attach a class to a list of nodes in one statement:
```
class nodeId1,nodeId2 className; class nodeId1,nodeId2 className;
```
A shorter form of adding a class is to attach the classname to the node using the `:::`operator as per below: A shorter form of adding a class is to attach the classname to the node using the `:::`operator as per below:
@@ -1110,7 +1138,9 @@ flowchart LR
If a class is named default it will be assigned to all classes without specific class definitions. If a class is named default it will be assigned to all classes without specific class definitions.
```
classDef default fill:#f9f,stroke:#333,stroke-width:4px; classDef default fill:#f9f,stroke:#333,stroke-width:4px;
```
## Basic support for fontawesome ## Basic support for fontawesome
@@ -1183,7 +1213,9 @@ Starting with Mermaid version 9.4, you can use an alternate renderer named elk.
The _elk_ renderer is an experimental feature. The _elk_ renderer is an experimental feature.
You can change the renderer to elk by adding this directive: You can change the renderer to elk by adding this directive:
```
%%{init: {"flowchart": {"defaultRenderer": "elk"}} }%% %%{init: {"flowchart": {"defaultRenderer": "elk"}} }%%
```
> **Note** > **Note**
> Note that the site needs to use mermaid version 9.4+ for this to work and have this featured enabled in the lazy-loading configuration. > Note that the site needs to use mermaid version 9.4+ for this to work and have this featured enabled in the lazy-loading configuration.

View File

@@ -167,6 +167,38 @@ gantt
The `title` is an _optional_ string to be displayed at the top of the Gantt chart to describe the chart as a whole. The `title` is an _optional_ string to be displayed at the top of the Gantt chart to describe the chart as a whole.
### Excludes
The `excludes` is an _optional_ attribute that accepts specific dates in YYYY-MM-DD format, days of the week ("sunday") or "weekends", but not the word "weekdays".
These date will be marked on the graph, and be excluded from the duration calculation of tasks. Meaning that if there are excluded dates during a task interval, the number of 'skipped' days will be added to the end of the task to ensure the duration is as specified in the code.
#### Weekend (v\<MERMAID_RELEASE_VERSION>+)
When excluding weekends, it is possible to configure the weekends to be either Friday and Saturday or Saturday and Sunday. By default weekends are Saturday and Sunday.
To define the weekend start day, there is an _optional_ attribute `weekend` that can be added in a new line followed by either `friday` or `saturday`.
```mermaid-example
gantt
title A Gantt Diagram Excluding Fri - Sat weekends
dateFormat YYYY-MM-DD
excludes weekends
weekend friday
section Section
A task :a1, 2024-01-01, 30d
Another task :after a1, 20d
```
```mermaid
gantt
title A Gantt Diagram Excluding Fri - Sat weekends
dateFormat YYYY-MM-DD
excludes weekends
weekend friday
section Section
A task :a1, 2024-01-01, 30d
Another task :after a1, 20d
```
### Section statements ### Section statements
You can divide the chart into various sections, for example to separate different parts of a project like development and documentation. You can divide the chart into various sections, for example to separate different parts of a project like development and documentation.
@@ -436,11 +468,15 @@ Styling of the Gantt diagram is done by defining a number of CSS classes. During
You can style or hide the marker for the current date. To style it, add a value for the `todayMarker` key. You can style or hide the marker for the current date. To style it, add a value for the `todayMarker` key.
```
todayMarker stroke-width:5px,stroke:#0f0,opacity:0.5 todayMarker stroke-width:5px,stroke:#0f0,opacity:0.5
```
To hide the marker, set `todayMarker` to `off`. To hide the marker, set `todayMarker` to `off`.
```
todayMarker off todayMarker off
```
## Configuration ## Configuration
@@ -482,8 +518,10 @@ mermaid.ganttConfig = {
It is possible to bind a click event to a task. The click can lead to either a javascript callback or to a link which will be opened in the current browser tab. **Note**: This functionality is disabled when using `securityLevel='strict'` and enabled when using `securityLevel='loose'`. It is possible to bind a click event to a task. The click can lead to either a javascript callback or to a link which will be opened in the current browser tab. **Note**: This functionality is disabled when using `securityLevel='strict'` and enabled when using `securityLevel='loose'`.
```
click taskId call callback(arguments) click taskId call callback(arguments)
click taskId href URL click taskId href URL
```
- taskId is the id of the task - taskId is the id of the task
- callback is the name of a javascript function defined on the page displaying the graph, the function will be called with the taskId as the parameter if no other arguments are specified. - callback is the name of a javascript function defined on the page displaying the graph, the function will be called with the taskId as the parameter if no other arguments are specified.

View File

@@ -836,9 +836,9 @@ Here, we have changed the default main branch name to `MetroLine1`.
## Orientation (v10.3.0+) ## Orientation (v10.3.0+)
Mermaid supports two graph orientations: **Left-to-Right** (default) and **Top-to-Bottom**. Mermaid supports three graph orientations: **Left-to-Right** (default), **Top-to-Bottom**, and **Bottom-to-Top**.
You can set this with either `LR:` (for [**Left-to-Right**](#left-to-right-default-lr)) or `TB:` (for [**Top-to-Bottom**](#top-to-bottom-tb)) after `gitGraph`. You can set this with either `LR:` (for [**Left-to-Right**](#left-to-right-default-lr)), `TB:` (for [**Top-to-Bottom**](#top-to-bottom-tb)) or `BT:` (for [**Bottom-to-Top**](#bottom-to-top-bt)) after `gitGraph`.
### Left to Right (default, `LR:`) ### Left to Right (default, `LR:`)
@@ -916,6 +916,44 @@ Usage example:
commit commit
``` ```
### Bottom to Top (`BT:`) (v\<MERMAID_RELEASE_VERSION>+)
In `BT` (**Bottom-to-Top**) orientation, the commits run from bottom to top of the graph and branches are arranged side-by-side.
To orient the graph this way, you need to add `BT:` after gitGraph.
Usage example:
```mermaid-example
gitGraph BT:
commit
commit
branch develop
commit
commit
checkout main
commit
commit
merge develop
commit
commit
```
```mermaid
gitGraph BT:
commit
commit
branch develop
commit
commit
checkout main
commit
commit
merge develop
commit
commit
```
## Parallel commits (v10.8.0+) ## Parallel commits (v10.8.0+)
Commits in Mermaid display temporal information in gitgraph by default. For example if two commits are one commit away from its parent, the commit that was made earlier is rendered closer to its parent. You can turn this off by enabling the `parallelCommits` flag. Commits in Mermaid display temporal information in gitgraph by default. For example if two commits are one commit away from its parent, the commit that was made earlier is rendered closer to its parent. You can turn this off by enabling the `parallelCommits` flag.

View File

@@ -60,11 +60,13 @@ The syntax for creating Mindmaps is simple and relies on indentation for setting
In the following example you can see how there are 3 different levels. One with starting at the left of the text and another level with two rows starting at the same column, defining the node A. At the end there is one more level where the text is indented further than the previous lines defining the nodes B and C. In the following example you can see how there are 3 different levels. One with starting at the left of the text and another level with two rows starting at the same column, defining the node A. At the end there is one more level where the text is indented further than the previous lines defining the nodes B and C.
```
mindmap mindmap
Root Root
A A
B B
C C
```
In summary is a simple text outline where there is one node at the root level called `Root` which has one child `A`. `A` in turn has two children `B`and `C`. In the diagram below we can see this rendered as a mindmap. In summary is a simple text outline where there is one node at the root level called `Root` which has one child `A`. `A` in turn has two children `B`and `C`. In the diagram below we can see this rendered as a mindmap.
@@ -230,11 +232,13 @@ _These classes need to be supplied by the site administrator._
The actual indentation does not really matter only compared with the previous rows. If we take the previous example and disrupt it a little we can see how the calculations are performed. Let us start with placing C with a smaller indentation than `B` but larger then `A`. The actual indentation does not really matter only compared with the previous rows. If we take the previous example and disrupt it a little we can see how the calculations are performed. Let us start with placing C with a smaller indentation than `B` but larger then `A`.
```
mindmap mindmap
Root Root
A A
B B
C C
```
This outline is unclear as `B` clearly is a child of `A` but when we move on to `C` the clarity is lost. `C` is not a child of `B` with a higher indentation nor does it have the same indentation as `B`. The only thing that is clear is that the first node with smaller indentation, indicating a parent, is A. Then Mermaid relies on this known truth and compensates for the unclear indentation and selects `A` as a parent of `C` leading till the same diagram with `B` and `C` as siblings. This outline is unclear as `B` clearly is a child of `A` but when we move on to `C` the clarity is lost. `C` is not a child of `B` with a higher indentation nor does it have the same indentation as `B`. The only thing that is clear is that the first node with smaller indentation, indicating a parent, is A. Then Mermaid relies on this known truth and compensates for the unclear indentation and selects `A` as a parent of `C` leading till the same diagram with `B` and `C` as siblings.

View File

@@ -7,7 +7,7 @@
# Pie chart diagrams # Pie chart diagrams
> A pie chart (or a circle chart) is a circular statistical graphic, which is divided into slices to illustrate numerical proportion. In a pie chart, the arc length of each slice (and consequently its central angle and area), is proportional to the quantity it represents. While it is named for its resemblance to a pie which has been sliced, there are variations on the way it can be presented. The earliest known pie chart is generally credited to William Playfair's Statistical Breviary of 1801 > A pie chart (or a circle chart) is a circular statistical graphic, which is divided into slices to illustrate numerical proportion. In a pie chart, the arc length of each slice (and consequently its central angle and area), is proportional to the quantity it represents. While it is named for its resemblance to a pie which has been sliced, there are variations on the way it can be presented. The earliest known pie chart is generally credited to William Playfair's Statistical Breviary of 1801
> \-Wikipedia > -Wikipedia
Mermaid can render Pie Chart diagrams. Mermaid can render Pie Chart diagrams.

View File

@@ -59,8 +59,10 @@ The title is a short description of the chart and it will always render on top o
#### Example #### Example
```
quadrantChart quadrantChart
title This is a sample example title This is a sample example
```
### x-axis ### x-axis

View File

@@ -56,12 +56,14 @@ An important note on user text: all input can be surrounded in quotes or not. Fo
A requirement definition contains a requirement type, name, id, text, risk, and verification method. The syntax follows: A requirement definition contains a requirement type, name, id, text, risk, and verification method. The syntax follows:
```
<type> user_defined_name { <type> user_defined_name {
id: user_defined_id id: user_defined_id
text: user_defined text text: user_defined text
risk: <risk> risk: <risk>
verifymethod: <method> verifymethod: <method>
} }
```
Type, risk, and method are enumerations defined in SysML. Type, risk, and method are enumerations defined in SysML.
@@ -75,10 +77,12 @@ Type, risk, and method are enumerations defined in SysML.
An element definition contains an element name, type, and document reference. These three are all user defined. The element feature is intended to be lightweight but allow requirements to be connected to portions of other documents. An element definition contains an element name, type, and document reference. These three are all user defined. The element feature is intended to be lightweight but allow requirements to be connected to portions of other documents.
```
element user_defined_name { element user_defined_name {
type: user_defined_type type: user_defined_type
docref: user_defined_ref docref: user_defined_ref
} }
```
### Relationship ### Relationship
@@ -86,11 +90,15 @@ Relationships are comprised of a source node, destination node, and relationship
Each follows the definition format of Each follows the definition format of
```
{name of source} - <type> -> {name of destination} {name of source} - <type> -> {name of destination}
```
or or
```
{name of destination} <- <type> - {name of source} {name of destination} <- <type> - {name of source}
```
"name of source" and "name of destination" should be names of requirement or element nodes defined elsewhere. "name of source" and "name of destination" should be names of requirement or element nodes defined elsewhere.

View File

@@ -42,16 +42,16 @@ appearance by doing the following:
sequenceDiagram sequenceDiagram
participant Alice participant Alice
participant Bob participant Bob
Alice->>Bob: Hi Bob
Bob->>Alice: Hi Alice Bob->>Alice: Hi Alice
Alice->>Bob: Hi Bob
``` ```
```mermaid ```mermaid
sequenceDiagram sequenceDiagram
participant Alice participant Alice
participant Bob participant Bob
Alice->>Bob: Hi Bob
Bob->>Alice: Hi Alice Bob->>Alice: Hi Alice
Alice->>Bob: Hi Bob
``` ```
### Actors ### Actors
@@ -98,8 +98,10 @@ sequenceDiagram
It is possible to create and destroy actors by messages. To do so, add a create or destroy directive before the message. It is possible to create and destroy actors by messages. To do so, add a create or destroy directive before the message.
```
create participant B create participant B
A --> B: Hello A --> B: Hello
```
Create directives support actor/participant distinction and aliases. The sender or the recipient of a message can be destroyed but only the recipient can be created. Create directives support actor/participant distinction and aliases. The sender or the recipient of a message can be destroyed but only the recipient can be created.
@@ -143,6 +145,7 @@ And fixing diagram code does not get rid of this error and rendering of all othe
The actor(s) can be grouped in vertical boxes. You can define a color (if not, it will be transparent) and/or a descriptive label using the following notation: The actor(s) can be grouped in vertical boxes. You can define a color (if not, it will be transparent) and/or a descriptive label using the following notation:
```
box Aqua Group Description box Aqua Group Description
... actors ... ... actors ...
end end
@@ -152,13 +155,16 @@ The actor(s) can be grouped in vertical boxes. You can define a color (if not, i
box rgb(33,66,99) box rgb(33,66,99)
... actors ... ... actors ...
end end
```
> **Note** > **Note**
> If your group name is a color you can force the color to be transparent: > If your group name is a color you can force the color to be transparent:
```
box transparent Aqua box transparent Aqua
... actors ... ... actors ...
end end
```
```mermaid-example ```mermaid-example
sequenceDiagram sequenceDiagram
@@ -196,7 +202,9 @@ The actor(s) can be grouped in vertical boxes. You can define a color (if not, i
Messages can be of two displayed either solid or with a dotted line. Messages can be of two displayed either solid or with a dotted line.
```
[Actor][Arrow][Actor]:Message text [Actor][Arrow][Actor]:Message text
```
There are six types of arrows currently supported: There are six types of arrows currently supported:
@@ -314,9 +322,11 @@ sequenceDiagram
It is possible to express loops in a sequence diagram. This is done by the notation It is possible to express loops in a sequence diagram. This is done by the notation
```
loop Loop text loop Loop text
... statements ... ... statements ...
end end
```
See the example below: See the example below:
@@ -340,17 +350,21 @@ sequenceDiagram
It is possible to express alternative paths in a sequence diagram. This is done by the notation It is possible to express alternative paths in a sequence diagram. This is done by the notation
```
alt Describing text alt Describing text
... statements ... ... statements ...
else else
... statements ... ... statements ...
end end
```
or if there is sequence that is optional (if without else). or if there is sequence that is optional (if without else).
```
opt Describing text opt Describing text
... statements ... ... statements ...
end end
```
See the example below: See the example below:
@@ -386,6 +400,7 @@ It is possible to show actions that are happening in parallel.
This is done by the notation This is done by the notation
```
par [Action 1] par [Action 1]
... statements ... ... statements ...
and [Action 2] and [Action 2]
@@ -393,6 +408,7 @@ This is done by the notation
and [Action N] and [Action N]
... statements ... ... statements ...
end end
```
See the example below: See the example below:
@@ -454,6 +470,7 @@ It is possible to show actions that must happen automatically with conditional h
This is done by the notation This is done by the notation
```
critical [Action that must be performed] critical [Action that must be performed]
... statements ... ... statements ...
option [Circumstance A] option [Circumstance A]
@@ -461,6 +478,7 @@ This is done by the notation
option [Circumstance B] option [Circumstance B]
... statements ... ... statements ...
end end
```
See the example below: See the example below:
@@ -510,9 +528,11 @@ It is possible to indicate a stop of the sequence within the flow (usually used
This is done by the notation This is done by the notation
```
break [something happened] break [something happened]
... statements ... ... statements ...
end end
```
See the example below: See the example below:
@@ -542,15 +562,17 @@ It is possible to highlight flows by providing colored background rects. This is
The colors are defined using rgb and rgba syntax. The colors are defined using rgb and rgba syntax.
```
rect rgb(0, 255, 0) rect rgb(0, 255, 0)
... content ... ... content ...
end end
```
<!----> ```
rect rgba(0, 0, 255, .1) rect rgba(0, 0, 255, .1)
... content ... ... content ...
end end
```
See the examples below: See the examples below:
@@ -674,7 +696,9 @@ Actors can have popup-menus containing individualized links to external pages. F
This can be configured by adding one or more link lines with the format: This can be configured by adding one or more link lines with the format:
```
link <actor>: <link-label> @ <link-url> link <actor>: <link-label> @ <link-url>
```
```mermaid-example ```mermaid-example
sequenceDiagram sequenceDiagram
@@ -708,7 +732,9 @@ There is an advanced syntax that relies on JSON formatting. If you are comfortab
This can be configured by adding the links lines with the format: This can be configured by adding the links lines with the format:
```
links <actor>: <json-formatted link-name link-url pairs> links <actor>: <json-formatted link-name link-url pairs>
```
An example is below: An example is below:
@@ -741,11 +767,13 @@ Styling of a sequence diagram is done by defining a number of css classes. Durin
### Classes used ### Classes used
| Class | Description | | Class | Description |
| ------------ | -------------------------------------------------------------- | | -------------- | -------------------------------------------------------------- |
| actor | Styles for the actor box. | | actor | Styles for the actor box. |
| actor-top | Styles for the actor figure/ box at the top of the diagram. | | actor-top | Styles for the actor figure/ box at the top of the diagram. |
| actor-bottom | Styles for the actor figure/ box at the bottom of the diagram. | | actor-bottom | Styles for the actor figure/ box at the bottom of the diagram. |
| text.actor | Styles for text in the actor box. | | text.actor | Styles for text of all of the actors. |
| text.actor-box | Styles for text of the actor box. |
| text.actor-man | Styles for text of the actor figure. |
| actor-line | The vertical line for an actor. | | actor-line | The vertical line for an actor. |
| messageLine0 | Styles for the solid message line. | | messageLine0 | Styles for the solid message line. |
| messageLine1 | Styles for the dotted message line. | | messageLine1 | Styles for the dotted message line. |

View File

@@ -467,7 +467,9 @@ a _[valid CSS property name](https://www.w3.org/TR/CSS/#properties)_ followed by
Here is an example of a classDef with just one property-value pair: Here is an example of a classDef with just one property-value pair:
```
classDef movement font-style:italic; classDef movement font-style:italic;
```
where where
@@ -478,7 +480,9 @@ If you want to have more than one _property-value pair_ then you put a comma (`,
Here is an example with three property-value pairs: Here is an example with three property-value pairs:
```
classDef badBadEvent fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow classDef badBadEvent fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow
```
where where

View File

@@ -39,8 +39,10 @@ xychart-beta
The chart can be drawn horizontal or vertical, default value is vertical. The chart can be drawn horizontal or vertical, default value is vertical.
```
xychart-beta horizontal xychart-beta horizontal
... ...
```
### Title ### Title
@@ -48,9 +50,11 @@ The title is a short description of the chart and it will always render on top o
#### Example #### Example
```
xychart-beta xychart-beta
title "This is a simple example" title "This is a simple example"
... ...
```
> **Note** > **Note**
> If the title is a single word one no need to use `"`, but if it has space `"` is needed > If the title is a single word one no need to use `"`, but if it has space `"` is needed
@@ -96,8 +100,10 @@ A bar chart offers the capability to graphically depict bars.
The only two things required are the chart name (`xychart-beta`) and one data set. So you will be able to draw a chart with a simple config like The only two things required are the chart name (`xychart-beta`) and one data set. So you will be able to draw a chart with a simple config like
```
xychart-beta xychart-beta
line [+1.3, .6, 2.4, -.34] line [+1.3, .6, 2.4, -.34]
```
## Chart Configurations ## Chart Configurations

View File

@@ -423,6 +423,7 @@ It is possible to indicate a stop of the sequence within the flow (usually used
This is done by the notation This is done by the notation
```
try { try {
...statements... ...statements...
} catch { } catch {
@@ -430,6 +431,7 @@ This is done by the notation
} finally { } finally {
...statements... ...statements...
} }
```
See the example below: See the example below:

View File

@@ -25,8 +25,8 @@
"dev:vite": "tsx .vite/server.ts", "dev:vite": "tsx .vite/server.ts",
"dev:coverage": "pnpm coverage:cypress:clean && VITE_COVERAGE=true pnpm dev:vite", "dev:coverage": "pnpm coverage:cypress:clean && VITE_COVERAGE=true pnpm dev:vite",
"release": "pnpm build", "release": "pnpm build",
"lint": "eslint --cache --cache-strategy content --ignore-path .gitignore . && pnpm lint:jison && prettier --cache --check .", "lint": "cross-env NODE_OPTIONS=--max_old_space_size=8192 eslint --cache --cache-strategy content --ignore-path .gitignore . && pnpm lint:jison && prettier --cache --check .",
"lint:fix": "eslint --cache --cache-strategy content --fix --ignore-path .gitignore . && prettier --write . && tsx scripts/fixCSpell.ts", "lint:fix": "cross-env NODE_OPTIONS=--max_old_space_size=8192 eslint --cache --cache-strategy content --fix --ignore-path .gitignore . && prettier --write . && tsx scripts/fixCSpell.ts",
"lint:jison": "tsx ./scripts/jison/lint.mts", "lint:jison": "tsx ./scripts/jison/lint.mts",
"contributors": "tsx scripts/updateContributors.ts", "contributors": "tsx scripts/updateContributors.ts",
"cypress": "cypress run", "cypress": "cypress run",
@@ -61,70 +61,68 @@
] ]
}, },
"devDependencies": { "devDependencies": {
"@applitools/eyes-cypress": "^3.40.6", "@applitools/eyes-cypress": "^3.42.3",
"@commitlint/cli": "^17.6.1", "@cspell/eslint-plugin": "^8.6.0",
"@commitlint/config-conventional": "^17.6.1", "@cypress/code-coverage": "^3.12.30",
"@cspell/eslint-plugin": "^8.3.2", "@rollup/plugin-typescript": "^11.1.6",
"@cypress/code-coverage": "^3.12.18", "@types/cors": "^2.8.17",
"@rollup/plugin-typescript": "^11.1.1", "@types/eslint": "^8.56.6",
"@types/cors": "^2.8.13", "@types/express": "^4.17.21",
"@types/eslint": "^8.37.0", "@types/js-yaml": "^4.0.9",
"@types/express": "^4.17.17", "@types/jsdom": "^21.1.6",
"@types/js-yaml": "^4.0.5", "@types/lodash": "^4.17.0",
"@types/jsdom": "^21.1.1", "@types/mdast": "^4.0.3",
"@types/lodash": "^4.14.194", "@types/node": "^20.11.30",
"@types/mdast": "^3.0.11", "@types/rollup-plugin-visualizer": "^4.2.4",
"@types/node": "^20.11.17", "@typescript-eslint/eslint-plugin": "^7.3.1",
"@types/prettier": "^2.7.2", "@typescript-eslint/parser": "^7.3.1",
"@types/rollup-plugin-visualizer": "^4.2.1", "@vitest/coverage-v8": "^1.4.0",
"@typescript-eslint/eslint-plugin": "^6.7.2", "@vitest/spy": "^1.4.0",
"@typescript-eslint/parser": "^6.7.2", "@vitest/ui": "^1.4.0",
"@vitest/coverage-v8": "^0.34.0",
"@vitest/spy": "^0.34.0",
"@vitest/ui": "^0.34.0",
"ajv": "^8.12.0", "ajv": "^8.12.0",
"chokidar": "^3.5.3", "chokidar": "^3.6.0",
"concurrently": "^8.0.1", "concurrently": "^8.2.2",
"cors": "^2.8.5", "cors": "^2.8.5",
"cspell": "^8.3.2", "cross-env": "^7.0.3",
"cypress": "^12.17.4", "cspell": "^8.6.0",
"cypress": "^13.7.1",
"cypress-image-snapshot": "^4.0.1", "cypress-image-snapshot": "^4.0.1",
"esbuild": "^0.20.0", "esbuild": "^0.20.2",
"eslint": "^8.47.0", "eslint": "^8.57.0",
"eslint-config-prettier": "^8.8.0", "eslint-config-prettier": "^9.1.0",
"eslint-plugin-cypress": "^2.13.2", "eslint-plugin-cypress": "^2.15.1",
"eslint-plugin-html": "^7.1.0", "eslint-plugin-html": "^8.0.0",
"eslint-plugin-jest": "^27.2.1", "eslint-plugin-jest": "^27.9.0",
"eslint-plugin-jsdoc": "^46.0.0", "eslint-plugin-jsdoc": "^48.2.1",
"eslint-plugin-json": "^3.1.0", "eslint-plugin-json": "^3.1.0",
"eslint-plugin-lodash": "^7.4.0", "eslint-plugin-lodash": "^7.4.0",
"eslint-plugin-markdown": "^3.0.0", "eslint-plugin-markdown": "^4.0.1",
"eslint-plugin-no-only-tests": "^3.1.0", "eslint-plugin-no-only-tests": "^3.1.0",
"eslint-plugin-tsdoc": "^0.2.17", "eslint-plugin-tsdoc": "^0.2.17",
"eslint-plugin-unicorn": "^47.0.0", "eslint-plugin-unicorn": "^51.0.1",
"express": "^4.18.2", "express": "^4.19.1",
"globby": "^13.1.4", "globby": "^14.0.1",
"husky": "^8.0.3", "husky": "^9.0.11",
"jest": "^29.5.0", "jest": "^29.7.0",
"jison": "^0.4.18", "jison": "^0.4.18",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
"jsdom": "^22.0.0", "jsdom": "^24.0.0",
"langium-cli": "3.0.1", "langium-cli": "3.0.1",
"lint-staged": "^13.2.1", "lint-staged": "^15.2.2",
"markdown-table": "^3.0.3", "markdown-table": "^3.0.3",
"nyc": "^15.1.0", "nyc": "^15.1.0",
"path-browserify": "^1.0.1", "path-browserify": "^1.0.1",
"pnpm": "^8.6.8", "pnpm": "^8.15.5",
"prettier": "^2.8.8", "prettier": "^3.2.5",
"prettier-plugin-jsdoc": "^0.4.2", "prettier-plugin-jsdoc": "^1.3.0",
"rimraf": "^5.0.0", "rimraf": "^5.0.5",
"rollup-plugin-visualizer": "^5.9.2", "rollup-plugin-visualizer": "^5.12.0",
"start-server-and-test": "^2.0.0", "start-server-and-test": "^2.0.3",
"tsx": "^4.6.2", "tsx": "^4.7.1",
"typescript": "^5.1.3", "typescript": "^5.4.3",
"vite": "^4.5.2", "vite": "^5.2.3",
"vite-plugin-istanbul": "^4.1.0", "vite-plugin-istanbul": "^6.0.0",
"vitest": "^0.34.0" "vitest": "^1.4.0"
}, },
"nyc": { "nyc": {
"report-dir": "coverage/cypress" "report-dir": "coverage/cypress"

View File

@@ -38,14 +38,14 @@
] ]
}, },
"dependencies": { "dependencies": {
"@braintree/sanitize-url": "^6.0.1", "@braintree/sanitize-url": "^6.0.4",
"d3": "^7.0.0", "d3": "^7.9.0",
"khroma": "^2.0.0" "khroma": "^2.1.0"
}, },
"devDependencies": { "devDependencies": {
"concurrently": "^8.0.0", "concurrently": "^8.2.2",
"rimraf": "^5.0.0", "mermaid": "workspace:*",
"mermaid": "workspace:*" "rimraf": "^5.0.5"
}, },
"files": [ "files": [
"dist" "dist"

View File

@@ -29,15 +29,15 @@
"author": "Knut Sveidqvist", "author": "Knut Sveidqvist",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"d3": "^7.4.0", "d3": "^7.9.0",
"dagre-d3-es": "7.0.10", "dagre-d3-es": "7.0.10",
"khroma": "^2.0.0", "elkjs": "^0.9.2",
"elkjs": "^0.9.0" "khroma": "^2.1.0"
}, },
"devDependencies": { "devDependencies": {
"concurrently": "^8.0.0", "concurrently": "^8.2.2",
"rimraf": "^5.0.0", "mermaid": "workspace:^",
"mermaid": "workspace:^" "rimraf": "^5.0.5"
}, },
"files": [ "files": [
"dist" "dist"

View File

@@ -1,6 +1,6 @@
// @ts-ignore: JISON typing missing // @ts-ignore: JISON typing missing
import parser from '../../mermaid/src/diagrams/flowchart/parser/flow.jison'; import parser from '../../mermaid/src/diagrams/flowchart/parser/flow.jison';
import * as db from '../../mermaid/src/diagrams/flowchart/flowDb.js'; import db from '../../mermaid/src/diagrams/flowchart/flowDb.js';
import styles from '../../mermaid/src/diagrams/flowchart/styles.js'; import styles from '../../mermaid/src/diagrams/flowchart/styles.js';
import renderer from './flowRenderer-elk.js'; import renderer from './flowRenderer-elk.js';

View File

@@ -6,6 +6,7 @@ import { findCommonAncestor } from './render-utils.js';
import { labelHelper } from '../../mermaid/src/dagre-wrapper/shapes/util.js'; import { labelHelper } from '../../mermaid/src/dagre-wrapper/shapes/util.js';
import { getConfig } from '../../mermaid/src/config.js'; import { getConfig } from '../../mermaid/src/config.js';
import { log } from '../../mermaid/src/logger.js'; import { log } from '../../mermaid/src/logger.js';
import utils from '../../mermaid/src/utils.js';
import { setupGraphViewbox } from '../../mermaid/src/setupGraphViewbox.js'; import { setupGraphViewbox } from '../../mermaid/src/setupGraphViewbox.js';
import common from '../../mermaid/src/diagrams/common/common.js'; import common from '../../mermaid/src/diagrams/common/common.js';
import { interpolateToCurve, getStylesFromArray } from '../../mermaid/src/utils.js'; import { interpolateToCurve, getStylesFromArray } from '../../mermaid/src/utils.js';
@@ -655,6 +656,11 @@ const insertEdge = function (edgesEl, edge, edgeData, diagObj, parentLookupDb, i
.attr('d', curve(points)) .attr('d', curve(points))
.attr('class', 'path ' + edgeData.classes) .attr('class', 'path ' + edgeData.classes)
.attr('fill', 'none'); .attr('fill', 'none');
Object.entries(edgeData).forEach(([key, value]) => {
if (key !== 'classes') {
edgePath.attr(key, value);
}
});
const edgeG = edgesEl.insert('g').attr('class', 'edgeLabel'); const edgeG = edgesEl.insert('g').attr('class', 'edgeLabel');
const edgeWithLabel = select(edgeG.node().appendChild(edge.labelEl)); const edgeWithLabel = select(edgeG.node().appendChild(edge.labelEl));
const box = edgeWithLabel.node().firstChild.getBoundingClientRect(); const box = edgeWithLabel.node().firstChild.getBoundingClientRect();
@@ -702,21 +708,15 @@ const insertChildren = (nodeArray, parentLookupDb) => {
*/ */
export const draw = async function (text, id, _version, diagObj) { export const draw = async function (text, id, _version, diagObj) {
// Add temporary render element const { securityLevel, flowchart: conf } = getConfig();
diagObj.db.clear();
nodeDb = {}; nodeDb = {};
portPos = {}; portPos = {};
diagObj.db.setGen('gen-2');
// Parse the graph definition
diagObj.parser.parse(text);
const renderEl = select('body').append('div').attr('style', 'height:400px').attr('id', 'cy'); const renderEl = select('body').append('div').attr('style', 'height:400px').attr('id', 'cy');
let graph = { let graph = {
id: 'root', id: 'root',
layoutOptions: { layoutOptions: {
'elk.hierarchyHandling': 'INCLUDE_CHILDREN', 'elk.hierarchyHandling': 'INCLUDE_CHILDREN',
'org.eclipse.elk.padding': '[top=100, left=100, bottom=110, right=110]', 'elk.layered.spacing.edgeNodeBetweenLayers': conf?.nodeSpacing ? `${conf.nodeSpacing}` : '30',
'elk.layered.spacing.edgeNodeBetweenLayers': '30',
// 'elk.layered.mergeEdges': 'true', // 'elk.layered.mergeEdges': 'true',
'elk.direction': 'DOWN', 'elk.direction': 'DOWN',
// 'elk.ports.sameLayerEdges': true, // 'elk.ports.sameLayerEdges': true,
@@ -744,7 +744,6 @@ export const draw = async function (text, id, _version, diagObj) {
graph.layoutOptions['elk.direction'] = 'LEFT'; graph.layoutOptions['elk.direction'] = 'LEFT';
break; break;
} }
const { securityLevel, flowchart: conf } = getConfig();
// Find the root dom node to ne used in rendering // Find the root dom node to ne used in rendering
// Handle root and document for when rendering in sandbox mode // Handle root and document for when rendering in sandbox mode
@@ -759,7 +758,6 @@ export const draw = async function (text, id, _version, diagObj) {
const doc = securityLevel === 'sandbox' ? sandboxElement.nodes()[0].contentDocument : document; const doc = securityLevel === 'sandbox' ? sandboxElement.nodes()[0].contentDocument : document;
const svg = root.select(`[id="${id}"]`); const svg = root.select(`[id="${id}"]`);
// Define the supported markers for the diagram // Define the supported markers for the diagram
const markers = ['point', 'circle', 'cross']; const markers = ['point', 'circle', 'cross'];
@@ -841,6 +839,7 @@ export const draw = async function (text, id, _version, diagObj) {
log.info('after layout', JSON.stringify(graph, null, 2)); log.info('after layout', JSON.stringify(graph, null, 2));
const g = await elk.layout(graph); const g = await elk.layout(graph);
drawNodes(0, 0, g.children, svg, subGraphsEl, diagObj, 0); drawNodes(0, 0, g.children, svg, subGraphsEl, diagObj, 0);
utils.insertTitle(svg, 'flowchartTitleText', conf.titleTopMargin, diagObj.db.getDiagramTitle());
log.info('after layout', g); log.info('after layout', g);
g.edges?.map((edge) => { g.edges?.map((edge) => {
insertEdge(edgesEl, edge, edge.edgeData, diagObj, parentLookupDb, id); insertEdge(edgesEl, edge, edge.edgeData, diagObj, parentLookupDb, id);

View File

@@ -34,7 +34,7 @@
], ],
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@zenuml/core": "^3.17.2" "@zenuml/core": "^3.19.2"
}, },
"devDependencies": { "devDependencies": {
"mermaid": "workspace:^" "mermaid": "workspace:^"

View File

@@ -68,69 +68,69 @@
] ]
}, },
"dependencies": { "dependencies": {
"@braintree/sanitize-url": "^6.0.1", "@braintree/sanitize-url": "^7.0.1",
"@mermaid-js/parser": "workspace:^", "@mermaid-js/parser": "workspace:^",
"cytoscape": "^3.28.1", "cytoscape": "^3.28.1",
"cytoscape-cose-bilkent": "^4.1.0", "cytoscape-cose-bilkent": "^4.1.0",
"d3": "^7.4.0", "d3": "^7.9.0",
"d3-sankey": "^0.12.3", "d3-sankey": "^0.12.3",
"dagre-d3-es": "7.0.10", "dagre-d3-es": "7.0.10",
"dayjs": "^1.11.7", "dayjs": "^1.11.10",
"dompurify": "^3.0.5", "dompurify": "^3.0.11",
"elkjs": "^0.9.0", "elkjs": "^0.9.2",
"katex": "^0.16.9", "katex": "^0.16.9",
"khroma": "^2.0.0", "khroma": "^2.1.0",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"mdast-util-from-markdown": "^1.3.0", "mdast-util-from-markdown": "^2.0.0",
"stylis": "^4.1.3", "stylis": "^4.3.1",
"ts-dedent": "^2.2.0", "ts-dedent": "^2.2.0",
"uuid": "^9.0.0" "uuid": "^9.0.1"
}, },
"devDependencies": { "devDependencies": {
"@adobe/jsonschema2md": "^7.1.4", "@adobe/jsonschema2md": "^7.1.5",
"@types/cytoscape": "^3.19.9", "@types/cytoscape": "^3.19.16",
"@types/d3": "^7.4.0", "@types/d3": "^7.4.3",
"@types/d3-sankey": "^0.12.1", "@types/d3-sankey": "^0.12.4",
"@types/d3-scale": "^4.0.3", "@types/d3-scale": "^4.0.8",
"@types/d3-scale-chromatic": "^3.0.0", "@types/d3-scale-chromatic": "^3.0.3",
"@types/d3-selection": "^3.0.5", "@types/d3-selection": "^3.0.10",
"@types/d3-shape": "^3.1.1", "@types/d3-shape": "^3.1.6",
"@types/dompurify": "^3.0.2", "@types/dompurify": "^3.0.5",
"@types/jsdom": "^21.1.1", "@types/jsdom": "^21.1.6",
"@types/katex": "^0.16.7", "@types/katex": "^0.16.7",
"@types/lodash-es": "^4.17.7", "@types/lodash-es": "^4.17.12",
"@types/micromatch": "^4.0.2", "@types/micromatch": "^4.0.6",
"@types/prettier": "^2.7.2", "@types/prettier": "^3.0.0",
"@types/stylis": "^4.0.2", "@types/stylis": "^4.2.5",
"@types/uuid": "^9.0.1", "@types/uuid": "^9.0.8",
"@typescript-eslint/eslint-plugin": "^5.59.0", "@typescript-eslint/eslint-plugin": "^7.3.1",
"@typescript-eslint/parser": "^5.59.0", "@typescript-eslint/parser": "^7.3.1",
"ajv": "^8.11.2", "ajv": "^8.12.0",
"chokidar": "^3.5.3", "chokidar": "^3.6.0",
"concurrently": "^8.0.1", "concurrently": "^8.2.2",
"cpy-cli": "^4.2.0", "cpy-cli": "^5.0.0",
"csstree-validator": "^3.0.0", "csstree-validator": "^3.0.0",
"globby": "^13.1.4", "globby": "^14.0.1",
"jison": "^0.4.18", "jison": "^0.4.18",
"js-base64": "^3.7.5", "js-base64": "^3.7.7",
"jsdom": "^22.0.0", "jsdom": "^24.0.0",
"json-schema-to-typescript": "^11.0.3", "json-schema-to-typescript": "^13.1.2",
"micromatch": "^4.0.5", "micromatch": "^4.0.5",
"path-browserify": "^1.0.1", "path-browserify": "^1.0.1",
"prettier": "^2.8.8", "prettier": "^3.2.5",
"remark": "^14.0.2", "remark": "^15.0.1",
"remark-frontmatter": "^4.0.1", "remark-frontmatter": "^5.0.0",
"remark-gfm": "^3.0.1", "remark-gfm": "^4.0.0",
"rimraf": "^5.0.0", "rimraf": "^5.0.5",
"start-server-and-test": "^2.0.0", "start-server-and-test": "^2.0.3",
"type-fest": "^4.1.0", "type-fest": "^4.13.1",
"typedoc": "^0.25.0", "typedoc": "^0.25.12",
"typedoc-plugin-markdown": "^3.15.2", "typedoc-plugin-markdown": "^3.17.1",
"typescript": "^5.0.4", "typescript": "^5.4.3",
"unist-util-flatmap": "^1.0.0", "unist-util-flatmap": "^1.0.0",
"unist-util-visit": "^4.1.2", "unist-util-visit": "^5.0.0",
"vitepress": "^1.0.0-rc.40", "vitepress": "^1.0.1",
"vitepress-plugin-search": "^1.0.4-alpha.22" "vitepress-plugin-search": "1.0.4-alpha.22"
}, },
"files": [ "files": [
"dist/", "dist/",

View File

@@ -85,7 +85,7 @@ const LOGMSG_COPIED = `, and copied to ${FINAL_DOCS_DIR}`;
const WARN_DOCSDIR_DOESNT_MATCH = `Changed files were transformed in ${SOURCE_DOCS_DIR} but do not match the files in ${FINAL_DOCS_DIR}. Please run 'pnpm --filter mermaid run docs:build' after making changes to ${SOURCE_DOCS_DIR} to update the ${FINAL_DOCS_DIR} directory with the transformed files.`; const WARN_DOCSDIR_DOESNT_MATCH = `Changed files were transformed in ${SOURCE_DOCS_DIR} but do not match the files in ${FINAL_DOCS_DIR}. Please run 'pnpm --filter mermaid run docs:build' after making changes to ${SOURCE_DOCS_DIR} to update the ${FINAL_DOCS_DIR} directory with the transformed files.`;
const prettierConfig = prettier.resolveConfig.sync('.') ?? {}; const prettierConfig = (await prettier.resolveConfig('.')) ?? {};
// From https://github.com/vuejs/vitepress/blob/428eec3750d6b5648a77ac52d88128df0554d4d1/src/node/markdownToVue.ts#L20-L21 // From https://github.com/vuejs/vitepress/blob/428eec3750d6b5648a77ac52d88128df0554d4d1/src/node/markdownToVue.ts#L20-L21
const includesRE = /<!--\s*@include:\s*(.*?)\s*-->/g; const includesRE = /<!--\s*@include:\s*(.*?)\s*-->/g;
const includedFiles: Set<string> = new Set(); const includedFiles: Set<string> = new Set();
@@ -326,7 +326,7 @@ export function transformMarkdownAst({
* *
* @param file {string} name of the file that will be verified * @param file {string} name of the file that will be verified
*/ */
const transformMarkdown = (file: string) => { const transformMarkdown = async (file: string) => {
const doc = injectPlaceholders(transformIncludeStatements(file, readSyncedUTF8file(file))); const doc = injectPlaceholders(transformIncludeStatements(file, readSyncedUTF8file(file)));
let transformed = remark() let transformed = remark()
@@ -347,7 +347,7 @@ const transformMarkdown = (file: string) => {
transformed = doc; transformed = doc;
} }
const formatted = prettier.format(transformed, { const formatted = await prettier.format(transformed, {
parser: 'markdown', parser: 'markdown',
...prettierConfig, ...prettierConfig,
}); });
@@ -454,7 +454,7 @@ async function transformJsonSchema(file: string) {
const transformed = transformer.stringify(await transformer.run(markdownAst as Root)); const transformed = transformer.stringify(await transformer.run(markdownAst as Root));
const formatted = prettier.format(transformed, { const formatted = await prettier.format(transformed, {
parser: 'markdown', parser: 'markdown',
...prettierConfig, ...prettierConfig,
}); });
@@ -472,7 +472,7 @@ async function transformJsonSchema(file: string) {
* *
* @param filename {string} name of the HTML file to transform * @param filename {string} name of the HTML file to transform
*/ */
const transformHtml = (filename: string) => { const transformHtml = async (filename: string) => {
/** /**
* Insert the '...auto generated...' comment into an HTML file after the<html> element * Insert the '...auto generated...' comment into an HTML file after the<html> element
* *
@@ -496,7 +496,7 @@ const transformHtml = (filename: string) => {
}; };
const transformedHTML = insertAutoGeneratedComment(filename); const transformedHTML = insertAutoGeneratedComment(filename);
const formattedHTML = prettier.format(transformedHTML, { const formattedHTML = await prettier.format(transformedHTML, {
parser: 'html', parser: 'html',
...prettierConfig, ...prettierConfig,
}); });
@@ -541,7 +541,7 @@ export const processDocs = async () => {
const mdFileGlobs = getGlobs([posix.join(sourceDirGlob, '*.md')]); const mdFileGlobs = getGlobs([posix.join(sourceDirGlob, '*.md')]);
const mdFiles = await getFilesFromGlobs(mdFileGlobs); const mdFiles = await getFilesFromGlobs(mdFileGlobs);
console.log(`${action} ${mdFiles.length} markdown files...`); console.log(`${action} ${mdFiles.length} markdown files...`);
mdFiles.forEach(transformMarkdown); await Promise.all(mdFiles.map(transformMarkdown));
for (const includedFile of includedFiles) { for (const includedFile of includedFiles) {
rmSync(includedFile, { force: true }); rmSync(includedFile, { force: true });
@@ -552,7 +552,7 @@ export const processDocs = async () => {
const htmlFileGlobs = getGlobs([posix.join(sourceDirGlob, '*.html')]); const htmlFileGlobs = getGlobs([posix.join(sourceDirGlob, '*.html')]);
const htmlFiles = await getFilesFromGlobs(htmlFileGlobs); const htmlFiles = await getFilesFromGlobs(htmlFileGlobs);
console.log(`${action} ${htmlFiles.length} html files...`); console.log(`${action} ${htmlFiles.length} html files...`);
htmlFiles.forEach(transformHtml); await Promise.all(htmlFiles.map(transformHtml));
const otherFileGlobs = getGlobs([sourceDirGlob, '!**/*.md', '!**/*.html']); const otherFileGlobs = getGlobs([sourceDirGlob, '!**/*.md', '!**/*.html']);
const otherFiles = await getFilesFromGlobs(otherFileGlobs); const otherFiles = await getFilesFromGlobs(otherFileGlobs);
@@ -591,9 +591,9 @@ export const processDocs = async () => {
return; return;
} }
if (isMd(path)) { if (isMd(path)) {
transformMarkdown(path); void transformMarkdown(path);
} else if (isHtml(path)) { } else if (isHtml(path)) {
transformHtml(path); void transformHtml(path);
} else if (isOther(path)) { } else if (isOther(path)) {
copyTransformedContents(path, true); copyTransformedContents(path, true);
} }

View File

@@ -124,7 +124,7 @@ export const setConfig = (conf: MermaidConfig): MermaidConfig => {
* | --------- | ------------------------- | ----------- | ------------------------------ | * | --------- | ------------------------- | ----------- | ------------------------------ |
* | getConfig | Obtains the currentConfig | Get Request | Any Values from current Config | * | getConfig | Obtains the currentConfig | Get Request | Any Values from current Config |
* *
* **Notes**: Returns **any** the currentConfig * **Notes**: Avoid calling this function repeatedly. Instead, store the result in a variable and use it, and pass it down to function calls.
* *
* @returns The currentConfig * @returns The currentConfig
*/ */

View File

@@ -159,6 +159,13 @@ export interface MermaidConfig {
dompurifyConfig?: DOMPurifyConfiguration; dompurifyConfig?: DOMPurifyConfiguration;
wrap?: boolean; wrap?: boolean;
fontSize?: number; fontSize?: number;
markdownAutoWrap?: boolean;
/**
* Suppresses inserting 'Syntax error' diagram in the DOM.
* This is useful when you want to control how to handle syntax errors in your application.
*
*/
suppressErrorRendering?: boolean;
} }
/** /**
* The object containing configurations specific for packet diagrams. * The object containing configurations specific for packet diagrams.

View File

@@ -30,7 +30,7 @@ const rect = (parent, node) => {
// .appendChild(createLabel(node.labelText, node.labelStyle, undefined, true)); // .appendChild(createLabel(node.labelText, node.labelStyle, undefined, true));
const text = const text =
node.labelType === 'markdown' node.labelType === 'markdown'
? createText(label, node.labelText, { style: node.labelStyle, useHtmlLabels }) ? createText(label, node.labelText, { style: node.labelStyle, useHtmlLabels }, siteConfig)
: label.node().appendChild(createLabel(node.labelText, node.labelStyle, undefined, true)); : label.node().appendChild(createLabel(node.labelText, node.labelStyle, undefined, true));
// Get the size of the label // Get the size of the label

View File

@@ -18,15 +18,21 @@ export const clear = () => {
}; };
export const insertEdgeLabel = (elem, edge) => { export const insertEdgeLabel = (elem, edge) => {
const useHtmlLabels = evaluate(getConfig().flowchart.htmlLabels); const config = getConfig();
const useHtmlLabels = evaluate(config.flowchart.htmlLabels);
// Create the actual text element // Create the actual text element
const labelElement = const labelElement =
edge.labelType === 'markdown' edge.labelType === 'markdown'
? createText(elem, edge.label, { ? createText(
elem,
edge.label,
{
style: edge.labelStyle, style: edge.labelStyle,
useHtmlLabels, useHtmlLabels,
addSvgBackground: true, addSvgBackground: true,
}) },
config
)
: createLabel(edge.label, edge.labelStyle); : createLabel(edge.label, edge.labelStyle);
// Create outer g, edgeLabel, this will be positioned after graph layout // Create outer g, edgeLabel, this will be positioned after graph layout

View File

@@ -54,6 +54,14 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit
if (node && node.clusterNode) { if (node && node.clusterNode) {
// const children = graph.children(v); // const children = graph.children(v);
log.info('Cluster identified', v, node.width, graph.node(v)); log.info('Cluster identified', v, node.width, graph.node(v));
// `node.graph.setGraph` applies the graph configurations such as nodeSpacing to subgraphs as without this the default values would be used
// We override only the `ranksep` and `nodesep` configurations to allow for setting subgraph spacing while avoiding overriding other properties
const { ranksep, nodesep } = graph.graph();
node.graph.setGraph({
...node.graph.graph(),
ranksep,
nodesep,
});
const o = await recursiveRender( const o = await recursiveRender(
nodes, nodes,
node.graph, node.graph,

View File

@@ -6,8 +6,9 @@ import { evaluate, sanitizeText } from '../../diagrams/common/common.js';
import { decodeEntities } from '../../utils.js'; import { decodeEntities } from '../../utils.js';
export const labelHelper = async (parent, node, _classes, isNode) => { export const labelHelper = async (parent, node, _classes, isNode) => {
const config = getConfig();
let classes; let classes;
const useHtmlLabels = node.useHtmlLabels || evaluate(getConfig().flowchart.htmlLabels); const useHtmlLabels = node.useHtmlLabels || evaluate(config.flowchart.htmlLabels);
if (!_classes) { if (!_classes) {
classes = 'node default'; classes = 'node default';
} else { } else {
@@ -35,26 +36,26 @@ export const labelHelper = async (parent, node, _classes, isNode) => {
let text; let text;
if (node.labelType === 'markdown') { if (node.labelType === 'markdown') {
// text = textNode; // text = textNode;
text = createText(label, sanitizeText(decodeEntities(labelText), getConfig()), { text = createText(
label,
sanitizeText(decodeEntities(labelText), config),
{
useHtmlLabels, useHtmlLabels,
width: node.width || getConfig().flowchart.wrappingWidth, width: node.width || config.flowchart.wrappingWidth,
classes: 'markdown-node-label', classes: 'markdown-node-label',
}); },
config
);
} else { } else {
text = textNode.appendChild( text = textNode.appendChild(
createLabel( createLabel(sanitizeText(decodeEntities(labelText), config), node.labelStyle, false, isNode)
sanitizeText(decodeEntities(labelText), getConfig()),
node.labelStyle,
false,
isNode
)
); );
} }
// Get the size of the label // Get the size of the label
let bbox = text.getBBox(); let bbox = text.getBBox();
const halfPadding = node.padding / 2; const halfPadding = node.padding / 2;
if (evaluate(getConfig().flowchart.htmlLabels)) { if (evaluate(config.flowchart.htmlLabels)) {
const div = text.children[0]; const div = text.children[0];
const dv = select(text); const dv = select(text);
@@ -76,8 +77,8 @@ export const labelHelper = async (parent, node, _classes, isNode) => {
if (noImgText) { if (noImgText) {
// default size if no text // default size if no text
const bodyFontSize = getConfig().fontSize const bodyFontSize = config.fontSize
? getConfig().fontSize ? config.fontSize
: window.getComputedStyle(document.body).fontSize; : window.getComputedStyle(document.body).fontSize;
const enlargingFactor = 5; const enlargingFactor = 5;
const width = parseInt(bodyFontSize, 10) * enlargingFactor + 'px'; const width = parseInt(bodyFontSize, 10) * enlargingFactor + 'px';

View File

@@ -53,7 +53,7 @@ describe('diagram-orchestration', () => {
expect(() => expect(() =>
detectType('flowchart TD; A-->B', { flowchart: { defaultRenderer: 'dagre-d3' } }) detectType('flowchart TD; A-->B', { flowchart: { defaultRenderer: 'dagre-d3' } })
).toThrowErrorMatchingInlineSnapshot( ).toThrowErrorMatchingInlineSnapshot(
'"No diagram type detected matching given configuration for text: flowchart TD; A-->B"' `[UnknownDiagramError: No diagram type detected matching given configuration for text: flowchart TD; A-->B]`
); );
// graph & dagre-wrapper => flowchart-v2 // graph & dagre-wrapper => flowchart-v2

View File

@@ -17,16 +17,16 @@ describe('DiagramAPI', () => {
it('should throw error if diagram is not defined', () => { it('should throw error if diagram is not defined', () => {
expect(() => getDiagram('loki')).toThrowErrorMatchingInlineSnapshot( expect(() => getDiagram('loki')).toThrowErrorMatchingInlineSnapshot(
'"Diagram loki not found."' `[Error: Diagram loki not found.]`
); );
}); });
it('should handle diagram registrations', () => { it('should handle diagram registrations', () => {
expect(() => getDiagram('loki')).toThrowErrorMatchingInlineSnapshot( expect(() => getDiagram('loki')).toThrowErrorMatchingInlineSnapshot(
'"Diagram loki not found."' `[Error: Diagram loki not found.]`
); );
expect(() => detectType('loki diagram')).toThrowErrorMatchingInlineSnapshot( expect(() => detectType('loki diagram')).toThrowErrorMatchingInlineSnapshot(
'"No diagram type detected matching given configuration for text: loki diagram"' `[UnknownDiagramError: No diagram type detected matching given configuration for text: loki diagram]`
); );
const detector: DiagramDetector = (str: string) => { const detector: DiagramDetector = (str: string) => {
return str.match('loki') !== null; return str.match('loki') !== null;

View File

@@ -65,23 +65,23 @@ describe('diagram detection', () => {
test('should throw the right error for incorrect diagram', async () => { test('should throw the right error for incorrect diagram', async () => {
await expect(Diagram.fromText('graph TD; A-->')).rejects.toThrowErrorMatchingInlineSnapshot(` await expect(Diagram.fromText('graph TD; A-->')).rejects.toThrowErrorMatchingInlineSnapshot(`
"Parse error on line 2: [Error: Parse error on line 2:
graph TD; A--> graph TD; A-->
--------------^ --------------^
Expecting 'AMP', 'COLON', 'PIPE', 'TESTSTR', 'DOWN', 'DEFAULT', 'NUM', 'COMMA', 'NODE_STRING', 'BRKT', 'MINUS', 'MULT', 'UNICODE_TEXT', got 'EOF'" Expecting 'AMP', 'COLON', 'PIPE', 'TESTSTR', 'DOWN', 'DEFAULT', 'NUM', 'COMMA', 'NODE_STRING', 'BRKT', 'MINUS', 'MULT', 'UNICODE_TEXT', got 'EOF']
`); `);
await expect(Diagram.fromText('sequenceDiagram; A-->B')).rejects await expect(Diagram.fromText('sequenceDiagram; A-->B')).rejects
.toThrowErrorMatchingInlineSnapshot(` .toThrowErrorMatchingInlineSnapshot(`
"Parse error on line 1: [Error: Parse error on line 1:
...quenceDiagram; A-->B ...quenceDiagram; A-->B
-----------------------^ -----------------------^
Expecting 'TXT', got 'NEWLINE'" Expecting 'TXT', got 'NEWLINE']
`); `);
}); });
test('should throw the right error for unregistered diagrams', async () => { test('should throw the right error for unregistered diagrams', async () => {
await expect(Diagram.fromText('thor TD; A-->B')).rejects.toThrowErrorMatchingInlineSnapshot( await expect(Diagram.fromText('thor TD; A-->B')).rejects.toThrowErrorMatchingInlineSnapshot(
'"No diagram type detected matching given configuration for text: thor TD; A-->B"' `[UnknownDiagramError: No diagram type detected matching given configuration for text: thor TD; A-->B]`
); );
}); });

View File

@@ -346,11 +346,9 @@ export const renderKatex = async (text: string, config: MermaidConfig): Promise<
.split(lineBreakRegex) .split(lineBreakRegex)
.map((line) => .map((line) =>
hasKatex(line) hasKatex(line)
? ` ? `<div style="display: flex; align-items: center; justify-content: center; white-space: nowrap;">
<div style="display: flex; align-items: center; justify-content: center; white-space: nowrap;">
${line} ${line}
</div> </div>`
`
: `<div>${line}</div>` : `<div>${line}</div>`
) )
.join('') .join('')

View File

@@ -67,9 +67,8 @@ describe('the flowchart renderer', function () {
}); });
}); });
['Multi<br>Line', 'Multi<br/>Line', 'Multi<br />Line', 'Multi<br\t/>Line'].forEach(function ( ['Multi<br>Line', 'Multi<br/>Line', 'Multi<br />Line', 'Multi<br\t/>Line'].forEach(
labelText function (labelText) {
) {
it('should handle multiline texts with different line breaks', async function () { it('should handle multiline texts with different line breaks', async function () {
const addedNodes = []; const addedNodes = [];
const fakeDiag = { const fakeDiag = {
@@ -109,7 +108,8 @@ describe('the flowchart renderer', function () {
expect(addedNodes[0][1].label.firstChild.innerHTML).toEqual('Multi'); // <tspan> node, line 1 expect(addedNodes[0][1].label.firstChild.innerHTML).toEqual('Multi'); // <tspan> node, line 1
expect(addedNodes[0][1].label.lastChild.innerHTML).toEqual('Line'); // <tspan> node, line 2 expect(addedNodes[0][1].label.lastChild.innerHTML).toEqual('Line'); // <tspan> node, line 2
}); });
}); }
);
[ [
[['fill:#fff'], 'fill:#fff;', ''], [['fill:#fff'], 'fill:#fff;', ''],

View File

@@ -21,6 +21,7 @@ dayjs.extend(dayjsIsoWeek);
dayjs.extend(dayjsCustomParseFormat); dayjs.extend(dayjsCustomParseFormat);
dayjs.extend(dayjsAdvancedFormat); dayjs.extend(dayjsAdvancedFormat);
const WEEKEND_START_DAY = { friday: 5, saturday: 6 };
let dateFormat = ''; let dateFormat = '';
let axisFormat = ''; let axisFormat = '';
let tickInterval = undefined; let tickInterval = undefined;
@@ -37,6 +38,7 @@ let funs = [];
let inclusiveEndDates = false; let inclusiveEndDates = false;
let topAxis = false; let topAxis = false;
let weekday = 'sunday'; let weekday = 'sunday';
let weekend = 'saturday';
// The serial order of the task in the script // The serial order of the task in the script
let lastOrder = 0; let lastOrder = 0;
@@ -63,6 +65,7 @@ export const clear = function () {
links = {}; links = {};
commonClear(); commonClear();
weekday = 'sunday'; weekday = 'sunday';
weekend = 'saturday';
}; };
export const setAxisFormat = function (txt) { export const setAxisFormat = function (txt) {
@@ -167,7 +170,11 @@ export const isInvalidDate = function (date, dateFormat, excludes, includes) {
if (includes.includes(date.format(dateFormat.trim()))) { if (includes.includes(date.format(dateFormat.trim()))) {
return false; return false;
} }
if (date.isoWeekday() >= 6 && excludes.includes('weekends')) { if (
excludes.includes('weekends') &&
(date.isoWeekday() === WEEKEND_START_DAY[weekend] ||
date.isoWeekday() === WEEKEND_START_DAY[weekend] + 1)
) {
return true; return true;
} }
if (excludes.includes(date.format('dddd').toLowerCase())) { if (excludes.includes(date.format('dddd').toLowerCase())) {
@@ -184,6 +191,10 @@ export const getWeekday = function () {
return weekday; return weekday;
}; };
export const setWeekend = function (startDay) {
weekend = startDay;
};
/** /**
* TODO: fully document what this function does and what types it accepts * TODO: fully document what this function does and what types it accepts
* *
@@ -781,6 +792,7 @@ export default {
isInvalidDate, isInvalidDate,
setWeekday, setWeekday,
getWeekday, getWeekday,
setWeekend,
}; };
/** /**

View File

@@ -267,6 +267,21 @@ describe('when using the ganttDb', function () {
expect(tasks[6].task).toEqual('test7'); expect(tasks[6].task).toEqual('test7');
}); });
it('should ignore weekends starting on friday', function () {
ganttDb.setDateFormat('YYYY-MM-DD');
ganttDb.setExcludes('weekends');
ganttDb.setWeekend('friday');
ganttDb.addSection('friday-saturday weekends skip test');
ganttDb.addTask('test1', 'id1,2024-02-28, 3d');
const tasks = ganttDb.getTasks();
expect(tasks[0].startTime).toEqual(dayjs('2024-02-28', 'YYYY-MM-DD').toDate());
expect(tasks[0].endTime).toEqual(dayjs('2024-03-04', 'YYYY-MM-DD').toDate());
expect(tasks[0].id).toEqual('id1');
expect(tasks[0].task).toEqual('test1');
});
it('should maintain the order in which tasks are created', function () { it('should maintain the order in which tasks are created', function () {
ganttDb.setAccTitle('Project Execution'); ganttDb.setAccTitle('Project Execution');
ganttDb.setDateFormat('YYYY-MM-DD'); ganttDb.setDateFormat('YYYY-MM-DD');

View File

@@ -84,6 +84,8 @@ weekday\s+thursday return 'weekday_thursday'
weekday\s+friday return 'weekday_friday' weekday\s+friday return 'weekday_friday'
weekday\s+saturday return 'weekday_saturday' weekday\s+saturday return 'weekday_saturday'
weekday\s+sunday return 'weekday_sunday' weekday\s+sunday return 'weekday_sunday'
weekend\s+friday return 'weekend_friday'
weekend\s+saturday return 'weekend_saturday'
\d\d\d\d"-"\d\d"-"\d\d return 'date'; \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' "accDescription"\s[^#\n;]+ return 'accDescription'
@@ -128,6 +130,11 @@ weekday
| weekday_sunday { yy.setWeekday("sunday");} | weekday_sunday { yy.setWeekday("sunday");}
; ;
weekend
: weekend_friday { yy.setWeekend("friday");}
| weekend_saturday { yy.setWeekend("saturday");}
;
statement statement
: dateFormat {yy.setDateFormat($1.substr(11));$$=$1.substr(11);} : dateFormat {yy.setDateFormat($1.substr(11));$$=$1.substr(11);}
| inclusiveEndDates {yy.enableInclusiveEndDates();$$=$1.substr(18);} | inclusiveEndDates {yy.enableInclusiveEndDates();$$=$1.substr(18);}
@@ -138,6 +145,7 @@ statement
| includes {yy.setIncludes($1.substr(9));$$=$1.substr(9);} | includes {yy.setIncludes($1.substr(9));$$=$1.substr(9);}
| todayMarker {yy.setTodayMarker($1.substr(12));$$=$1.substr(12);} | todayMarker {yy.setTodayMarker($1.substr(12));$$=$1.substr(12);}
| weekday | weekday
| weekend
| title {yy.setDiagramTitle($1.substr(6));$$=$1.substr(6);} | title {yy.setDiagramTitle($1.substr(6));$$=$1.substr(6);}
| acc_title acc_title_value { $$=$2.trim();yy.setAccTitle($$); } | acc_title acc_title_value { $$=$2.trim();yy.setAccTitle($$); }
| acc_descr acc_descr_value { $$=$2.trim();yy.setAccDescription($$); } | acc_descr acc_descr_value { $$=$2.trim();yy.setAccDescription($$); }

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