mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-11-13 01:04:12 +01:00
Merge branch 'develop' into UpdateClasstoMatchUmlSpecs
This commit is contained in:
9
codecov.yaml → .github/codecov.yaml
vendored
9
codecov.yaml → .github/codecov.yaml
vendored
@@ -1,6 +1,15 @@
|
|||||||
|
codecov:
|
||||||
|
branch: develop
|
||||||
|
|
||||||
comment:
|
comment:
|
||||||
layout: 'reach, diff, flags, files'
|
layout: 'reach, diff, flags, files'
|
||||||
behavior: default
|
behavior: default
|
||||||
require_changes: false # if true: only post the comment if coverage changes
|
require_changes: false # if true: only post the comment if coverage changes
|
||||||
require_base: no # [yes :: must have a base report to post]
|
require_base: no # [yes :: must have a base report to post]
|
||||||
require_head: yes # [yes :: must have a head report to post]
|
require_head: yes # [yes :: must have a head report to post]
|
||||||
|
|
||||||
|
coverage:
|
||||||
|
status:
|
||||||
|
project:
|
||||||
|
default:
|
||||||
|
threshold: 2%
|
||||||
4
.github/workflows/build-docs.yml
vendored
4
.github/workflows/build-docs.yml
vendored
@@ -2,13 +2,13 @@ name: Build Vitepress docs
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
|
merge_group:
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
# Build job
|
build-docs:
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
|
|||||||
3
.github/workflows/build.yml
vendored
3
.github/workflows/build.yml
vendored
@@ -2,6 +2,7 @@ name: Build
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push: {}
|
push: {}
|
||||||
|
merge_group:
|
||||||
pull_request:
|
pull_request:
|
||||||
types:
|
types:
|
||||||
- opened
|
- opened
|
||||||
@@ -12,7 +13,7 @@ permissions:
|
|||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build-mermaid:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
|
|||||||
2
.github/workflows/check-readme-in-sync.yml
vendored
2
.github/workflows/check-readme-in-sync.yml
vendored
@@ -14,7 +14,7 @@ permissions:
|
|||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check:
|
check-readme:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
|
|||||||
7
.github/workflows/checks.yml
vendored
7
.github/workflows/checks.yml
vendored
@@ -1,15 +1,16 @@
|
|||||||
on:
|
on:
|
||||||
push: {}
|
push:
|
||||||
|
merge_group:
|
||||||
pull_request:
|
pull_request:
|
||||||
types:
|
types:
|
||||||
- opened
|
- opened
|
||||||
- synchronize
|
- synchronize
|
||||||
- ready_for_review
|
- ready_for_review
|
||||||
|
|
||||||
name: Static analysis
|
name: Static analysis on Test files
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
check-tests:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
name: check tests
|
name: check tests
|
||||||
if: github.repository_owner == 'mermaid-js'
|
if: github.repository_owner == 'mermaid-js'
|
||||||
|
|||||||
2
.github/workflows/e2e-applitools.yml
vendored
2
.github/workflows/e2e-applitools.yml
vendored
@@ -19,7 +19,7 @@ env:
|
|||||||
USE_APPLI: ${{ secrets.APPLITOOLS_API_KEY && 'true' || '' }}
|
USE_APPLI: ${{ secrets.APPLITOOLS_API_KEY && 'true' || '' }}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
e2e-applitools:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
|
|||||||
9
.github/workflows/e2e.yml
vendored
9
.github/workflows/e2e.yml
vendored
@@ -1,12 +1,15 @@
|
|||||||
name: E2E
|
name: E2E
|
||||||
|
|
||||||
on: [push, pull_request]
|
on:
|
||||||
|
push:
|
||||||
|
pull_request:
|
||||||
|
merge_group:
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
e2e:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
@@ -49,7 +52,7 @@ jobs:
|
|||||||
files: coverage/cypress/lcov.info
|
files: coverage/cypress/lcov.info
|
||||||
flags: e2e
|
flags: e2e
|
||||||
name: mermaid-codecov
|
name: mermaid-codecov
|
||||||
fail_ci_if_error: true
|
fail_ci_if_error: false
|
||||||
verbose: true
|
verbose: true
|
||||||
- name: Upload Artifacts
|
- name: Upload Artifacts
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
|
|||||||
3
.github/workflows/lint.yml
vendored
3
.github/workflows/lint.yml
vendored
@@ -1,7 +1,8 @@
|
|||||||
name: Lint
|
name: Lint
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push: {}
|
push:
|
||||||
|
merge_group:
|
||||||
pull_request:
|
pull_request:
|
||||||
types:
|
types:
|
||||||
- opened
|
- opened
|
||||||
|
|||||||
6
.github/workflows/publish-docs.yml
vendored
6
.github/workflows/publish-docs.yml
vendored
@@ -19,7 +19,7 @@ concurrency:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
# Build job
|
# Build job
|
||||||
build:
|
build-docs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
@@ -48,11 +48,11 @@ jobs:
|
|||||||
path: packages/mermaid/src/vitepress/.vitepress/dist
|
path: packages/mermaid/src/vitepress/.vitepress/dist
|
||||||
|
|
||||||
# Deployment job
|
# Deployment job
|
||||||
deploy:
|
deploy-docs:
|
||||||
environment:
|
environment:
|
||||||
name: github-pages
|
name: github-pages
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: build
|
needs: build-docs
|
||||||
steps:
|
steps:
|
||||||
- name: Deploy to GitHub Pages
|
- name: Deploy to GitHub Pages
|
||||||
id: deployment
|
id: deployment
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ on:
|
|||||||
- 'release/**'
|
- 'release/**'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
publish:
|
publish-preview:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|||||||
12
.github/workflows/test.yml
vendored
12
.github/workflows/test.yml
vendored
@@ -1,12 +1,12 @@
|
|||||||
name: Unit Tests
|
name: Unit Tests
|
||||||
|
|
||||||
on: [push, pull_request]
|
on: [push, pull_request, merge_group]
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
unit-test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
@@ -47,11 +47,5 @@ jobs:
|
|||||||
files: ./coverage/vitest/lcov.info
|
files: ./coverage/vitest/lcov.info
|
||||||
flags: unit
|
flags: unit
|
||||||
name: mermaid-codecov
|
name: mermaid-codecov
|
||||||
fail_ci_if_error: true
|
fail_ci_if_error: false
|
||||||
verbose: true
|
verbose: true
|
||||||
# Coveralls is throwing 500. Disabled for now.
|
|
||||||
# - name: Upload Coverage to Coveralls
|
|
||||||
# uses: coverallsapp/github-action@v2
|
|
||||||
# with:
|
|
||||||
# github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
# flag-name: unit
|
|
||||||
|
|||||||
2
.github/workflows/update-browserlist.yml
vendored
2
.github/workflows/update-browserlist.yml
vendored
@@ -5,7 +5,7 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
update-browser-list:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|||||||
13
__mocks__/sankeyRenderer.js
Normal file
13
__mocks__/sankeyRenderer.js
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
/**
|
||||||
|
* Mocked Sankey diagram renderer
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { vi } from 'vitest';
|
||||||
|
|
||||||
|
export const draw = vi.fn().mockImplementation(() => {
|
||||||
|
return '';
|
||||||
|
});
|
||||||
|
|
||||||
|
export default {
|
||||||
|
draw,
|
||||||
|
};
|
||||||
@@ -106,6 +106,7 @@
|
|||||||
"rehype",
|
"rehype",
|
||||||
"roledescription",
|
"roledescription",
|
||||||
"sandboxed",
|
"sandboxed",
|
||||||
|
"sankey",
|
||||||
"setupgraphviewbox",
|
"setupgraphviewbox",
|
||||||
"shiki",
|
"shiki",
|
||||||
"sidharth",
|
"sidharth",
|
||||||
|
|||||||
144
cypress/integration/rendering/sankey.spec.ts
Normal file
144
cypress/integration/rendering/sankey.spec.ts
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
|
||||||
|
|
||||||
|
describe('Sankey Diagram', () => {
|
||||||
|
it('should render a simple example', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
sankey-beta
|
||||||
|
|
||||||
|
sourceNode,targetNode,10
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when given a linkColor', function () {
|
||||||
|
this.beforeAll(() => {
|
||||||
|
cy.wrap(
|
||||||
|
`sankey-beta
|
||||||
|
a,b,10
|
||||||
|
`
|
||||||
|
).as('graph');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('links should use hex color', function () {
|
||||||
|
renderGraph(this.graph, { sankey: { linkColor: '#636465' } });
|
||||||
|
|
||||||
|
cy.get('.link path').should((link) => {
|
||||||
|
expect(link.attr('stroke')).to.equal('#636465');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('links should be the same color as source node', function () {
|
||||||
|
renderGraph(this.graph, { sankey: { linkColor: 'source' } });
|
||||||
|
|
||||||
|
cy.get('.link path').then((link) => {
|
||||||
|
cy.get('.node[id="node-1"] rect').should((node) =>
|
||||||
|
expect(link.attr('stroke')).to.equal(node.attr('fill'))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('links should be the same color as target node', function () {
|
||||||
|
renderGraph(this.graph, { sankey: { linkColor: 'target' } });
|
||||||
|
|
||||||
|
cy.get('.link path').then((link) => {
|
||||||
|
cy.get('.node[id="node-2"] rect').should((node) =>
|
||||||
|
expect(link.attr('stroke')).to.equal(node.attr('fill'))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('links must be gradient', function () {
|
||||||
|
renderGraph(this.graph, { sankey: { linkColor: 'gradient' } });
|
||||||
|
|
||||||
|
cy.get('.link path').should((link) => {
|
||||||
|
expect(link.attr('stroke')).to.equal('url(#linearGradient-3)');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when given a nodeAlignment', function () {
|
||||||
|
this.beforeAll(() => {
|
||||||
|
cy.wrap(
|
||||||
|
`
|
||||||
|
sankey-beta
|
||||||
|
|
||||||
|
a,b,8
|
||||||
|
b,c,8
|
||||||
|
c,d,8
|
||||||
|
d,e,8
|
||||||
|
|
||||||
|
x,c,4
|
||||||
|
c,y,4
|
||||||
|
`
|
||||||
|
).as('graph');
|
||||||
|
});
|
||||||
|
|
||||||
|
this.afterEach(() => {
|
||||||
|
cy.get('.node[id="node-1"]').should((node) => {
|
||||||
|
expect(node.attr('x')).to.equal('0');
|
||||||
|
});
|
||||||
|
cy.get('.node[id="node-2"]').should((node) => {
|
||||||
|
expect(node.attr('x')).to.equal('100');
|
||||||
|
});
|
||||||
|
cy.get('.node[id="node-3"]').should((node) => {
|
||||||
|
expect(node.attr('x')).to.equal('200');
|
||||||
|
});
|
||||||
|
cy.get('.node[id="node-4"]').should((node) => {
|
||||||
|
expect(node.attr('x')).to.equal('300');
|
||||||
|
});
|
||||||
|
cy.get('.node[id="node-5"]').should((node) => {
|
||||||
|
expect(node.attr('x')).to.equal('400');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should justify nodes', function () {
|
||||||
|
renderGraph(this.graph, {
|
||||||
|
sankey: { nodeAlignment: 'justify', width: 410, useMaxWidth: false },
|
||||||
|
});
|
||||||
|
cy.get('.node[id="node-6"]').should((node) => {
|
||||||
|
expect(node.attr('x')).to.equal('0');
|
||||||
|
});
|
||||||
|
cy.get('.node[id="node-7"]').should((node) => {
|
||||||
|
expect(node.attr('x')).to.equal('400');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should align nodes left', function () {
|
||||||
|
renderGraph(this.graph, {
|
||||||
|
sankey: { nodeAlignment: 'left', width: 410, useMaxWidth: false },
|
||||||
|
});
|
||||||
|
cy.get('.node[id="node-6"]').should((node) => {
|
||||||
|
expect(node.attr('x')).to.equal('0');
|
||||||
|
});
|
||||||
|
cy.get('.node[id="node-7"]').should((node) => {
|
||||||
|
expect(node.attr('x')).to.equal('300');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should align nodes right', function () {
|
||||||
|
renderGraph(this.graph, {
|
||||||
|
sankey: { nodeAlignment: 'right', width: 410, useMaxWidth: false },
|
||||||
|
});
|
||||||
|
cy.get('.node[id="node-6"]').should((node) => {
|
||||||
|
expect(node.attr('x')).to.equal('100');
|
||||||
|
});
|
||||||
|
cy.get('.node[id="node-7"]').should((node) => {
|
||||||
|
expect(node.attr('x')).to.equal('400');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should center nodes', function () {
|
||||||
|
renderGraph(this.graph, {
|
||||||
|
sankey: { nodeAlignment: 'center', width: 410, useMaxWidth: false },
|
||||||
|
});
|
||||||
|
cy.get('.node[id="node-6"]').should((node) => {
|
||||||
|
expect(node.attr('x')).to.equal('100');
|
||||||
|
});
|
||||||
|
cy.get('.node[id="node-7"]').should((node) => {
|
||||||
|
expect(node.attr('x')).to.equal('300');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -156,6 +156,81 @@ context('Sequence diagram', () => {
|
|||||||
`
|
`
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
it('should render a sequence diagram with basic actor creation and destruction', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
sequenceDiagram
|
||||||
|
Alice ->> Bob: Hello Bob, how are you ?
|
||||||
|
Bob ->> Alice: Fine, thank you. And you?
|
||||||
|
create participant Polo
|
||||||
|
Alice ->> Polo: Hi Polo!
|
||||||
|
create actor Ola1 as Ola
|
||||||
|
Polo ->> Ola1: Hiii
|
||||||
|
Ola1 ->> Alice: Hi too
|
||||||
|
destroy Ola1
|
||||||
|
Alice --x Ola1: Bye!
|
||||||
|
Alice ->> Bob: And now?
|
||||||
|
create participant Ola2 as Ola
|
||||||
|
Alice ->> Ola2: Hello again
|
||||||
|
destroy Alice
|
||||||
|
Alice --x Ola2: Bye for me!
|
||||||
|
destroy Bob
|
||||||
|
Ola2 --> Bob: The end
|
||||||
|
`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('should render a sequence diagram with actor creation and destruction coupled with backgrounds, loops and notes', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
sequenceDiagram
|
||||||
|
accTitle: test the accTitle
|
||||||
|
accDescr: Test a description
|
||||||
|
|
||||||
|
participant Alice
|
||||||
|
participant Bob
|
||||||
|
autonumber 10 10
|
||||||
|
rect rgb(200, 220, 100)
|
||||||
|
rect rgb(200, 255, 200)
|
||||||
|
|
||||||
|
Alice ->> Bob: Hello Bob, how are you?
|
||||||
|
create participant John as John<br />Second Line
|
||||||
|
Bob-->>John: How about you John?
|
||||||
|
end
|
||||||
|
|
||||||
|
Bob--x Alice: I am good thanks!
|
||||||
|
Bob-x John: I am good thanks!
|
||||||
|
Note right of John: John thinks a long<br />long time, so long<br />that the text does<br />not fit on a row.
|
||||||
|
|
||||||
|
Bob-->Alice: Checking with John...
|
||||||
|
Note over John:wrap: John looks like he's still thinking, so Bob prods him a bit.
|
||||||
|
Bob-x John: Hey John - we're still waiting to know<br />how you're doing
|
||||||
|
Note over John:nowrap: John's trying hard not to break his train of thought.
|
||||||
|
destroy John
|
||||||
|
Bob-x John: John! Cmon!
|
||||||
|
Note over John: After a few more moments, John<br />finally snaps out of it.
|
||||||
|
end
|
||||||
|
|
||||||
|
autonumber off
|
||||||
|
alt either this
|
||||||
|
create actor Lola
|
||||||
|
Alice->>+Lola: Yes
|
||||||
|
Lola-->>-Alice: OK
|
||||||
|
else or this
|
||||||
|
autonumber
|
||||||
|
Alice->>Lola: No
|
||||||
|
else or this will happen
|
||||||
|
Alice->Lola: Maybe
|
||||||
|
end
|
||||||
|
autonumber 200
|
||||||
|
par this happens in parallel
|
||||||
|
destroy Bob
|
||||||
|
Alice -->> Bob: Parallel message 1
|
||||||
|
and
|
||||||
|
Alice -->> Lola: Parallel message 2
|
||||||
|
end
|
||||||
|
`
|
||||||
|
);
|
||||||
|
});
|
||||||
context('font settings', () => {
|
context('font settings', () => {
|
||||||
it('should render different note fonts when configured', () => {
|
it('should render different note fonts when configured', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
|
|||||||
@@ -75,6 +75,9 @@
|
|||||||
<li>
|
<li>
|
||||||
<h2><a href="./zenuml.html">ZenUML</a></h2>
|
<h2><a href="./zenuml.html">ZenUML</a></h2>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<h2><a href="./sankey.html">Sankey</a></h2>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
108
demos/sankey.html
Normal file
108
demos/sankey.html
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" xmlns="http://www.w3.org/1999/html">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<title>States Mermaid Quick Test Page</title>
|
||||||
|
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=" />
|
||||||
|
<style>
|
||||||
|
div.mermaid {
|
||||||
|
/* font-family: 'trebuchet ms', verdana, arial; */
|
||||||
|
font-family: 'Courier New', Courier, monospace !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>Sankey diagram demos</h1>
|
||||||
|
<h2>Energy flow</h2>
|
||||||
|
<pre class="mermaid">
|
||||||
|
sankey-beta
|
||||||
|
|
||||||
|
Agricultural 'waste',Bio-conversion,124.729
|
||||||
|
Bio-conversion,Liquid,0.597
|
||||||
|
Bio-conversion,Losses,26.862
|
||||||
|
Bio-conversion,Solid,280.322
|
||||||
|
Bio-conversion,Gas,81.144
|
||||||
|
Biofuel imports,Liquid,35
|
||||||
|
Biomass imports,Solid,35
|
||||||
|
Coal imports,Coal,11.606
|
||||||
|
Coal reserves,Coal,63.965
|
||||||
|
Coal,Solid,75.571
|
||||||
|
District heating,Industry,10.639
|
||||||
|
District heating,Heating and cooling - commercial,22.505
|
||||||
|
District heating,Heating and cooling - homes,46.184
|
||||||
|
Electricity grid,Over generation / exports,104.453
|
||||||
|
Electricity grid,Heating and cooling - homes,113.726
|
||||||
|
Electricity grid,H2 conversion,27.14
|
||||||
|
Electricity grid,Industry,342.165
|
||||||
|
Electricity grid,Road transport,37.797
|
||||||
|
Electricity grid,Agriculture,4.412
|
||||||
|
Electricity grid,Heating and cooling - commercial,40.858
|
||||||
|
Electricity grid,Losses,56.691
|
||||||
|
Electricity grid,Rail transport,7.863
|
||||||
|
Electricity grid,Lighting & appliances - commercial,90.008
|
||||||
|
Electricity grid,Lighting & appliances - homes,93.494
|
||||||
|
Gas imports,Ngas,40.719
|
||||||
|
Gas reserves,Ngas,82.233
|
||||||
|
Gas,Heating and cooling - commercial,0.129
|
||||||
|
Gas,Losses,1.401
|
||||||
|
Gas,Thermal generation,151.891
|
||||||
|
Gas,Agriculture,2.096
|
||||||
|
Gas,Industry,48.58
|
||||||
|
Geothermal,Electricity grid,7.013
|
||||||
|
H2 conversion,H2,20.897
|
||||||
|
H2 conversion,Losses,6.242
|
||||||
|
H2,Road transport,20.897
|
||||||
|
Hydro,Electricity grid,6.995
|
||||||
|
Liquid,Industry,121.066
|
||||||
|
Liquid,International shipping,128.69
|
||||||
|
Liquid,Road transport,135.835
|
||||||
|
Liquid,Domestic aviation,14.458
|
||||||
|
Liquid,International aviation,206.267
|
||||||
|
Liquid,Agriculture,3.64
|
||||||
|
Liquid,National navigation,33.218
|
||||||
|
Liquid,Rail transport,4.413
|
||||||
|
Marine algae,Bio-conversion,4.375
|
||||||
|
Ngas,Gas,122.952
|
||||||
|
Nuclear,Thermal generation,839.978
|
||||||
|
Oil imports,Oil,504.287
|
||||||
|
Oil reserves,Oil,107.703
|
||||||
|
Oil,Liquid,611.99
|
||||||
|
Other waste,Solid,56.587
|
||||||
|
Other waste,Bio-conversion,77.81
|
||||||
|
Pumped heat,Heating and cooling - homes,193.026
|
||||||
|
Pumped heat,Heating and cooling - commercial,70.672
|
||||||
|
Solar PV,Electricity grid,59.901
|
||||||
|
Solar Thermal,Heating and cooling - homes,19.263
|
||||||
|
Solar,Solar Thermal,19.263
|
||||||
|
Solar,Solar PV,59.901
|
||||||
|
Solid,Agriculture,0.882
|
||||||
|
Solid,Thermal generation,400.12
|
||||||
|
Solid,Industry,46.477
|
||||||
|
Thermal generation,Electricity grid,525.531
|
||||||
|
Thermal generation,Losses,787.129
|
||||||
|
Thermal generation,District heating,79.329
|
||||||
|
Tidal,Electricity grid,9.452
|
||||||
|
UK land based bioenergy,Bio-conversion,182.01
|
||||||
|
Wave,Electricity grid,19.013
|
||||||
|
Wind,Electricity grid,289.366
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<script type="module">
|
||||||
|
import mermaid from './mermaid.esm.mjs';
|
||||||
|
mermaid.initialize({
|
||||||
|
theme: 'default',
|
||||||
|
logLevel: 3,
|
||||||
|
securityLevel: 'loose',
|
||||||
|
sankey: {
|
||||||
|
title: 'Hey, this is Sankey-Beta',
|
||||||
|
width: 1200,
|
||||||
|
height: 600,
|
||||||
|
linkColor: 'gradient',
|
||||||
|
nodeAlignment: 'justify',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -1,9 +1,36 @@
|
|||||||
version: '3.9'
|
version: '3.9'
|
||||||
services:
|
services:
|
||||||
mermaid:
|
mermaid:
|
||||||
image: node:20.3.1-alpine3.18
|
image: node:18.16.1-alpine3.18
|
||||||
stdin_open: true
|
stdin_open: true
|
||||||
tty: true
|
tty: true
|
||||||
working_dir: /mermaid
|
working_dir: /mermaid
|
||||||
|
mem_limit: '2G'
|
||||||
|
environment:
|
||||||
|
- NODE_OPTIONS=--max_old_space_size=2048
|
||||||
volumes:
|
volumes:
|
||||||
- ./:/mermaid
|
- ./:/mermaid
|
||||||
|
- root_cache:/root/.cache
|
||||||
|
- root_local:/root/.local
|
||||||
|
- root_npm:/root/.npm
|
||||||
|
ports:
|
||||||
|
- 9000:9000
|
||||||
|
- 3333:3333
|
||||||
|
cypress:
|
||||||
|
image: cypress/included:12.16.0
|
||||||
|
stdin_open: true
|
||||||
|
tty: true
|
||||||
|
working_dir: /mermaid
|
||||||
|
mem_limit: '2G'
|
||||||
|
entrypoint: cypress
|
||||||
|
environment:
|
||||||
|
- DISPLAY
|
||||||
|
volumes:
|
||||||
|
- ./:/mermaid
|
||||||
|
- /tmp/.X11-unix:/tmp/.X11-unix
|
||||||
|
network_mode: host
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
root_cache:
|
||||||
|
root_local:
|
||||||
|
root_npm:
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[defaultConfig.ts:2293](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L2293)
|
[defaultConfig.ts:2300](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L2300)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -73,9 +73,9 @@ To make a custom theme, modify `themeVariables` via `init`.
|
|||||||
|
|
||||||
You will need to use the [base](#available-themes) theme as it is the only modifiable theme.
|
You will need to use the [base](#available-themes) theme as it is the only modifiable theme.
|
||||||
|
|
||||||
| Parameter | Description | Type | Properties |
|
| Parameter | Description | Type | Properties |
|
||||||
| -------------- | ------------------------------------ | ------ | --------------------------------------------------------------------------------------------------- |
|
| -------------- | ------------------------------------ | ------ | ----------------------------------------------------------------------------------- |
|
||||||
| themeVariables | Modifiable with the `init` directive | Object | `primaryColor`, `primaryTextColor`, `lineColor` ([see full list](#theme-variables-reference-table)) |
|
| themeVariables | Modifiable with the `init` directive | Object | `primaryColor`, `primaryTextColor`, `lineColor` ([see full list](#theme-variables)) |
|
||||||
|
|
||||||
Example of modifying `themeVariables` using the `init` directive:
|
Example of modifying `themeVariables` using the `init` directive:
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
# Announcements
|
# Announcements
|
||||||
|
|
||||||
## [subhash-halder contributed quadrant charts so you can show your manager what to select - just like the strategy consultants at BCG do](https://www.mermaidchart.com/blog/posts/subhash-halder-contributed-quadrant-charts-so-you-can-show-your-manager-what-to-select-just-like-the-strategy-consultants-at-bcg-do/)
|
## [Sequence diagrams, the only good thing UML brought to software development](https://www.mermaidchart.com/blog/posts/sequence-diagrams-the-good-thing-uml-brought-to-software-development/)
|
||||||
|
|
||||||
8 June 2023 · 7 mins
|
15 June 2023 · 12 mins
|
||||||
|
|
||||||
A quadrant chart is a useful diagram that helps users visualize data and identify patterns in a data set.
|
Sequence diagrams really shine when you’re documenting different parts of a system and the various ways these parts interact with each other.
|
||||||
|
|||||||
@@ -6,6 +6,12 @@
|
|||||||
|
|
||||||
# Blog
|
# Blog
|
||||||
|
|
||||||
|
## [Sequence diagrams, the only good thing UML brought to software development](https://www.mermaidchart.com/blog/posts/sequence-diagrams-the-good-thing-uml-brought-to-software-development/)
|
||||||
|
|
||||||
|
15 June 2023 · 12 mins
|
||||||
|
|
||||||
|
Sequence diagrams really shine when you’re documenting different parts of a system and the various ways these parts interact with each other.
|
||||||
|
|
||||||
## [subhash-halder contributed quadrant charts so you can show your manager what to select - just like the strategy consultants at BCG do](https://www.mermaidchart.com/blog/posts/subhash-halder-contributed-quadrant-charts-so-you-can-show-your-manager-what-to-select-just-like-the-strategy-consultants-at-bcg-do/)
|
## [subhash-halder contributed quadrant charts so you can show your manager what to select - just like the strategy consultants at BCG do](https://www.mermaidchart.com/blog/posts/subhash-halder-contributed-quadrant-charts-so-you-can-show-your-manager-what-to-select-just-like-the-strategy-consultants-at-bcg-do/)
|
||||||
|
|
||||||
8 June 2023 · 7 mins
|
8 June 2023 · 7 mins
|
||||||
|
|||||||
510
docs/syntax/sankey.md
Normal file
510
docs/syntax/sankey.md
Normal file
@@ -0,0 +1,510 @@
|
|||||||
|
> **Warning**
|
||||||
|
>
|
||||||
|
> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
|
||||||
|
>
|
||||||
|
> ## Please edit the corresponding file in [/packages/mermaid/src/docs/syntax/sankey.md](../../packages/mermaid/src/docs/syntax/sankey.md).
|
||||||
|
|
||||||
|
# Sankey diagrams
|
||||||
|
|
||||||
|
> A sankey diagram is a visualization used to depict a flow from one set of values to another.
|
||||||
|
|
||||||
|
::: warning
|
||||||
|
This is an experimental diagram. Its syntax are very close to plain CSV, but it is to be extended in the nearest future.
|
||||||
|
:::
|
||||||
|
|
||||||
|
The things being connected are called nodes and the connections are called links.
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
This example taken from [observable](https://observablehq.com/@d3/sankey/2?collection=@d3/d3-sankey). It may be rendered a little bit differently, though, in terms of size and colors.
|
||||||
|
|
||||||
|
```mermaid-example
|
||||||
|
sankey-beta
|
||||||
|
|
||||||
|
Agricultural 'waste',Bio-conversion,124.729
|
||||||
|
Bio-conversion,Liquid,0.597
|
||||||
|
Bio-conversion,Losses,26.862
|
||||||
|
Bio-conversion,Solid,280.322
|
||||||
|
Bio-conversion,Gas,81.144
|
||||||
|
Biofuel imports,Liquid,35
|
||||||
|
Biomass imports,Solid,35
|
||||||
|
Coal imports,Coal,11.606
|
||||||
|
Coal reserves,Coal,63.965
|
||||||
|
Coal,Solid,75.571
|
||||||
|
District heating,Industry,10.639
|
||||||
|
District heating,Heating and cooling - commercial,22.505
|
||||||
|
District heating,Heating and cooling - homes,46.184
|
||||||
|
Electricity grid,Over generation / exports,104.453
|
||||||
|
Electricity grid,Heating and cooling - homes,113.726
|
||||||
|
Electricity grid,H2 conversion,27.14
|
||||||
|
Electricity grid,Industry,342.165
|
||||||
|
Electricity grid,Road transport,37.797
|
||||||
|
Electricity grid,Agriculture,4.412
|
||||||
|
Electricity grid,Heating and cooling - commercial,40.858
|
||||||
|
Electricity grid,Losses,56.691
|
||||||
|
Electricity grid,Rail transport,7.863
|
||||||
|
Electricity grid,Lighting & appliances - commercial,90.008
|
||||||
|
Electricity grid,Lighting & appliances - homes,93.494
|
||||||
|
Gas imports,Ngas,40.719
|
||||||
|
Gas reserves,Ngas,82.233
|
||||||
|
Gas,Heating and cooling - commercial,0.129
|
||||||
|
Gas,Losses,1.401
|
||||||
|
Gas,Thermal generation,151.891
|
||||||
|
Gas,Agriculture,2.096
|
||||||
|
Gas,Industry,48.58
|
||||||
|
Geothermal,Electricity grid,7.013
|
||||||
|
H2 conversion,H2,20.897
|
||||||
|
H2 conversion,Losses,6.242
|
||||||
|
H2,Road transport,20.897
|
||||||
|
Hydro,Electricity grid,6.995
|
||||||
|
Liquid,Industry,121.066
|
||||||
|
Liquid,International shipping,128.69
|
||||||
|
Liquid,Road transport,135.835
|
||||||
|
Liquid,Domestic aviation,14.458
|
||||||
|
Liquid,International aviation,206.267
|
||||||
|
Liquid,Agriculture,3.64
|
||||||
|
Liquid,National navigation,33.218
|
||||||
|
Liquid,Rail transport,4.413
|
||||||
|
Marine algae,Bio-conversion,4.375
|
||||||
|
Ngas,Gas,122.952
|
||||||
|
Nuclear,Thermal generation,839.978
|
||||||
|
Oil imports,Oil,504.287
|
||||||
|
Oil reserves,Oil,107.703
|
||||||
|
Oil,Liquid,611.99
|
||||||
|
Other waste,Solid,56.587
|
||||||
|
Other waste,Bio-conversion,77.81
|
||||||
|
Pumped heat,Heating and cooling - homes,193.026
|
||||||
|
Pumped heat,Heating and cooling - commercial,70.672
|
||||||
|
Solar PV,Electricity grid,59.901
|
||||||
|
Solar Thermal,Heating and cooling - homes,19.263
|
||||||
|
Solar,Solar Thermal,19.263
|
||||||
|
Solar,Solar PV,59.901
|
||||||
|
Solid,Agriculture,0.882
|
||||||
|
Solid,Thermal generation,400.12
|
||||||
|
Solid,Industry,46.477
|
||||||
|
Thermal generation,Electricity grid,525.531
|
||||||
|
Thermal generation,Losses,787.129
|
||||||
|
Thermal generation,District heating,79.329
|
||||||
|
Tidal,Electricity grid,9.452
|
||||||
|
UK land based bioenergy,Bio-conversion,182.01
|
||||||
|
Wave,Electricity grid,19.013
|
||||||
|
Wind,Electricity grid,289.366
|
||||||
|
```
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
sankey-beta
|
||||||
|
|
||||||
|
Agricultural 'waste',Bio-conversion,124.729
|
||||||
|
Bio-conversion,Liquid,0.597
|
||||||
|
Bio-conversion,Losses,26.862
|
||||||
|
Bio-conversion,Solid,280.322
|
||||||
|
Bio-conversion,Gas,81.144
|
||||||
|
Biofuel imports,Liquid,35
|
||||||
|
Biomass imports,Solid,35
|
||||||
|
Coal imports,Coal,11.606
|
||||||
|
Coal reserves,Coal,63.965
|
||||||
|
Coal,Solid,75.571
|
||||||
|
District heating,Industry,10.639
|
||||||
|
District heating,Heating and cooling - commercial,22.505
|
||||||
|
District heating,Heating and cooling - homes,46.184
|
||||||
|
Electricity grid,Over generation / exports,104.453
|
||||||
|
Electricity grid,Heating and cooling - homes,113.726
|
||||||
|
Electricity grid,H2 conversion,27.14
|
||||||
|
Electricity grid,Industry,342.165
|
||||||
|
Electricity grid,Road transport,37.797
|
||||||
|
Electricity grid,Agriculture,4.412
|
||||||
|
Electricity grid,Heating and cooling - commercial,40.858
|
||||||
|
Electricity grid,Losses,56.691
|
||||||
|
Electricity grid,Rail transport,7.863
|
||||||
|
Electricity grid,Lighting & appliances - commercial,90.008
|
||||||
|
Electricity grid,Lighting & appliances - homes,93.494
|
||||||
|
Gas imports,Ngas,40.719
|
||||||
|
Gas reserves,Ngas,82.233
|
||||||
|
Gas,Heating and cooling - commercial,0.129
|
||||||
|
Gas,Losses,1.401
|
||||||
|
Gas,Thermal generation,151.891
|
||||||
|
Gas,Agriculture,2.096
|
||||||
|
Gas,Industry,48.58
|
||||||
|
Geothermal,Electricity grid,7.013
|
||||||
|
H2 conversion,H2,20.897
|
||||||
|
H2 conversion,Losses,6.242
|
||||||
|
H2,Road transport,20.897
|
||||||
|
Hydro,Electricity grid,6.995
|
||||||
|
Liquid,Industry,121.066
|
||||||
|
Liquid,International shipping,128.69
|
||||||
|
Liquid,Road transport,135.835
|
||||||
|
Liquid,Domestic aviation,14.458
|
||||||
|
Liquid,International aviation,206.267
|
||||||
|
Liquid,Agriculture,3.64
|
||||||
|
Liquid,National navigation,33.218
|
||||||
|
Liquid,Rail transport,4.413
|
||||||
|
Marine algae,Bio-conversion,4.375
|
||||||
|
Ngas,Gas,122.952
|
||||||
|
Nuclear,Thermal generation,839.978
|
||||||
|
Oil imports,Oil,504.287
|
||||||
|
Oil reserves,Oil,107.703
|
||||||
|
Oil,Liquid,611.99
|
||||||
|
Other waste,Solid,56.587
|
||||||
|
Other waste,Bio-conversion,77.81
|
||||||
|
Pumped heat,Heating and cooling - homes,193.026
|
||||||
|
Pumped heat,Heating and cooling - commercial,70.672
|
||||||
|
Solar PV,Electricity grid,59.901
|
||||||
|
Solar Thermal,Heating and cooling - homes,19.263
|
||||||
|
Solar,Solar Thermal,19.263
|
||||||
|
Solar,Solar PV,59.901
|
||||||
|
Solid,Agriculture,0.882
|
||||||
|
Solid,Thermal generation,400.12
|
||||||
|
Solid,Industry,46.477
|
||||||
|
Thermal generation,Electricity grid,525.531
|
||||||
|
Thermal generation,Losses,787.129
|
||||||
|
Thermal generation,District heating,79.329
|
||||||
|
Tidal,Electricity grid,9.452
|
||||||
|
UK land based bioenergy,Bio-conversion,182.01
|
||||||
|
Wave,Electricity grid,19.013
|
||||||
|
Wind,Electricity grid,289.366
|
||||||
|
```
|
||||||
|
|
||||||
|
::: details
|
||||||
|
|
||||||
|
```mermaid-example
|
||||||
|
sankey-beta
|
||||||
|
|
||||||
|
Agricultural 'waste',Bio-conversion,124.729
|
||||||
|
Bio-conversion,Liquid,0.597
|
||||||
|
Bio-conversion,Losses,26.862
|
||||||
|
Bio-conversion,Solid,280.322
|
||||||
|
Bio-conversion,Gas,81.144
|
||||||
|
Biofuel imports,Liquid,35
|
||||||
|
Biomass imports,Solid,35
|
||||||
|
Coal imports,Coal,11.606
|
||||||
|
Coal reserves,Coal,63.965
|
||||||
|
Coal,Solid,75.571
|
||||||
|
District heating,Industry,10.639
|
||||||
|
District heating,Heating and cooling - commercial,22.505
|
||||||
|
District heating,Heating and cooling - homes,46.184
|
||||||
|
Electricity grid,Over generation / exports,104.453
|
||||||
|
Electricity grid,Heating and cooling - homes,113.726
|
||||||
|
Electricity grid,H2 conversion,27.14
|
||||||
|
Electricity grid,Industry,342.165
|
||||||
|
Electricity grid,Road transport,37.797
|
||||||
|
Electricity grid,Agriculture,4.412
|
||||||
|
Electricity grid,Heating and cooling - commercial,40.858
|
||||||
|
Electricity grid,Losses,56.691
|
||||||
|
Electricity grid,Rail transport,7.863
|
||||||
|
Electricity grid,Lighting & appliances - commercial,90.008
|
||||||
|
Electricity grid,Lighting & appliances - homes,93.494
|
||||||
|
Gas imports,Ngas,40.719
|
||||||
|
Gas reserves,Ngas,82.233
|
||||||
|
Gas,Heating and cooling - commercial,0.129
|
||||||
|
Gas,Losses,1.401
|
||||||
|
Gas,Thermal generation,151.891
|
||||||
|
Gas,Agriculture,2.096
|
||||||
|
Gas,Industry,48.58
|
||||||
|
Geothermal,Electricity grid,7.013
|
||||||
|
H2 conversion,H2,20.897
|
||||||
|
H2 conversion,Losses,6.242
|
||||||
|
H2,Road transport,20.897
|
||||||
|
Hydro,Electricity grid,6.995
|
||||||
|
Liquid,Industry,121.066
|
||||||
|
Liquid,International shipping,128.69
|
||||||
|
Liquid,Road transport,135.835
|
||||||
|
Liquid,Domestic aviation,14.458
|
||||||
|
Liquid,International aviation,206.267
|
||||||
|
Liquid,Agriculture,3.64
|
||||||
|
Liquid,National navigation,33.218
|
||||||
|
Liquid,Rail transport,4.413
|
||||||
|
Marine algae,Bio-conversion,4.375
|
||||||
|
Ngas,Gas,122.952
|
||||||
|
Nuclear,Thermal generation,839.978
|
||||||
|
Oil imports,Oil,504.287
|
||||||
|
Oil reserves,Oil,107.703
|
||||||
|
Oil,Liquid,611.99
|
||||||
|
Other waste,Solid,56.587
|
||||||
|
Other waste,Bio-conversion,77.81
|
||||||
|
Pumped heat,Heating and cooling - homes,193.026
|
||||||
|
Pumped heat,Heating and cooling - commercial,70.672
|
||||||
|
Solar PV,Electricity grid,59.901
|
||||||
|
Solar Thermal,Heating and cooling - homes,19.263
|
||||||
|
Solar,Solar Thermal,19.263
|
||||||
|
Solar,Solar PV,59.901
|
||||||
|
Solid,Agriculture,0.882
|
||||||
|
Solid,Thermal generation,400.12
|
||||||
|
Solid,Industry,46.477
|
||||||
|
Thermal generation,Electricity grid,525.531
|
||||||
|
Thermal generation,Losses,787.129
|
||||||
|
Thermal generation,District heating,79.329
|
||||||
|
Tidal,Electricity grid,9.452
|
||||||
|
UK land based bioenergy,Bio-conversion,182.01
|
||||||
|
Wave,Electricity grid,19.013
|
||||||
|
Wind,Electricity grid,289.366
|
||||||
|
```
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
sankey-beta
|
||||||
|
|
||||||
|
Agricultural 'waste',Bio-conversion,124.729
|
||||||
|
Bio-conversion,Liquid,0.597
|
||||||
|
Bio-conversion,Losses,26.862
|
||||||
|
Bio-conversion,Solid,280.322
|
||||||
|
Bio-conversion,Gas,81.144
|
||||||
|
Biofuel imports,Liquid,35
|
||||||
|
Biomass imports,Solid,35
|
||||||
|
Coal imports,Coal,11.606
|
||||||
|
Coal reserves,Coal,63.965
|
||||||
|
Coal,Solid,75.571
|
||||||
|
District heating,Industry,10.639
|
||||||
|
District heating,Heating and cooling - commercial,22.505
|
||||||
|
District heating,Heating and cooling - homes,46.184
|
||||||
|
Electricity grid,Over generation / exports,104.453
|
||||||
|
Electricity grid,Heating and cooling - homes,113.726
|
||||||
|
Electricity grid,H2 conversion,27.14
|
||||||
|
Electricity grid,Industry,342.165
|
||||||
|
Electricity grid,Road transport,37.797
|
||||||
|
Electricity grid,Agriculture,4.412
|
||||||
|
Electricity grid,Heating and cooling - commercial,40.858
|
||||||
|
Electricity grid,Losses,56.691
|
||||||
|
Electricity grid,Rail transport,7.863
|
||||||
|
Electricity grid,Lighting & appliances - commercial,90.008
|
||||||
|
Electricity grid,Lighting & appliances - homes,93.494
|
||||||
|
Gas imports,Ngas,40.719
|
||||||
|
Gas reserves,Ngas,82.233
|
||||||
|
Gas,Heating and cooling - commercial,0.129
|
||||||
|
Gas,Losses,1.401
|
||||||
|
Gas,Thermal generation,151.891
|
||||||
|
Gas,Agriculture,2.096
|
||||||
|
Gas,Industry,48.58
|
||||||
|
Geothermal,Electricity grid,7.013
|
||||||
|
H2 conversion,H2,20.897
|
||||||
|
H2 conversion,Losses,6.242
|
||||||
|
H2,Road transport,20.897
|
||||||
|
Hydro,Electricity grid,6.995
|
||||||
|
Liquid,Industry,121.066
|
||||||
|
Liquid,International shipping,128.69
|
||||||
|
Liquid,Road transport,135.835
|
||||||
|
Liquid,Domestic aviation,14.458
|
||||||
|
Liquid,International aviation,206.267
|
||||||
|
Liquid,Agriculture,3.64
|
||||||
|
Liquid,National navigation,33.218
|
||||||
|
Liquid,Rail transport,4.413
|
||||||
|
Marine algae,Bio-conversion,4.375
|
||||||
|
Ngas,Gas,122.952
|
||||||
|
Nuclear,Thermal generation,839.978
|
||||||
|
Oil imports,Oil,504.287
|
||||||
|
Oil reserves,Oil,107.703
|
||||||
|
Oil,Liquid,611.99
|
||||||
|
Other waste,Solid,56.587
|
||||||
|
Other waste,Bio-conversion,77.81
|
||||||
|
Pumped heat,Heating and cooling - homes,193.026
|
||||||
|
Pumped heat,Heating and cooling - commercial,70.672
|
||||||
|
Solar PV,Electricity grid,59.901
|
||||||
|
Solar Thermal,Heating and cooling - homes,19.263
|
||||||
|
Solar,Solar Thermal,19.263
|
||||||
|
Solar,Solar PV,59.901
|
||||||
|
Solid,Agriculture,0.882
|
||||||
|
Solid,Thermal generation,400.12
|
||||||
|
Solid,Industry,46.477
|
||||||
|
Thermal generation,Electricity grid,525.531
|
||||||
|
Thermal generation,Losses,787.129
|
||||||
|
Thermal generation,District heating,79.329
|
||||||
|
Tidal,Electricity grid,9.452
|
||||||
|
UK land based bioenergy,Bio-conversion,182.01
|
||||||
|
Wave,Electricity grid,19.013
|
||||||
|
Wind,Electricity grid,289.366
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
## Syntax
|
||||||
|
|
||||||
|
The idea behind syntax is that a user types `sankey-beta` keyword first, then pastes raw CSV below and get the result.
|
||||||
|
|
||||||
|
It implements CSV standard as [described here](https://www.ietf.org/rfc/rfc4180.txt) with subtle **differences**:
|
||||||
|
|
||||||
|
- CSV must contain **3 columns only**
|
||||||
|
- It is **allowed** to have **empty lines** without comma separators for visual purposes
|
||||||
|
|
||||||
|
### Basic
|
||||||
|
|
||||||
|
It is implied that 3 columns inside CSV should represent `source`, `target` and `value` accordingly:
|
||||||
|
|
||||||
|
```mermaid-example
|
||||||
|
sankey-beta
|
||||||
|
|
||||||
|
%% source,target,value
|
||||||
|
Electricity grid,Over generation / exports,104.453
|
||||||
|
Electricity grid,Heating and cooling - homes,113.726
|
||||||
|
Electricity grid,H2 conversion,27.14
|
||||||
|
```
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
sankey-beta
|
||||||
|
|
||||||
|
%% source,target,value
|
||||||
|
Electricity grid,Over generation / exports,104.453
|
||||||
|
Electricity grid,Heating and cooling - homes,113.726
|
||||||
|
Electricity grid,H2 conversion,27.14
|
||||||
|
```
|
||||||
|
|
||||||
|
```mermaid-example
|
||||||
|
sankey-beta
|
||||||
|
|
||||||
|
%% source,target,value
|
||||||
|
Electricity grid,Over generation / exports,104.453
|
||||||
|
Electricity grid,Heating and cooling - homes,113.726
|
||||||
|
Electricity grid,H2 conversion,27.14
|
||||||
|
```
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
sankey-beta
|
||||||
|
|
||||||
|
%% source,target,value
|
||||||
|
Electricity grid,Over generation / exports,104.453
|
||||||
|
Electricity grid,Heating and cooling - homes,113.726
|
||||||
|
Electricity grid,H2 conversion,27.14
|
||||||
|
```
|
||||||
|
|
||||||
|
### Empty Lines
|
||||||
|
|
||||||
|
CSV does not support empty lines without comma delimeters by default. But you can add them if needed:
|
||||||
|
|
||||||
|
```mermaid-example
|
||||||
|
sankey-beta
|
||||||
|
|
||||||
|
Bio-conversion,Losses,26.862
|
||||||
|
|
||||||
|
Bio-conversion,Solid,280.322
|
||||||
|
|
||||||
|
Bio-conversion,Gas,81.144
|
||||||
|
```
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
sankey-beta
|
||||||
|
|
||||||
|
Bio-conversion,Losses,26.862
|
||||||
|
|
||||||
|
Bio-conversion,Solid,280.322
|
||||||
|
|
||||||
|
Bio-conversion,Gas,81.144
|
||||||
|
```
|
||||||
|
|
||||||
|
```mermaid-example
|
||||||
|
sankey-beta
|
||||||
|
|
||||||
|
Bio-conversion,Losses,26.862
|
||||||
|
|
||||||
|
Bio-conversion,Solid,280.322
|
||||||
|
|
||||||
|
Bio-conversion,Gas,81.144
|
||||||
|
```
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
sankey-beta
|
||||||
|
|
||||||
|
Bio-conversion,Losses,26.862
|
||||||
|
|
||||||
|
Bio-conversion,Solid,280.322
|
||||||
|
|
||||||
|
Bio-conversion,Gas,81.144
|
||||||
|
```
|
||||||
|
|
||||||
|
### Commas
|
||||||
|
|
||||||
|
If you need to have a comma, wrap it in double quotes:
|
||||||
|
|
||||||
|
```mermaid-example
|
||||||
|
sankey-beta
|
||||||
|
|
||||||
|
Pumped heat,"Heating and cooling, homes",193.026
|
||||||
|
Pumped heat,"Heating and cooling, commercial",70.672
|
||||||
|
```
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
sankey-beta
|
||||||
|
|
||||||
|
Pumped heat,"Heating and cooling, homes",193.026
|
||||||
|
Pumped heat,"Heating and cooling, commercial",70.672
|
||||||
|
```
|
||||||
|
|
||||||
|
```mermaid-example
|
||||||
|
sankey-beta
|
||||||
|
|
||||||
|
Pumped heat,"Heating and cooling, homes",193.026
|
||||||
|
Pumped heat,"Heating and cooling, commercial",70.672
|
||||||
|
```
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
sankey-beta
|
||||||
|
|
||||||
|
Pumped heat,"Heating and cooling, homes",193.026
|
||||||
|
Pumped heat,"Heating and cooling, commercial",70.672
|
||||||
|
```
|
||||||
|
|
||||||
|
### Double Quotes
|
||||||
|
|
||||||
|
If you need to have double quote, put a pair of them inside quoted string:
|
||||||
|
|
||||||
|
```mermaid-example
|
||||||
|
sankey-beta
|
||||||
|
|
||||||
|
Pumped heat,"Heating and cooling, ""homes""",193.026
|
||||||
|
Pumped heat,"Heating and cooling, ""commercial""",70.672
|
||||||
|
```
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
sankey-beta
|
||||||
|
|
||||||
|
Pumped heat,"Heating and cooling, ""homes""",193.026
|
||||||
|
Pumped heat,"Heating and cooling, ""commercial""",70.672
|
||||||
|
```
|
||||||
|
|
||||||
|
```mermaid-example
|
||||||
|
sankey-beta
|
||||||
|
|
||||||
|
Pumped heat,"Heating and cooling, ""homes""",193.026
|
||||||
|
Pumped heat,"Heating and cooling, ""commercial""",70.672
|
||||||
|
```
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
sankey-beta
|
||||||
|
|
||||||
|
Pumped heat,"Heating and cooling, ""homes""",193.026
|
||||||
|
Pumped heat,"Heating and cooling, ""commercial""",70.672
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
You can customize link colors, node alignments and diagram dimensions.
|
||||||
|
|
||||||
|
```html
|
||||||
|
<script>
|
||||||
|
const config = {
|
||||||
|
startOnLoad: true,
|
||||||
|
securityLevel: 'loose',
|
||||||
|
sankey: {
|
||||||
|
width: 800,
|
||||||
|
height: 400,
|
||||||
|
linkColor: 'source',
|
||||||
|
nodeAlignment: 'left',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
mermaid.initialize(config);
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Links Coloring
|
||||||
|
|
||||||
|
You can adjust links' color by setting `linkColor` to one of those:
|
||||||
|
|
||||||
|
- `source` - link will be of a source node color
|
||||||
|
- `target` - link will be of a target node color
|
||||||
|
- `gradient` - link color will be smoothly transient between source and target node colors
|
||||||
|
- hex code of color, like `#a1a1a1`
|
||||||
|
|
||||||
|
### Node Alignment
|
||||||
|
|
||||||
|
Graph layout can be changed by setting `nodeAlignment` to:
|
||||||
|
|
||||||
|
- `justify`
|
||||||
|
- `center`
|
||||||
|
- `left`
|
||||||
|
- `right`
|
||||||
@@ -94,6 +94,43 @@ sequenceDiagram
|
|||||||
J->>A: Great!
|
J->>A: Great!
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Actor Creation and Destruction
|
||||||
|
|
||||||
|
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
|
||||||
|
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.
|
||||||
|
|
||||||
|
```mermaid-example
|
||||||
|
sequenceDiagram
|
||||||
|
Alice->>Bob: Hello Bob, how are you ?
|
||||||
|
Bob->>Alice: Fine, thank you. And you?
|
||||||
|
create participant Carl
|
||||||
|
Alice->>Carl: Hi Carl!
|
||||||
|
create actor D as Donald
|
||||||
|
Carl->>D: Hi!
|
||||||
|
destroy Carl
|
||||||
|
Alice-xCarl: We are too many
|
||||||
|
destroy Bob
|
||||||
|
Bob->>Alice: I agree
|
||||||
|
```
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
sequenceDiagram
|
||||||
|
Alice->>Bob: Hello Bob, how are you ?
|
||||||
|
Bob->>Alice: Fine, thank you. And you?
|
||||||
|
create participant Carl
|
||||||
|
Alice->>Carl: Hi Carl!
|
||||||
|
create actor D as Donald
|
||||||
|
Carl->>D: Hi!
|
||||||
|
destroy Carl
|
||||||
|
Alice-xCarl: We are too many
|
||||||
|
destroy Bob
|
||||||
|
Bob->>Alice: I agree
|
||||||
|
```
|
||||||
|
|
||||||
### Grouping / Box
|
### Grouping / Box
|
||||||
|
|
||||||
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:
|
||||||
|
|||||||
@@ -487,7 +487,7 @@ where
|
|||||||
- the second _property_ is `color` and its _value_ is `white`
|
- the second _property_ is `color` and its _value_ is `white`
|
||||||
- the third _property_ is `font-weight` and its _value_ is `bold`
|
- the third _property_ is `font-weight` and its _value_ is `bold`
|
||||||
- the fourth _property_ is `stroke-width` and its _value_ is `2px`
|
- the fourth _property_ is `stroke-width` and its _value_ is `2px`
|
||||||
- the fifth _property_ is `stroke` and its _value_ is `yello`
|
- the fifth _property_ is `stroke` and its _value_ is `yellow`
|
||||||
|
|
||||||
### Apply classDef styles to states
|
### Apply classDef styles to states
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "mermaid-monorepo",
|
"name": "mermaid-monorepo",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "10.2.3",
|
"version": "10.2.4",
|
||||||
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
|
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"packageManager": "pnpm@8.6.5",
|
"packageManager": "pnpm@8.6.5",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mermaid",
|
"name": "mermaid",
|
||||||
"version": "10.2.3",
|
"version": "10.2.4",
|
||||||
"description": "Markdown-ish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
|
"description": "Markdown-ish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"module": "./dist/mermaid.core.mjs",
|
"module": "./dist/mermaid.core.mjs",
|
||||||
@@ -53,13 +53,16 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@braintree/sanitize-url": "^6.0.2",
|
"@braintree/sanitize-url": "^6.0.2",
|
||||||
|
"@types/d3-scale": "^4.0.3",
|
||||||
|
"@types/d3-scale-chromatic": "^3.0.0",
|
||||||
"cytoscape": "^3.23.0",
|
"cytoscape": "^3.23.0",
|
||||||
"cytoscape-cose-bilkent": "^4.1.0",
|
"cytoscape-cose-bilkent": "^4.1.0",
|
||||||
"cytoscape-fcose": "^2.1.0",
|
"cytoscape-fcose": "^2.1.0",
|
||||||
"d3": "^7.4.0",
|
"d3": "^7.4.0",
|
||||||
|
"d3-sankey": "^0.12.3",
|
||||||
"dagre-d3-es": "7.0.10",
|
"dagre-d3-es": "7.0.10",
|
||||||
"dayjs": "^1.11.7",
|
"dayjs": "^1.11.7",
|
||||||
"dompurify": "3.0.3",
|
"dompurify": "3.0.4",
|
||||||
"elkjs": "^0.8.2",
|
"elkjs": "^0.8.2",
|
||||||
"khroma": "^2.0.0",
|
"khroma": "^2.0.0",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
@@ -73,6 +76,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/cytoscape": "^3.19.9",
|
"@types/cytoscape": "^3.19.9",
|
||||||
"@types/d3": "^7.4.0",
|
"@types/d3": "^7.4.0",
|
||||||
|
"@types/d3-sankey": "^0.12.1",
|
||||||
"@types/d3-selection": "^3.0.5",
|
"@types/d3-selection": "^3.0.5",
|
||||||
"@types/dompurify": "^3.0.2",
|
"@types/dompurify": "^3.0.2",
|
||||||
"@types/jsdom": "^21.1.1",
|
"@types/jsdom": "^21.1.1",
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ export interface MermaidConfig {
|
|||||||
mindmap?: MindmapDiagramConfig;
|
mindmap?: MindmapDiagramConfig;
|
||||||
gitGraph?: GitGraphDiagramConfig;
|
gitGraph?: GitGraphDiagramConfig;
|
||||||
c4?: C4DiagramConfig;
|
c4?: C4DiagramConfig;
|
||||||
|
sankey?: SankeyDiagramConfig;
|
||||||
dompurifyConfig?: DOMPurify.Config;
|
dompurifyConfig?: DOMPurify.Config;
|
||||||
wrap?: boolean;
|
wrap?: boolean;
|
||||||
fontSize?: number;
|
fontSize?: number;
|
||||||
@@ -411,6 +412,26 @@ export interface FlowchartDiagramConfig extends BaseDiagramConfig {
|
|||||||
wrappingWidth?: number;
|
wrappingWidth?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum SankeyLinkColor {
|
||||||
|
source = 'source',
|
||||||
|
target = 'target',
|
||||||
|
gradient = 'gradient',
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum SankeyNodeAlignment {
|
||||||
|
left = 'left',
|
||||||
|
right = 'right',
|
||||||
|
center = 'center',
|
||||||
|
justify = 'justify',
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SankeyDiagramConfig extends BaseDiagramConfig {
|
||||||
|
width?: number;
|
||||||
|
height?: number;
|
||||||
|
linkColor?: SankeyLinkColor | string;
|
||||||
|
nodeAlignment?: SankeyNodeAlignment;
|
||||||
|
}
|
||||||
|
|
||||||
export interface FontConfig {
|
export interface FontConfig {
|
||||||
fontSize?: string | number;
|
fontSize?: string | number;
|
||||||
fontFamily?: string;
|
fontFamily?: string;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import theme from './themes/index.js';
|
import theme from './themes/index.js';
|
||||||
import { MermaidConfig } from './config.type.js';
|
import { MermaidConfig, SankeyLinkColor, SankeyNodeAlignment } from './config.type.js';
|
||||||
/**
|
/**
|
||||||
* **Configuration methods in Mermaid version 8.6.0 have been updated, to learn more[[click
|
* **Configuration methods in Mermaid version 8.6.0 have been updated, to learn more[[click
|
||||||
* here](8.6.0_docs.md)].**
|
* here](8.6.0_docs.md)].**
|
||||||
@@ -2270,6 +2270,13 @@ const config: Partial<MermaidConfig> = {
|
|||||||
padding: 10,
|
padding: 10,
|
||||||
maxNodeWidth: 200,
|
maxNodeWidth: 200,
|
||||||
},
|
},
|
||||||
|
sankey: {
|
||||||
|
width: 800,
|
||||||
|
height: 400,
|
||||||
|
linkColor: SankeyLinkColor.gradient,
|
||||||
|
nodeAlignment: SankeyNodeAlignment.justify,
|
||||||
|
useMaxWidth: false,
|
||||||
|
},
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import errorDiagram from '../diagrams/error/errorDiagram.js';
|
|||||||
import flowchartElk from '../diagrams/flowchart/elk/detector.js';
|
import flowchartElk from '../diagrams/flowchart/elk/detector.js';
|
||||||
import timeline from '../diagrams/timeline/detector.js';
|
import timeline from '../diagrams/timeline/detector.js';
|
||||||
import mindmap from '../diagrams/mindmap/detector.js';
|
import mindmap from '../diagrams/mindmap/detector.js';
|
||||||
|
import sankey from '../diagrams/sankey/sankeyDetector.js';
|
||||||
import { registerLazyLoadedDiagrams } from './detectType.js';
|
import { registerLazyLoadedDiagrams } from './detectType.js';
|
||||||
import { registerDiagram } from './diagramAPI.js';
|
import { registerDiagram } from './diagramAPI.js';
|
||||||
|
|
||||||
@@ -79,6 +80,7 @@ export const addDiagrams = () => {
|
|||||||
stateV2,
|
stateV2,
|
||||||
state,
|
state,
|
||||||
journey,
|
journey,
|
||||||
quadrantChart
|
quadrantChart,
|
||||||
|
sankey
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
99
packages/mermaid/src/diagrams/sankey/parser/energy.csv
Normal file
99
packages/mermaid/src/diagrams/sankey/parser/energy.csv
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
%% There are leading and trailing spaces, do not crop
|
||||||
|
Agricultural 'waste',Bio-conversion,124.729
|
||||||
|
%% line with a comment
|
||||||
|
|
||||||
|
%% Normal line
|
||||||
|
Bio-conversion,Liquid,0.597
|
||||||
|
|
||||||
|
%% Line with unquoted sankey keyword
|
||||||
|
sankey,target,10
|
||||||
|
|
||||||
|
%% Quoted sankey keyword
|
||||||
|
"sankey",target,10
|
||||||
|
|
||||||
|
%% Another normal line
|
||||||
|
Bio-conversion,Losses,26.862
|
||||||
|
|
||||||
|
%% Line with integer amount
|
||||||
|
Bio-conversion,Solid,280
|
||||||
|
|
||||||
|
%% Some blank lines in the middle of CSV
|
||||||
|
|
||||||
|
|
||||||
|
%% Another normal line
|
||||||
|
Bio-conversion,Gas,81.144
|
||||||
|
|
||||||
|
%% Quoted line
|
||||||
|
"Biofuel imports",Liquid,35
|
||||||
|
|
||||||
|
%% Quoted line with escaped quotes inside
|
||||||
|
"""Biomass imports""",Solid,35
|
||||||
|
|
||||||
|
%% Lines containing commas inside
|
||||||
|
%% Quoted and unquoted values should be equal in terms of graph
|
||||||
|
"District heating","Heating and cooling, commercial",22.505
|
||||||
|
District heating,"Heating and cooling, homes",46.184
|
||||||
|
|
||||||
|
%% A bunch of lines, normal CSV
|
||||||
|
Coal imports,Coal,11.606
|
||||||
|
Coal reserves,Coal,63.965
|
||||||
|
Coal,Solid,75.571
|
||||||
|
District heating,Industry,10.639
|
||||||
|
Electricity grid,Over generation / exports,104.453
|
||||||
|
Electricity grid,Heating and cooling - homes,113.726
|
||||||
|
Electricity grid,H2 conversion,27.14
|
||||||
|
Electricity grid,Industry,342.165
|
||||||
|
Electricity grid,Road transport,37.797
|
||||||
|
Electricity grid,Agriculture,4.412
|
||||||
|
Electricity grid,Heating and cooling - commercial,40.858
|
||||||
|
Electricity grid,Losses,56.691
|
||||||
|
Electricity grid,Rail transport,7.863
|
||||||
|
Electricity grid,Lighting & appliances - commercial,90.008
|
||||||
|
Electricity grid,Lighting & appliances - homes,93.494
|
||||||
|
Gas imports,Ngas,40.719
|
||||||
|
Gas reserves,Ngas,82.233
|
||||||
|
Gas,Heating and cooling - commercial,0.129
|
||||||
|
Gas,Losses,1.401
|
||||||
|
Gas,Thermal generation,151.891
|
||||||
|
Gas,Agriculture,2.096
|
||||||
|
Gas,Industry,48.58
|
||||||
|
Geothermal,Electricity grid,7.013
|
||||||
|
H2 conversion,H2,20.897
|
||||||
|
H2 conversion,Losses,6.242
|
||||||
|
H2,Road transport,20.897
|
||||||
|
Hydro,Electricity grid,6.995
|
||||||
|
Liquid,Industry,121.066
|
||||||
|
Liquid,International shipping,128.69
|
||||||
|
Liquid,Road transport,135.835
|
||||||
|
Liquid,Domestic aviation,14.458
|
||||||
|
Liquid,International aviation,206.267
|
||||||
|
Liquid,Agriculture,3.64
|
||||||
|
Liquid,National navigation,33.218
|
||||||
|
Liquid,Rail transport,4.413
|
||||||
|
Marine algae,Bio-conversion,4.375
|
||||||
|
Ngas,Gas,122.952
|
||||||
|
Nuclear,Thermal generation,839.978
|
||||||
|
Oil imports,Oil,504.287
|
||||||
|
Oil reserves,Oil,107.703
|
||||||
|
Oil,Liquid,611.99
|
||||||
|
Other waste,Solid,56.587
|
||||||
|
Other waste,Bio-conversion,77.81
|
||||||
|
Pumped heat,Heating and cooling - homes,193.026
|
||||||
|
Pumped heat,Heating and cooling - commercial,70.672
|
||||||
|
Solar PV,Electricity grid,59.901
|
||||||
|
Solar Thermal,Heating and cooling - homes,19.263
|
||||||
|
Solar,Solar Thermal,19.263
|
||||||
|
Solar,Solar PV,59.901
|
||||||
|
Solid,Agriculture,0.882
|
||||||
|
Solid,Thermal generation,400.12
|
||||||
|
Solid,Industry,46.477
|
||||||
|
Thermal generation,Electricity grid,525.531
|
||||||
|
Thermal generation,Losses,787.129
|
||||||
|
Thermal generation,District heating,79.329
|
||||||
|
Tidal,Electricity grid,9.452
|
||||||
|
UK land based bioenergy,Bio-conversion,182.01
|
||||||
|
"""Wave""",Electricity grid,19.013
|
||||||
|
"""Wind""",Electricity grid,289.366
|
||||||
|
|
||||||
|
%% lines at the end, do not remove
|
||||||
|
|
||||||
|
Can't render this file because it has a wrong number of fields in line 2.
|
69
packages/mermaid/src/diagrams/sankey/parser/sankey.jison
Normal file
69
packages/mermaid/src/diagrams/sankey/parser/sankey.jison
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
/** mermaid */
|
||||||
|
|
||||||
|
//---------------------------------------------------------
|
||||||
|
// We support csv format as defined here:
|
||||||
|
// https://www.ietf.org/rfc/rfc4180.txt
|
||||||
|
// There are some minor changes for compliance with jison
|
||||||
|
// We also parse only 3 columns: source,target,value
|
||||||
|
// And allow blank lines for visual purposes
|
||||||
|
//---------------------------------------------------------
|
||||||
|
|
||||||
|
%lex
|
||||||
|
|
||||||
|
%options case-insensitive
|
||||||
|
%options easy_keword_rules
|
||||||
|
|
||||||
|
%x escaped_text
|
||||||
|
%x csv
|
||||||
|
|
||||||
|
// as per section 6.1 of RFC 2234 [2]
|
||||||
|
COMMA \u002C
|
||||||
|
CR \u000D
|
||||||
|
LF \u000A
|
||||||
|
CRLF \u000D\u000A
|
||||||
|
ESCAPED_QUOTE \u0022
|
||||||
|
DQUOTE \u0022
|
||||||
|
TEXTDATA [\u0020-\u0021\u0023-\u002B\u002D-\u007E]
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
<INITIAL>"sankey-beta" { this.pushState('csv'); return 'SANKEY'; }
|
||||||
|
<INITIAL,csv><<EOF>> { return 'EOF' } // match end of file
|
||||||
|
<INITIAL,csv>({CRLF}|{LF}) { return 'NEWLINE' }
|
||||||
|
<INITIAL,csv>{COMMA} { return 'COMMA' }
|
||||||
|
<INITIAL,csv>{DQUOTE} { this.pushState('escaped_text'); return 'DQUOTE'; }
|
||||||
|
<INITIAL,csv>{TEXTDATA}* { return 'NON_ESCAPED_TEXT' }
|
||||||
|
<INITIAL,csv,escaped_text>{DQUOTE}(?!{DQUOTE}) {this.popState('escaped_text'); return 'DQUOTE'; } // unescaped DQUOTE closes string
|
||||||
|
<INITIAL,csv,escaped_text>({TEXTDATA}|{COMMA}|{CR}|{LF}|{DQUOTE}{DQUOTE})* { return 'ESCAPED_TEXT'; }
|
||||||
|
|
||||||
|
/lex
|
||||||
|
|
||||||
|
%start start
|
||||||
|
|
||||||
|
%% // language grammar
|
||||||
|
|
||||||
|
start: SANKEY NEWLINE csv opt_eof;
|
||||||
|
|
||||||
|
csv: record csv_tail;
|
||||||
|
csv_tail: NEWLINE csv | ;
|
||||||
|
opt_eof: EOF | ;
|
||||||
|
|
||||||
|
record
|
||||||
|
: field\[source] COMMA field\[target] COMMA field\[value] {
|
||||||
|
const source = yy.findOrCreateNode($source.trim().replaceAll('""', '"'));
|
||||||
|
const target = yy.findOrCreateNode($target.trim().replaceAll('""', '"'));
|
||||||
|
const value = parseFloat($value.trim());
|
||||||
|
yy.addLink(source,target,value);
|
||||||
|
} // parse only 3 fields, this is not part of CSV standard
|
||||||
|
;
|
||||||
|
|
||||||
|
field
|
||||||
|
: escaped { $$=$escaped; }
|
||||||
|
| non_escaped { $$=$non_escaped; }
|
||||||
|
;
|
||||||
|
|
||||||
|
escaped: DQUOTE ESCAPED_TEXT DQUOTE { $$=$ESCAPED_TEXT; };
|
||||||
|
|
||||||
|
non_escaped: NON_ESCAPED_TEXT { $$=$NON_ESCAPED_TEXT; };
|
||||||
|
|
||||||
|
|
||||||
24
packages/mermaid/src/diagrams/sankey/parser/sankey.spec.ts
Normal file
24
packages/mermaid/src/diagrams/sankey/parser/sankey.spec.ts
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
// @ts-ignore: jison doesn't export types
|
||||||
|
import sankey from './sankey.jison';
|
||||||
|
import db from '../sankeyDB.js';
|
||||||
|
import { cleanupComments } from '../../../diagram-api/comments.js';
|
||||||
|
import { prepareTextForParsing } from '../sankeyUtils.js';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
|
||||||
|
describe('Sankey diagram', function () {
|
||||||
|
describe('when parsing an info graph it', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
sankey.parser.yy = db;
|
||||||
|
sankey.parser.yy.clear();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('parses csv', async () => {
|
||||||
|
const csv = path.resolve(__dirname, './energy.csv');
|
||||||
|
const data = fs.readFileSync(csv, 'utf8');
|
||||||
|
const graphDefinition = prepareTextForParsing(cleanupComments('sankey-beta\n\n ' + data));
|
||||||
|
|
||||||
|
sankey.parser.parse(graphDefinition);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
81
packages/mermaid/src/diagrams/sankey/sankeyDB.ts
Normal file
81
packages/mermaid/src/diagrams/sankey/sankeyDB.ts
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
import * as configApi from '../../config.js';
|
||||||
|
import common from '../common/common.js';
|
||||||
|
import {
|
||||||
|
setAccTitle,
|
||||||
|
getAccTitle,
|
||||||
|
getAccDescription,
|
||||||
|
setAccDescription,
|
||||||
|
setDiagramTitle,
|
||||||
|
getDiagramTitle,
|
||||||
|
clear as commonClear,
|
||||||
|
} from '../../commonDb.js';
|
||||||
|
|
||||||
|
// Sankey diagram represented by nodes and links between those nodes
|
||||||
|
let links: SankeyLink[] = [];
|
||||||
|
// Array of nodes guarantees their order
|
||||||
|
let nodes: SankeyNode[] = [];
|
||||||
|
// We also have to track nodes uniqueness (by ID)
|
||||||
|
let nodesMap: Record<string, SankeyNode> = {};
|
||||||
|
|
||||||
|
const clear = (): void => {
|
||||||
|
links = [];
|
||||||
|
nodes = [];
|
||||||
|
nodesMap = {};
|
||||||
|
commonClear();
|
||||||
|
};
|
||||||
|
|
||||||
|
class SankeyLink {
|
||||||
|
constructor(public source: SankeyNode, public target: SankeyNode, public value: number = 0) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param source - Node where the link starts
|
||||||
|
* @param target - Node where the link ends
|
||||||
|
* @param value - number, float or integer, describes the amount to be passed
|
||||||
|
*/
|
||||||
|
const addLink = (source: SankeyNode, target: SankeyNode, value: number): void => {
|
||||||
|
links.push(new SankeyLink(source, target, value));
|
||||||
|
};
|
||||||
|
|
||||||
|
class SankeyNode {
|
||||||
|
constructor(public ID: string) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
const findOrCreateNode = (ID: string): SankeyNode => {
|
||||||
|
ID = common.sanitizeText(ID, configApi.getConfig());
|
||||||
|
|
||||||
|
if (!nodesMap[ID]) {
|
||||||
|
nodesMap[ID] = new SankeyNode(ID);
|
||||||
|
nodes.push(nodesMap[ID]);
|
||||||
|
}
|
||||||
|
return nodesMap[ID];
|
||||||
|
};
|
||||||
|
|
||||||
|
const getNodes = () => nodes;
|
||||||
|
const getLinks = () => links;
|
||||||
|
|
||||||
|
const getGraph = () => ({
|
||||||
|
nodes: nodes.map((node) => ({ id: node.ID })),
|
||||||
|
links: links.map((link) => ({
|
||||||
|
source: link.source.ID,
|
||||||
|
target: link.target.ID,
|
||||||
|
value: link.value,
|
||||||
|
})),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default {
|
||||||
|
nodesMap,
|
||||||
|
getConfig: () => configApi.getConfig().sankey,
|
||||||
|
getNodes,
|
||||||
|
getLinks,
|
||||||
|
getGraph,
|
||||||
|
addLink,
|
||||||
|
findOrCreateNode,
|
||||||
|
getAccTitle,
|
||||||
|
setAccTitle,
|
||||||
|
getAccDescription,
|
||||||
|
setAccDescription,
|
||||||
|
getDiagramTitle,
|
||||||
|
setDiagramTitle,
|
||||||
|
clear,
|
||||||
|
};
|
||||||
20
packages/mermaid/src/diagrams/sankey/sankeyDetector.ts
Normal file
20
packages/mermaid/src/diagrams/sankey/sankeyDetector.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-api/types.js';
|
||||||
|
|
||||||
|
const id = 'sankey';
|
||||||
|
|
||||||
|
const detector: DiagramDetector = (txt) => {
|
||||||
|
return /^\s*sankey-beta/.test(txt);
|
||||||
|
};
|
||||||
|
|
||||||
|
const loader = async () => {
|
||||||
|
const { diagram } = await import('./sankeyDiagram.js');
|
||||||
|
return { id, diagram };
|
||||||
|
};
|
||||||
|
|
||||||
|
const plugin: ExternalDiagramDefinition = {
|
||||||
|
id,
|
||||||
|
detector,
|
||||||
|
loader,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default plugin;
|
||||||
15
packages/mermaid/src/diagrams/sankey/sankeyDiagram.ts
Normal file
15
packages/mermaid/src/diagrams/sankey/sankeyDiagram.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { DiagramDefinition } from '../../diagram-api/types.js';
|
||||||
|
// @ts-ignore: jison doesn't export types
|
||||||
|
import parser from './parser/sankey.jison';
|
||||||
|
import db from './sankeyDB.js';
|
||||||
|
import renderer from './sankeyRenderer.js';
|
||||||
|
import { prepareTextForParsing } from './sankeyUtils.js';
|
||||||
|
|
||||||
|
const originalParse = parser.parse.bind(parser);
|
||||||
|
parser.parse = (text: string) => originalParse(prepareTextForParsing(text));
|
||||||
|
|
||||||
|
export const diagram: DiagramDefinition = {
|
||||||
|
parser,
|
||||||
|
db,
|
||||||
|
renderer,
|
||||||
|
};
|
||||||
205
packages/mermaid/src/diagrams/sankey/sankeyRenderer.ts
Normal file
205
packages/mermaid/src/diagrams/sankey/sankeyRenderer.ts
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
import { Diagram } from '../../Diagram.js';
|
||||||
|
import * as configApi from '../../config.js';
|
||||||
|
|
||||||
|
import {
|
||||||
|
select as d3select,
|
||||||
|
scaleOrdinal as d3scaleOrdinal,
|
||||||
|
schemeTableau10 as d3schemeTableau10,
|
||||||
|
} from 'd3';
|
||||||
|
|
||||||
|
import {
|
||||||
|
sankey as d3Sankey,
|
||||||
|
sankeyLinkHorizontal as d3SankeyLinkHorizontal,
|
||||||
|
sankeyLeft as d3SankeyLeft,
|
||||||
|
sankeyRight as d3SankeyRight,
|
||||||
|
sankeyCenter as d3SankeyCenter,
|
||||||
|
sankeyJustify as d3SankeyJustify,
|
||||||
|
SankeyNode as d3SankeyNode,
|
||||||
|
} from 'd3-sankey';
|
||||||
|
import { configureSvgSize } from '../../setupGraphViewbox.js';
|
||||||
|
import { Uid } from '../../rendering-util/uid.js';
|
||||||
|
import { SankeyLinkColor, SankeyNodeAlignment } from '../../config.type.js';
|
||||||
|
|
||||||
|
// Map config options to alignment functions
|
||||||
|
const alignmentsMap: Record<
|
||||||
|
SankeyNodeAlignment,
|
||||||
|
(node: d3SankeyNode<object, object>, n: number) => number
|
||||||
|
> = {
|
||||||
|
[SankeyNodeAlignment.left]: d3SankeyLeft,
|
||||||
|
[SankeyNodeAlignment.right]: d3SankeyRight,
|
||||||
|
[SankeyNodeAlignment.center]: d3SankeyCenter,
|
||||||
|
[SankeyNodeAlignment.justify]: d3SankeyJustify,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws Sankey diagram.
|
||||||
|
*
|
||||||
|
* @param text - The text of the diagram
|
||||||
|
* @param id - The id of the diagram which will be used as a DOM element id¨
|
||||||
|
* @param _version - Mermaid version from package.json
|
||||||
|
* @param diagObj - A standard diagram containing the db and the text and type etc of the diagram
|
||||||
|
*/
|
||||||
|
export const draw = function (text: string, id: string, _version: string, diagObj: Diagram): void {
|
||||||
|
// Get Sankey config
|
||||||
|
const { securityLevel, sankey: conf } = configApi.getConfig();
|
||||||
|
const defaultSankeyConfig = configApi!.defaultConfig!.sankey!;
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
// This code repeats for every diagram
|
||||||
|
// Figure out what is happening there, probably it should be separated
|
||||||
|
// The main thing is svg object that is a d3 wrapper for svg operations
|
||||||
|
//
|
||||||
|
let sandboxElement: any;
|
||||||
|
if (securityLevel === 'sandbox') {
|
||||||
|
sandboxElement = d3select('#i' + id);
|
||||||
|
}
|
||||||
|
const root =
|
||||||
|
securityLevel === 'sandbox'
|
||||||
|
? d3select(sandboxElement.nodes()[0].contentDocument.body)
|
||||||
|
: d3select('body');
|
||||||
|
// @ts-ignore TODO root.select is not callable
|
||||||
|
const svg = securityLevel === 'sandbox' ? root.select(`[id="${id}"]`) : d3select(`[id="${id}"]`);
|
||||||
|
|
||||||
|
// Establish svg dimensions and get width and height
|
||||||
|
//
|
||||||
|
const width = conf?.width || defaultSankeyConfig.width!;
|
||||||
|
const height = conf?.height || defaultSankeyConfig.width!;
|
||||||
|
const useMaxWidth = conf?.useMaxWidth || defaultSankeyConfig.useMaxWidth!;
|
||||||
|
const nodeAlignment = conf?.nodeAlignment || defaultSankeyConfig.nodeAlignment!;
|
||||||
|
|
||||||
|
// FIX: using max width prevents height from being set, is it intended?
|
||||||
|
// to add height directly one can use `svg.attr('height', height)`
|
||||||
|
//
|
||||||
|
// @ts-ignore TODO: svg type vs selection mismatch
|
||||||
|
configureSvgSize(svg, height, width, useMaxWidth);
|
||||||
|
|
||||||
|
// Prepare data for construction based on diagObj.db
|
||||||
|
// This must be a mutable object with `nodes` and `links` properties:
|
||||||
|
//
|
||||||
|
// {
|
||||||
|
// "nodes": [ { "id": "Alice" }, { "id": "Bob" }, { "id": "Carol" } ],
|
||||||
|
// "links": [ { "source": "Alice", "target": "Bob", "value": 23 }, { "source": "Bob", "target": "Carol", "value": 43 } ]
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @ts-ignore TODO: db should be coerced to sankey DB type
|
||||||
|
const graph = diagObj.db.getGraph();
|
||||||
|
|
||||||
|
// Get alignment function
|
||||||
|
const nodeAlign = alignmentsMap[nodeAlignment];
|
||||||
|
|
||||||
|
// Construct and configure a Sankey generator
|
||||||
|
// That will be a function that calculates nodes and links dimensions
|
||||||
|
//
|
||||||
|
const nodeWidth = 10;
|
||||||
|
const sankey = d3Sankey()
|
||||||
|
.nodeId((d: any) => d.id) // we use 'id' property to identify node
|
||||||
|
.nodeWidth(nodeWidth)
|
||||||
|
.nodePadding(10)
|
||||||
|
.nodeAlign(nodeAlign)
|
||||||
|
.extent([
|
||||||
|
[0, 0],
|
||||||
|
[width, height],
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Compute the Sankey layout: calculate nodes and links positions
|
||||||
|
// Our `graph` object will be mutated by this and enriched with other properties
|
||||||
|
//
|
||||||
|
sankey(graph);
|
||||||
|
|
||||||
|
// Get color scheme for the graph
|
||||||
|
const colorScheme = d3scaleOrdinal(d3schemeTableau10);
|
||||||
|
|
||||||
|
// Create rectangles for nodes
|
||||||
|
svg
|
||||||
|
.append('g')
|
||||||
|
.attr('class', 'nodes')
|
||||||
|
.selectAll('.node')
|
||||||
|
.data(graph.nodes)
|
||||||
|
.join('g')
|
||||||
|
.attr('class', 'node')
|
||||||
|
.attr('id', (d: any) => (d.uid = Uid.next('node-')).id)
|
||||||
|
.attr('transform', function (d: any) {
|
||||||
|
return 'translate(' + d.x0 + ',' + d.y0 + ')';
|
||||||
|
})
|
||||||
|
.attr('x', (d: any) => d.x0)
|
||||||
|
.attr('y', (d: any) => d.y0)
|
||||||
|
.append('rect')
|
||||||
|
.attr('height', (d: any) => {
|
||||||
|
return d.y1 - d.y0;
|
||||||
|
})
|
||||||
|
.attr('width', (d: any) => d.x1 - d.x0)
|
||||||
|
.attr('fill', (d: any) => colorScheme(d.id));
|
||||||
|
|
||||||
|
// Create labels for nodes
|
||||||
|
svg
|
||||||
|
.append('g')
|
||||||
|
.attr('class', 'node-labels')
|
||||||
|
.attr('font-family', 'sans-serif')
|
||||||
|
.attr('font-size', 14)
|
||||||
|
.selectAll('text')
|
||||||
|
.data(graph.nodes)
|
||||||
|
.join('text')
|
||||||
|
.attr('x', (d: any) => (d.x0 < width / 2 ? d.x1 + 6 : d.x0 - 6))
|
||||||
|
.attr('y', (d: any) => (d.y1 + d.y0) / 2)
|
||||||
|
.attr('dy', '0.35em')
|
||||||
|
.attr('text-anchor', (d: any) => (d.x0 < width / 2 ? 'start' : 'end'))
|
||||||
|
.text((d: any) => d.id);
|
||||||
|
|
||||||
|
// Creates the paths that represent the links.
|
||||||
|
const link = svg
|
||||||
|
.append('g')
|
||||||
|
.attr('class', 'links')
|
||||||
|
.attr('fill', 'none')
|
||||||
|
.attr('stroke-opacity', 0.5)
|
||||||
|
.selectAll('.link')
|
||||||
|
.data(graph.links)
|
||||||
|
.join('g')
|
||||||
|
.attr('class', 'link')
|
||||||
|
.style('mix-blend-mode', 'multiply');
|
||||||
|
|
||||||
|
const linkColor = conf?.linkColor || SankeyLinkColor.gradient;
|
||||||
|
|
||||||
|
if (linkColor === SankeyLinkColor.gradient) {
|
||||||
|
const gradient = link
|
||||||
|
.append('linearGradient')
|
||||||
|
.attr('id', (d: any) => (d.uid = Uid.next('linearGradient-')).id)
|
||||||
|
.attr('gradientUnits', 'userSpaceOnUse')
|
||||||
|
.attr('x1', (d: any) => d.source.x1)
|
||||||
|
.attr('x2', (d: any) => d.target.x0);
|
||||||
|
|
||||||
|
gradient
|
||||||
|
.append('stop')
|
||||||
|
.attr('offset', '0%')
|
||||||
|
.attr('stop-color', (d: any) => colorScheme(d.source.id));
|
||||||
|
|
||||||
|
gradient
|
||||||
|
.append('stop')
|
||||||
|
.attr('offset', '100%')
|
||||||
|
.attr('stop-color', (d: any) => colorScheme(d.target.id));
|
||||||
|
}
|
||||||
|
|
||||||
|
let coloring: any;
|
||||||
|
switch (linkColor) {
|
||||||
|
case SankeyLinkColor.gradient:
|
||||||
|
coloring = (d: any) => d.uid;
|
||||||
|
break;
|
||||||
|
case SankeyLinkColor.source:
|
||||||
|
coloring = (d: any) => colorScheme(d.source.id);
|
||||||
|
break;
|
||||||
|
case SankeyLinkColor.target:
|
||||||
|
coloring = (d: any) => colorScheme(d.target.id);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
coloring = linkColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
link
|
||||||
|
.append('path')
|
||||||
|
.attr('d', d3SankeyLinkHorizontal())
|
||||||
|
.attr('stroke', coloring)
|
||||||
|
.attr('stroke-width', (d: any) => Math.max(1, d.width));
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
draw,
|
||||||
|
};
|
||||||
8
packages/mermaid/src/diagrams/sankey/sankeyUtils.ts
Normal file
8
packages/mermaid/src/diagrams/sankey/sankeyUtils.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
export const prepareTextForParsing = (text: string): string => {
|
||||||
|
const textToParse = text
|
||||||
|
.replaceAll(/^[^\S\n\r]+|[^\S\n\r]+$/g, '') // remove all trailing spaces for each row
|
||||||
|
.replaceAll(/([\n\r])+/g, '\n') // remove empty lines duplicated
|
||||||
|
.trim();
|
||||||
|
|
||||||
|
return textToParse;
|
||||||
|
};
|
||||||
@@ -38,6 +38,8 @@
|
|||||||
"box" { this.begin('LINE'); return 'box'; }
|
"box" { this.begin('LINE'); return 'box'; }
|
||||||
"participant" { this.begin('ID'); return 'participant'; }
|
"participant" { this.begin('ID'); return 'participant'; }
|
||||||
"actor" { this.begin('ID'); return 'participant_actor'; }
|
"actor" { this.begin('ID'); return 'participant_actor'; }
|
||||||
|
"create" return 'create';
|
||||||
|
"destroy" { this.begin('ID'); return 'destroy'; }
|
||||||
<ID>[^\->:\n,;]+?([\-]*[^\->:\n,;]+?)*?(?=((?!\n)\s)+"as"(?!\n)\s|[#\n;]|$) { yytext = yytext.trim(); this.begin('ALIAS'); return 'ACTOR'; }
|
<ID>[^\->:\n,;]+?([\-]*[^\->:\n,;]+?)*?(?=((?!\n)\s)+"as"(?!\n)\s|[#\n;]|$) { yytext = yytext.trim(); this.begin('ALIAS'); return 'ACTOR'; }
|
||||||
<ALIAS>"as" { this.popState(); this.popState(); this.begin('LINE'); return 'AS'; }
|
<ALIAS>"as" { this.popState(); this.popState(); this.begin('LINE'); return 'AS'; }
|
||||||
<ALIAS>(?:) { this.popState(); this.popState(); return 'NEWLINE'; }
|
<ALIAS>(?:) { this.popState(); this.popState(); return 'NEWLINE'; }
|
||||||
@@ -138,6 +140,7 @@ directive
|
|||||||
|
|
||||||
statement
|
statement
|
||||||
: participant_statement
|
: participant_statement
|
||||||
|
| 'create' participant_statement {$2.type='createParticipant'; $$=$2;}
|
||||||
| 'box' restOfLine box_section end
|
| 'box' restOfLine box_section end
|
||||||
{
|
{
|
||||||
$3.unshift({type: 'boxStart', boxData:yy.parseBoxData($2) });
|
$3.unshift({type: 'boxStart', boxData:yy.parseBoxData($2) });
|
||||||
@@ -234,10 +237,11 @@ else_sections
|
|||||||
;
|
;
|
||||||
|
|
||||||
participant_statement
|
participant_statement
|
||||||
: 'participant' actor 'AS' restOfLine 'NEWLINE' {$2.type='addParticipant';$2.description=yy.parseMessage($4); $$=$2;}
|
: 'participant' actor 'AS' restOfLine 'NEWLINE' {$2.draw='participant'; $2.type='addParticipant';$2.description=yy.parseMessage($4); $$=$2;}
|
||||||
| 'participant' actor 'NEWLINE' {$2.type='addParticipant';$$=$2;}
|
| 'participant' actor 'NEWLINE' {$2.draw='participant'; $2.type='addParticipant';$$=$2;}
|
||||||
| 'participant_actor' actor 'AS' restOfLine 'NEWLINE' {$2.type='addActor';$2.description=yy.parseMessage($4); $$=$2;}
|
| 'participant_actor' actor 'AS' restOfLine 'NEWLINE' {$2.draw='actor'; $2.type='addParticipant';$2.description=yy.parseMessage($4); $$=$2;}
|
||||||
| 'participant_actor' actor 'NEWLINE' {$2.type='addActor'; $$=$2;}
|
| 'participant_actor' actor 'NEWLINE' {$2.draw='actor'; $2.type='addParticipant'; $$=$2;}
|
||||||
|
| 'destroy' actor 'NEWLINE' {$2.type='destroyParticipant'; $$=$2;}
|
||||||
;
|
;
|
||||||
|
|
||||||
note_statement
|
note_statement
|
||||||
|
|||||||
@@ -14,12 +14,16 @@ import {
|
|||||||
|
|
||||||
let prevActor = undefined;
|
let prevActor = undefined;
|
||||||
let actors = {};
|
let actors = {};
|
||||||
|
let createdActors = {};
|
||||||
|
let destroyedActors = {};
|
||||||
let boxes = [];
|
let boxes = [];
|
||||||
let messages = [];
|
let messages = [];
|
||||||
const notes = [];
|
const notes = [];
|
||||||
let sequenceNumbersEnabled = false;
|
let sequenceNumbersEnabled = false;
|
||||||
let wrapEnabled;
|
let wrapEnabled;
|
||||||
let currentBox = undefined;
|
let currentBox = undefined;
|
||||||
|
let lastCreated = undefined;
|
||||||
|
let lastDestroyed = undefined;
|
||||||
|
|
||||||
export const parseDirective = function (statement, context, type) {
|
export const parseDirective = function (statement, context, type) {
|
||||||
mermaidAPI.parseDirective(this, statement, context, type);
|
mermaidAPI.parseDirective(this, statement, context, type);
|
||||||
@@ -165,6 +169,12 @@ export const getBoxes = function () {
|
|||||||
export const getActors = function () {
|
export const getActors = function () {
|
||||||
return actors;
|
return actors;
|
||||||
};
|
};
|
||||||
|
export const getCreatedActors = function () {
|
||||||
|
return createdActors;
|
||||||
|
};
|
||||||
|
export const getDestroyedActors = function () {
|
||||||
|
return destroyedActors;
|
||||||
|
};
|
||||||
export const getActor = function (id) {
|
export const getActor = function (id) {
|
||||||
return actors[id];
|
return actors[id];
|
||||||
};
|
};
|
||||||
@@ -194,6 +204,8 @@ export const autoWrap = () => {
|
|||||||
|
|
||||||
export const clear = function () {
|
export const clear = function () {
|
||||||
actors = {};
|
actors = {};
|
||||||
|
createdActors = {};
|
||||||
|
destroyedActors = {};
|
||||||
boxes = [];
|
boxes = [];
|
||||||
messages = [];
|
messages = [];
|
||||||
sequenceNumbersEnabled = false;
|
sequenceNumbersEnabled = false;
|
||||||
@@ -459,10 +471,21 @@ export const apply = function (param) {
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 'addParticipant':
|
case 'addParticipant':
|
||||||
addActor(param.actor, param.actor, param.description, 'participant');
|
addActor(param.actor, param.actor, param.description, param.draw);
|
||||||
break;
|
break;
|
||||||
case 'addActor':
|
case 'createParticipant':
|
||||||
addActor(param.actor, param.actor, param.description, 'actor');
|
if (actors[param.actor]) {
|
||||||
|
throw new Error(
|
||||||
|
"It is not possible to have actors with the same id, even if one is destroyed before the next is created. Use 'AS' aliases to simulate the behavior"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
lastCreated = param.actor;
|
||||||
|
addActor(param.actor, param.actor, param.description, param.draw);
|
||||||
|
createdActors[param.actor] = messages.length;
|
||||||
|
break;
|
||||||
|
case 'destroyParticipant':
|
||||||
|
lastDestroyed = param.actor;
|
||||||
|
destroyedActors[param.actor] = messages.length;
|
||||||
break;
|
break;
|
||||||
case 'activeStart':
|
case 'activeStart':
|
||||||
addSignal(param.actor, undefined, undefined, param.signalType);
|
addSignal(param.actor, undefined, undefined, param.signalType);
|
||||||
@@ -486,6 +509,27 @@ export const apply = function (param) {
|
|||||||
addDetails(param.actor, param.text);
|
addDetails(param.actor, param.text);
|
||||||
break;
|
break;
|
||||||
case 'addMessage':
|
case 'addMessage':
|
||||||
|
if (lastCreated) {
|
||||||
|
if (param.to !== lastCreated) {
|
||||||
|
throw new Error(
|
||||||
|
'The created participant ' +
|
||||||
|
lastCreated +
|
||||||
|
' does not have an associated creating message after its declaration. Please check the sequence diagram.'
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
lastCreated = undefined;
|
||||||
|
}
|
||||||
|
} else if (lastDestroyed) {
|
||||||
|
if (param.to !== lastDestroyed && param.from !== lastDestroyed) {
|
||||||
|
throw new Error(
|
||||||
|
'The destroyed participant ' +
|
||||||
|
lastDestroyed +
|
||||||
|
' does not have an associated destroying message after its declaration. Please check the sequence diagram.'
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
lastDestroyed = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
addSignal(param.from, param.to, param.msg, param.signalType);
|
addSignal(param.from, param.to, param.msg, param.signalType);
|
||||||
break;
|
break;
|
||||||
case 'boxStart':
|
case 'boxStart':
|
||||||
@@ -566,6 +610,8 @@ export default {
|
|||||||
showSequenceNumbers,
|
showSequenceNumbers,
|
||||||
getMessages,
|
getMessages,
|
||||||
getActors,
|
getActors,
|
||||||
|
getCreatedActors,
|
||||||
|
getDestroyedActors,
|
||||||
getActor,
|
getActor,
|
||||||
getActorKeys,
|
getActorKeys,
|
||||||
getActorProperty,
|
getActorProperty,
|
||||||
|
|||||||
@@ -1404,6 +1404,62 @@ link a: Tests @ https://tests.contoso.com/?svc=alice@contoso.com
|
|||||||
expect(boxes[0].actorKeys).toEqual(['a', 'b']);
|
expect(boxes[0].actorKeys).toEqual(['a', 'b']);
|
||||||
expect(boxes[0].fill).toEqual('Aqua');
|
expect(boxes[0].fill).toEqual('Aqua');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should handle simple actor creation', async () => {
|
||||||
|
const str = `
|
||||||
|
sequenceDiagram
|
||||||
|
participant a as Alice
|
||||||
|
a ->>b: Hello Bob?
|
||||||
|
create participant c
|
||||||
|
b-->>c: Hello c!
|
||||||
|
c ->> b: Hello b?
|
||||||
|
create actor d as Donald
|
||||||
|
a ->> d: Hello Donald?
|
||||||
|
`;
|
||||||
|
await mermaidAPI.parse(str);
|
||||||
|
const actors = diagram.db.getActors();
|
||||||
|
const createdActors = diagram.db.getCreatedActors();
|
||||||
|
expect(actors['c'].name).toEqual('c');
|
||||||
|
expect(actors['c'].description).toEqual('c');
|
||||||
|
expect(actors['c'].type).toEqual('participant');
|
||||||
|
expect(createdActors['c']).toEqual(1);
|
||||||
|
expect(actors['d'].name).toEqual('d');
|
||||||
|
expect(actors['d'].description).toEqual('Donald');
|
||||||
|
expect(actors['d'].type).toEqual('actor');
|
||||||
|
expect(createdActors['d']).toEqual(3);
|
||||||
|
});
|
||||||
|
it('should handle simple actor destruction', async () => {
|
||||||
|
const str = `
|
||||||
|
sequenceDiagram
|
||||||
|
participant a as Alice
|
||||||
|
a ->>b: Hello Bob?
|
||||||
|
destroy a
|
||||||
|
b-->>a: Hello Alice!
|
||||||
|
b ->> c: Where is Alice?
|
||||||
|
destroy c
|
||||||
|
b ->> c: Where are you?
|
||||||
|
`;
|
||||||
|
await mermaidAPI.parse(str);
|
||||||
|
const destroyedActors = diagram.db.getDestroyedActors();
|
||||||
|
expect(destroyedActors['a']).toEqual(1);
|
||||||
|
expect(destroyedActors['c']).toEqual(3);
|
||||||
|
});
|
||||||
|
it('should handle the creation and destruction of the same actor', async () => {
|
||||||
|
const str = `
|
||||||
|
sequenceDiagram
|
||||||
|
a ->>b: Hello Bob?
|
||||||
|
create participant c
|
||||||
|
b ->>c: Hello c!
|
||||||
|
c ->> b: Hello b?
|
||||||
|
destroy c
|
||||||
|
b ->> c : Bye c !
|
||||||
|
`;
|
||||||
|
await mermaidAPI.parse(str);
|
||||||
|
const createdActors = diagram.db.getCreatedActors();
|
||||||
|
const destroyedActors = diagram.db.getDestroyedActors();
|
||||||
|
expect(createdActors['c']).toEqual(1);
|
||||||
|
expect(destroyedActors['c']).toEqual(3);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
describe('when checking the bounds in a sequenceDiagram', function () {
|
describe('when checking the bounds in a sequenceDiagram', function () {
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
@@ -1973,7 +2029,9 @@ participant Alice`;
|
|||||||
expect(bounds.startx).toBe(0);
|
expect(bounds.startx).toBe(0);
|
||||||
expect(bounds.starty).toBe(0);
|
expect(bounds.starty).toBe(0);
|
||||||
expect(bounds.stopx).toBe(conf.width);
|
expect(bounds.stopx).toBe(conf.width);
|
||||||
expect(bounds.stopy).toBe(models.lastActor().y + models.lastActor().height + conf.boxMargin);
|
expect(bounds.stopy).toBe(
|
||||||
|
models.lastActor().stopy + models.lastActor().height + conf.boxMargin
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -2025,7 +2083,7 @@ participant Alice
|
|||||||
expect(bounds.startx).toBe(0);
|
expect(bounds.startx).toBe(0);
|
||||||
expect(bounds.starty).toBe(0);
|
expect(bounds.starty).toBe(0);
|
||||||
expect(bounds.stopy).toBe(
|
expect(bounds.stopy).toBe(
|
||||||
models.lastActor().y + models.lastActor().height + mermaid.sequence.boxMargin
|
models.lastActor().stopy + models.lastActor().height + mermaid.sequence.boxMargin
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should handle one actor, when logLevel is 3 (dfg0)', async () => {
|
it('should handle one actor, when logLevel is 3 (dfg0)', async () => {
|
||||||
@@ -2045,7 +2103,7 @@ participant Alice
|
|||||||
expect(bounds.startx).toBe(0);
|
expect(bounds.startx).toBe(0);
|
||||||
expect(bounds.starty).toBe(0);
|
expect(bounds.starty).toBe(0);
|
||||||
expect(bounds.stopy).toBe(
|
expect(bounds.stopy).toBe(
|
||||||
models.lastActor().y + models.lastActor().height + mermaid.sequence.boxMargin
|
models.lastActor().stopy + models.lastActor().height + mermaid.sequence.boxMargin
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should hide sequence numbers when autonumber is removed when autonumber is enabled', async () => {
|
it('should hide sequence numbers when autonumber is removed when autonumber is enabled', async () => {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// @ts-nocheck TODO: fix file
|
// @ts-nocheck TODO: fix file
|
||||||
import { select, selectAll } from 'd3';
|
import { select, selectAll } from 'd3';
|
||||||
import svgDraw, { drawText, fixLifeLineHeights } from './svgDraw.js';
|
import svgDraw, { ACTOR_TYPE_WIDTH, drawText, fixLifeLineHeights } from './svgDraw.js';
|
||||||
import { log } from '../../logger.js';
|
import { log } from '../../logger.js';
|
||||||
import common from '../common/common.js';
|
import common from '../common/common.js';
|
||||||
import * as svgDrawCommon from '../common/svgDrawCommon';
|
import * as svgDrawCommon from '../common/svgDrawCommon';
|
||||||
@@ -478,29 +478,19 @@ const drawMessage = function (diagram, msgModel, lineStartY: number, diagObj: Di
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const drawActors = function (
|
const addActorRenderingData = function (
|
||||||
diagram,
|
diagram,
|
||||||
actors,
|
actors,
|
||||||
|
createdActors,
|
||||||
actorKeys,
|
actorKeys,
|
||||||
verticalPos,
|
verticalPos,
|
||||||
configuration,
|
|
||||||
messages,
|
messages,
|
||||||
isFooter
|
isFooter
|
||||||
) {
|
) {
|
||||||
if (configuration.hideUnusedParticipants === true) {
|
|
||||||
const newActors = new Set();
|
|
||||||
messages.forEach((message) => {
|
|
||||||
newActors.add(message.from);
|
|
||||||
newActors.add(message.to);
|
|
||||||
});
|
|
||||||
actorKeys = actorKeys.filter((actorKey) => newActors.has(actorKey));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw the actors
|
|
||||||
let prevWidth = 0;
|
let prevWidth = 0;
|
||||||
let prevMargin = 0;
|
let prevMargin = 0;
|
||||||
let maxHeight = 0;
|
|
||||||
let prevBox = undefined;
|
let prevBox = undefined;
|
||||||
|
let maxHeight = 0;
|
||||||
|
|
||||||
for (const actorKey of actorKeys) {
|
for (const actorKey of actorKeys) {
|
||||||
const actor = actors[actorKey];
|
const actor = actors[actorKey];
|
||||||
@@ -528,12 +518,16 @@ export const drawActors = function (
|
|||||||
actor.height = common.getMax(actor.height || conf.height, conf.height);
|
actor.height = common.getMax(actor.height || conf.height, conf.height);
|
||||||
actor.margin = actor.margin || conf.actorMargin;
|
actor.margin = actor.margin || conf.actorMargin;
|
||||||
|
|
||||||
actor.x = prevWidth + prevMargin;
|
maxHeight = common.getMax(maxHeight, actor.height);
|
||||||
actor.y = bounds.getVerticalPos();
|
|
||||||
|
// if the actor is created by a message, widen margin
|
||||||
|
if (createdActors[actor.name]) {
|
||||||
|
prevMargin += actor.width / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
actor.x = prevWidth + prevMargin;
|
||||||
|
actor.starty = bounds.getVerticalPos();
|
||||||
|
|
||||||
// Draw the box with the attached line
|
|
||||||
const height = svgDraw.drawActor(diagram, actor, conf, isFooter);
|
|
||||||
maxHeight = common.getMax(maxHeight, height);
|
|
||||||
bounds.insert(actor.x, verticalPos, actor.x + actor.width, actor.height);
|
bounds.insert(actor.x, verticalPos, actor.x + actor.width, actor.height);
|
||||||
|
|
||||||
prevWidth += actor.width + prevMargin;
|
prevWidth += actor.width + prevMargin;
|
||||||
@@ -554,6 +548,28 @@ export const drawActors = function (
|
|||||||
bounds.bumpVerticalPos(maxHeight);
|
bounds.bumpVerticalPos(maxHeight);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const drawActors = function (diagram, actors, actorKeys, isFooter) {
|
||||||
|
if (!isFooter) {
|
||||||
|
for (const actorKey of actorKeys) {
|
||||||
|
const actor = actors[actorKey];
|
||||||
|
// Draw the box with the attached line
|
||||||
|
svgDraw.drawActor(diagram, actor, conf, false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let maxHeight = 0;
|
||||||
|
bounds.bumpVerticalPos(conf.boxMargin * 2);
|
||||||
|
for (const actorKey of actorKeys) {
|
||||||
|
const actor = actors[actorKey];
|
||||||
|
if (!actor.stopy) {
|
||||||
|
actor.stopy = bounds.getVerticalPos();
|
||||||
|
}
|
||||||
|
const height = svgDraw.drawActor(diagram, actor, conf, true);
|
||||||
|
maxHeight = common.getMax(maxHeight, height);
|
||||||
|
}
|
||||||
|
bounds.bumpVerticalPos(maxHeight + conf.boxMargin);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const drawActorsPopup = function (diagram, actors, actorKeys, doc) {
|
export const drawActorsPopup = function (diagram, actors, actorKeys, doc) {
|
||||||
let maxHeight = 0;
|
let maxHeight = 0;
|
||||||
let maxWidth = 0;
|
let maxWidth = 0;
|
||||||
@@ -633,6 +649,95 @@ function adjustLoopHeightForWrap(loopWidths, msg, preMargin, postMargin, addLoop
|
|||||||
bounds.bumpVerticalPos(heightAdjust);
|
bounds.bumpVerticalPos(heightAdjust);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjust the msgModel and the actor for the rendering in case the latter is created or destroyed by the msg
|
||||||
|
* @param msg - the potentially creating or destroying message
|
||||||
|
* @param msgModel - the model associated with the message
|
||||||
|
* @param lineStartY - the y position of the message line
|
||||||
|
* @param index - the index of the current actor under consideration
|
||||||
|
* @param actors - the array of all actors
|
||||||
|
* @param createdActors - the array of actors created in the diagram
|
||||||
|
* @param destroyedActors - the array of actors destroyed in the diagram
|
||||||
|
*/
|
||||||
|
function adjustCreatedDestroyedData(
|
||||||
|
msg,
|
||||||
|
msgModel,
|
||||||
|
lineStartY,
|
||||||
|
index,
|
||||||
|
actors,
|
||||||
|
createdActors,
|
||||||
|
destroyedActors
|
||||||
|
) {
|
||||||
|
function receiverAdjustment(actor, adjustment) {
|
||||||
|
if (actor.x < actors[msg.from].x) {
|
||||||
|
bounds.insert(
|
||||||
|
msgModel.stopx - adjustment,
|
||||||
|
msgModel.starty,
|
||||||
|
msgModel.startx,
|
||||||
|
msgModel.stopy + actor.height / 2 + conf.noteMargin
|
||||||
|
);
|
||||||
|
msgModel.stopx = msgModel.stopx + adjustment;
|
||||||
|
} else {
|
||||||
|
bounds.insert(
|
||||||
|
msgModel.startx,
|
||||||
|
msgModel.starty,
|
||||||
|
msgModel.stopx + adjustment,
|
||||||
|
msgModel.stopy + actor.height / 2 + conf.noteMargin
|
||||||
|
);
|
||||||
|
msgModel.stopx = msgModel.stopx - adjustment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function senderAdjustment(actor, adjustment) {
|
||||||
|
if (actor.x < actors[msg.to].x) {
|
||||||
|
bounds.insert(
|
||||||
|
msgModel.startx - adjustment,
|
||||||
|
msgModel.starty,
|
||||||
|
msgModel.stopx,
|
||||||
|
msgModel.stopy + actor.height / 2 + conf.noteMargin
|
||||||
|
);
|
||||||
|
msgModel.startx = msgModel.startx + adjustment;
|
||||||
|
} else {
|
||||||
|
bounds.insert(
|
||||||
|
msgModel.stopx,
|
||||||
|
msgModel.starty,
|
||||||
|
msgModel.startx + adjustment,
|
||||||
|
msgModel.stopy + actor.height / 2 + conf.noteMargin
|
||||||
|
);
|
||||||
|
msgModel.startx = msgModel.startx - adjustment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if it is a create message
|
||||||
|
if (createdActors[msg.to] == index) {
|
||||||
|
const actor = actors[msg.to];
|
||||||
|
const adjustment = actor.type == 'actor' ? ACTOR_TYPE_WIDTH / 2 + 3 : actor.width / 2 + 3;
|
||||||
|
receiverAdjustment(actor, adjustment);
|
||||||
|
actor.starty = lineStartY - actor.height / 2;
|
||||||
|
bounds.bumpVerticalPos(actor.height / 2);
|
||||||
|
}
|
||||||
|
// if it is a destroy sender message
|
||||||
|
else if (destroyedActors[msg.from] == index) {
|
||||||
|
const actor = actors[msg.from];
|
||||||
|
if (conf.mirrorActors) {
|
||||||
|
const adjustment = actor.type == 'actor' ? ACTOR_TYPE_WIDTH / 2 : actor.width / 2;
|
||||||
|
senderAdjustment(actor, adjustment);
|
||||||
|
}
|
||||||
|
actor.stopy = lineStartY - actor.height / 2;
|
||||||
|
bounds.bumpVerticalPos(actor.height / 2);
|
||||||
|
}
|
||||||
|
// if it is a destroy receiver message
|
||||||
|
else if (destroyedActors[msg.to] == index) {
|
||||||
|
const actor = actors[msg.to];
|
||||||
|
if (conf.mirrorActors) {
|
||||||
|
const adjustment = actor.type == 'actor' ? ACTOR_TYPE_WIDTH / 2 + 3 : actor.width / 2 + 3;
|
||||||
|
receiverAdjustment(actor, adjustment);
|
||||||
|
}
|
||||||
|
actor.stopy = lineStartY - actor.height / 2;
|
||||||
|
bounds.bumpVerticalPos(actor.height / 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draws a sequenceDiagram in the tag with id: id based on the graph definition in text.
|
* Draws a sequenceDiagram in the tag with id: id based on the graph definition in text.
|
||||||
*
|
*
|
||||||
@@ -666,8 +771,10 @@ export const draw = function (_text: string, id: string, _version: string, diagO
|
|||||||
|
|
||||||
// Fetch data from the parsing
|
// Fetch data from the parsing
|
||||||
const actors = diagObj.db.getActors();
|
const actors = diagObj.db.getActors();
|
||||||
|
const createdActors = diagObj.db.getCreatedActors();
|
||||||
|
const destroyedActors = diagObj.db.getDestroyedActors();
|
||||||
const boxes = diagObj.db.getBoxes();
|
const boxes = diagObj.db.getBoxes();
|
||||||
const actorKeys = diagObj.db.getActorKeys();
|
let actorKeys = diagObj.db.getActorKeys();
|
||||||
const messages = diagObj.db.getMessages();
|
const messages = diagObj.db.getMessages();
|
||||||
const title = diagObj.db.getDiagramTitle();
|
const title = diagObj.db.getDiagramTitle();
|
||||||
const hasBoxes = diagObj.db.hasAtLeastOneBox();
|
const hasBoxes = diagObj.db.hasAtLeastOneBox();
|
||||||
@@ -686,7 +793,16 @@ export const draw = function (_text: string, id: string, _version: string, diagO
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
drawActors(diagram, actors, actorKeys, 0, conf, messages, false);
|
if (conf.hideUnusedParticipants === true) {
|
||||||
|
const newActors = new Set();
|
||||||
|
messages.forEach((message) => {
|
||||||
|
newActors.add(message.from);
|
||||||
|
newActors.add(message.to);
|
||||||
|
});
|
||||||
|
actorKeys = actorKeys.filter((actorKey) => newActors.has(actorKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
addActorRenderingData(diagram, actors, createdActors, actorKeys, 0, messages, false);
|
||||||
const loopWidths = calculateLoopBounds(messages, actors, maxMessageWidthPerActor, diagObj);
|
const loopWidths = calculateLoopBounds(messages, actors, maxMessageWidthPerActor, diagObj);
|
||||||
|
|
||||||
// The arrow head definition is attached to the svg once
|
// The arrow head definition is attached to the svg once
|
||||||
@@ -720,7 +836,8 @@ export const draw = function (_text: string, id: string, _version: string, diagO
|
|||||||
let sequenceIndex = 1;
|
let sequenceIndex = 1;
|
||||||
let sequenceIndexStep = 1;
|
let sequenceIndexStep = 1;
|
||||||
const messagesToDraw = [];
|
const messagesToDraw = [];
|
||||||
messages.forEach(function (msg) {
|
const backgrounds = [];
|
||||||
|
messages.forEach(function (msg, index) {
|
||||||
let loopModel, noteModel, msgModel;
|
let loopModel, noteModel, msgModel;
|
||||||
|
|
||||||
switch (msg.type) {
|
switch (msg.type) {
|
||||||
@@ -757,7 +874,7 @@ export const draw = function (_text: string, id: string, _version: string, diagO
|
|||||||
break;
|
break;
|
||||||
case diagObj.db.LINETYPE.RECT_END:
|
case diagObj.db.LINETYPE.RECT_END:
|
||||||
loopModel = bounds.endLoop();
|
loopModel = bounds.endLoop();
|
||||||
svgDraw.drawBackgroundRect(diagram, loopModel);
|
backgrounds.push(loopModel);
|
||||||
bounds.models.addLoop(loopModel);
|
bounds.models.addLoop(loopModel);
|
||||||
bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos());
|
bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos());
|
||||||
break;
|
break;
|
||||||
@@ -876,13 +993,20 @@ export const draw = function (_text: string, id: string, _version: string, diagO
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
try {
|
try {
|
||||||
// lastMsg = msg
|
|
||||||
bounds.resetVerticalPos();
|
|
||||||
msgModel = msg.msgModel;
|
msgModel = msg.msgModel;
|
||||||
msgModel.starty = bounds.getVerticalPos();
|
msgModel.starty = bounds.getVerticalPos();
|
||||||
msgModel.sequenceIndex = sequenceIndex;
|
msgModel.sequenceIndex = sequenceIndex;
|
||||||
msgModel.sequenceVisible = diagObj.db.showSequenceNumbers();
|
msgModel.sequenceVisible = diagObj.db.showSequenceNumbers();
|
||||||
const lineStartY = boundMessage(diagram, msgModel);
|
const lineStartY = boundMessage(diagram, msgModel);
|
||||||
|
adjustCreatedDestroyedData(
|
||||||
|
msg,
|
||||||
|
msgModel,
|
||||||
|
lineStartY,
|
||||||
|
index,
|
||||||
|
actors,
|
||||||
|
createdActors,
|
||||||
|
destroyedActors
|
||||||
|
);
|
||||||
messagesToDraw.push({ messageModel: msgModel, lineStartY: lineStartY });
|
messagesToDraw.push({ messageModel: msgModel, lineStartY: lineStartY });
|
||||||
bounds.models.addMessage(msgModel);
|
bounds.models.addMessage(msgModel);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -907,15 +1031,16 @@ export const draw = function (_text: string, id: string, _version: string, diagO
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
messagesToDraw.forEach((e) => drawMessage(diagram, e.messageModel, e.lineStartY, diagObj));
|
log.debug('createdActors', createdActors);
|
||||||
|
log.debug('destroyedActors', destroyedActors);
|
||||||
|
|
||||||
|
drawActors(diagram, actors, actorKeys, false);
|
||||||
|
messagesToDraw.forEach((e) => drawMessage(diagram, e.messageModel, e.lineStartY, diagObj));
|
||||||
if (conf.mirrorActors) {
|
if (conf.mirrorActors) {
|
||||||
// Draw actors below diagram
|
drawActors(diagram, actors, actorKeys, true);
|
||||||
bounds.bumpVerticalPos(conf.boxMargin * 2);
|
|
||||||
drawActors(diagram, actors, actorKeys, bounds.getVerticalPos(), conf, messages, true);
|
|
||||||
bounds.bumpVerticalPos(conf.boxMargin);
|
|
||||||
fixLifeLineHeights(diagram, bounds.getVerticalPos());
|
|
||||||
}
|
}
|
||||||
|
backgrounds.forEach((e) => svgDraw.drawBackgroundRect(diagram, e));
|
||||||
|
fixLifeLineHeights(diagram, actors, actorKeys, conf);
|
||||||
|
|
||||||
bounds.models.boxes.forEach(function (box) {
|
bounds.models.boxes.forEach(function (box) {
|
||||||
box.height = bounds.getVerticalPos() - box.y;
|
box.height = bounds.getVerticalPos() - box.y;
|
||||||
@@ -937,11 +1062,6 @@ export const draw = function (_text: string, id: string, _version: string, diagO
|
|||||||
|
|
||||||
const { bounds: box } = bounds.getBounds();
|
const { bounds: box } = bounds.getBounds();
|
||||||
|
|
||||||
// Adjust line height of actor lines now that the height of the diagram is known
|
|
||||||
log.debug('For line height fix Querying: #' + id + ' .actor-line');
|
|
||||||
const actorLines = selectAll('#' + id + ' .actor-line');
|
|
||||||
actorLines.attr('y2', box.stopy);
|
|
||||||
|
|
||||||
// Make sure the height of the diagram supports long menus.
|
// Make sure the height of the diagram supports long menus.
|
||||||
let boxHeight = box.stopy - box.starty;
|
let boxHeight = box.stopy - box.starty;
|
||||||
if (boxHeight < requiredBoxSize.maxHeight) {
|
if (boxHeight < requiredBoxSize.maxHeight) {
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import { addFunction } from '../../interactionDb.js';
|
|||||||
import { ZERO_WIDTH_SPACE, parseFontSize } from '../../utils.js';
|
import { ZERO_WIDTH_SPACE, parseFontSize } from '../../utils.js';
|
||||||
import { sanitizeUrl } from '@braintree/sanitize-url';
|
import { sanitizeUrl } from '@braintree/sanitize-url';
|
||||||
|
|
||||||
|
export const ACTOR_TYPE_WIDTH = 18 * 2;
|
||||||
|
|
||||||
export const drawRect = function (elem, rectData) {
|
export const drawRect = function (elem, rectData) {
|
||||||
return svgDrawCommon.drawRect(elem, rectData);
|
return svgDrawCommon.drawRect(elem, rectData);
|
||||||
};
|
};
|
||||||
@@ -294,14 +296,19 @@ export const drawLabel = function (elem, txtObject) {
|
|||||||
|
|
||||||
let actorCnt = -1;
|
let actorCnt = -1;
|
||||||
|
|
||||||
export const fixLifeLineHeights = (diagram, bounds) => {
|
export const fixLifeLineHeights = (diagram, actors, actorKeys, conf) => {
|
||||||
if (!diagram.selectAll) {
|
if (!diagram.select) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
diagram
|
actorKeys.forEach((actorKey) => {
|
||||||
.selectAll('.actor-line')
|
const actor = actors[actorKey];
|
||||||
.attr('class', '200')
|
const actorDOM = diagram.select('#actor' + actor.actorCnt);
|
||||||
.attr('y2', bounds - 55);
|
if (!conf.mirrorActors && actor.stopy) {
|
||||||
|
actorDOM.attr('y2', actor.stopy + actor.height / 2);
|
||||||
|
} else if (conf.mirrorActors) {
|
||||||
|
actorDOM.attr('y2', actor.stopy);
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -313,10 +320,11 @@ export const fixLifeLineHeights = (diagram, bounds) => {
|
|||||||
* @param {boolean} isFooter - If the actor is the footer one
|
* @param {boolean} isFooter - If the actor is the footer one
|
||||||
*/
|
*/
|
||||||
const drawActorTypeParticipant = function (elem, actor, conf, isFooter) {
|
const drawActorTypeParticipant = function (elem, actor, conf, isFooter) {
|
||||||
|
const actorY = isFooter ? actor.stopy : actor.starty;
|
||||||
const center = actor.x + actor.width / 2;
|
const center = actor.x + actor.width / 2;
|
||||||
const centerY = actor.y + 5;
|
const centerY = actorY + 5;
|
||||||
|
|
||||||
const boxpluslineGroup = elem.append('g');
|
const boxpluslineGroup = elem.append('g').lower();
|
||||||
var g = boxpluslineGroup;
|
var g = boxpluslineGroup;
|
||||||
|
|
||||||
if (!isFooter) {
|
if (!isFooter) {
|
||||||
@@ -328,6 +336,7 @@ const drawActorTypeParticipant = function (elem, actor, conf, isFooter) {
|
|||||||
.attr('x2', center)
|
.attr('x2', center)
|
||||||
.attr('y2', 2000)
|
.attr('y2', 2000)
|
||||||
.attr('class', 'actor-line')
|
.attr('class', 'actor-line')
|
||||||
|
.attr('class', '200')
|
||||||
.attr('stroke-width', '0.5px')
|
.attr('stroke-width', '0.5px')
|
||||||
.attr('stroke', '#999');
|
.attr('stroke', '#999');
|
||||||
|
|
||||||
@@ -348,7 +357,7 @@ const drawActorTypeParticipant = function (elem, actor, conf, isFooter) {
|
|||||||
rect.fill = '#eaeaea';
|
rect.fill = '#eaeaea';
|
||||||
}
|
}
|
||||||
rect.x = actor.x;
|
rect.x = actor.x;
|
||||||
rect.y = actor.y;
|
rect.y = actorY;
|
||||||
rect.width = actor.width;
|
rect.width = actor.width;
|
||||||
rect.height = actor.height;
|
rect.height = actor.height;
|
||||||
rect.class = cssclass;
|
rect.class = cssclass;
|
||||||
@@ -388,8 +397,11 @@ const drawActorTypeParticipant = function (elem, actor, conf, isFooter) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const drawActorTypeActor = function (elem, actor, conf, isFooter) {
|
const drawActorTypeActor = function (elem, actor, conf, isFooter) {
|
||||||
|
const actorY = isFooter ? actor.stopy : actor.starty;
|
||||||
const center = actor.x + actor.width / 2;
|
const center = actor.x + actor.width / 2;
|
||||||
const centerY = actor.y + 80;
|
const centerY = actorY + 80;
|
||||||
|
|
||||||
|
elem.lower();
|
||||||
|
|
||||||
if (!isFooter) {
|
if (!isFooter) {
|
||||||
actorCnt++;
|
actorCnt++;
|
||||||
@@ -401,15 +413,18 @@ const drawActorTypeActor = function (elem, actor, conf, isFooter) {
|
|||||||
.attr('x2', center)
|
.attr('x2', center)
|
||||||
.attr('y2', 2000)
|
.attr('y2', 2000)
|
||||||
.attr('class', 'actor-line')
|
.attr('class', 'actor-line')
|
||||||
|
.attr('class', '200')
|
||||||
.attr('stroke-width', '0.5px')
|
.attr('stroke-width', '0.5px')
|
||||||
.attr('stroke', '#999');
|
.attr('stroke', '#999');
|
||||||
|
|
||||||
|
actor.actorCnt = actorCnt;
|
||||||
}
|
}
|
||||||
const actElem = elem.append('g');
|
const actElem = elem.append('g');
|
||||||
actElem.attr('class', 'actor-man');
|
actElem.attr('class', 'actor-man');
|
||||||
|
|
||||||
const rect = svgDrawCommon.getNoteRect();
|
const rect = svgDrawCommon.getNoteRect();
|
||||||
rect.x = actor.x;
|
rect.x = actor.x;
|
||||||
rect.y = actor.y;
|
rect.y = actorY;
|
||||||
rect.fill = '#eaeaea';
|
rect.fill = '#eaeaea';
|
||||||
rect.width = actor.width;
|
rect.width = actor.width;
|
||||||
rect.height = actor.height;
|
rect.height = actor.height;
|
||||||
@@ -421,33 +436,33 @@ const drawActorTypeActor = function (elem, actor, conf, isFooter) {
|
|||||||
.append('line')
|
.append('line')
|
||||||
.attr('id', 'actor-man-torso' + actorCnt)
|
.attr('id', 'actor-man-torso' + actorCnt)
|
||||||
.attr('x1', center)
|
.attr('x1', center)
|
||||||
.attr('y1', actor.y + 25)
|
.attr('y1', actorY + 25)
|
||||||
.attr('x2', center)
|
.attr('x2', center)
|
||||||
.attr('y2', actor.y + 45);
|
.attr('y2', actorY + 45);
|
||||||
|
|
||||||
actElem
|
actElem
|
||||||
.append('line')
|
.append('line')
|
||||||
.attr('id', 'actor-man-arms' + actorCnt)
|
.attr('id', 'actor-man-arms' + actorCnt)
|
||||||
.attr('x1', center - 18)
|
.attr('x1', center - ACTOR_TYPE_WIDTH / 2)
|
||||||
.attr('y1', actor.y + 33)
|
.attr('y1', actorY + 33)
|
||||||
.attr('x2', center + 18)
|
.attr('x2', center + ACTOR_TYPE_WIDTH / 2)
|
||||||
.attr('y2', actor.y + 33);
|
.attr('y2', actorY + 33);
|
||||||
actElem
|
actElem
|
||||||
.append('line')
|
.append('line')
|
||||||
.attr('x1', center - 18)
|
.attr('x1', center - ACTOR_TYPE_WIDTH / 2)
|
||||||
.attr('y1', actor.y + 60)
|
.attr('y1', actorY + 60)
|
||||||
.attr('x2', center)
|
.attr('x2', center)
|
||||||
.attr('y2', actor.y + 45);
|
.attr('y2', actorY + 45);
|
||||||
actElem
|
actElem
|
||||||
.append('line')
|
.append('line')
|
||||||
.attr('x1', center)
|
.attr('x1', center)
|
||||||
.attr('y1', actor.y + 45)
|
.attr('y1', actorY + 45)
|
||||||
.attr('x2', center + 16)
|
.attr('x2', center + ACTOR_TYPE_WIDTH / 2 - 2)
|
||||||
.attr('y2', actor.y + 60);
|
.attr('y2', actorY + 60);
|
||||||
|
|
||||||
const circle = actElem.append('circle');
|
const circle = actElem.append('circle');
|
||||||
circle.attr('cx', actor.x + actor.width / 2);
|
circle.attr('cx', actor.x + actor.width / 2);
|
||||||
circle.attr('cy', actor.y + 10);
|
circle.attr('cy', actorY + 10);
|
||||||
circle.attr('r', 15);
|
circle.attr('r', 15);
|
||||||
circle.attr('width', actor.width);
|
circle.attr('width', actor.width);
|
||||||
circle.attr('height', actor.height);
|
circle.attr('height', actor.height);
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ function sidebarSyntax() {
|
|||||||
{ text: 'Mindmaps 🔥', link: '/syntax/mindmap' },
|
{ text: 'Mindmaps 🔥', link: '/syntax/mindmap' },
|
||||||
{ text: 'Timeline 🔥', link: '/syntax/timeline' },
|
{ text: 'Timeline 🔥', link: '/syntax/timeline' },
|
||||||
{ text: 'Zenuml 🔥', link: '/syntax/zenuml' },
|
{ text: 'Zenuml 🔥', link: '/syntax/zenuml' },
|
||||||
|
{ text: 'Sankey 🔥', link: '/syntax/sankey' },
|
||||||
{ text: 'Other Examples', link: '/syntax/examples' },
|
{ text: 'Other Examples', link: '/syntax/examples' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ async function download(url: string, fileName: URL) {
|
|||||||
const image = await fetch(url);
|
const image = await fetch(url);
|
||||||
await writeFile(fileName, Buffer.from(await image.arrayBuffer()));
|
await writeFile(fileName, Buffer.from(await image.arrayBuffer()));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error('failed to load', url, error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,10 +26,13 @@ async function fetchAvatars() {
|
|||||||
await mkdir(fileURLToPath(new URL(getAvatarPath('none'))).replace('none.png', ''), {
|
await mkdir(fileURLToPath(new URL(getAvatarPath('none'))).replace('none.png', ''), {
|
||||||
recursive: true,
|
recursive: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
contributors = JSON.parse(await readFile(pathContributors, { encoding: 'utf-8' }));
|
contributors = JSON.parse(await readFile(pathContributors, { encoding: 'utf-8' }));
|
||||||
for (const name of contributors) {
|
let avatars = contributors.map((name) => {
|
||||||
await download(`https://github.com/${name}.png?size=100`, getAvatarPath(name));
|
download(`https://github.com/${name}.png?size=100`, getAvatarPath(name));
|
||||||
}
|
});
|
||||||
|
|
||||||
|
await Promise.all(avatars);
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchAvatars();
|
fetchAvatars();
|
||||||
|
|||||||
@@ -10,23 +10,27 @@ interface Contributor {
|
|||||||
|
|
||||||
async function fetchContributors() {
|
async function fetchContributors() {
|
||||||
const collaborators: string[] = [];
|
const collaborators: string[] = [];
|
||||||
let page = 1;
|
try {
|
||||||
let data: Contributor[] = [];
|
let page = 1;
|
||||||
do {
|
let data: Contributor[] = [];
|
||||||
const response = await fetch(
|
do {
|
||||||
`https://api.github.com/repos/mermaid-js/mermaid/contributors?per_page=100&page=${page}`,
|
const response = await fetch(
|
||||||
{
|
`https://api.github.com/repos/mermaid-js/mermaid/contributors?per_page=100&page=${page}`,
|
||||||
method: 'GET',
|
{
|
||||||
headers: {
|
method: 'GET',
|
||||||
'content-type': 'application/json',
|
headers: {
|
||||||
},
|
'content-type': 'application/json',
|
||||||
}
|
},
|
||||||
);
|
}
|
||||||
data = await response.json();
|
);
|
||||||
collaborators.push(...data.map((i) => i.login));
|
data = await response.json();
|
||||||
console.log(`Fetched page ${page}`);
|
collaborators.push(...data.map((i) => i.login));
|
||||||
page++;
|
console.log(`Fetched page ${page}`);
|
||||||
} while (data.length === 100);
|
page++;
|
||||||
|
} while (data.length === 100);
|
||||||
|
} catch (e) {
|
||||||
|
/* contributors fetching failure must not hinder docs development */
|
||||||
|
}
|
||||||
return collaborators.filter((name) => !name.includes('[bot]'));
|
return collaborators.filter((name) => !name.includes('[bot]'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,9 +55,9 @@ To make a custom theme, modify `themeVariables` via `init`.
|
|||||||
|
|
||||||
You will need to use the [base](#available-themes) theme as it is the only modifiable theme.
|
You will need to use the [base](#available-themes) theme as it is the only modifiable theme.
|
||||||
|
|
||||||
| Parameter | Description | Type | Properties |
|
| Parameter | Description | Type | Properties |
|
||||||
| -------------- | ------------------------------------ | ------ | --------------------------------------------------------------------------------------------------- |
|
| -------------- | ------------------------------------ | ------ | ----------------------------------------------------------------------------------- |
|
||||||
| themeVariables | Modifiable with the `init` directive | Object | `primaryColor`, `primaryTextColor`, `lineColor` ([see full list](#theme-variables-reference-table)) |
|
| themeVariables | Modifiable with the `init` directive | Object | `primaryColor`, `primaryTextColor`, `lineColor` ([see full list](#theme-variables)) |
|
||||||
|
|
||||||
Example of modifying `themeVariables` using the `init` directive:
|
Example of modifying `themeVariables` using the `init` directive:
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Announcements
|
# Announcements
|
||||||
|
|
||||||
## [subhash-halder contributed quadrant charts so you can show your manager what to select - just like the strategy consultants at BCG do](https://www.mermaidchart.com/blog/posts/subhash-halder-contributed-quadrant-charts-so-you-can-show-your-manager-what-to-select-just-like-the-strategy-consultants-at-bcg-do/)
|
## [Sequence diagrams, the only good thing UML brought to software development](https://www.mermaidchart.com/blog/posts/sequence-diagrams-the-good-thing-uml-brought-to-software-development/)
|
||||||
|
|
||||||
8 June 2023 · 7 mins
|
15 June 2023 · 12 mins
|
||||||
|
|
||||||
A quadrant chart is a useful diagram that helps users visualize data and identify patterns in a data set.
|
Sequence diagrams really shine when you’re documenting different parts of a system and the various ways these parts interact with each other.
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
# Blog
|
# Blog
|
||||||
|
|
||||||
|
## [Sequence diagrams, the only good thing UML brought to software development](https://www.mermaidchart.com/blog/posts/sequence-diagrams-the-good-thing-uml-brought-to-software-development/)
|
||||||
|
|
||||||
|
15 June 2023 · 12 mins
|
||||||
|
|
||||||
|
Sequence diagrams really shine when you’re documenting different parts of a system and the various ways these parts interact with each other.
|
||||||
|
|
||||||
## [subhash-halder contributed quadrant charts so you can show your manager what to select - just like the strategy consultants at BCG do](https://www.mermaidchart.com/blog/posts/subhash-halder-contributed-quadrant-charts-so-you-can-show-your-manager-what-to-select-just-like-the-strategy-consultants-at-bcg-do/)
|
## [subhash-halder contributed quadrant charts so you can show your manager what to select - just like the strategy consultants at BCG do](https://www.mermaidchart.com/blog/posts/subhash-halder-contributed-quadrant-charts-so-you-can-show-your-manager-what-to-select-just-like-the-strategy-consultants-at-bcg-do/)
|
||||||
|
|
||||||
8 June 2023 · 7 mins
|
8 June 2023 · 7 mins
|
||||||
|
|||||||
292
packages/mermaid/src/docs/syntax/sankey.md
Normal file
292
packages/mermaid/src/docs/syntax/sankey.md
Normal file
@@ -0,0 +1,292 @@
|
|||||||
|
# Sankey diagrams
|
||||||
|
|
||||||
|
> A sankey diagram is a visualization used to depict a flow from one set of values to another.
|
||||||
|
|
||||||
|
::: warning
|
||||||
|
This is an experimental diagram. Its syntax are very close to plain CSV, but it is to be extended in the nearest future.
|
||||||
|
:::
|
||||||
|
|
||||||
|
The things being connected are called nodes and the connections are called links.
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
This example taken from [observable](https://observablehq.com/@d3/sankey/2?collection=@d3/d3-sankey). It may be rendered a little bit differently, though, in terms of size and colors.
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
sankey-beta
|
||||||
|
|
||||||
|
Agricultural 'waste',Bio-conversion,124.729
|
||||||
|
Bio-conversion,Liquid,0.597
|
||||||
|
Bio-conversion,Losses,26.862
|
||||||
|
Bio-conversion,Solid,280.322
|
||||||
|
Bio-conversion,Gas,81.144
|
||||||
|
Biofuel imports,Liquid,35
|
||||||
|
Biomass imports,Solid,35
|
||||||
|
Coal imports,Coal,11.606
|
||||||
|
Coal reserves,Coal,63.965
|
||||||
|
Coal,Solid,75.571
|
||||||
|
District heating,Industry,10.639
|
||||||
|
District heating,Heating and cooling - commercial,22.505
|
||||||
|
District heating,Heating and cooling - homes,46.184
|
||||||
|
Electricity grid,Over generation / exports,104.453
|
||||||
|
Electricity grid,Heating and cooling - homes,113.726
|
||||||
|
Electricity grid,H2 conversion,27.14
|
||||||
|
Electricity grid,Industry,342.165
|
||||||
|
Electricity grid,Road transport,37.797
|
||||||
|
Electricity grid,Agriculture,4.412
|
||||||
|
Electricity grid,Heating and cooling - commercial,40.858
|
||||||
|
Electricity grid,Losses,56.691
|
||||||
|
Electricity grid,Rail transport,7.863
|
||||||
|
Electricity grid,Lighting & appliances - commercial,90.008
|
||||||
|
Electricity grid,Lighting & appliances - homes,93.494
|
||||||
|
Gas imports,Ngas,40.719
|
||||||
|
Gas reserves,Ngas,82.233
|
||||||
|
Gas,Heating and cooling - commercial,0.129
|
||||||
|
Gas,Losses,1.401
|
||||||
|
Gas,Thermal generation,151.891
|
||||||
|
Gas,Agriculture,2.096
|
||||||
|
Gas,Industry,48.58
|
||||||
|
Geothermal,Electricity grid,7.013
|
||||||
|
H2 conversion,H2,20.897
|
||||||
|
H2 conversion,Losses,6.242
|
||||||
|
H2,Road transport,20.897
|
||||||
|
Hydro,Electricity grid,6.995
|
||||||
|
Liquid,Industry,121.066
|
||||||
|
Liquid,International shipping,128.69
|
||||||
|
Liquid,Road transport,135.835
|
||||||
|
Liquid,Domestic aviation,14.458
|
||||||
|
Liquid,International aviation,206.267
|
||||||
|
Liquid,Agriculture,3.64
|
||||||
|
Liquid,National navigation,33.218
|
||||||
|
Liquid,Rail transport,4.413
|
||||||
|
Marine algae,Bio-conversion,4.375
|
||||||
|
Ngas,Gas,122.952
|
||||||
|
Nuclear,Thermal generation,839.978
|
||||||
|
Oil imports,Oil,504.287
|
||||||
|
Oil reserves,Oil,107.703
|
||||||
|
Oil,Liquid,611.99
|
||||||
|
Other waste,Solid,56.587
|
||||||
|
Other waste,Bio-conversion,77.81
|
||||||
|
Pumped heat,Heating and cooling - homes,193.026
|
||||||
|
Pumped heat,Heating and cooling - commercial,70.672
|
||||||
|
Solar PV,Electricity grid,59.901
|
||||||
|
Solar Thermal,Heating and cooling - homes,19.263
|
||||||
|
Solar,Solar Thermal,19.263
|
||||||
|
Solar,Solar PV,59.901
|
||||||
|
Solid,Agriculture,0.882
|
||||||
|
Solid,Thermal generation,400.12
|
||||||
|
Solid,Industry,46.477
|
||||||
|
Thermal generation,Electricity grid,525.531
|
||||||
|
Thermal generation,Losses,787.129
|
||||||
|
Thermal generation,District heating,79.329
|
||||||
|
Tidal,Electricity grid,9.452
|
||||||
|
UK land based bioenergy,Bio-conversion,182.01
|
||||||
|
Wave,Electricity grid,19.013
|
||||||
|
Wind,Electricity grid,289.366
|
||||||
|
```
|
||||||
|
|
||||||
|
::: details
|
||||||
|
|
||||||
|
```mermaid-example
|
||||||
|
sankey-beta
|
||||||
|
|
||||||
|
Agricultural 'waste',Bio-conversion,124.729
|
||||||
|
Bio-conversion,Liquid,0.597
|
||||||
|
Bio-conversion,Losses,26.862
|
||||||
|
Bio-conversion,Solid,280.322
|
||||||
|
Bio-conversion,Gas,81.144
|
||||||
|
Biofuel imports,Liquid,35
|
||||||
|
Biomass imports,Solid,35
|
||||||
|
Coal imports,Coal,11.606
|
||||||
|
Coal reserves,Coal,63.965
|
||||||
|
Coal,Solid,75.571
|
||||||
|
District heating,Industry,10.639
|
||||||
|
District heating,Heating and cooling - commercial,22.505
|
||||||
|
District heating,Heating and cooling - homes,46.184
|
||||||
|
Electricity grid,Over generation / exports,104.453
|
||||||
|
Electricity grid,Heating and cooling - homes,113.726
|
||||||
|
Electricity grid,H2 conversion,27.14
|
||||||
|
Electricity grid,Industry,342.165
|
||||||
|
Electricity grid,Road transport,37.797
|
||||||
|
Electricity grid,Agriculture,4.412
|
||||||
|
Electricity grid,Heating and cooling - commercial,40.858
|
||||||
|
Electricity grid,Losses,56.691
|
||||||
|
Electricity grid,Rail transport,7.863
|
||||||
|
Electricity grid,Lighting & appliances - commercial,90.008
|
||||||
|
Electricity grid,Lighting & appliances - homes,93.494
|
||||||
|
Gas imports,Ngas,40.719
|
||||||
|
Gas reserves,Ngas,82.233
|
||||||
|
Gas,Heating and cooling - commercial,0.129
|
||||||
|
Gas,Losses,1.401
|
||||||
|
Gas,Thermal generation,151.891
|
||||||
|
Gas,Agriculture,2.096
|
||||||
|
Gas,Industry,48.58
|
||||||
|
Geothermal,Electricity grid,7.013
|
||||||
|
H2 conversion,H2,20.897
|
||||||
|
H2 conversion,Losses,6.242
|
||||||
|
H2,Road transport,20.897
|
||||||
|
Hydro,Electricity grid,6.995
|
||||||
|
Liquid,Industry,121.066
|
||||||
|
Liquid,International shipping,128.69
|
||||||
|
Liquid,Road transport,135.835
|
||||||
|
Liquid,Domestic aviation,14.458
|
||||||
|
Liquid,International aviation,206.267
|
||||||
|
Liquid,Agriculture,3.64
|
||||||
|
Liquid,National navigation,33.218
|
||||||
|
Liquid,Rail transport,4.413
|
||||||
|
Marine algae,Bio-conversion,4.375
|
||||||
|
Ngas,Gas,122.952
|
||||||
|
Nuclear,Thermal generation,839.978
|
||||||
|
Oil imports,Oil,504.287
|
||||||
|
Oil reserves,Oil,107.703
|
||||||
|
Oil,Liquid,611.99
|
||||||
|
Other waste,Solid,56.587
|
||||||
|
Other waste,Bio-conversion,77.81
|
||||||
|
Pumped heat,Heating and cooling - homes,193.026
|
||||||
|
Pumped heat,Heating and cooling - commercial,70.672
|
||||||
|
Solar PV,Electricity grid,59.901
|
||||||
|
Solar Thermal,Heating and cooling - homes,19.263
|
||||||
|
Solar,Solar Thermal,19.263
|
||||||
|
Solar,Solar PV,59.901
|
||||||
|
Solid,Agriculture,0.882
|
||||||
|
Solid,Thermal generation,400.12
|
||||||
|
Solid,Industry,46.477
|
||||||
|
Thermal generation,Electricity grid,525.531
|
||||||
|
Thermal generation,Losses,787.129
|
||||||
|
Thermal generation,District heating,79.329
|
||||||
|
Tidal,Electricity grid,9.452
|
||||||
|
UK land based bioenergy,Bio-conversion,182.01
|
||||||
|
Wave,Electricity grid,19.013
|
||||||
|
Wind,Electricity grid,289.366
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
## Syntax
|
||||||
|
|
||||||
|
The idea behind syntax is that a user types `sankey-beta` keyword first, then pastes raw CSV below and get the result.
|
||||||
|
|
||||||
|
It implements CSV standard as [described here](https://www.ietf.org/rfc/rfc4180.txt) with subtle **differences**:
|
||||||
|
|
||||||
|
- CSV must contain **3 columns only**
|
||||||
|
- It is **allowed** to have **empty lines** without comma separators for visual purposes
|
||||||
|
|
||||||
|
### Basic
|
||||||
|
|
||||||
|
It is implied that 3 columns inside CSV should represent `source`, `target` and `value` accordingly:
|
||||||
|
|
||||||
|
```mermaid-example
|
||||||
|
sankey-beta
|
||||||
|
|
||||||
|
%% source,target,value
|
||||||
|
Electricity grid,Over generation / exports,104.453
|
||||||
|
Electricity grid,Heating and cooling - homes,113.726
|
||||||
|
Electricity grid,H2 conversion,27.14
|
||||||
|
```
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
sankey-beta
|
||||||
|
|
||||||
|
%% source,target,value
|
||||||
|
Electricity grid,Over generation / exports,104.453
|
||||||
|
Electricity grid,Heating and cooling - homes,113.726
|
||||||
|
Electricity grid,H2 conversion,27.14
|
||||||
|
```
|
||||||
|
|
||||||
|
### Empty Lines
|
||||||
|
|
||||||
|
CSV does not support empty lines without comma delimeters by default. But you can add them if needed:
|
||||||
|
|
||||||
|
```mermaid-example
|
||||||
|
sankey-beta
|
||||||
|
|
||||||
|
Bio-conversion,Losses,26.862
|
||||||
|
|
||||||
|
Bio-conversion,Solid,280.322
|
||||||
|
|
||||||
|
Bio-conversion,Gas,81.144
|
||||||
|
```
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
sankey-beta
|
||||||
|
|
||||||
|
Bio-conversion,Losses,26.862
|
||||||
|
|
||||||
|
Bio-conversion,Solid,280.322
|
||||||
|
|
||||||
|
Bio-conversion,Gas,81.144
|
||||||
|
```
|
||||||
|
|
||||||
|
### Commas
|
||||||
|
|
||||||
|
If you need to have a comma, wrap it in double quotes:
|
||||||
|
|
||||||
|
```mermaid-example
|
||||||
|
sankey-beta
|
||||||
|
|
||||||
|
Pumped heat,"Heating and cooling, homes",193.026
|
||||||
|
Pumped heat,"Heating and cooling, commercial",70.672
|
||||||
|
```
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
sankey-beta
|
||||||
|
|
||||||
|
Pumped heat,"Heating and cooling, homes",193.026
|
||||||
|
Pumped heat,"Heating and cooling, commercial",70.672
|
||||||
|
```
|
||||||
|
|
||||||
|
### Double Quotes
|
||||||
|
|
||||||
|
If you need to have double quote, put a pair of them inside quoted string:
|
||||||
|
|
||||||
|
```mermaid-example
|
||||||
|
sankey-beta
|
||||||
|
|
||||||
|
Pumped heat,"Heating and cooling, ""homes""",193.026
|
||||||
|
Pumped heat,"Heating and cooling, ""commercial""",70.672
|
||||||
|
```
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
sankey-beta
|
||||||
|
|
||||||
|
Pumped heat,"Heating and cooling, ""homes""",193.026
|
||||||
|
Pumped heat,"Heating and cooling, ""commercial""",70.672
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
You can customize link colors, node alignments and diagram dimensions.
|
||||||
|
|
||||||
|
```html
|
||||||
|
<script>
|
||||||
|
const config = {
|
||||||
|
startOnLoad: true,
|
||||||
|
securityLevel: 'loose',
|
||||||
|
sankey: {
|
||||||
|
width: 800,
|
||||||
|
height: 400,
|
||||||
|
linkColor: 'source',
|
||||||
|
nodeAlignment: 'left',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
mermaid.initialize(config);
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Links Coloring
|
||||||
|
|
||||||
|
You can adjust links' color by setting `linkColor` to one of those:
|
||||||
|
|
||||||
|
- `source` - link will be of a source node color
|
||||||
|
- `target` - link will be of a target node color
|
||||||
|
- `gradient` - link color will be smoothly transient between source and target node colors
|
||||||
|
- hex code of color, like `#a1a1a1`
|
||||||
|
|
||||||
|
### Node Alignment
|
||||||
|
|
||||||
|
Graph layout can be changed by setting `nodeAlignment` to:
|
||||||
|
|
||||||
|
- `justify`
|
||||||
|
- `center`
|
||||||
|
- `left`
|
||||||
|
- `right`
|
||||||
@@ -58,6 +58,31 @@ sequenceDiagram
|
|||||||
J->>A: Great!
|
J->>A: Great!
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Actor Creation and Destruction
|
||||||
|
|
||||||
|
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
|
||||||
|
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.
|
||||||
|
|
||||||
|
```mermaid-example
|
||||||
|
sequenceDiagram
|
||||||
|
Alice->>Bob: Hello Bob, how are you ?
|
||||||
|
Bob->>Alice: Fine, thank you. And you?
|
||||||
|
create participant Carl
|
||||||
|
Alice->>Carl: Hi Carl!
|
||||||
|
create actor D as Donald
|
||||||
|
Carl->>D: Hi!
|
||||||
|
destroy Carl
|
||||||
|
Alice-xCarl: We are too many
|
||||||
|
destroy Bob
|
||||||
|
Bob->>Alice: I agree
|
||||||
|
```
|
||||||
|
|
||||||
### Grouping / Box
|
### Grouping / Box
|
||||||
|
|
||||||
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:
|
||||||
|
|||||||
@@ -304,7 +304,7 @@ where
|
|||||||
- the second _property_ is `color` and its _value_ is `white`
|
- the second _property_ is `color` and its _value_ is `white`
|
||||||
- the third _property_ is `font-weight` and its _value_ is `bold`
|
- the third _property_ is `font-weight` and its _value_ is `bold`
|
||||||
- the fourth _property_ is `stroke-width` and its _value_ is `2px`
|
- the fourth _property_ is `stroke-width` and its _value_ is `2px`
|
||||||
- the fifth _property_ is `stroke` and its _value_ is `yello`
|
- the fifth _property_ is `stroke` and its _value_ is `yellow`
|
||||||
|
|
||||||
### Apply classDef styles to states
|
### Apply classDef styles to states
|
||||||
|
|
||||||
|
|||||||
18
packages/mermaid/src/rendering-util/uid.ts
Normal file
18
packages/mermaid/src/rendering-util/uid.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
export class Uid {
|
||||||
|
private static count = 0;
|
||||||
|
id: string;
|
||||||
|
href: string;
|
||||||
|
|
||||||
|
public static next(name: string): Uid {
|
||||||
|
return new Uid(name + ++Uid.count);
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(id: string) {
|
||||||
|
this.id = id;
|
||||||
|
this.href = `#${id}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
toString(): string {
|
||||||
|
return 'url(' + this.href + ')';
|
||||||
|
}
|
||||||
|
}
|
||||||
211
pnpm-lock.yaml
generated
211
pnpm-lock.yaml
generated
@@ -194,6 +194,12 @@ importers:
|
|||||||
'@braintree/sanitize-url':
|
'@braintree/sanitize-url':
|
||||||
specifier: ^6.0.2
|
specifier: ^6.0.2
|
||||||
version: 6.0.2
|
version: 6.0.2
|
||||||
|
'@types/d3-scale':
|
||||||
|
specifier: ^4.0.3
|
||||||
|
version: 4.0.3
|
||||||
|
'@types/d3-scale-chromatic':
|
||||||
|
specifier: ^3.0.0
|
||||||
|
version: 3.0.0
|
||||||
cytoscape:
|
cytoscape:
|
||||||
specifier: ^3.23.0
|
specifier: ^3.23.0
|
||||||
version: 3.23.0
|
version: 3.23.0
|
||||||
@@ -206,6 +212,9 @@ importers:
|
|||||||
d3:
|
d3:
|
||||||
specifier: ^7.4.0
|
specifier: ^7.4.0
|
||||||
version: 7.8.2
|
version: 7.8.2
|
||||||
|
d3-sankey:
|
||||||
|
specifier: ^0.12.3
|
||||||
|
version: 0.12.3
|
||||||
dagre-d3-es:
|
dagre-d3-es:
|
||||||
specifier: 7.0.10
|
specifier: 7.0.10
|
||||||
version: 7.0.10
|
version: 7.0.10
|
||||||
@@ -213,8 +222,8 @@ importers:
|
|||||||
specifier: ^1.11.7
|
specifier: ^1.11.7
|
||||||
version: 1.11.7
|
version: 1.11.7
|
||||||
dompurify:
|
dompurify:
|
||||||
specifier: 3.0.3
|
specifier: 3.0.4
|
||||||
version: 3.0.3
|
version: 3.0.4
|
||||||
elkjs:
|
elkjs:
|
||||||
specifier: ^0.8.2
|
specifier: ^0.8.2
|
||||||
version: 0.8.2
|
version: 0.8.2
|
||||||
@@ -249,6 +258,9 @@ importers:
|
|||||||
'@types/d3':
|
'@types/d3':
|
||||||
specifier: ^7.4.0
|
specifier: ^7.4.0
|
||||||
version: 7.4.0
|
version: 7.4.0
|
||||||
|
'@types/d3-sankey':
|
||||||
|
specifier: ^0.12.1
|
||||||
|
version: 0.12.1
|
||||||
'@types/d3-selection':
|
'@types/d3-selection':
|
||||||
specifier: ^3.0.5
|
specifier: ^3.0.5
|
||||||
version: 3.0.5
|
version: 3.0.5
|
||||||
@@ -451,31 +463,6 @@ importers:
|
|||||||
specifier: ^7.0.0
|
specifier: ^7.0.0
|
||||||
version: 7.0.0
|
version: 7.0.0
|
||||||
|
|
||||||
packages/mermaid/src/vitepress:
|
|
||||||
dependencies:
|
|
||||||
'@vueuse/core':
|
|
||||||
specifier: ^10.1.0
|
|
||||||
version: 10.1.0(vue@3.2.47)
|
|
||||||
vue:
|
|
||||||
specifier: ^3.2.47
|
|
||||||
version: 3.2.47
|
|
||||||
devDependencies:
|
|
||||||
pathe:
|
|
||||||
specifier: ^1.1.0
|
|
||||||
version: 1.1.0
|
|
||||||
unocss:
|
|
||||||
specifier: ^0.53.0
|
|
||||||
version: 0.53.0(postcss@8.4.23)(vite@4.3.9)
|
|
||||||
unplugin-vue-components:
|
|
||||||
specifier: ^0.25.0
|
|
||||||
version: 0.25.0(rollup@2.79.1)(vue@3.2.47)
|
|
||||||
vite:
|
|
||||||
specifier: ^4.3.3
|
|
||||||
version: 4.3.9(@types/node@18.16.0)
|
|
||||||
vitepress:
|
|
||||||
specifier: 1.0.0-beta.2
|
|
||||||
version: 1.0.0-beta.2(@algolia/client-search@4.14.2)(@types/node@18.16.0)(search-insights@2.6.0)
|
|
||||||
|
|
||||||
tests/webpack:
|
tests/webpack:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@mermaid-js/mermaid-example-diagram':
|
'@mermaid-js/mermaid-example-diagram':
|
||||||
@@ -4009,6 +3996,10 @@ packages:
|
|||||||
'@types/d3-color': 3.1.0
|
'@types/d3-color': 3.1.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@types/d3-path@1.0.9:
|
||||||
|
resolution: {integrity: sha512-NaIeSIBiFgSC6IGUBjZWcscUJEq7vpVu7KthHN8eieTV9d9MqkSOZLH4chq1PmcKy06PNe3axLeKmRIyxJ+PZQ==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@types/d3-path@3.0.0:
|
/@types/d3-path@3.0.0:
|
||||||
resolution: {integrity: sha512-0g/A+mZXgFkQxN3HniRDbXMN79K3CdTpLsevj+PXiTcb2hVyvkZUBg37StmgCQkaD84cUJ4uaDAWq7UJOQy2Tg==}
|
resolution: {integrity: sha512-0g/A+mZXgFkQxN3HniRDbXMN79K3CdTpLsevj+PXiTcb2hVyvkZUBg37StmgCQkaD84cUJ4uaDAWq7UJOQy2Tg==}
|
||||||
dev: true
|
dev: true
|
||||||
@@ -4025,20 +4016,30 @@ packages:
|
|||||||
resolution: {integrity: sha512-IIE6YTekGczpLYo/HehAy3JGF1ty7+usI97LqraNa8IiDur+L44d0VOjAvFQWJVdZOJHukUJw+ZdZBlgeUsHOQ==}
|
resolution: {integrity: sha512-IIE6YTekGczpLYo/HehAy3JGF1ty7+usI97LqraNa8IiDur+L44d0VOjAvFQWJVdZOJHukUJw+ZdZBlgeUsHOQ==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@types/d3-scale-chromatic@3.0.0:
|
/@types/d3-sankey@0.12.1:
|
||||||
resolution: {integrity: sha512-dsoJGEIShosKVRBZB0Vo3C8nqSDqVGujJU6tPznsBJxNJNwMF8utmS83nvCBKQYPpjCzaaHcrf66iTRpZosLPw==}
|
resolution: {integrity: sha512-10X6l6lXB42udBNX9/fDN+kJuooifSMk7+x4U9815eobavldqis4wDdFQUQjMazh+qlzsUZsGzXKxfWFUVt+3w==}
|
||||||
|
dependencies:
|
||||||
|
'@types/d3-shape': 1.3.8
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@types/d3-scale@4.0.2:
|
/@types/d3-scale-chromatic@3.0.0:
|
||||||
resolution: {integrity: sha512-Yk4htunhPAwN0XGlIwArRomOjdoBFXC3+kCxK2Ubg7I9shQlVSJy/pG/Ht5ASN+gdMIalpk8TJ5xV74jFsetLA==}
|
resolution: {integrity: sha512-dsoJGEIShosKVRBZB0Vo3C8nqSDqVGujJU6tPznsBJxNJNwMF8utmS83nvCBKQYPpjCzaaHcrf66iTRpZosLPw==}
|
||||||
|
|
||||||
|
/@types/d3-scale@4.0.3:
|
||||||
|
resolution: {integrity: sha512-PATBiMCpvHJSMtZAMEhc2WyL+hnzarKzI6wAHYjhsonjWJYGq5BXTzQjv4l8m2jO183/4wZ90rKvSeT7o72xNQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/d3-time': 3.0.0
|
'@types/d3-time': 3.0.0
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@types/d3-selection@3.0.5:
|
/@types/d3-selection@3.0.5:
|
||||||
resolution: {integrity: sha512-xCB0z3Hi8eFIqyja3vW8iV01+OHGYR2di/+e+AiOcXIOrY82lcvWW8Ke1DYE/EUVMsBl4Db9RppSBS3X1U6J0w==}
|
resolution: {integrity: sha512-xCB0z3Hi8eFIqyja3vW8iV01+OHGYR2di/+e+AiOcXIOrY82lcvWW8Ke1DYE/EUVMsBl4Db9RppSBS3X1U6J0w==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@types/d3-shape@1.3.8:
|
||||||
|
resolution: {integrity: sha512-gqfnMz6Fd5H6GOLYixOZP/xlrMtJms9BaS+6oWxTKHNqPGZ93BkWWupQSCYm6YHqx6h9wjRupuJb90bun6ZaYg==}
|
||||||
|
dependencies:
|
||||||
|
'@types/d3-path': 1.0.9
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@types/d3-shape@3.1.0:
|
/@types/d3-shape@3.1.0:
|
||||||
resolution: {integrity: sha512-jYIYxFFA9vrJ8Hd4Se83YI6XF+gzDL1aC5DCsldai4XYYiVNdhtpGbA/GM6iyQ8ayhSp3a148LY34hy7A4TxZA==}
|
resolution: {integrity: sha512-jYIYxFFA9vrJ8Hd4Se83YI6XF+gzDL1aC5DCsldai4XYYiVNdhtpGbA/GM6iyQ8ayhSp3a148LY34hy7A4TxZA==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -4051,7 +4052,6 @@ packages:
|
|||||||
|
|
||||||
/@types/d3-time@3.0.0:
|
/@types/d3-time@3.0.0:
|
||||||
resolution: {integrity: sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==}
|
resolution: {integrity: sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==}
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@types/d3-timer@3.0.0:
|
/@types/d3-timer@3.0.0:
|
||||||
resolution: {integrity: sha512-HNB/9GHqu7Fo8AQiugyJbv6ZxYz58wef0esl4Mv828w1ZKpAshw/uFWVDUcIB9KKFeFKoxS3cHY07FFgtTRZ1g==}
|
resolution: {integrity: sha512-HNB/9GHqu7Fo8AQiugyJbv6ZxYz58wef0esl4Mv828w1ZKpAshw/uFWVDUcIB9KKFeFKoxS3cHY07FFgtTRZ1g==}
|
||||||
@@ -4094,7 +4094,7 @@ packages:
|
|||||||
'@types/d3-polygon': 3.0.0
|
'@types/d3-polygon': 3.0.0
|
||||||
'@types/d3-quadtree': 3.0.2
|
'@types/d3-quadtree': 3.0.2
|
||||||
'@types/d3-random': 3.0.1
|
'@types/d3-random': 3.0.1
|
||||||
'@types/d3-scale': 4.0.2
|
'@types/d3-scale': 4.0.3
|
||||||
'@types/d3-scale-chromatic': 3.0.0
|
'@types/d3-scale-chromatic': 3.0.0
|
||||||
'@types/d3-selection': 3.0.5
|
'@types/d3-selection': 3.0.5
|
||||||
'@types/d3-shape': 3.1.0
|
'@types/d3-shape': 3.1.0
|
||||||
@@ -4685,17 +4685,6 @@ packages:
|
|||||||
- vite
|
- vite
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@unocss/astro@0.53.0(vite@4.3.9):
|
|
||||||
resolution: {integrity: sha512-8bR7ysIMZEOpcjd/cVmogcABSFDYPjUqMnbflv44p1A2/deemo9CIkpRARoq/96NQuzWJsKhKodcQodExZcqiA==}
|
|
||||||
dependencies:
|
|
||||||
'@unocss/core': 0.53.0
|
|
||||||
'@unocss/reset': 0.53.0
|
|
||||||
'@unocss/vite': 0.53.0(vite@4.3.9)
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- rollup
|
|
||||||
- vite
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@unocss/cli@0.53.0(rollup@2.79.1):
|
/@unocss/cli@0.53.0(rollup@2.79.1):
|
||||||
resolution: {integrity: sha512-9WNBHy8m8tMqwcp7mUhebRUBvHQfbx01CMe5cAFLmUYtJULM+8IjJxqERkaAZyyoOXf1TNO2v1dFAmCwhMRCLQ==}
|
resolution: {integrity: sha512-9WNBHy8m8tMqwcp7mUhebRUBvHQfbx01CMe5cAFLmUYtJULM+8IjJxqERkaAZyyoOXf1TNO2v1dFAmCwhMRCLQ==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
@@ -4874,26 +4863,6 @@ packages:
|
|||||||
- rollup
|
- rollup
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@unocss/vite@0.53.0(vite@4.3.9):
|
|
||||||
resolution: {integrity: sha512-JoZhKVNruRjfySMVg/zNJbLEn/NTXj29Wf0SN4++xnGKrSapkPzYC46psL5bm5N5v4SHdpepTCoonC3FWCY6Fw==}
|
|
||||||
peerDependencies:
|
|
||||||
vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0
|
|
||||||
dependencies:
|
|
||||||
'@ampproject/remapping': 2.2.1
|
|
||||||
'@rollup/pluginutils': 5.0.2(rollup@2.79.1)
|
|
||||||
'@unocss/config': 0.53.0
|
|
||||||
'@unocss/core': 0.53.0
|
|
||||||
'@unocss/inspector': 0.53.0
|
|
||||||
'@unocss/scope': 0.53.0
|
|
||||||
'@unocss/transformer-directives': 0.53.0
|
|
||||||
chokidar: 3.5.3
|
|
||||||
fast-glob: 3.2.12
|
|
||||||
magic-string: 0.30.0
|
|
||||||
vite: 4.3.9(@types/node@18.16.0)
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- rollup
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@vite-pwa/vitepress@0.2.0(vite-plugin-pwa@0.16.0):
|
/@vite-pwa/vitepress@0.2.0(vite-plugin-pwa@0.16.0):
|
||||||
resolution: {integrity: sha512-dVQVaP6NB9woCFe4UASUqRp7uwBQJOVXlJlqK4krqXcbb3NuXIXIWOnU7HLpJnHqZj5U/81gKtLN6gs5gJBwiQ==}
|
resolution: {integrity: sha512-dVQVaP6NB9woCFe4UASUqRp7uwBQJOVXlJlqK4krqXcbb3NuXIXIWOnU7HLpJnHqZj5U/81gKtLN6gs5gJBwiQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -7200,6 +7169,12 @@ packages:
|
|||||||
lodash: 4.17.21
|
lodash: 4.17.21
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/d3-array@2.12.1:
|
||||||
|
resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==}
|
||||||
|
dependencies:
|
||||||
|
internmap: 1.0.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/d3-array@3.2.0:
|
/d3-array@3.2.0:
|
||||||
resolution: {integrity: sha512-3yXFQo0oG3QCxbF06rMPFyGRMGJNS7NvsV1+2joOjbBE+9xvWQ8+GcMJAjRCzw06zQ3/arXeJgbPYcjUCuC+3g==}
|
resolution: {integrity: sha512-3yXFQo0oG3QCxbF06rMPFyGRMGJNS7NvsV1+2joOjbBE+9xvWQ8+GcMJAjRCzw06zQ3/arXeJgbPYcjUCuC+3g==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
@@ -7317,6 +7292,10 @@ packages:
|
|||||||
d3-color: 3.1.0
|
d3-color: 3.1.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/d3-path@1.0.9:
|
||||||
|
resolution: {integrity: sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/d3-path@3.0.1:
|
/d3-path@3.0.1:
|
||||||
resolution: {integrity: sha512-gq6gZom9AFZby0YLduxT1qmrp4xpBA1YZr19OI717WIdKE2OM5ETq5qrHLb301IgxhLwcuxvGZVLeeWc/k1I6w==}
|
resolution: {integrity: sha512-gq6gZom9AFZby0YLduxT1qmrp4xpBA1YZr19OI717WIdKE2OM5ETq5qrHLb301IgxhLwcuxvGZVLeeWc/k1I6w==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
@@ -7337,6 +7316,13 @@ packages:
|
|||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/d3-sankey@0.12.3:
|
||||||
|
resolution: {integrity: sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==}
|
||||||
|
dependencies:
|
||||||
|
d3-array: 2.12.1
|
||||||
|
d3-shape: 1.3.7
|
||||||
|
dev: false
|
||||||
|
|
||||||
/d3-scale-chromatic@3.0.0:
|
/d3-scale-chromatic@3.0.0:
|
||||||
resolution: {integrity: sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==}
|
resolution: {integrity: sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
@@ -7361,6 +7347,12 @@ packages:
|
|||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/d3-shape@1.3.7:
|
||||||
|
resolution: {integrity: sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==}
|
||||||
|
dependencies:
|
||||||
|
d3-path: 1.0.9
|
||||||
|
dev: false
|
||||||
|
|
||||||
/d3-shape@3.1.0:
|
/d3-shape@3.1.0:
|
||||||
resolution: {integrity: sha512-tGDh1Muf8kWjEDT/LswZJ8WF85yDZLvVJpYU9Nq+8+yW1Z5enxrmXOhTArlkaElU+CTn0OTVNli+/i+HP45QEQ==}
|
resolution: {integrity: sha512-tGDh1Muf8kWjEDT/LswZJ8WF85yDZLvVJpYU9Nq+8+yW1Z5enxrmXOhTArlkaElU+CTn0OTVNli+/i+HP45QEQ==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
@@ -7765,8 +7757,8 @@ packages:
|
|||||||
domelementtype: 2.3.0
|
domelementtype: 2.3.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/dompurify@3.0.3:
|
/dompurify@3.0.4:
|
||||||
resolution: {integrity: sha512-axQ9zieHLnAnHh0sfAamKYiqXMJAVwu+LM/alQ7WDagoWessyWvMSFyW65CqF3owufNu8HBcE4cM2Vflu7YWcQ==}
|
resolution: {integrity: sha512-ae0mA+Qiqp6C29pqZX3fQgK+F91+F7wobM/v8DRzDqJdZJELXiFUx4PP4pK/mzUS0xkiSEx3Ncd9gr69jg3YsQ==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/domutils@3.0.1:
|
/domutils@3.0.1:
|
||||||
@@ -9044,7 +9036,7 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
foreground-child: 3.1.1
|
foreground-child: 3.1.1
|
||||||
jackspeak: 2.1.1
|
jackspeak: 2.1.1
|
||||||
minimatch: 9.0.1
|
minimatch: 9.0.0
|
||||||
minipass: 5.0.0
|
minipass: 5.0.0
|
||||||
path-scurry: 1.7.0
|
path-scurry: 1.7.0
|
||||||
dev: true
|
dev: true
|
||||||
@@ -9596,6 +9588,10 @@ packages:
|
|||||||
side-channel: 1.0.4
|
side-channel: 1.0.4
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/internmap@1.0.1:
|
||||||
|
resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/internmap@2.0.3:
|
/internmap@2.0.3:
|
||||||
resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==}
|
resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
@@ -14636,42 +14632,6 @@ packages:
|
|||||||
- vite
|
- vite
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/unocss@0.53.0(postcss@8.4.23)(vite@4.3.9):
|
|
||||||
resolution: {integrity: sha512-kY4h5ERiDYlSnL2X+hbDfh+uaF7QNouy7j51GOTUr3Q0aaWehaNd05b15SjHrab559dEC0mYfrSEdh/DnCK1cw==}
|
|
||||||
engines: {node: '>=14'}
|
|
||||||
peerDependencies:
|
|
||||||
'@unocss/webpack': 0.53.0
|
|
||||||
peerDependenciesMeta:
|
|
||||||
'@unocss/webpack':
|
|
||||||
optional: true
|
|
||||||
dependencies:
|
|
||||||
'@unocss/astro': 0.53.0(vite@4.3.9)
|
|
||||||
'@unocss/cli': 0.53.0(rollup@2.79.1)
|
|
||||||
'@unocss/core': 0.53.0
|
|
||||||
'@unocss/extractor-arbitrary-variants': 0.53.0
|
|
||||||
'@unocss/postcss': 0.53.0(postcss@8.4.23)
|
|
||||||
'@unocss/preset-attributify': 0.53.0
|
|
||||||
'@unocss/preset-icons': 0.53.0
|
|
||||||
'@unocss/preset-mini': 0.53.0
|
|
||||||
'@unocss/preset-tagify': 0.53.0
|
|
||||||
'@unocss/preset-typography': 0.53.0
|
|
||||||
'@unocss/preset-uno': 0.53.0
|
|
||||||
'@unocss/preset-web-fonts': 0.53.0
|
|
||||||
'@unocss/preset-wind': 0.53.0
|
|
||||||
'@unocss/reset': 0.53.0
|
|
||||||
'@unocss/transformer-attributify-jsx': 0.53.0
|
|
||||||
'@unocss/transformer-attributify-jsx-babel': 0.53.0
|
|
||||||
'@unocss/transformer-compile-class': 0.53.0
|
|
||||||
'@unocss/transformer-directives': 0.53.0
|
|
||||||
'@unocss/transformer-variant-group': 0.53.0
|
|
||||||
'@unocss/vite': 0.53.0(vite@4.3.9)
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- postcss
|
|
||||||
- rollup
|
|
||||||
- supports-color
|
|
||||||
- vite
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/unpipe@1.0.0:
|
/unpipe@1.0.0:
|
||||||
resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
|
resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
|
||||||
engines: {node: '>= 0.8'}
|
engines: {node: '>= 0.8'}
|
||||||
@@ -15041,49 +15001,6 @@ packages:
|
|||||||
- terser
|
- terser
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/vitepress@1.0.0-beta.2(@algolia/client-search@4.14.2)(@types/node@18.16.0)(search-insights@2.6.0):
|
|
||||||
resolution: {integrity: sha512-DBXYjtYbm3W1IPPJ2TiCaK/XK+o/2XmL2+jslOGKm+txcbmG0kbeB+vadC5tCUZA9NdA+9Ywj3M4548c7t/SDg==}
|
|
||||||
hasBin: true
|
|
||||||
dependencies:
|
|
||||||
'@docsearch/css': 3.5.1
|
|
||||||
'@docsearch/js': 3.5.1(@algolia/client-search@4.14.2)(search-insights@2.6.0)
|
|
||||||
'@vitejs/plugin-vue': 4.2.3(vite@4.3.9)(vue@3.3.4)
|
|
||||||
'@vue/devtools-api': 6.5.0
|
|
||||||
'@vueuse/core': 10.1.2(vue@3.3.4)
|
|
||||||
'@vueuse/integrations': 10.1.2(focus-trap@7.4.3)(vue@3.3.4)
|
|
||||||
body-scroll-lock: 4.0.0-beta.0
|
|
||||||
focus-trap: 7.4.3
|
|
||||||
mark.js: 8.11.1
|
|
||||||
minisearch: 6.1.0
|
|
||||||
shiki: 0.14.2
|
|
||||||
vite: 4.3.9(@types/node@18.16.0)
|
|
||||||
vue: 3.3.4
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- '@algolia/client-search'
|
|
||||||
- '@types/node'
|
|
||||||
- '@types/react'
|
|
||||||
- '@vue/composition-api'
|
|
||||||
- async-validator
|
|
||||||
- axios
|
|
||||||
- change-case
|
|
||||||
- drauu
|
|
||||||
- fuse.js
|
|
||||||
- idb-keyval
|
|
||||||
- jwt-decode
|
|
||||||
- less
|
|
||||||
- nprogress
|
|
||||||
- qrcode
|
|
||||||
- react
|
|
||||||
- react-dom
|
|
||||||
- sass
|
|
||||||
- search-insights
|
|
||||||
- sortablejs
|
|
||||||
- stylus
|
|
||||||
- sugarss
|
|
||||||
- terser
|
|
||||||
- universal-cookie
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/vitepress@1.0.0-beta.3(@algolia/client-search@4.14.2)(@types/node@18.16.0)(search-insights@2.6.0):
|
/vitepress@1.0.0-beta.3(@algolia/client-search@4.14.2)(@types/node@18.16.0)(search-insights@2.6.0):
|
||||||
resolution: {integrity: sha512-GR5Pvr/o343NN1M4Na1shhDYZRrQbjmLq7WE0lla0H8iDPAsHE8agTHLWfu3FWx+3q2KA29sv16+0O9RQKGjlA==}
|
resolution: {integrity: sha512-GR5Pvr/o343NN1M4Na1shhDYZRrQbjmLq7WE0lla0H8iDPAsHE8agTHLWfu3FWx+3q2KA29sv16+0O9RQKGjlA==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|||||||
81
run
81
run
@@ -1,40 +1,93 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
RUN="docker-compose run --rm"
|
RUN="docker-compose run --rm"
|
||||||
|
|
||||||
|
ansi() { echo -e "\e[${1}m${*:2}\e[0m"; }
|
||||||
|
bold() { ansi 1 "$@"; }
|
||||||
|
# italic() { ansi 3 "$@"; }
|
||||||
|
underline() { ansi 4 "$@"; }
|
||||||
|
# strikethrough() { ansi 9 "$@"; }
|
||||||
|
# red() { ansi 31 "$@"; }
|
||||||
|
|
||||||
|
name=$(basename $0)
|
||||||
command=$1
|
command=$1
|
||||||
args=${@:2}
|
args=${@:2}
|
||||||
|
|
||||||
case $command in
|
case $command in
|
||||||
|
|
||||||
sh)
|
sh)
|
||||||
$RUN mermaid sh $args
|
$RUN mermaid sh -c "npx $args"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
install)
|
pnpm)
|
||||||
$RUN mermaid sh -c "npx pnpm install"
|
$RUN mermaid sh -c "npx pnpm $args"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
test)
|
dev)
|
||||||
$RUN mermaid sh -c "npx pnpm test"
|
$RUN --service-ports mermaid sh -c "npx pnpm run dev"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
lint)
|
docs:dev)
|
||||||
$RUN mermaid sh -c "npx pnpm -w run lint:fix"
|
$RUN --service-ports mermaid sh -c "cd packages/mermaid/src/docs && npx pnpm prefetch && npx vitepress --port 3333 --host"
|
||||||
|
;;
|
||||||
|
|
||||||
|
cypress)
|
||||||
|
$RUN cypress $args
|
||||||
;;
|
;;
|
||||||
|
|
||||||
help)
|
help)
|
||||||
|
|
||||||
|
# Alignment of help message must be as it is, it will be nice looking when printed
|
||||||
|
usage=$(
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
Run commonly used commands within docker containers
|
|
||||||
|
|
||||||
$0 install # Equvalent of pnpm install
|
$(bold MERMAID LOCAL DOCKER DEVELOPMENT)
|
||||||
$0 lint # Equvalent of pnpm -w run lint:fix
|
|
||||||
$0 sh # Open sh inside docker container for development
|
Welcome! Thank you for joining the development.
|
||||||
|
This is a script for running commands within docker containers at ease.
|
||||||
|
__________________________________________________________________________________________
|
||||||
|
|
||||||
|
Development quick start guide:
|
||||||
|
|
||||||
|
$(bold ./$name pnpm install) # Install packages
|
||||||
|
$(bold ./$name dev) # Run dev server with examples, open http://localhost:9000
|
||||||
|
$(bold ./$name pnpm vitest) # Run watcher for unit tests
|
||||||
|
$(bold ./$name cypress) # Run integration tests (after starting dev server)
|
||||||
|
$(bold ./$name pnpm build) # Prepare it for production
|
||||||
|
$(bold ./$name docs:dev) # Then add documentation, open http://localhost:3333
|
||||||
|
__________________________________________________________________________________________
|
||||||
|
|
||||||
|
Commands:
|
||||||
|
|
||||||
|
$(bold ./$name pnpm) # Run any 'pnpm' command
|
||||||
|
$(bold ./$name dev) # Run dev server with examples, open http://localhost:9000
|
||||||
|
$(bold ./$name docs:dev) # For docs contributions, open http://localhost:3333
|
||||||
|
$(bold ./$name cypress) # Run integration tests
|
||||||
|
$(bold ./$name sh) # Open 'sh' inside docker container for development
|
||||||
|
$(bold ./$name help) # Show this help
|
||||||
|
__________________________________________________________________________________________
|
||||||
|
|
||||||
|
Examples of frequiently used commands:
|
||||||
|
|
||||||
|
$(bold ./$name pnpm add --filter mermaid) $(underline package)
|
||||||
|
Add package to mermaid
|
||||||
|
|
||||||
|
$(bold git diff --name-only develop \| xargs ./$name pnpm prettier --write)
|
||||||
|
Prettify everything you added so far
|
||||||
|
|
||||||
|
$(bold ./$name cypress open --project .)
|
||||||
|
Open cypress interactive GUI
|
||||||
|
|
||||||
|
$(bold ./$name cypress run --spec cypress/integration/rendering/)$(underline test.spec.ts)
|
||||||
|
Run specific test in cypress\n
|
||||||
|
|
||||||
$0 help # Show this help
|
|
||||||
EOF
|
EOF
|
||||||
|
)
|
||||||
|
|
||||||
|
echo -n -e "$usage"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
$0 help
|
$name help
|
||||||
;;
|
;;
|
||||||
|
|
||||||
esac
|
esac
|
||||||
|
|||||||
Reference in New Issue
Block a user