Merge branch 'develop' of github.com:mermaid-js/mermaid into develop

This commit is contained in:
Per Brolin 2022-11-21 14:45:25 +01:00
commit fdbc4ce0ed
154 changed files with 4801 additions and 4306 deletions

45
.github/workflows/link-checker.yml vendored Normal file
View File

@ -0,0 +1,45 @@
# This Link Checker is run on all documentation files once per week.
# references:
# - https://github.com/lycheeverse/lychee-action
# - https://github.com/lycheeverse/lychee
name: Link Checker
on:
push:
branches:
- develop
- master
pull_request:
branches:
- develop
- master
schedule:
# * is a special character in YAML so you have to quote this string
- cron: '30 8 * * 5'
jobs:
linkChecker:
runs-on: ubuntu-latest
permissions:
# lychee only uses the GITHUB_TOKEN to avoid rate-limiting
contents: read
steps:
- uses: actions/checkout@v3
- name: Restore lychee cache
uses: actions/cache@v3
with:
path: .lycheecache
key: cache-lychee-${{ github.sha }}
restore-keys: cache-lychee-
- name: Link Checker
uses: lycheeverse/lychee-action@v1.5.4
with:
args: --verbose --no-progress --cache --max-cache-age 1d packages/mermaid/src/docs/**/*.md README.md README.zh-CN.md
fail: true
jobSummary: true
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}

4
.gitignore vendored
View File

@ -32,3 +32,7 @@ cypress/snapshots/
.eslintcache
.tsbuildinfo
tsconfig.tsbuildinfo
knsv*.html
local*.html
stats/

13
.lycheeignore Normal file
View File

@ -0,0 +1,13 @@
# These links are ignored by our link checker https://github.com/lycheeverse/lychee
# The file allows you to list multiple regular expressions for exclusion (one pattern per line).
# Network error: Forbidden
https://codepen.io
# Network error: The certificate was not trusted
https://mkdocs.org/
https://osawards.com/javascript/#nominees
https://osawards.com/javascript/2019
# Don't check files that are generated during the build via `pnpm docs:code`
packages/mermaid/src/docs/config/setup/*

4
.npmrc
View File

@ -1 +1,3 @@
auto-install-peers=true
auto-install-peers=true
strict-peer-dependencies=false
use-inline-specifiers-lockfile-format=true

View File

@ -1,11 +1,14 @@
import { build, InlineConfig } from 'vite';
import { build, InlineConfig, type PluginOption } from 'vite';
import { resolve } from 'path';
import { fileURLToPath } from 'url';
import jisonPlugin from './jisonPlugin.js';
import pkg from '../package.json' assert { type: 'json' };
import { readFileSync } from 'fs';
import { visualizer } from 'rollup-plugin-visualizer';
import type { TemplateType } from 'rollup-plugin-visualizer/dist/plugin/template-types.js';
const { dependencies } = pkg;
const visualize = process.argv.includes('--visualize');
const watch = process.argv.includes('--watch');
const mermaidOnly = process.argv.includes('--mermaid');
const __dirname = fileURLToPath(new URL('.', import.meta.url));
type OutputOptions = Exclude<
@ -13,6 +16,20 @@ type OutputOptions = Exclude<
undefined
>['output'];
const visualizerOptions = (packageName: string, core = false): PluginOption[] => {
if (packageName !== 'mermaid' || !visualize) {
return [];
}
return ['network', 'treemap', 'sunburst'].map((chartType) =>
visualizer({
filename: `./stats/${chartType}${core ? '.core' : ''}.html`,
template: chartType as TemplateType,
gzipSize: true,
brotliSize: true,
})
);
};
const packageOptions = {
mermaid: {
name: 'mermaid',
@ -22,23 +39,13 @@ const packageOptions = {
'mermaid-mindmap': {
name: 'mermaid-mindmap',
packageName: 'mermaid-mindmap',
file: 'diagram-definition.ts',
},
'mermaid-mindmap-detector': {
name: 'mermaid-mindmap-detector',
packageName: 'mermaid-mindmap',
file: 'detector.ts',
},
'mermaid-example-diagram': {
name: 'mermaid-example-diagram',
packageName: 'mermaid-example-diagram',
file: 'diagram-definition.ts',
},
'mermaid-example-diagram-detector': {
name: 'mermaid-example-diagram-detector',
packageName: 'mermaid-example-diagram',
file: 'detector.ts',
},
// 'mermaid-example-diagram-detector': {
// name: 'mermaid-example-diagram-detector',
// packageName: 'mermaid-example-diagram',
// file: 'detector.ts',
// },
};
interface BuildOptions {
@ -68,6 +75,9 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions)
];
if (core) {
const { dependencies } = JSON.parse(
readFileSync(resolve(__dirname, `../packages/${packageName}/package.json`), 'utf-8')
);
// Core build is used to generate file without bundled dependencies.
// This is used by downstream projects to bundle dependencies themselves.
external.push(...Object.keys(dependencies));
@ -102,7 +112,7 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions)
resolve: {
extensions: ['.jison', '.js', '.ts', '.json'],
},
plugins: [jisonPlugin()],
plugins: [jisonPlugin(), ...visualizerOptions(packageName, core)],
};
if (watch && config.build) {
@ -110,7 +120,7 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions)
include: [
'packages/mermaid-mindmap/src/**',
'packages/mermaid/src/**',
'packages/mermaid-example-diagram/src/**',
// 'packages/mermaid-example-diagram/src/**',
],
};
}
@ -128,15 +138,20 @@ const buildPackage = async (entryName: keyof typeof packageOptions) => {
const main = async () => {
const packageNames = Object.keys(packageOptions) as (keyof typeof packageOptions)[];
for (const pkg of packageNames) {
for (const pkg of packageNames.filter((pkg) => !mermaidOnly || pkg === 'mermaid')) {
await buildPackage(pkg);
}
};
if (watch) {
build(getBuildConfig({ minify: false, watch, entryName: 'mermaid' }));
build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-mindmap' }));
build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-example-diagram' }));
build(getBuildConfig({ minify: false, watch, core: true, entryName: 'mermaid' }));
if (!mermaidOnly) {
build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-mindmap' }));
// build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-example-diagram' }));
}
} else if (visualize) {
await build(getBuildConfig({ minify: false, core: true, entryName: 'mermaid' }));
await build(getBuildConfig({ minify: false, core: false, entryName: 'mermaid' }));
} else {
void main();
}

View File

@ -1,6 +0,0 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"module": "ES2022"
}
}

View File

@ -72,7 +72,7 @@ flowchart LR
If you want to preview the whole documentation site on your machine:
```sh
cd mermaid
cd packages/mermaid
pnpm i
pnpm docs:dev
```

View File

@ -1,23 +1,6 @@
# mermaid
[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
# Whoa, what's going on here?
We are transforming the Mermaid repository to a so called mono-repo. This is a part of the effort to decouple the diagrams from the core of mermaid. This will:
- Make it possible to select which diagrams to include on your site
- Open up for lazy loading
- Make it possible to add diagrams from outside of the Mermaid repository
- Separate the release flow between different diagrams and the Mermaid core
As such be aware of some changes..
# We use pnpm now
# The source code has moved
It is now located in the src folder for each respective package located as subfolders in packages.
[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![npm minified gzipped bundle size](https://img.shields.io/bundlephobia/minzip/mermaid)](https://bundlephobia.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
English | [简体中文](./README.zh-CN.md)

View File

@ -1,6 +1,6 @@
# mermaid
[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![npm minified gzipped bundle size](https://img.shields.io/bundlephobia/minzip/mermaid)](https://bundlephobia.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
[English](./README.md) | 简体中文
@ -24,9 +24,9 @@ Mermaid 是一个基于 Javascript 的图表绘制工具,通过解析类 Markd
Mermaid 通过允许用户创建便于修改的图表来解决这一难题,它也可以作为生产脚本(或其他代码)的一部分。<br/>
<br/>
Mermaid 甚至能让非程序员也能通过 [Mermaid Live Editor](https://mermaid.live/) 轻松创建详细的图表。<br/>
你可以访问 [教程](./docs/Tutorials.md) 来查看 Live Editor 的视频教程,也可以查看 [Mermaid 的集成和使用](./docs/integrations.md) 这个清单来检查你的文档工具是否已经集成了 Mermaid 支持。
你可以访问 [教程](./docs/config/Tutorials.md) 来查看 Live Editor 的视频教程,也可以查看 [Mermaid 的集成和使用](./docs/misc/integrations.md) 这个清单来检查你的文档工具是否已经集成了 Mermaid 支持。
如果想要查看关于 Mermaid 更详细的介绍及基础使用方式,可以查看 [入门指引](./docs/n00b-overview.md), [用法](./docs/usage.md) 和 [教程](./docs/Tutorials.md).
如果想要查看关于 Mermaid 更详细的介绍及基础使用方式,可以查看 [入门指引](./docs/community/n00b-overview.md), [用法](./docs/config/usage.md) 和 [教程](./docs/config/Tutorials.md).
🌐 [CDN](https://unpkg.com/mermaid/) | 📖 [文档](https://mermaidjs.github.io) | 🙌 [贡献](https://github.com/mermaid-js/mermaid/blob/develop/CONTRIBUTING.md) | 📜 [更新日志](./docs/CHANGELOG.md)

View File

@ -53,6 +53,18 @@ export const MockD3 = (name, parent) => {
get __parent() {
return parent;
},
node() {
return {
getBBox() {
return {
x: 5,
y: 10,
height: 15,
width: 20,
};
},
};
},
};
elem.append = (name) => {
const mockElem = MockD3(name, elem);

View File

@ -14,6 +14,7 @@
"bilkent",
"bisheng",
"brolin",
"brotli",
"codedoc",
"colour",
"cpettitt",
@ -70,6 +71,7 @@
"substate",
"sveidqvist",
"techn",
"treemap",
"ts-nocheck",
"tuleap",
"verdana",
@ -116,5 +118,8 @@
"Multi-line code blocks",
"HTML Tags"
],
"ignorePaths": ["packages/mermaid/src/docs/CHANGELOG.md"]
"ignorePaths": [
"packages/mermaid/src/docs/CHANGELOG.md",
"packages/mermaid/src/docs/.vitepress/redirect.ts"
]
}

View File

@ -0,0 +1,13 @@
describe('mermaid', () => {
describe('registerDiagram', () => {
it('should work on @mermaid-js/mermaid-mindmap and mermaid-example-diagram', () => {
const url = 'http://localhost:9000/external-diagrams-mindmap.html';
cy.visit(url);
cy.get('svg', {
// may be a bit slower than normal, since vite might need to re-compile mermaid/mermaid-mindmap/mermaid-example-diagram
timeout: 10000,
}).matchImageSnapshot();
});
});
});

View File

@ -496,4 +496,16 @@ describe('Class diagram V2', () => {
);
cy.get('svg');
});
it('1433: should render a simple class with a title', () => {
imgSnapshotTest(
`---
title: simple class diagram
---
classDiagram-v2
class Class10
`,
{}
);
});
});

View File

@ -273,4 +273,17 @@ describe('Entity Relationship Diagram', () => {
);
cy.get('svg');
});
it('1433: should render a simple ER diagram with a title', () => {
imgSnapshotTest(
`---
title: simple ER diagram
---
erDiagram
CUSTOMER ||--o{ ORDER : places
ORDER ||--|{ LINE-ITEM : contains
`,
{}
);
});
});

View File

@ -663,4 +663,15 @@ flowchart RL
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
it('1433: should render a titled flowchart with titleTopMargin set to 0', () => {
imgSnapshotTest(
`---
title: Simple flowchart
---
flowchart TD
A --> B
`,
{ titleTopMargin: 0 }
);
});
});

View File

@ -322,4 +322,15 @@ describe('Git Graph diagram', () => {
{}
);
});
it('1433: should render a simple gitgraph with a title', () => {
imgSnapshotTest(
`---
title: simple gitGraph
---
gitGraph
commit
`,
{}
);
});
});

View File

@ -1,75 +0,0 @@
import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
describe('Mindmap', () => {
it('square shape', () => {
imgSnapshotTest(
`
mindmap
root[
The root
]
`,
{}
);
cy.get('svg');
});
it('rounded rect shape', () => {
imgSnapshotTest(
`
mindmap
root((
The root
))
`,
{}
);
cy.get('svg');
});
it('circle shape', () => {
imgSnapshotTest(
`
mindmap
root(
The root
)
`,
{}
);
cy.get('svg');
});
it('default shape', () => {
imgSnapshotTest(
`
mindmap
The root
`,
{}
);
cy.get('svg');
});
it('adding children', () => {
imgSnapshotTest(
`
mindmap
The root
child1
child2
`,
{}
);
cy.get('svg');
});
it('adding grand children', () => {
imgSnapshotTest(
`
mindmap
The root
child1
child2
child3
`,
{}
);
cy.get('svg');
});
});

View File

@ -1,115 +0,0 @@
import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
describe('Mindmaps', () => {
it('Only a root', () => {
imgSnapshotTest(
`mindmap
root
`,
{}
);
});
it('a root with a shape', () => {
imgSnapshotTest(
`mindmap
root[root]
`,
{}
);
});
it('a root with wrapping text and a shape', () => {
imgSnapshotTest(
`mindmap
root[A root with a long text that wraps to keep the node size in check]
`,
{}
);
});
it('a root with an icon', () => {
imgSnapshotTest(
`mindmap
root[root]
::icon(mdi mdi-fire)
`,
{}
);
});
it('Blang and cloud shape', () => {
imgSnapshotTest(
`mindmap
root))bang((
::icon(mdi mdi-fire)
a))Another bang((
::icon(mdi mdi-fire)
a)A cloud(
::icon(mdi mdi-fire)
`,
{}
);
});
it('Blang and cloud shape with icons', () => {
imgSnapshotTest(
`mindmap
root))bang((
a))Another bang((
a)A cloud(
`,
{}
);
});
it('braches', () => {
imgSnapshotTest(
`mindmap
root
child1
grandchild 1
grandchild 2
child2
grandchild 3
grandchild 4
child3
grandchild 5
grandchild 6
`,
{}
);
});
it('braches with shapes and labels', () => {
imgSnapshotTest(
`mindmap
root
child1((Circle))
grandchild 1
grandchild 2
child2(Round rectangle)
grandchild 3
grandchild 4
child3[Square]
grandchild 5
::icon(mdi mdi-fire)
gc6((grand<br/>child 6))
::icon(mdi mdi-fire)
`,
{}
);
});
it('text shouhld wrap with icon', () => {
imgSnapshotTest(
`mindmap
root
Child3(A node with an icon and with a long text that wraps to keep the node size in check)
`,
{}
);
});
/* The end */
});

View File

@ -0,0 +1,233 @@
import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
/**
* Check whether the SVG Element has a Mindmap root
*
* Sometimes, Cypress takes a snapshot before the mermaid mindmap has finished
* generating the SVG.
*
* @param $p - The element to check.
*/
function shouldHaveRoot($p: JQuery<SVGSVGElement>) {
// get HTML Element from jquery element
const svgElement = $p[0];
expect(svgElement.nodeName).equal('svg');
const sectionRoots = svgElement.getElementsByClassName('mindmap-node section-root');
// mindmap should have at least one root section
expect(sectionRoots).to.have.lengthOf.at.least(1);
}
describe('Mindmaps', () => {
it('Only a root', () => {
imgSnapshotTest(
`mindmap
root
`,
{},
undefined,
shouldHaveRoot
);
});
it('a root with a shape', () => {
imgSnapshotTest(
`mindmap
root[root]
`,
{},
undefined,
shouldHaveRoot
);
});
it('a root with wrapping text and a shape', () => {
imgSnapshotTest(
`mindmap
root[A root with a long text that wraps to keep the node size in check]
`,
{},
undefined,
shouldHaveRoot
);
});
it('a root with an icon', () => {
imgSnapshotTest(
`mindmap
root[root]
::icon(mdi mdi-fire)
`,
{},
undefined,
shouldHaveRoot
);
});
it('Blang and cloud shape', () => {
imgSnapshotTest(
`mindmap
root))bang((
::icon(mdi mdi-fire)
a))Another bang((
::icon(mdi mdi-fire)
a)A cloud(
::icon(mdi mdi-fire)
`,
{},
undefined,
shouldHaveRoot
);
});
it('Blang and cloud shape with icons', () => {
imgSnapshotTest(
`mindmap
root))bang((
a))Another bang((
a)A cloud(
`,
{},
undefined,
shouldHaveRoot
);
});
it('braches', () => {
imgSnapshotTest(
`mindmap
root
child1
grandchild 1
grandchild 2
child2
grandchild 3
grandchild 4
child3
grandchild 5
grandchild 6
`,
{},
undefined,
shouldHaveRoot
);
});
it('braches with shapes and labels', () => {
imgSnapshotTest(
`mindmap
root
child1((Circle))
grandchild 1
grandchild 2
child2(Round rectangle)
grandchild 3
grandchild 4
child3[Square]
grandchild 5
::icon(mdi mdi-fire)
gc6((grand<br/>child 6))
::icon(mdi mdi-fire)
`,
{},
undefined,
shouldHaveRoot
);
});
it('text shouhld wrap with icon', () => {
imgSnapshotTest(
`mindmap
root
Child3(A node with an icon and with a long text that wraps to keep the node size in check)
`,
{},
undefined,
shouldHaveRoot
);
});
it('square shape', () => {
imgSnapshotTest(
`
mindmap
root[
The root
]
`,
{},
undefined,
shouldHaveRoot
);
cy.get('svg');
});
it('rounded rect shape', () => {
imgSnapshotTest(
`
mindmap
root((
The root
))
`,
{},
undefined,
shouldHaveRoot
);
cy.get('svg');
});
it('circle shape', () => {
imgSnapshotTest(
`
mindmap
root(
The root
)
`,
{},
undefined,
shouldHaveRoot
);
cy.get('svg');
});
it('default shape', () => {
imgSnapshotTest(
`
mindmap
The root
`,
{},
undefined,
shouldHaveRoot
);
cy.get('svg');
});
it('adding children', () => {
imgSnapshotTest(
`
mindmap
The root
child1
child2
`,
{},
undefined,
shouldHaveRoot
);
cy.get('svg');
});
it('adding grand children', () => {
imgSnapshotTest(
`
mindmap
The root
child1
child2
child3
`,
{},
undefined,
shouldHaveRoot
);
cy.get('svg');
});
/* The end */
});

View File

@ -559,4 +559,16 @@ stateDiagram-v2
);
});
});
it('1433: should render a simple state diagram with a title', () => {
imgSnapshotTest(
`---
title: simple state diagram
---
stateDiagram-v2
[*] --> State1
State1 --> [*]
`,
{}
);
});
});

View File

@ -0,0 +1,49 @@
<html>
<body>
<h1>Should correctly load a third-party diagram using registerDiagram</h1>
<pre id="diagram" class="mermaid">
mindmap
root
A
B
C
D
E
A2
B2
C2
D2
E2
child1((Circle))
grandchild 1
grandchild 2
child2(Round rectangle)
grandchild 3
grandchild 4
child3[Square]
grandchild 5
::icon(mdi mdi-fire)
gc6((grand<br/>child 6))
::icon(mdi mdi-fire)
gc7((grand<br/>grand<br/>child 8))
</pre>
<!-- <pre id="diagram" class="mermaid2">
example-diagram
</pre> -->
<!-- <div id="cy"></div> -->
<!-- <script src="http://localhost:9000/packages/mermaid-mindmap/dist/mermaid-mindmap-detector.js"></script> -->
<!-- <script src="./mermaid-example-diagram-detector.js"></script> -->
<!-- <script src="//cdn.jsdelivr.net/npm/mermaid@9.1.7/dist/mermaid.min.js"></script> -->
<!-- <script type="module" src="./external-diagrams-mindmap.mjs" /> -->
<script type="module">
import mindmap from '../../packages/mermaid-mindmap/src/detector';
// import example from '../../packages/mermaid-example-diagram/src/detector';
import mermaid from '../../packages/mermaid/src/mermaid';
await mermaid.registerExternalDiagrams([mindmap]);
await mermaid.initialize({ logLevel: 0 });
await mermaid.initThrowsErrorsAsync();
</script>
</body>
</html>

View File

@ -63,24 +63,19 @@ flowchart TD
</pre>
<pre id="diagram" class="mermaid">
mindmap
root((mindmap))
Origins
Long history
::icon(fa fa-book)
Popularisation
::icon(fa fa-book)
British popular psychology author Tony Buzan
Research
::icon(fa fa-book)
On effectivness<br/>and features
On Automatic creation
Uses
Creative techniques
Strategic planning
Argument mapping
Tools
Pen and paper
Mermaid
root
child1((Circle))
grandchild 1
grandchild 2
child2(Round rectangle)
grandchild 3
grandchild 4
child3[Square]
grandchild 5
::icon(mdi mdi-fire)
gc6((grand<br/>child 6))
::icon(mdi mdi-fire)
gc7((grand<br/>grand<br/>child 8))
</pre>
<pre id="diagram" class="mermaid">
gantt

View File

@ -14,16 +14,14 @@
mermaid.init({ startOnLoad: false });
mermaid.mermaidAPI.initialize({ securityLevel: 'strict' });
(async () => {
try {
console.log('rendering');
await mermaid.mermaidAPI.render('graphDiv', `>`);
} catch (e) {}
try {
console.log('rendering');
mermaid.mermaidAPI.render('graphDiv', `>`);
} catch (e) {}
await mermaid.mermaidAPI.render('graphDiv', `graph LR\n a --> b`, (html) => {
document.getElementById('graph').innerHTML = html;
});
})();
mermaid.mermaidAPI.render('graphDiv', `graph LR\n a --> b`, (html) => {
document.getElementById('graph').innerHTML = html;
});
</script>
</body>
</html>

View File

@ -19,10 +19,9 @@
function rerender(text) {
const graphText = `graph TD
A[${text}] -->|Get money| B(Go shopping)`;
mermaid.mermaidAPI.render('id', graphText).then((svg) => {
console.log('\x1b[35m%s\x1b[0m', '>> graph', svg);
document.getElementById('graph').innerHTML = svg;
});
const graph = mermaid.mermaidAPI.render('id', graphText);
console.log('\x1b[35m%s\x1b[0m', '>> graph', graph);
document.getElementById('graph').innerHTML = graph;
}
</script>
<button id="rerender" onclick="rerender('Saturday')">Rerender</button>

View File

@ -1,4 +1,5 @@
import mermaid2 from '../../packages/mermaid/src/mermaid';
import mindmap from '../../packages/mermaid-mindmap/src/detector';
function b64ToUtf8(str) {
return decodeURIComponent(escape(window.atob(str)));
@ -9,7 +10,7 @@ function b64ToUtf8(str) {
* configuration for mermaid rendering and calls init for rendering the mermaid diagrams on the
* page.
*/
const contentLoaded = function () {
const contentLoaded = async function () {
let pos = document.location.href.indexOf('?graph=');
if (pos > 0) {
pos = pos + 7;
@ -36,8 +37,7 @@ const contentLoaded = function () {
document.getElementsByTagName('body')[0].appendChild(div);
}
graphObj.mermaid.lazyLoadedDiagrams = ['/mermaid-mindmap-detector.esm.mjs'];
await mermaid2.registerExternalDiagrams([mindmap]);
mermaid2.initialize(graphObj.mermaid);
mermaid2.init();
}

8
cypress/tsconfig.json Normal file
View File

@ -0,0 +1,8 @@
{
"compilerOptions": {
"target": "es2020",
"lib": ["es2020", "dom"],
"types": ["cypress", "node"]
},
"include": ["**/*.ts"]
}

View File

@ -17,6 +17,9 @@
<h1>Class diagram demos</h1>
<pre class="mermaid">
---
title: Demo Class Diagram
---
classDiagram
accTitle: Demo Class Diagram
accDescr: This class diagram show the abstract Animal class, and 3 classes that inherit from it: Duck, Fish, and Zebra.

View File

@ -20,6 +20,9 @@
<body>
<pre class="mermaid">
---
title: This is a title
---
erDiagram
%% title This is a title
%% accDescription Test a description

View File

@ -17,6 +17,9 @@
<h2>Sample 1</h2>
<h3>graph</h3>
<pre class="mermaid">
---
title: This is a complicated flow
---
graph LR
accTitle: This is a complicated flow
accDescr: This is the descriptoin for the complicated flow.
@ -221,6 +224,9 @@
<h2>Sample 2</h2>
<h3>graph</h3>
<pre class="mermaid">
---
title: What to buy
---
graph TD
accTitle: What to buy
accDescr: Options of what to buy with Christmas money

View File

@ -16,6 +16,9 @@
<body>
<h1>Git diagram demo</h1>
<pre class="mermaid">
---
title: Simple Git diagram
---
gitGraph:
options
{

View File

@ -48,6 +48,9 @@
<li>
<h2><a href="./journey.html">Journey</a></h2>
</li>
<li>
<h2><a href="./mindmap.html">Mindmap</a></h2>
</li>
<li>
<h2><a href="./pie.html">Pie</a></h2>
</li>

View File

@ -16,8 +16,10 @@
<body>
<h1>Journey diagram demo</h1>
<pre class="mermaid">
journey
title My working day
---
title: My working day
---
journey
accTitle: Very simple journey demo
accDescr: 2 main sections: work and home, each with just a few tasks

108
demos/mindmap.html Normal file
View File

@ -0,0 +1,108 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Mindmap 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>Mindmap diagram demo</h1>
<pre class="mermaid">
mindmap
root
child1((Circle))
grandchild 1
grandchild 2
child2(Round rectangle)
grandchild 3
grandchild 4
child3[Square]
grandchild 5
::icon(mdi mdi-fire)
gc6((grand<br/>child 6))
::icon(mdi mdi-fire)
gc7((grand<br/>grand<br/>child 8))
</pre>
<h2>Mindmap with root wrapping text and a shape</h2>
<pre class="mermaid">
mindmap
root[A root with a long text that wraps to keep the node size in check]
</pre>
<script type="module">
import mermaid from './mermaid.esm.mjs';
import mermaidMindmap from './mermaid-mindmap.esm.mjs';
const ALLOWED_TAGS = [
'a',
'b',
'blockquote',
'br',
'dd',
'div',
'dl',
'dt',
'em',
'foreignObject',
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
'h7',
'h8',
'hr',
'i',
'li',
'ul',
'ol',
'p',
'pre',
'span',
'strike',
'strong',
'table',
'tbody',
'td',
'tfoot',
'th',
'thead',
'tr',
];
mermaid.parseError = function (err, hash) {
// console.error('Mermaid error: ', err);
};
await mermaid.registerExternalDiagrams([mermaidMindmap]);
mermaid.initialize({
theme: 'base',
startOnLoad: true,
logLevel: 0,
flowchart: {
useMaxWidth: false,
htmlLabels: true,
},
gantt: {
useMaxWidth: false,
},
useMaxWidth: false,
});
function callback() {
alert('It worked');
}
mermaid.parseError = function (err, hash) {
console.error('In parse error:');
console.error(err);
};
</script>
</body>
</html>

View File

@ -17,6 +17,9 @@
<h1>State diagram demos</h1>
<h2>Very simple showing change from State1 to State2</h2>
<pre class="mermaid">
---
title: Very simple diagram
---
stateDiagram
accTitle: This is the accessible title
accDescr:This is an accessible description
@ -43,6 +46,9 @@
</code>
</p>
<pre class="mermaid">
---
title: Very simple diagram
---
stateDiagram-v2
accTitle: This is the accessible title
accDescr: This is an accessible description

View File

@ -12,7 +12,7 @@ So you want to help? That's great!
Here are a few things to get you started on the right path.
**The Docs Structure is dictated by [sidebar.md](https://github.com/mermaid-js/mermaid/edit/develop/src/docs/_sidebar.md)**
**The Docs Structure is dictated by [.vitepress/config.ts](https://github.com/mermaid-js/mermaid/blob/develop/packages/mermaid/src/docs/.vitepress/config.ts)**.
**Note: Commits and Pull Requests should be directed to the develop branch.**
@ -32,7 +32,7 @@ We make all changes via Pull Requests. As we have many Pull Requests from develo
- Large changes reviewed by knsv or other developer asked to review by knsv
- Smaller, low-risk changes like dependencies, documentation, etc. can be merged by active collaborators
- Documentation (we encourage updates to the `src/docs` folder; you can submit them via direct commits)
- Documentation (we encourage updates to the `/packages/mermaid/src/docs` folder; you can submit them via direct commits)
When you commit code, create a branch with the following naming convention:
@ -50,9 +50,9 @@ Start with the type, such as **feature** or **bug**, followed by the issue numbe
If it is not in the documentation, it's like it never happened. Wouldn't that be sad? With all the effort that was put into the feature?
The docs are located in the `src/docs` folder and are written in Markdown. Just pick the right section and start typing. If you want to propose changes to the structure of the documentation, such as adding a new section or a new file you do that via the **[sidebar](https://github.com/mermaid-js/mermaid/edit/develop/src/docs/_sidebar.md)**.
The docs are located in the `src/docs` folder and are written in Markdown. Just pick the right section and start typing. If you want to propose changes to the structure of the documentation, such as adding a new section or a new file you do that via **[.vitepress/config.ts](https://github.com/mermaid-js/mermaid/blob/develop/packages/mermaid/src/docs/.vitepress/config.ts)**.
> **All the documents displayed in the GitHub.io page are listed in [sidebar.md](https://github.com/mermaid-js/mermaid/edit/develop/src/docs/_sidebar.md)**.
> **All the documents displayed in the GitHub.io page are listed in [.vitepress/config.ts](https://github.com/mermaid-js/mermaid/blob/develop/packages/mermaid/src/docs/.vitepress/config.ts)**.
The contents of <https://mermaid-js.github.io/mermaid/> are based on the docs from the `master` branch. Updates committed to the `master` branch are reflected in the [Mermaid Docs](https://mermaid-js.github.io/mermaid/) once released.
@ -64,7 +64,7 @@ The documentation is located in the `src/docs` directory and organized according
The `docs` folder will be automatically generated when committing to `src/docs` and should not be edited manually.
We encourage contributions to the documentation at [mermaid-js/mermaid/src/docs](https://github.com/mermaid-js/mermaid/tree/develop/src/docs). We publish documentation using GitHub Pages with [Docsify](https://www.youtube.com/watch?v=TV88lp7egMw&t=3s)
We encourage contributions to the documentation at [mermaid-js/mermaid/src/docs](https://github.com/mermaid-js/mermaid/tree/develop/packages/mermaid/src/docs). We publish documentation using GitHub Pages with [Docsify](https://www.youtube.com/watch?v=TV88lp7egMw&t=3s)
### Add Unit Tests for Parsing
@ -117,7 +117,7 @@ Markdown is used to format the text, for more information about Markdown [see th
To edit Docs on your computer:
1. Find the Markdown file (.md) to edit in the [mermaid-js/mermaid/src/docs](https://github.com/mermaid-js/mermaid/tree/develop/src/docs) directory in the `develop` branch.
1. Find the Markdown file (.md) to edit in the [packages/mermaid/src/docs](https://github.com/mermaid-js/mermaid/tree/develop/packages/mermaid/src/docs) directory in the `develop` branch.
2. Create a fork of the develop branch.
3. Make changes or add new documentation.
4. Commit changes to your fork and push it to GitHub.
@ -126,7 +126,7 @@ To edit Docs on your computer:
To edit Docs on GitHub:
1. Login to [GitHub.com](https://www.github.com).
2. Navigate to [mermaid-js/mermaid/src/docs](https://github.com/mermaid-js/mermaid/tree/develop/src/docs).
2. Navigate to [packages/mermaid/src/docs](https://github.com/mermaid-js/mermaid/tree/develop/packages/mermaid/src/docs).
3. To edit a file, click the pencil icon at the top-right of the file contents panel.
4. Describe what you changed in the **Propose file change** section, located at the bottom of the page.
5. Submit your changes by clicking the button **Propose file change** at the bottom (by automatic creation of a fork and a new branch).

View File

@ -45,7 +45,7 @@ It is a relatively straightforward solution to a significant hurdle with the sof
**Nodes**
> These are the boxes that contain text or otherwise discrete pieces of each diagram, separated generally by arrows, except for Gantt Charts and User Journey Diagrams. They will be referred often in the instructions. Read for Diagram Specific [Syntax](../intro/n00b-syntaxReference)
> These are the boxes that contain text or otherwise discrete pieces of each diagram, separated generally by arrows, except for Gantt Charts and User Journey Diagrams. They will be referred often in the instructions. Read for Diagram Specific [Syntax](../intro/n00b-syntaxReference.md)
## Advantages of using Mermaid

View File

@ -10,13 +10,13 @@ The Mermaid team takes the security of Mermaid and the applications that use Mer
## Reporting vulnerabilities
To report a vulnerability, please e-mail security@mermaid.live with a description of the issue, the steps you took to create the issue, affected versions, and if known, mitigations for the issue.
To report a vulnerability, please e-mail <security@mermaid.live> with a description of the issue, the steps you took to create the issue, affected versions, and if known, mitigations for the issue.
We aim to reply within three working days, probably much sooner.
You should expect a close collaboration as we work to resolve the issue you have reported. Please reach out to security@mermaid.live again if you do not receive prompt attention and regular updates.
You should expect a close collaboration as we work to resolve the issue you have reported. Please reach out to <security@mermaid.live> again if you do not receive prompt attention and regular updates.
You may also reach out to the team via our public Slack chat channels; however, please make sure to e-mail security@mernaid.live when reporting an issue, and avoid revealing information about vulnerabilities in public as that could that could put users at risk.
You may also reach out to the team via our public Slack chat channels; however, please make sure to e-mail <security@mermaid.live> when reporting an issue, and avoid revealing information about vulnerabilities in public as that could that could put users at risk.
## Best practices

View File

@ -12,8 +12,8 @@
With version 8.6.0 comes the release of directives for mermaid, a new system for modifying configurations, with the aim of establishing centralized, sane defaults and simple implementation.
`directives` allow for a single-use overwriting of `config`, as it has been discussed in [Configurations](../config/configuration).
This allows site Diagram Authors to instantiate temporary modifications to `config` through the use of [Directives](directives), which are parsed before rendering diagram definitions. This allows the Diagram Authors to alter the appearance of the diagrams.
`directives` allow for a single-use overwriting of `config`, as it has been discussed in [Configurations](../config/configuration.md).
This allows site Diagram Authors to instantiate temporary modifications to `config` through the use of [Directives](directives.md), which are parsed before rendering diagram definitions. This allows the Diagram Authors to alter the appearance of the diagrams.
**A likely application for this is in the creation of diagrams/charts inside company/organizational webpages, that rely on mermaid for diagram and chart rendering.**
@ -219,4 +219,4 @@ Example of **object.Assign**:
> **Note**
> default: current siteConfig (optional, default `getSiteConfig()`)
## For more information, read [Setup](setup/README).
## For more information, read [Setup](./setup/README.md).

View File

@ -28,7 +28,7 @@ The definitions that can be generated the Live-Editor are also backwards-compati
## Mermaid with HTML
Examples are provided in [Getting Started](../intro/n00b-gettingStarted)
Examples are provided in [Getting Started](../intro/n00b-gettingStarted.md)
**CodePen Examples:**

View File

@ -36,7 +36,7 @@ Pushes in a directive to the configuration
#### Defined in
[config.ts:191](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L191)
[config.ts:193](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L193)
---
@ -60,7 +60,7 @@ The currentConfig
#### Defined in
[config.ts:136](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L136)
[config.ts:138](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L138)
---
@ -84,7 +84,7 @@ The siteConfig
#### Defined in
[config.ts:96](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L96)
[config.ts:97](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L97)
---
@ -118,7 +118,7 @@ The siteConfig
#### Defined in
[config.ts:223](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L223)
[config.ts:225](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L225)
---
@ -147,7 +147,7 @@ options in-place
#### Defined in
[config.ts:151](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L151)
[config.ts:153](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L153)
---
@ -167,7 +167,7 @@ options in-place
#### Defined in
[config.ts:75](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L75)
[config.ts:76](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L76)
---
@ -199,7 +199,7 @@ The currentConfig merged with the sanitized conf
#### Defined in
[config.ts:113](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L113)
[config.ts:114](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L114)
---
@ -232,7 +232,7 @@ The new siteConfig
#### Defined in
[config.ts:61](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L61)
[config.ts:62](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L62)
---
@ -273,4 +273,4 @@ The new siteConfig
#### Defined in
[config.ts:79](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L79)
[config.ts:80](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L80)

View File

@ -14,7 +14,7 @@
#### Defined in
[defaultConfig.ts:1882](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L1882)
[defaultConfig.ts:1933](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L1933)
---

View File

@ -16,7 +16,7 @@ Renames and re-exports [mermaidAPI](mermaidAPI.md#mermaidapi)
### mermaidAPI
`Const` **mermaidAPI**: `Readonly`<{ `defaultConfig`: `MermaidConfig` = configApi.defaultConfig; `getConfig`: () => `MermaidConfig` = configApi.getConfig; `getSiteConfig`: () => `MermaidConfig` = configApi.getSiteConfig; `globalReset`: () => `void` ; `initialize`: (`options`: `MermaidConfig`) => `Promise`<`void`> ; `parse`: (`text`: `string`, `parseError?`: `ParseErrorFunction`) => `boolean` ; `parseDirective`: (`p`: `any`, `statement`: `string`, `context`: `string`, `type`: `string`) => `void` ; `render`: (`id`: `string`, `text`: `string`, `cb`: (`svgCode`: `string`, `bindFunctions?`: (`element`: `Element`) => `void`) => `void`, `svgContainingElement?`: `Element`) => `Promise`<`void`> ; `reset`: () => `void` ; `setConfig`: (`conf`: `MermaidConfig`) => `MermaidConfig` = configApi.setConfig; `updateSiteConfig`: (`conf`: `MermaidConfig`) => `MermaidConfig` = configApi.updateSiteConfig }>
`Const` **mermaidAPI**: `Readonly`<{ `defaultConfig`: `MermaidConfig` = configApi.defaultConfig; `getConfig`: () => `MermaidConfig` = configApi.getConfig; `getSiteConfig`: () => `MermaidConfig` = configApi.getSiteConfig; `globalReset`: () => `void` ; `initialize`: (`options`: `MermaidConfig`) => `void` ; `parse`: (`text`: `string`, `parseError?`: `ParseErrorFunction`) => `boolean` ; `parseAsync`: (`text`: `string`, `parseError?`: `ParseErrorFunction`) => `Promise`<`boolean`> ; `parseDirective`: (`p`: `any`, `statement`: `string`, `context`: `string`, `type`: `string`) => `void` ; `render`: (`id`: `string`, `text`: `string`, `cb?`: (`svgCode`: `string`, `bindFunctions?`: (`element`: `Element`) => `void`) => `void`, `svgContainingElement?`: `Element`) => `string` ; `renderAsync`: (`id`: `string`, `text`: `string`, `cb?`: (`svgCode`: `string`, `bindFunctions?`: (`element`: `Element`) => `void`) => `void`, `svgContainingElement?`: `Element`) => `Promise`<`string`> ; `reset`: () => `void` ; `setConfig`: (`conf`: `MermaidConfig`) => `MermaidConfig` = configApi.setConfig; `updateSiteConfig`: (`conf`: `MermaidConfig`) => `MermaidConfig` = configApi.updateSiteConfig }>
## mermaidAPI configuration defaults
@ -80,7 +80,7 @@ mermaid.initialize(config);
#### Defined in
[mermaidAPI.ts:740](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L740)
[mermaidAPI.ts:949](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L949)
## Functions
@ -111,7 +111,7 @@ Return the last node appended
#### Defined in
[mermaidAPI.ts:283](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L283)
[mermaidAPI.ts:292](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L292)
---
@ -137,7 +137,7 @@ the cleaned up svgCode
#### Defined in
[mermaidAPI.ts:234](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L234)
[mermaidAPI.ts:243](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L243)
---
@ -163,7 +163,7 @@ the string with all the user styles
#### Defined in
[mermaidAPI.ts:161](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L161)
[mermaidAPI.ts:170](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L170)
---
@ -186,7 +186,7 @@ the string with all the user styles
#### Defined in
[mermaidAPI.ts:211](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L211)
[mermaidAPI.ts:220](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L220)
---
@ -213,7 +213,7 @@ with an enclosing block that has each of the cssClasses followed by !important;
#### Defined in
[mermaidAPI.ts:145](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L145)
[mermaidAPI.ts:154](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L154)
---
@ -233,7 +233,7 @@ with an enclosing block that has each of the cssClasses followed by !important;
#### Defined in
[mermaidAPI.ts:119](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L119)
[mermaidAPI.ts:128](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L128)
---
@ -253,7 +253,7 @@ with an enclosing block that has each of the cssClasses followed by !important;
#### Defined in
[mermaidAPI.ts:90](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L90)
[mermaidAPI.ts:99](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L99)
---
@ -279,7 +279,7 @@ Put the svgCode into an iFrame. Return the iFrame code
#### Defined in
[mermaidAPI.ts:262](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L262)
[mermaidAPI.ts:271](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L271)
---
@ -305,4 +305,4 @@ Remove any existing elements from the given document
#### Defined in
[mermaidAPI.ts:334](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L334)
[mermaidAPI.ts:343](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L343)

View File

@ -18,7 +18,7 @@ Please note that you can switch versions through the dropdown box at the top rig
## Using mermaid
For the majority of users, Using the [Live Editor](https://mermaid.live/) would be sufficient, however you may also opt to deploy mermaid as a dependency or using the [Mermaid API](setup/README).
For the majority of users, Using the [Live Editor](https://mermaid.live/) would be sufficient, however you may also opt to deploy mermaid as a dependency or using the [Mermaid API](./setup/README.md).
We have compiled some Video [Tutorials](./Tutorials.md) on how to use the mermaid Live Editor.
@ -41,7 +41,7 @@ We have compiled some Video [Tutorials](./Tutorials.md) on how to use the mermai
**Hosting mermaid on a web page.**
> Note:This topic explored in greater depth in the [User Guide for Beginners](../intro/n00b-gettingStarted)
> Note:This topic explored in greater depth in the [User Guide for Beginners](../intro/n00b-gettingStarted.md)
The easiest way to integrate mermaid on a web page requires two elements:
@ -62,7 +62,7 @@ Example:
```html
<script type="module">
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@9/dist/mermaid.esm.min.mjs';
import mermaid from 'https://unpkg.com/mermaid@9/dist/mermaid.esm.min.mjs';
mermaid.initialize({ startOnLoad: true });
</script>
```
@ -85,7 +85,7 @@ Example:
B-->D(fa:fa-spinner);
</pre>
<script type="module">
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@9/dist/mermaid.esm.min.mjs';
import mermaid from 'https://unpkg.com/mermaid@9/dist/mermaid.esm.min.mjs';
mermaid.initialize({ startOnLoad: true });
</script>
</body>
@ -326,7 +326,7 @@ setting the options in mermaid.
4. Instantiation of the configuration using the **mermaid.init** call- **Deprecated**
The list above has two ways too many of doing this. Three are deprecated and will eventually be removed. The list of
configuration objects are described [in the mermaidAPI documentation](setup/README).
configuration objects are described [in the mermaidAPI documentation](./setup/README.md).
## Using the `mermaidAPI.initialize`/`mermaid.initialize` call

179
docs/index.html.todo Normal file
View File

@ -0,0 +1,179 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>
mermaid - Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams,
gantt charts and git graphs.
</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta
name="description"
content="Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs."
/>
<meta
name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
/>
<!-- <link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/vue.css"> -->
<link rel="stylesheet" href="theme.css" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/all.min.css"
/>
<script
defer
data-domain="mermaid-js.github.io"
src="https://plausible.io/js/plausible.js"
></script>
<script>
const require = {
paths: { vs: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.29.1/min/vs' },
};
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.29.1/min/vs/loader.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.29.1/min/vs/editor/editor.main.nls.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.29.1/min/vs/editor/editor.main.js"></script>
<script>
exports = {};
</script>
<script src="https://unpkg.com/monaco-mermaid/browser.js"></script>
<style>
.markdown-section {
max-width: 1200px;
}
</style>
</head>
<body>
<div id="app"></div>
<script type="module">
import mermaid from 'https://unpkg.com/mermaid@9/dist/mermaid.esm.min.mjs';
import mindmap from 'https://unpkg.com/@mermaid-js/mermaid-mindmap@9/dist/mermaid-mindmap.esm.min.mjs';
await mermaid.registerExternalDiagrams([mindmap]);
window.mermaid = mermaid;
const isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
const conf = {
logLevel: 4,
startOnLoad: true,
themeCSS: '.label { font-family: Source Sans Pro,Helvetica Neue,Arial,sans-serif; }',
};
if (isDarkMode) conf.theme = 'dark';
async function loadMermaid() {
mermaid.parseError = (e) => {
console.log('parse error', e); // eslint-disable-line
};
await mermaid.registerExternalDiagrams([mindmap]);
mermaid.initialize(conf);
console.log('mermaid initialized'); // eslint-disable-line
}
await loadMermaid();
</script>
<script>
let initEditor = exports.default;
let parser = new DOMParser();
let currentCodeExample = 0;
let colorize = [];
let num = 0;
function colorizeEverything(html) {
initEditor(monaco);
return new Promise((resolve, reject) => {
monaco.editor.setTheme('mermaid');
const parsed = parser.parseFromString(html, 'text/html').body;
Promise.all(
[...parsed.querySelectorAll('pre[id*="code"]')].map((codeBlock) =>
monaco.editor.colorize(codeBlock.innerText, 'mermaid')
)
).then((result) => {
parsed
.querySelectorAll('pre[id*="code"]')
.forEach((codeBlock, index) => (codeBlock.innerHTML = result[index]));
resolve(parsed.innerHTML);
});
});
}
function escapeHTML(html) {
return html
.replaceAll('&', '&amp;')
.replaceAll('<', '&lt;')
.replaceAll('>', '&gt;')
.replaceAll('"', '&quot;')
.replaceAll("'", '&apos;');
}
window.$docsify = {
search: 'auto',
name: 'mermaid',
repo: 'https://github.com/mermaid-js/mermaid',
loadSidebar: true,
mergeNavbar: true,
maxLevel: 4,
subMaxLevel: 2,
markdown: {
renderer: {
code: function (code, lang) {
if (lang === 'mermaid-example') {
console.log('An example'); // eslint-disable-line
currentCodeExample++;
colorize.push(currentCodeExample);
return '<pre id="code' + currentCodeExample + '">' + escapeHTML(code) + '</pre>';
} else if (lang === 'mermaid') {
return '<pre class="mermaid">' + code + '</pre>';
}
return this.origin.code.apply(this, arguments);
},
heading: function (text) {
if (text.includes('THIS IS AN AUTOGENERATED FILE. DO NOT EDIT')) {
return '';
}
return this.origin.heading.apply(this, arguments);
},
},
},
plugins: [
function (hook, vm) {
hook.beforeEach(function (html) {
url = 'https://github.com/mermaid-js/mermaid/blob/develop/src/docs/' + vm.route.file;
const editHtml = '[:memo: Edit this Page](' + url + ')\n';
return editHtml + html;
});
// Invoked on each page load after new HTML has been appended to the DOM
hook.doneEach(async function () {
await mermaid.init();
});
hook.afterEach(function (html, next) {
next(html);
(async () => {
while (!window.hasOwnProperty('monaco'))
await new Promise((resolve) => setTimeout(resolve, 1000));
colorizeEverything(html).then(
(newHTML) =>
(document.querySelector('article.markdown-section').innerHTML = newHTML)
);
})();
});
},
],
};
</script>
<script>
window.onhashchange = function (a) {
// if (location && ga) {
// ga('send', 'pageview', location.hash);
// }
};
</script>
<script src="//cdn.jsdelivr.net/npm/docsify/lib/docsify.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/search.min.js"></script>
<!-- <script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/ga.min.js"></script> -->
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-coffeescript.min.js"></script>
</body>
</html>

View File

@ -10,11 +10,11 @@
It is a JavaScript based diagramming and charting tool that renders Markdown-inspired text definitions to create and modify diagrams dynamically.
> If you are familiar with Markdown you should have no problem learning [Mermaid's Syntax](n00b-syntaxReference).
> If you are familiar with Markdown you should have no problem learning [Mermaid's Syntax](n00b-syntaxReference.md).
<img src="/header.png" alt="" />
[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![npm minified gzipped bundle size](https://img.shields.io/bundlephobia/minzip/mermaid)](https://bundlephobia.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
<!-- Mermaid book banner -->
@ -35,7 +35,7 @@ Use Mermaid with your favorite applications, check out the list of [Integrations
For a more detailed introduction to Mermaid and some of its more basic uses, look to the [Beginner's Guide](../community/n00b-overview.md) and [Usage](../config/usage.md).
🌐 [CDN](https://unpkg.com/mermaid/) | 📖 [Documentation](https://mermaidjs.github.io) | 🙌 [Contribution](https://github.com/mermaid-js/mermaid/blob/develop/docs/development.md) | 🔌 [Plug-Ins](../misc/integrations.md)
🌐 [CDN](https://unpkg.com/mermaid/) | 📖 [Documentation](https://mermaidjs.github.io) | 🙌 [Contribution](../community/development.md) | 🔌 [Plug-Ins](../misc/integrations.md)
> 🖖 Keep a steady pulse: mermaid needs more Collaborators, [Read More](https://github.com/knsv/mermaid/issues/866).
@ -163,7 +163,7 @@ Class01 : int gorilla
Class08 <--> C2: Cool label
```
### Git graph
### [Git graph](../syntax/gitgraph.md)
```mermaid-example
gitGraph
@ -237,9 +237,9 @@ journey
## Installation
**In depth guides and examples can be found at [Getting Started](n00b-gettingStarted) and [Usage](../config/usage).**
**In depth guides and examples can be found at [Getting Started](./n00b-gettingStarted.md) and [Usage](../config/usage.md).**
**It would also be helpful to learn more about mermaid's [Syntax](n00b-syntaxReference).**
**It would also be helpful to learn more about mermaid's [Syntax](./n00b-syntaxReference.md).**
### CDN
@ -261,20 +261,20 @@ To Deploy Mermaid:
- Yarn: `yarn add mermaid`
- Pnpm: `pnpm add mermaid`
### [Mermaid API](../config/setup/README):
### [Mermaid API](../config/setup/README.md):
**To deploy mermaid without a bundler, one can insert a `script` tag with an absolute address and a `mermaid.initialize` call into the HTML like so:**
```html
<script type="module">
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@9/dist/mermaid.esm.min.mjs';
import mermaid from 'https://unpkg.com/mermaid@9/dist/mermaid.esm.min.mjs';
mermaid.initialize({ startOnLoad: true });
</script>
```
**Doing so will command the mermaid parser to look for the `<div>` or `<pre>` tags with `class="mermaid"`. From these tags mermaid will try to read the diagram/chart definitions and render them into SVG charts.**
**Examples can be found at** [Other examples](../syntax/examples)
**Examples can be found at** [Other examples](../syntax/examples.md)
## Sibling projects

View File

@ -53,7 +53,7 @@ graph TD
In the `Code` section one can write or edit raw mermaid code, and instantly `Preview` the rendered result on the panel beside it.
The `Configuration` Section is for changing the appearance and behavior of mermaid diagrams. An easy introduction to mermaid configuration is found in the [Advanced usage](../config/n00b-advanced.md) section. A complete configuration reference cataloging the default values can be found on the [mermaidAPI](../config/setup/README) page.
The `Configuration` Section is for changing the appearance and behavior of mermaid diagrams. An easy introduction to mermaid configuration is found in the [Advanced usage](../config/n00b-advanced.md) section. A complete configuration reference cataloging the default values can be found on the [mermaidAPI](../config/setup/README.md) page.
![Code,Config and Preview](./img/Code-Preview-Config.png)
@ -128,7 +128,7 @@ b. The importing of mermaid library through the `mermaid.esm.js` or `mermaid.esm
```html
<body>
<script type="module">
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@9/dist/mermaid.esm.min.mjs';
import mermaid from 'https://unpkg.com/mermaid@9/dist/mermaid.esm.min.mjs';
mermaid.initialize({ startOnLoad: true });
</script>
</body>
@ -168,7 +168,7 @@ Rendering in Mermaid is initialized by `mermaid.initialize()` call. You can plac
</pre>
<script type="module">
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@9/dist/mermaid.esm.min.mjs';
import mermaid from 'https://unpkg.com/mermaid@9/dist/mermaid.esm.min.mjs';
mermaid.initialize({ startOnLoad: true });
</script>
</body>

View File

@ -42,19 +42,19 @@ erDiagram
PRODUCT ||--o{ ORDER-ITEM : "ordered in"
```
The [Getting Started](n00b-gettingStarted) section can also provide some practical examples of mermaid syntax.
The [Getting Started](./n00b-gettingStarted.md) section can also provide some practical examples of mermaid syntax.
## Diagram Breaking
One should **beware the use of some words or symbols** that can break diagrams. These words or symbols are few and often only affect specific types of diagrams. The table below will continuously be updated.
| Diagram Breakers | Reason | Solution |
| -------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- | ------------------------------------------------- |
| **Comments** | | |
| [` %%{``}%% `](https://github.com/mermaid-js/mermaid/issues/1968) | Similar to [Directives](../config/directives.md) confuses the renderer. | In comments using `%%`, avoid using "{}". |
| **Flow-Charts** | | |
| 'end' | The word "End" can cause Flowcharts and Sequence diagrams to break | Wrap them in quotation marks to prevent breakage. |
| [Nodes inside Nodes](https://mermaid-js.github.io/mermaid/#/flowchart?id=special-characters-that-break-syntax) | Mermaid gets confused with nested shapes | wrap them in quotation marks to prevent breaking |
| Diagram Breakers | Reason | Solution |
| ------------------------------------------------------------------------------------ | ----------------------------------------------------------------------- | ------------------------------------------------- |
| **Comments** | | |
| [` %%{``}%% `](https://github.com/mermaid-js/mermaid/issues/1968) | Similar to [Directives](../config/directives.md) confuses the renderer. | In comments using `%%`, avoid using "{}". |
| **Flow-Charts** | | |
| 'end' | The word "End" can cause Flowcharts and Sequence diagrams to break | Wrap them in quotation marks to prevent breakage. |
| [Nodes inside Nodes](../syntax/flowchart.md?id=special-characters-that-break-syntax) | Mermaid gets confused with nested shapes | wrap them in quotation marks to prevent breaking |
### Mermaid Live Editor
@ -64,9 +64,9 @@ Now, that you've seen what you should not add to your diagrams, you can play aro
Configuration is the third part of Mermaid, after deployment and syntax. It deals with the different ways that Mermaid can be customized across different deployments.
If you are interested in altering and customizing your Mermaid Diagrams, you will find the methods and values available for [Configuration](../config/setup/README) here. It includes themes.
If you are interested in altering and customizing your Mermaid Diagrams, you will find the methods and values available for [Configuration](../config/setup/README.md) here. It includes themes.
This section will introduce the different methods of configuring the behaviors and appearances of Mermaid Diagrams.
The following are the most commonly used methods, and they are all tied to Mermaid [Deployment](n00b-gettingStarted) methods.
The following are the most commonly used methods, and they are all tied to Mermaid [Deployment](./n00b-gettingStarted.md) methods.
### Configuration Section in the [Live Editor](https://mermaid.live).

View File

@ -167,7 +167,6 @@ They also serve as proof of concept, for the variety of things that can be built
| Extensions for Mermaid | - | [🦊🔗](https://addons.mozilla.org/en-US/firefox/addon/markdown-viewer-chrome/) | [🔴🔗](https://addons.opera.com/en/extensions/details/extensions-for-mermaid/) | - | [🐙🔗](https://github.com/Stefan-S/mermaid-extension) |
| Chrome Diagrammer | [🎡🔗](https://chrome.google.com/webstore/detail/chrome-diagrammer/bkpbgjmkomfoakfklcjeoegkklgjnnpk) | - | - | - | - |
| Mermaid Diagrams | [🎡🔗](https://chrome.google.com/webstore/detail/mermaid-diagrams/phfcghedmopjadpojhmmaffjmfiakfil) | - | - | - | - |
| Mermaid Markdown | [🎡🔗](https://chrome.google.com/webstore/detail/mermaid-markdown/mboeoikjijmjcjgpccghbcoegikliijg) | - | - | - | - |
| Monkeys | [🎡🔗](https://chrome.google.com/webstore/detail/monkeys-mermaid-for-githu/cplfdpoajbclbgphaphphcldamfkjlgi) | - | - | - | - |
| Mermaid Previewer | [🎡🔗](https://chrome.google.com/webstore/detail/mermaid-previewer/oidjnlhbegipkcklbdfnbkikplpghfdl) | - | - | - | - |

View File

@ -14,6 +14,9 @@ The class diagram is the main building block of object-oriented modeling. It is
Mermaid can render class diagrams.
```mermaid-example
---
title: Animal example
---
classDiagram
note "From Duck till Zebra"
Animal <|-- Duck
@ -40,6 +43,9 @@ classDiagram
```
```mermaid
---
title: Animal example
---
classDiagram
note "From Duck till Zebra"
Animal <|-- Duck
@ -77,6 +83,9 @@ A single instance of a class in the diagram contains three compartments:
- The bottom compartment contains the operations the class can execute. They are also left-aligned and the first letter is lowercase.
```mermaid-example
---
title: Bank example
---
classDiagram
class BankAccount
BankAccount : +String owner
@ -87,6 +96,9 @@ classDiagram
```
```mermaid
---
title: Bank example
---
classDiagram
class BankAccount
BankAccount : +String owner
@ -255,16 +267,16 @@ A relationship is a general term covering the specific types of logical connecti
There are eight different types of relations defined for classes under UML which are currently supported:
| Type | Description |
| ---- | ------------- | ----------- |
| < | -- | Inheritance |
| \*-- | Composition |
| o-- | Aggregation |
| --> | Association |
| -- | Link (Solid) |
| ..> | Dependency |
| .. | > | Realization |
| .. | Link (Dashed) |
| Type | Description |
| ------- | ------------- |
| `<\|--` | Inheritance |
| `\*--` | Composition |
| `o--` | Aggregation |
| `-->` | Association |
| `--` | Link (Solid) |
| `..>` | Dependency |
| `..\|>` | Realization |
| `..` | Link (Dashed) |
```mermaid-example
classDiagram
@ -360,14 +372,14 @@ Here is the syntax:
Where `Relation Type` can be one of:
| Type | Description |
| ---- | ----------- | ----------- |
| < | | Inheritance |
| \* | Composition |
| o | Aggregation |
| > | Association |
| < | Association |
| | > | Realization |
| Type | Description |
| ----- | ----------- |
| `<\|` | Inheritance |
| `\*` | Composition |
| `o` | Aggregation |
| `>` | Association |
| `<` | Association |
| `\|>` | Realization |
And `Link` can be one of:

View File

@ -13,6 +13,9 @@ Note that practitioners of ER modelling almost always refer to _entity types_ si
Mermaid can render ER diagrams
```mermaid-example
---
title: Order example
---
erDiagram
CUSTOMER ||--o{ ORDER : places
ORDER ||--|{ LINE-ITEM : contains
@ -20,6 +23,9 @@ erDiagram
```
```mermaid
---
title: Order example
---
erDiagram
CUSTOMER ||--o{ ORDER : places
ORDER ||--|{ LINE-ITEM : contains

View File

@ -8,9 +8,9 @@
This page contains a collection of examples of diagrams and charts that can be created through mermaid and its myriad applications.
**If you wish to learn how to support mermaid on your webpage, read the [Beginner's Guide](../config/usage?id=usage).**
**If you wish to learn how to support mermaid on your webpage, read the [Beginner's Guide](../config/usage.md?id=usage).**
**If you wish to learn about mermaid's syntax, Read the [Diagram Syntax](../syntax/flowchart?id=flowcharts-basic-syntax) section.**
**If you wish to learn about mermaid's syntax, Read the [Diagram Syntax](../syntax/flowchart.md?id=flowcharts-basic-syntax) section.**
## Basic Pie Chart

View File

@ -15,11 +15,17 @@ It can also accommodate different arrow types, multi directional arrows, and lin
### A node (default)
```mermaid-example
---
title: Node
---
flowchart LR
id
```
```mermaid
---
title: Node
---
flowchart LR
id
```
@ -33,11 +39,17 @@ found for the node that will be used. Also if you define edges for the node late
one previously defined will be used when rendering the box.
```mermaid-example
---
title: Node with text
---
flowchart LR
id1[This is the text in the box]
```
```mermaid
---
title: Node with text
---
flowchart LR
id1[This is the text in the box]
```

View File

@ -201,7 +201,7 @@ More info in: https://momentjs.com/docs/#/parsing/string-format/
### Output date format on the axis
The default output date format is YYYY-MM-DD. You can define your custom `axisFormat`, like `2020-Q1` for the first quarter of the year 2020.
The default output date format is `YYYY-MM-DD`. You can define your custom `axisFormat`, like `2020-Q1` for the first quarter of the year 2020.
axisFormat %Y-%m-%d
@ -232,7 +232,7 @@ The following formatting strings are supported:
%Z - time zone offset, such as "-0700".
%% - a literal "%" character.
More info in: https://github.com/mbostock/d3/wiki/Time-Formatting
More info in: <https://github.com/d3/d3-time-format/tree/v4.0.0#locale_format>
### Axis ticks
@ -357,7 +357,7 @@ To hide the marker, set `todayMarker` to `off`.
It is possible to adjust the margins for rendering the gantt diagram.
This is done by defining the `ganttConfig` part of the configuration object.
How to use the CLI is described in the [mermaidCLI](../config/mermaidCLI) page.
How to use the CLI is described in the [mermaidCLI](../config/mermaidCLI.md) page.
mermaid.ganttConfig can be set to a JSON string with config parameters or the corresponding object.

View File

@ -13,31 +13,37 @@ These kind of diagram are particularly helpful to developers and devops teams to
Mermaid can render Git diagrams
```mermaid-example
gitGraph
commit
commit
branch develop
checkout develop
commit
commit
checkout main
merge develop
commit
commit
---
title: Example Git diagram
---
gitGraph
commit
commit
branch develop
checkout develop
commit
commit
checkout main
merge develop
commit
commit
```
```mermaid
gitGraph
commit
commit
branch develop
checkout develop
commit
commit
checkout main
merge develop
commit
commit
---
title: Example Git diagram
---
gitGraph
commit
commit
branch develop
checkout develop
commit
commit
checkout main
merge develop
commit
commit
```
In Mermaid, we support the basic git operations like:

View File

@ -152,6 +152,18 @@ mindmap
id)I am a cloud(
```
### Hexagon
```mermaid-example
mindmap
id{{I am a hexagon}}
```
```mermaid
mindmap
id{{I am a hexagon}}
```
### Default
```mermaid-example

View File

@ -730,7 +730,7 @@ text.actor {
Is it possible to adjust the margins for rendering the sequence diagram.
This is done by defining `mermaid.sequenceConfig` or by the CLI to use a json file with the configuration.
How to use the CLI is described in the [mermaidCLI](../config/mermaidCLI) page.
How to use the CLI is described in the [mermaidCLI](../config/mermaidCLI.md) page.
`mermaid.sequenceConfig` can be set to a JSON string with config parameters or the corresponding object.
```javascript

View File

@ -11,6 +11,9 @@
Mermaid can render state diagrams. The syntax tries to be compliant with the syntax used in plantUml as this will make it easier for users to share diagrams between mermaid and plantUml.
```mermaid-example
---
title: Simple sample
---
stateDiagram-v2
[*] --> Still
Still --> [*]
@ -22,6 +25,9 @@ stateDiagram-v2
```
```mermaid
---
title: Simple sample
---
stateDiagram-v2
[*] --> Still
Still --> [*]

View File

@ -1,21 +1,10 @@
{
"name": "mermaid-monorepo",
"private": true,
"version": "9.2.0-rc2",
"version": "9.2.2",
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
"main": "dist/mermaid.core.mjs",
"module": "dist/mermaid.core.mjs",
"types": "dist/mermaid.d.ts",
"type": "module",
"packageManager": "pnpm@7.15.0",
"exports": {
".": {
"require": "./dist/mermaid.min.js",
"import": "./dist/mermaid.core.mjs",
"types": "./dist/mermaid.d.ts"
},
"./*": "./*"
},
"packageManager": "pnpm@7.17.0",
"keywords": [
"diagram",
"markdown",
@ -26,14 +15,17 @@
"git graph"
],
"scripts": {
"build:vite": "ts-node-esm --transpileOnly --project=.vite/tsconfig.json .vite/build.ts",
"build:types": "concurrently \"tsc -p ./packages/mermaid/tsconfig.json --emitDeclarationOnly\" \"tsc -p ./packages/mermaid-mindmap/tsconfig.json --emitDeclarationOnly\"",
"build:vite": "ts-node-esm --transpileOnly .vite/build.ts",
"build:mermaid": "pnpm build:vite --mermaid",
"build:viz": "pnpm build:mermaid --visualize",
"build:types": "tsc -p ./packages/mermaid/tsconfig.json --emitDeclarationOnly && tsc -p ./packages/mermaid-mindmap/tsconfig.json --emitDeclarationOnly",
"build:watch": "pnpm build:vite --watch",
"build": "pnpm run -r clean && concurrently \"pnpm build:vite\" \"pnpm build:types\"",
"dev": "concurrently \"pnpm build:vite --watch\" \"ts-node-esm .vite/server.ts\"",
"release": "pnpm build",
"lint": "eslint --cache --ignore-path .gitignore . && pnpm --filter mermaid run lint:jison && prettier --check .",
"lint": "eslint --cache --ignore-path .gitignore . && pnpm lint:jison && prettier --check .",
"lint:fix": "eslint --fix --ignore-path .gitignore . && prettier --write . && ts-node-esm scripts/fixCSpell.ts",
"lint:jison": "ts-node-esm ./scripts/jison/lint.mts",
"cypress": "cypress run",
"cypress:open": "cypress open",
"e2e": "start-server-and-test dev http://localhost:9000/ cypress",
@ -61,88 +53,63 @@
"page"
]
},
"dependencies": {
"@braintree/sanitize-url": "6.0.2",
"@types/node": "18.11.9",
"@types/uuid": "8.3.4",
"d3": "7.6.1",
"dagre": "0.8.5",
"dagre-d3": "0.6.4",
"dompurify": "2.4.1",
"fast-clone": "1.5.13",
"graphlib": "2.1.8",
"khroma": "2.0.0",
"lodash": "4.17.21",
"moment-mini": "2.29.4",
"non-layered-tidy-tree-layout": "2.0.2",
"rollup": "3.3.0",
"stylis": "4.1.3",
"uuid": "9.0.0"
},
"devDependencies": {
"@applitools/eyes-cypress": "3.27.6",
"@commitlint/cli": "17.2.0",
"@commitlint/config-conventional": "17.2.0",
"@cspell/eslint-plugin": "6.14.2",
"@types/d3": "7.4.0",
"@types/dompurify": "2.4.0",
"@types/eslint": "8.4.10",
"@types/express": "4.17.14",
"@types/jsdom": "20.0.1",
"@types/lodash": "4.14.188",
"@types/mdast": "3.0.10",
"@types/prettier": "2.7.1",
"@types/stylis": "4.0.2",
"@typescript-eslint/eslint-plugin": "5.42.1",
"@typescript-eslint/parser": "5.42.1",
"@vitest/coverage-c8": "0.25.1",
"@vitest/ui": "0.25.1",
"concurrently": "7.5.0",
"coveralls": "3.1.1",
"cypress": "10.11.0",
"cypress-image-snapshot": "4.0.1",
"esbuild": "0.15.13",
"eslint": "8.27.0",
"eslint-config-prettier": "8.5.0",
"eslint-plugin-cypress": "2.12.1",
"eslint-plugin-html": "7.1.0",
"eslint-plugin-jest": "27.1.5",
"eslint-plugin-jsdoc": "39.6.2",
"eslint-plugin-json": "3.1.0",
"eslint-plugin-markdown": "3.0.0",
"eslint-plugin-no-only-tests": "3.1.0",
"eslint-plugin-tsdoc": "0.2.17",
"express": "4.18.2",
"globby": "13.1.2",
"husky": "8.0.2",
"identity-obj-proxy": "3.0.0",
"jest": "29.3.1",
"jison": "0.4.18",
"jsdom": "20.0.2",
"lint-staged": "13.0.3",
"markdown-it": "13.0.1",
"path-browserify": "1.0.1",
"pnpm": "7.15.0",
"prettier": "2.7.1",
"prettier-plugin-jsdoc": "0.4.2",
"remark": "14.0.2",
"rimraf": "3.0.2",
"start-server-and-test": "1.14.0",
"ts-node": "10.9.1",
"typescript": "4.8.4",
"unist-util-flatmap": "1.0.0",
"vite": "3.2.3",
"vitepress": "1.0.0-alpha.28",
"vitepress-plugin-mermaid": "2.0.8",
"vitepress-plugin-search": "1.0.4-alpha.15",
"vitest": "0.25.1"
"@applitools/eyes-cypress": "^3.27.6",
"@commitlint/cli": "^17.2.0",
"@commitlint/config-conventional": "^17.2.0",
"@cspell/eslint-plugin": "^6.14.2",
"@types/eslint": "^8.4.10",
"@types/express": "^4.17.14",
"@types/jsdom": "^20.0.1",
"@types/js-yaml": "^4.0.5",
"@types/lodash": "^4.14.188",
"@types/mdast": "^3.0.10",
"@types/node": "^18.11.9",
"@types/prettier": "^2.7.1",
"@types/rollup-plugin-visualizer": "^4.2.1",
"@typescript-eslint/eslint-plugin": "^5.42.1",
"@typescript-eslint/parser": "^5.42.1",
"@vitest/coverage-c8": "^0.25.1",
"@vitest/ui": "^0.25.1",
"concurrently": "^7.5.0",
"coveralls": "^3.1.1",
"cypress": "^10.11.0",
"cypress-image-snapshot": "^4.0.1",
"esbuild": "^0.15.13",
"eslint": "^8.27.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-cypress": "^2.12.1",
"eslint-plugin-html": "^7.1.0",
"eslint-plugin-jest": "^27.1.5",
"eslint-plugin-jsdoc": "^39.6.2",
"eslint-plugin-json": "^3.1.0",
"eslint-plugin-markdown": "^3.0.0",
"eslint-plugin-no-only-tests": "^3.1.0",
"eslint-plugin-tsdoc": "^0.2.17",
"express": "^4.18.2",
"globby": "^13.1.2",
"husky": "^8.0.2",
"identity-obj-proxy": "^3.0.0",
"jest": "^29.3.1",
"jison": "^0.4.18",
"jsdom": "^20.0.2",
"js-yaml": "^4.1.0",
"lint-staged": "^13.0.3",
"path-browserify": "^1.0.1",
"pnpm": "^7.15.0",
"prettier": "^2.7.1",
"prettier-plugin-jsdoc": "^0.4.2",
"rimraf": "^3.0.2",
"rollup-plugin-visualizer": "^5.8.3",
"start-server-and-test": "^1.14.0",
"ts-node": "^10.9.1",
"typescript": "^4.8.4",
"vite": "^3.2.3",
"vitepress": "^1.0.0-alpha.28",
"vitepress-plugin-mermaid": "^2.0.8",
"vitepress-plugin-search": "^1.0.4-alpha.15",
"vitest": "^0.25.1"
},
"resolutions": {
"d3": "7.6.1"
},
"files": [
"dist"
],
"sideEffects": [
"**/*.css",
"**/*.scss"

View File

@ -0,0 +1,3 @@
### Do not refer this package. It is not ready.
### Refer mermaid-mindmap instead.

View File

@ -50,8 +50,8 @@
},
"dependencies": {},
"devDependencies": {
"concurrently": "7.5.0",
"rimraf": "3.0.2"
"concurrently": "^7.5.0",
"rimraf": "^3.0.2"
},
"resolutions": {
"d3": "^7.0.0"

View File

@ -12,3 +12,5 @@ export const diagram = {
styles,
injectUtils,
};
export { detector, id } from './detector';

View File

@ -1,5 +1,3 @@
import { darken, lighten, isDark } from 'khroma';
const genSections = (options) => {
let sections = '';

View File

@ -1,14 +1,14 @@
{
"name": "@mermaid-js/mermaid-mindmap",
"version": "9.2.0-rc2",
"version": "9.2.2",
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
"main": "dist/mermaid-mindmap.core.mjs",
"module": "dist/mermaid-mindmap.core.mjs",
"types": "dist/detector.d.ts",
"type": "module",
"exports": {
".": {
"require": "./dist/mermaid-mindmap.min.js",
"import": "./dist/mermaid-mindmap.core.mjs"
"import": "./dist/mermaid-mindmap.core.mjs",
"types": "./dist/detector.d.ts"
},
"./*": "./*"
},
@ -19,18 +19,7 @@
"mermaid"
],
"scripts": {
"clean": "rimraf dist",
"build:types": "tsc -p ./tsconfig.json --emitDeclarationOnly",
"build:watch": "yarn build:code --watch",
"build:esbuild": "concurrently \"yarn build:code\" \"yarn build:types\"",
"build": "yarn clean; yarn build:esbuild",
"dev": "node .esbuild/serve.cjs",
"release": "yarn build",
"lint": "eslint --cache --ignore-path .gitignore . && yarn lint:jison && prettier --check .",
"lint:fix": "eslint --fix --ignore-path .gitignore . && prettier --write .",
"lint:jison": "ts-node-esm src/jison/lint.mts",
"todo-prepare": "concurrently \"husky install ../../.husky\" \"yarn build\"",
"todo-pre-commit": "lint-staged"
"prepublishOnly": "pnpm -w run build"
},
"repository": {
"type": "git",
@ -54,11 +43,13 @@
"cytoscape-cose-bilkent": "^4.1.0",
"cytoscape-fcose": "^2.1.0",
"d3": "^7.0.0",
"khroma": "^2.0.0",
"non-layered-tidy-tree-layout": "^2.0.2"
},
"devDependencies": {
"concurrently": "7.5.0",
"rimraf": "3.0.2"
"concurrently": "^7.5.0",
"mermaid": "workspace:*",
"rimraf": "^3.0.2"
},
"resolutions": {
"d3": "^7.0.0"

View File

@ -1,10 +1,20 @@
export const id = 'mindmap';
import type { ExternalDiagramDefinition } from 'mermaid';
export const detector = (txt: string) => {
const id = 'mindmap';
const detector = (txt: string) => {
return txt.match(/^\s*mindmap/) !== null;
};
export const loadDiagram = async () => {
const loader = async () => {
const { diagram } = await import('./diagram-definition');
return { id, diagram };
};
const plugin: ExternalDiagramDefinition = {
id,
detector,
loader,
};
export default plugin;

View File

@ -172,6 +172,18 @@ root
expect(mm.children.length).toEqual(0);
expect(mm.type).toEqual(mindmap.yy.nodeType.BANG);
});
it('MMP-12-a mutiple types (hexagon)', function () {
let str = `mindmap
root{{the root}}
`;
mindmap.parse(str);
const mm = mindmap.yy.getMindmap();
expect(mm.type).toEqual(mindmap.yy.nodeType.HEXAGON);
expect(mm.descr).toEqual('the root');
expect(mm.children.length).toEqual(0);
});
});
describe('decorations', function () {
it('MMP-13 should be possible to set an icon for the node', function () {

View File

@ -42,6 +42,9 @@ export const addNode = (level, id, descr, type) => {
case nodeType.RECT:
node.padding = 2 * conf.mindmap.padding;
break;
case nodeType.HEXAGON:
node.padding = 2 * conf.mindmap.padding;
break;
default:
node.padding = conf.mindmap.padding;
}
@ -79,6 +82,7 @@ export const nodeType = {
CIRCLE: 3,
CLOUD: 4,
BANG: 5,
HEXAGON: 6,
};
export const getType = (startStr, endStr) => {
@ -94,6 +98,8 @@ export const getType = (startStr, endStr) => {
return nodeType.CLOUD;
case '))':
return nodeType.BANG;
case '{{':
return nodeType.HEXAGON;
default:
return nodeType.DEFAULT;
}
@ -127,6 +133,8 @@ export const type2Str = (type) => {
return 'cloud';
case nodeType.BANG:
return 'bang';
case nodeType.HEXAGON:
return 'hexgon';
default:
return 'no-border';
}

View File

@ -25,11 +25,6 @@ function drawNodes(svg, mindmap, section, conf) {
}
/**
* @param edgesElem
* @param mindmap
* @param parent
* @param depth
* @param section
* @param edgesEl
* @param cy
*/
@ -51,11 +46,9 @@ function drawEdges(edgesEl, cy) {
}
/**
* @param {any} svg The svg element to draw the diagram onto
* @param {object} mindmap The mindmap data and hierarchy
* @param section
* @param mindmap The mindmap data and hierarchy
* @param cy
* @param {object} conf The configuration object
* @param conf The configuration object
* @param level
*/
function addNodes(mindmap, cy, conf, level) {
@ -99,10 +92,6 @@ function addNodes(mindmap, cy, conf, level) {
*/
function layoutMindmap(node, conf) {
return new Promise((resolve) => {
if (node.children.length === 0) {
return node;
}
// Add temporary render element
const renderEl = select('body').append('div').attr('id', 'cy').attr('style', 'display:none');
const cy = cytoscape({

View File

@ -33,11 +33,12 @@
"))" { yy.getLogger().trace('Explosion Bang'); this.begin('NODE');return 'NODE_DSTART'; }
")" { yy.getLogger().trace('Cloud Bang'); this.begin('NODE');return 'NODE_DSTART'; }
"((" { this.begin('NODE');return 'NODE_DSTART'; }
"{{" { this.begin('NODE');return 'NODE_DSTART'; }
"(" { this.begin('NODE');return 'NODE_DSTART'; }
"[" { this.begin('NODE');return 'NODE_DSTART'; }
[\s]+ return 'SPACELIST' /* skip all whitespace */ ;
// !(-\() return 'NODE_ID';
[^\(\[\n\-\)]+ return 'NODE_ID';
[^\(\[\n\-\)\{\}]+ return 'NODE_ID';
<<EOF>> return 'EOF';
<NODE>["] { yy.getLogger().trace('Starting NSTR');this.begin("NSTR");}
<NSTR>[^"]+ { yy.getLogger().trace('description:', yytext); return "NODE_DESCR";}
@ -45,11 +46,12 @@
<NODE>[\)]\) {this.popState();yy.getLogger().trace('node end ))');return "NODE_DEND";}
<NODE>[\)] {this.popState();yy.getLogger().trace('node end )');return "NODE_DEND";}
<NODE>[\]] {this.popState();yy.getLogger().trace('node end ...',yytext);return "NODE_DEND";}
<NODE>"}}" {this.popState();yy.getLogger().trace('node end ((');return "NODE_DEND";}
<NODE>"(-" {this.popState();yy.getLogger().trace('node end (-');return "NODE_DEND";}
<NODE>"-)" {this.popState();yy.getLogger().trace('node end (-');return "NODE_DEND";}
<NODE>"((" {this.popState();yy.getLogger().trace('node end ((');return "NODE_DEND";}
<NODE>"(" {this.popState();yy.getLogger().trace('node end ((');return "NODE_DEND";}
<NODE>[^\)\]\(]+ { yy.getLogger().trace('Long description:', yytext); return 'NODE_DESCR';}
<NODE>"(" {this.popState();yy.getLogger().trace('node end ((');return "NODE_DEND";}
<NODE>[^\)\]\(\}]+ { yy.getLogger().trace('Long description:', yytext); return 'NODE_DESCR';}
<NODE>.+(?!\(\() { yy.getLogger().trace('Long description:', yytext); return 'NODE_DESCR';}
// [\[] return 'NODE_START';
// .+ return 'TXT' ;

View File

@ -17,7 +17,7 @@ const genSections = (options) => {
sections += `
.section-${i - 1} rect, .section-${i - 1} path, .section-${i - 1} circle, .section-${
i - 1
} path {
} polygon, .section-${i - 1} path {
fill: ${options['cScale' + i]};
}
.section-${i - 1} text {
@ -55,7 +55,7 @@ const getStyles = (options) =>
stroke-width: 3;
}
${genSections(options)}
.section-root rect, .section-root path, .section-root circle {
.section-root rect, .section-root path, .section-root circle, .section-root polygon {
fill: ${options.git0};
}
.section-root text {

View File

@ -145,6 +145,45 @@ const circleBkg = function (elem, node) {
.attr('class', 'node-bkg node-' + db.type2Str(node.type))
.attr('r', node.width / 2);
};
/**
*
* @param parent
* @param w
* @param h
* @param points
* @param node
*/
function insertPolygonShape(parent, w, h, points, node) {
return parent
.insert('polygon', ':first-child')
.attr(
'points',
points
.map(function (d) {
return d.x + ',' + d.y;
})
.join(' ')
)
.attr('transform', 'translate(' + (node.width - w) / 2 + ', ' + h + ')');
}
const hexagonBkg = function (elem, node) {
const h = node.height;
const f = 4;
const m = h / f;
const w = node.width - node.padding + 2 * m;
const points = [
{ x: m, y: 0 },
{ x: w - m, y: 0 },
{ x: w, y: -h / 2 },
{ x: w - m, y: -h },
{ x: m, y: -h },
{ x: 0, y: -h / 2 },
];
const shapeSvg = insertPolygonShape(elem, w, h, points, node);
};
const roundedRectBkg = function (elem, node) {
elem
.append('rect')
@ -159,7 +198,6 @@ const roundedRectBkg = function (elem, node) {
/**
* @param {object} elem The D3 dom element in which the node is to be added
* @param {object} node The node to be added
* @param section
* @param fullSection
* @param {object} conf The configuration object
* @returns {number} The height nodes dom element
@ -253,6 +291,9 @@ export const drawNode = function (elem, node, fullSection, conf) {
case db.nodeType.BANG:
bangBkg(bkgElem, node, section, conf);
break;
case db.nodeType.HEXAGON:
hexagonBkg(bkgElem, node, section, conf);
break;
}
// Position the node to its coordinate

View File

@ -1,5 +1,6 @@
{
"src/docs/**": ["pnpm --filter mermaid run docs:build --git"],
"src/docs.mts": ["pnpm --filter mermaid run docs:build --git"],
"src/(defaultConfig|config|mermaidAPI).ts": ["pnpm --filter mermaid run docs:build --git"],
"*.jison": ["pnpm run lint:jison"]
}

346
packages/mermaid/README.md Normal file
View File

@ -0,0 +1,346 @@
# mermaid
[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![npm minified gzipped bundle size](https://img.shields.io/bundlephobia/minzip/mermaid)](https://bundlephobia.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
English | [简体中文](./README.zh-CN.md)
<img src="./img/header.png" alt="" />
:trophy: **Mermaid was nominated and won the [JS Open Source Awards (2019)](https://osawards.com/javascript/2019) in the category "The most exciting use of technology"!!!**
**Thanks to all involved, people committing pull requests, people answering questions! 🙏**
<a href="https://mermaid-js.github.io/mermaid/landing/"><img src="https://github.com/mermaid-js/mermaid/blob/master/docs/img/book-banner-post-release.jpg" alt="Explore Mermaid.js in depth, with real-world examples, tips & tricks from the creator... The first official book on Mermaid is available for purchase. Check it out!"></a>
## About
<!-- <Main description> -->
Mermaid is a JavaScript-based diagramming and charting tool that uses Markdown-inspired text definitions and a renderer to create and modify complex diagrams. The main purpose of Mermaid is to help documentation catch up with development.
> Doc-Rot is a Catch-22 that Mermaid helps to solve.
Diagramming and documentation costs precious developer time and gets outdated quickly.
But not having diagrams or docs ruins productivity and hurts organizational learning.<br/>
Mermaid addresses this problem by enabling users to create easily modifiable diagrams. It can also be made part of production scripts (and other pieces of code).<br/>
<br/>
Mermaid allows even non-programmers to easily create detailed diagrams through the [Mermaid Live Editor](https://mermaid.live/).<br/>
[Tutorials](./docs/Tutorials.md) has video tutorials.
Use Mermaid with your favorite applications, check out the list of [Integrations and Usages of Mermaid](./docs/integrations.md).
You can also use Mermaid within [GitHub](https://github.blog/2022-02-14-include-diagrams-markdown-files-mermaid/) as well many of your other favorite applications—check out the list of [Integrations and Usages of Mermaid](./docs/integrations.md).
For a more detailed introduction to Mermaid and some of its more basic uses, look to the [Beginner's Guide](./docs/n00b-overview.md), [Usage](./docs/usage.md) and [Tutorials](./docs/Tutorials.md).
🌐 [CDN](https://unpkg.com/mermaid/) | 📖 [Documentation](https://mermaidjs.github.io) | 🙌 [Contribution](https://github.com/mermaid-js/mermaid/blob/develop/CONTRIBUTING.md) | 📜 [Changelog](./docs/CHANGELOG.md)
In our release process we rely heavily on visual regression tests using [applitools](https://applitools.com/). Applitools is a great service which has been easy to use and integrate with our tests.
<a href="https://applitools.com/">
<svg width="170" height="32" viewBox="0 0 170 32" fill="none" xmlns="http://www.w3.org/2000/svg"><mask id="a" maskUnits="userSpaceOnUse" x="27" y="0" width="143" height="32"><path fill-rule="evenodd" clip-rule="evenodd" d="M27.732.227h141.391v31.19H27.733V.227z" fill="#fff"></path></mask><g mask="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M153.851 22.562l1.971-3.298c1.291 1.219 3.837 2.402 5.988 2.402 1.971 0 2.903-.753 2.903-1.829 0-2.832-10.253-.502-10.253-7.313 0-2.904 2.51-5.45 7.099-5.45 2.904 0 5.234 1.004 6.955 2.367l-1.829 3.226c-1.039-1.075-3.011-2.008-5.126-2.008-1.65 0-2.725.717-2.725 1.685 0 2.546 10.289.395 10.289 7.386 0 3.19-2.724 5.52-7.528 5.52-3.012 0-5.916-1.003-7.744-2.688zm-5.7 2.259h4.553V.908h-4.553v23.913zm-6.273-8.676c0-2.689-1.578-5.02-4.446-5.02-2.832 0-4.409 2.331-4.409 5.02 0 2.724 1.577 5.055 4.409 5.055 2.868 0 4.446-2.33 4.446-5.055zm-13.588 0c0-4.912 3.442-9.07 9.142-9.07 5.736 0 9.178 4.158 9.178 9.07 0 4.911-3.442 9.106-9.178 9.106-5.7 0-9.142-4.195-9.142-9.106zm-5.628 0c0-2.689-1.577-5.02-4.445-5.02-2.832 0-4.41 2.331-4.41 5.02 0 2.724 1.578 5.055 4.41 5.055 2.868 0 4.445-2.33 4.445-5.055zm-13.587 0c0-4.912 3.441-9.07 9.142-9.07 5.736 0 9.178 4.158 9.178 9.07 0 4.911-3.442 9.106-9.178 9.106-5.701 0-9.142-4.195-9.142-9.106zm-8.425 4.338v-8.999h-2.868v-3.98h2.868V2.773h4.553v4.733h3.514v3.979h-3.514v7.78c0 1.111.574 1.936 1.578 1.936.681 0 1.326-.251 1.577-.538l.968 3.478c-.681.609-1.9 1.11-3.8 1.11-3.191 0-4.876-1.648-4.876-4.767zm-8.962 4.338h4.553V7.505h-4.553V24.82zm-.43-21.905a2.685 2.685 0 012.688-2.69c1.506 0 2.725 1.184 2.725 2.69a2.724 2.724 0 01-2.725 2.724c-1.47 0-2.688-1.219-2.688-2.724zM84.482 24.82h4.553V.908h-4.553v23.913zm-6.165-8.676c0-2.976-1.793-5.02-4.41-5.02-1.47 0-3.119.825-3.908 1.973v6.094c.753 1.111 2.438 2.008 3.908 2.008 2.617 0 4.41-2.044 4.41-5.055zm-8.318 6.453v8.82h-4.553V7.504H70v2.187c1.327-1.685 3.227-2.618 5.342-2.618 4.446 0 7.672 3.299 7.672 9.07 0 5.773-3.226 9.107-7.672 9.107-2.043 0-3.907-.86-5.342-2.653zm-10.718-6.453c0-2.976-1.793-5.02-4.41-5.02-1.47 0-3.119.825-3.908 1.973v6.094c.753 1.111 2.438 2.008 3.908 2.008 2.617 0 4.41-2.044 4.41-5.055zm-8.318 6.453v8.82H46.41V7.504h4.553v2.187c1.327-1.685 3.227-2.618 5.342-2.618 4.446 0 7.672 3.299 7.672 9.07 0 5.773-3.226 9.107-7.672 9.107-2.043 0-3.908-.86-5.342-2.653zm-11.758-1.936V18.51c-.753-1.004-2.187-1.542-3.657-1.542-1.793 0-3.263.968-3.263 2.617 0 1.65 1.47 2.582 3.263 2.582 1.47 0 2.904-.502 3.657-1.506zm0 4.159v-1.829c-1.183 1.434-3.227 2.259-5.485 2.259-2.761 0-5.988-1.864-5.988-5.736 0-4.087 3.227-5.593 5.988-5.593 2.33 0 4.337.753 5.485 2.115V13.85c0-1.756-1.506-2.904-3.8-2.904-1.829 0-3.55.717-4.984 2.044L28.63 9.8c2.115-1.901 4.84-2.726 7.564-2.726 3.98 0 7.6 1.578 7.6 6.561v11.186h-4.588z" fill="#00A298"></path></g><path fill-rule="evenodd" clip-rule="evenodd" d="M14.934 16.177c0 1.287-.136 2.541-.391 3.752-1.666-1.039-3.87-2.288-6.777-3.752 2.907-1.465 5.11-2.714 6.777-3.753.255 1.211.39 2.466.39 3.753m4.6-7.666V4.486a78.064 78.064 0 01-4.336 3.567c-1.551-2.367-3.533-4.038-6.14-5.207C11.1 4.658 12.504 6.7 13.564 9.262 5.35 15.155 0 16.177 0 16.177s5.35 1.021 13.564 6.915c-1.06 2.563-2.463 4.603-4.507 6.415 2.607-1.169 4.589-2.84 6.14-5.207a77.978 77.978 0 014.336 3.568v-4.025s-.492-.82-2.846-2.492c.6-1.611.93-3.354.93-5.174a14.8 14.8 0 00-.93-5.174c2.354-1.673 2.846-2.492 2.846-2.492" fill="#00A298"></path></svg>
</a>
<!-- </Main description> -->
## Examples
**The following are some examples of the diagrams, charts and graphs that can be made using Mermaid. Click here to jump into the [text syntax](https://mermaid-js.github.io/mermaid/#/n00b-syntaxReference).**
<!-- <Flowchart> -->
### Flowchart [<a href="https://mermaid-js.github.io/mermaid/#/flowchart">docs</a> - <a href="https://mermaid.live/edit#pako:eNpNkMtqwzAQRX9FzKqFJK7t1km8KDQP6KJQSLOLvZhIY1tgS0GWmgbb_165IaFaiXvOFTPqgGtBkEJR6zOv0Fj2scsU8-ft8I5G5Gw6fe339GN7tnrYaafE45WvRsLW3Ya4bKVWwzVe_xU-FfVsc9hR62rLwvw_2591z7Y3FuUwgYZMg1L4ObrRzMBW1FAGqb8KKtCLGWRq8Ko7CbS0FdJqA2mBdUsTQGf110VxSK1xdJM2EkuDzd2qNQrypQ7s5TQuXcrW-ie5VoUsx9yZ2seVtac2DYIRz0ppK3eccd0ErRTjD1XfyyRIomSBUUzJPMaXOBb8GC4XRfQcFmL-FEYIwzD8AggvcHE">live editor</a>]
```
flowchart LR
A[Hard] -->|Text| B(Round)
B --> C{Decision}
C -->|One| D[Result 1]
C -->|Two| E[Result 2]
```
```mermaid
flowchart LR
A[Hard] -->|Text| B(Round)
B --> C{Decision}
C -->|One| D[Result 1]
C -->|Two| E[Result 2]
```
### Sequence diagram [<a href="https://mermaid-js.github.io/mermaid/#/sequenceDiagram">docs</a> - <a href="https://mermaid.live/edit#pako:eNo9kMluwjAQhl_F-AykQMuSA1WrbuLQQ3v1ZbAnsVXHkzrjVhHi3etQwKfRv4w-z0FqMihL2eF3wqDxyUEdoVHhwTuNk-12RzaU4g29JzHMY2HpV0BE0VO6V8ETtdkGz1Zb1F8qiPyG5LX84mrLAmpwoWNh-5a0pWCiAxUwGBXeiVHEU4oq8V_6AHYUwAu2lLLTjVQ4bc1rT2yleI0IfJG320faZ9ABbk-Jz3hZnFxBduR9L2oiM5Jj2WBswJn8-cMArSRbbFDJMo8GK0ielVThmKOpNcD4bBxTlGUFvsOxhMT02QctS44JL6HzAS-iJzCYOwfJfTscunYd542aQuXqQU_RZ9kyt11ZFIM9rR3btJ9qaorOGQuR7c9mWSznyzXMF7hcLeBusTB6P9usq_ntrDKrm9kc5PF4_AMJE56Z">live editor</a>]
```
sequenceDiagram
Alice->>John: Hello John, how are you?
loop Healthcheck
John->>John: Fight against hypochondria
end
Note right of John: Rational thoughts!
John-->>Alice: Great!
John->>Bob: How about you?
Bob-->>John: Jolly good!
```
```mermaid
sequenceDiagram
Alice->>John: Hello John, how are you?
loop Healthcheck
John->>John: Fight against hypochondria
end
Note right of John: Rational thoughts!
John-->>Alice: Great!
John->>Bob: How about you?
Bob-->>John: Jolly good!
```
### Gantt chart [<a href="https://mermaid-js.github.io/mermaid/#/gantt">docs</a> - <a href="https://mermaid.live/edit#pako:eNp90cGOgyAQBuBXIZxtFbG29bbZ3fsmvXKZylhJEAyOTZrGd1_sto3xsHMBhu-HBO689hp5xS_giJQbsCbjHTv9jcp9-q63SKhZpb3DhMXSOIiE5ZkoNpnYZGXynh6U-4jBK7JnVfBYJo9QvgjtEya1cj8QwFq0TMz4lZqxTBg0hOF5m1jifI2Lf7Bc490CyxUu1rhc4GLGPOEdhg6Mjq92V44xxanFDhWv4lRjA6MlxZWbIh17DYTf2pAPvGrADphwGMmfbq7mFYURX-jLwCVA91bWg8YYunO69Y8vMgPFI2vvGnOZ-2Owsd0S9UOVpvP29mKoHc_b2nfpYHQLgdrrsUzLvDxALrHcS9hJqeuzOB6avBCN3mciBz5N0y_wxZ0J">live editor</a>]
```
gantt
section Section
Completed :done, des1, 2014-01-06,2014-01-08
Active :active, des2, 2014-01-07, 3d
Parallel 1 : des3, after des1, 1d
Parallel 2 : des4, after des1, 1d
Parallel 3 : des5, after des3, 1d
Parallel 4 : des6, after des4, 1d
```
```mermaid
gantt
section Section
Completed :done, des1, 2014-01-06,2014-01-08
Active :active, des2, 2014-01-07, 3d
Parallel 1 : des3, after des1, 1d
Parallel 2 : des4, after des1, 1d
Parallel 3 : des5, after des3, 1d
Parallel 4 : des6, after des4, 1d
```
### Class diagram [<a href="https://mermaid-js.github.io/mermaid/#/classDiagram">docs</a> - <a href="https://mermaid.live/edit#pako:eNpdkTFPwzAQhf-K5QlQ2zQJJG1UBaGWDYmBgYEwXO1LYuTEwXYqlZL_jt02asXm--690zvfgTLFkWaUSTBmI6DS0BTt2lfzkKx-p1PytEO9f1FtdaQkI2ulZNGuVqK1qEtgmOfk7BitSzKdOhg59XuNGgk0RDxed-_IOr6uf8cZ6UhTZ8bvHqS5ub1mr9svZPbjk6DEBlu7AQuXyBkx4gcvDk9cUMJq0XT_YaW0kNK5j-ufAoRzcihaQvLcoN4Jv50vvVxw_xrnD3RCG9QNCO4-8OgpqK1dpoJm7smxhF7agp6kfcfB4jMXVmmalW4tnFDorXrbt4xmVvc4is53GKFUwNF5DtTuO3-sShjrJjLVlqLyvNfS4drazmRB4NuzSti6386YagIjeA3a1rtlEiRRsoAoxiSN4SGOOduGy0UZ3YclT-dhBHQYhj8dc6_I">live editor</a>]
```
classDiagram
Class01 <|-- AveryLongClass : Cool
<<Interface>> Class01
Class09 --> C2 : Where am I?
Class09 --* C3
Class09 --|> Class07
Class07 : equals()
Class07 : Object[] elementData
Class01 : size()
Class01 : int chimp
Class01 : int gorilla
class Class10 {
<<service>>
int id
size()
}
```
```mermaid
classDiagram
Class01 <|-- AveryLongClass : Cool
<<Interface>> Class01
Class09 --> C2 : Where am I?
Class09 --* C3
Class09 --|> Class07
Class07 : equals()
Class07 : Object[] elementData
Class01 : size()
Class01 : int chimp
Class01 : int gorilla
class Class10 {
<<service>>
int id
size()
}
```
### State diagram [<a href="https://mermaid-js.github.io/mermaid/#/stateDiagram">docs</a> - <a href="https://mermaid.live/edit#pako:eNpdkEFvgzAMhf8K8nEqpYSNthx22Xbcqcexg0sCiZQQlDhIFeK_L8A6TfXp6fOz9ewJGssFVOAJSbwr7ByadGR1n8T6evpO0vQ1uZDSekOrXGFsPqJPO6q-2-imH8f_0TeHXm50lfelsAMjnEHFY6xpMdRAUhhRQxUlFy0GTTXU_RytYeAx-AdXZB1ULWovdoCB7OXWN1CRC-Ju-r3uz6UtchGHJqDbsPygU57iysb2reoWHpyOWBINvsqypb3vFMlw3TfWZF5xiY7keC6zkpUnZIUojwW-FAVvrvn51LLnvOXHQ84Q5nn-AVtLcwk">live editor</a>]
```
stateDiagram-v2
[*] --> Still
Still --> [*]
Still --> Moving
Moving --> Still
Moving --> Crash
Crash --> [*]
```
```mermaid
stateDiagram-v2
[*] --> Still
Still --> [*]
Still --> Moving
Moving --> Still
Moving --> Crash
Crash --> [*]
```
### Pie chart [<a href="https://mermaid-js.github.io/mermaid/#/pie">docs</a> - <a href="https://mermaid.live/edit#pako:eNo9jsFugzAMhl8F-VzBgEEh13Uv0F1zcYkTIpEEBadShXj3BU3dzf_n77e8wxQUgYDVkvQSbsFsEgpRtEN_5i_kvzx05XiC-xvUHVzAUXRoVe7v0heFBJ7JkQSRR0Ua08ISpD-ymlaFTN_KcoggNC4bXQATh5-Xn0BwTPSWbhZNRPdvLQEV5dIO_FrPZ43dOJ-cgtfWnDzFJeOZed1EVZ3r0lie06Ocgqs2q2aMPD_HvuqbfsCmpf7aYte2anrU46Cbz1qr60fdIBzH8QvW9lkl">live editor</a>]
```
pie
"Dogs" : 386
"Cats" : 85.9
"Rats" : 15
```
```mermaid
pie
"Dogs" : 386
"Cats" : 85.9
"Rats" : 15
```
### Git graph [experimental - <a href="https://mermaid.live/edit#pako:eNqNkMFugzAMhl8F-VyVAR1tOW_aA-zKxSSGRCMJCk6lCvHuNZPKZdM0n-zf3_8r8QIqaIIGMqnB8kfEybQ--y4VnLP8-9RF9Mpkmm40hmlnDKmvkPiH_kfS7nFo_VN0FAf6XwocQGgxa_nGsm1bYEOOWmik1dRjGrmF1q-Cpkkj07u2HCI0PY4zHQATh8-7V9BwTPSE3iwOEd1OjQE1iWkBvk_bzQY7s0Sq4Hs7bHqKo8iGeZqbPN_WR7mpSd1RHpvPVhuMbG7XOq_L-oJlRfW5wteq0qorrpe-PBW9Pr8UJcK6rg-BLYPQ">live editor</a>]
### User Journey diagram [<a href="https://mermaid-js.github.io/mermaid/#/user-journey">docs</a> - <a href="https://mermaid.live/edit#pako:eNplkMFuwjAQRH9l5TMiTVIC-FqqnjhxzWWJN4khsSN7XRSh_HsdKBVt97R6Mzsj-yoqq0hIAXCywRkaSwNxWHNHsB_hYt1ZmwYUfiueKtbWwIcFtjf5zgH2eCZgQgkrCXt64GgMg2fUzkvIn5Xd_V5COtMFvCH_62ht_5yk7MU8sn61HDTfxD8VYiF6cj1qFd94nWkpuKWYKWRcFdUYOi5FaaZoDYNCpnel2Toha-w8LQQGtofRVEKyC_Qw7TQ2DvsfV2dRUTy6Ch6H-UMb7TlGVtbUupl5cF3ELfPgZZLM8rLR3IbjsrJ94rVq0XH7uS2SIis2mOVUrHNc5bmqjul2U2evaa3WL2mGYpqmL2BGiho">live editor</a>]
```
journey
title My working day
section Go to work
Make tea: 5: Me
Go upstairs: 3: Me
Do work: 1: Me, Cat
section Go home
Go downstairs: 5: Me
Sit down: 3: Me
```
```mermaid
journey
title My working day
section Go to work
Make tea: 5: Me
Go upstairs: 3: Me
Do work: 1: Me, Cat
section Go home
Go downstairs: 5: Me
Sit down: 3: Me
```
### C4 diagram [<a href="https://mermaid-js.github.io/mermaid/#/c4c">docs</a>]
```
C4Context
title System Context diagram for Internet Banking System
Person(customerA, "Banking Customer A", "A customer of the bank, with personal bank accounts.")
Person(customerB, "Banking Customer B")
Person_Ext(customerC, "Banking Customer C")
System(SystemAA, "Internet Banking System", "Allows customers to view information about their bank accounts, and make payments.")
Person(customerD, "Banking Customer D", "A customer of the bank, <br/> with personal bank accounts.")
Enterprise_Boundary(b1, "BankBoundary") {
SystemDb_Ext(SystemE, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transactions, etc.")
System_Boundary(b2, "BankBoundary2") {
System(SystemA, "Banking System A")
System(SystemB, "Banking System B", "A system of the bank, with personal bank accounts.")
}
System_Ext(SystemC, "E-mail system", "The internal Microsoft Exchange e-mail system.")
SystemDb(SystemD, "Banking System D Database", "A system of the bank, with personal bank accounts.")
Boundary(b3, "BankBoundary3", "boundary") {
SystemQueue(SystemF, "Banking System F Queue", "A system of the bank, with personal bank accounts.")
SystemQueue_Ext(SystemG, "Banking System G Queue", "A system of the bank, with personal bank accounts.")
}
}
BiRel(customerA, SystemAA, "Uses")
BiRel(SystemAA, SystemE, "Uses")
Rel(SystemAA, SystemC, "Sends e-mails", "SMTP")
Rel(SystemC, customerA, "Sends e-mails to")
```
```mermaid
C4Context
title System Context diagram for Internet Banking System
Person(customerA, "Banking Customer A", "A customer of the bank, with personal bank accounts.")
Person(customerB, "Banking Customer B")
Person_Ext(customerC, "Banking Customer C")
System(SystemAA, "Internet Banking System", "Allows customers to view information about their bank accounts, and make payments.")
Person(customerD, "Banking Customer D", "A customer of the bank, <br/> with personal bank accounts.")
Enterprise_Boundary(b1, "BankBoundary") {
SystemDb_Ext(SystemE, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transactions, etc.")
System_Boundary(b2, "BankBoundary2") {
System(SystemA, "Banking System A")
System(SystemB, "Banking System B", "A system of the bank, with personal bank accounts.")
}
System_Ext(SystemC, "E-mail system", "The internal Microsoft Exchange e-mail system.")
SystemDb(SystemD, "Banking System D Database", "A system of the bank, with personal bank accounts.")
Boundary(b3, "BankBoundary3", "boundary") {
SystemQueue(SystemF, "Banking System F Queue", "A system of the bank, with personal bank accounts.")
SystemQueue_Ext(SystemG, "Banking System G Queue", "A system of the bank, with personal bank accounts.")
}
}
BiRel(customerA, SystemAA, "Uses")
BiRel(SystemAA, SystemE, "Uses")
Rel(SystemAA, SystemC, "Sends e-mails", "SMTP")
Rel(SystemC, customerA, "Sends e-mails to")
```
## Release
For those who have the permission to do so:
Update version number in `package.json`.
```sh
npm publish
```
The above command generates files into the `dist` folder and publishes them to npmjs.org.
## Related projects
- [Command Line Interface](https://github.com/mermaid-js/mermaid-cli)
- [Live Editor](https://github.com/mermaid-js/mermaid-live-editor)
- [HTTP Server](https://github.com/TomWright/mermaid-server)
## Contributors [![Good first issue](https://img.shields.io/github/labels/mermaid-js/mermaid/Good%20first%20issue%21)](https://github.com/mermaid-js/mermaid/issues?q=is%3Aissue+is%3Aopen+label%3A%22Good+first+issue%21%22) [![Contributors](https://img.shields.io/github/contributors/mermaid-js/mermaid)](https://github.com/mermaid-js/mermaid/graphs/contributors) [![Commits](https://img.shields.io/github/commit-activity/m/mermaid-js/mermaid)](https://github.com/mermaid-js/mermaid/graphs/contributors)
Mermaid is a growing community and is always accepting new contributors. There's a lot of different ways to help out and we're always looking for extra hands! Look at [this issue](https://github.com/mermaid-js/mermaid/issues/866) if you want to know where to start helping out.
Detailed information about how to contribute can be found in the [contribution guide](CONTRIBUTING.md)
## Security and safe diagrams
For public sites, it can be precarious to retrieve text from users on the internet, storing that content for presentation in a browser at a later stage. The reason is that the user content can contain embedded malicious scripts that will run when the data is presented. For Mermaid this is a risk, specially as mermaid diagrams contain many characters that are used in html which makes the standard sanitation unusable as it also breaks the diagrams. We still make an effort to sanitise the incoming code and keep refining the process but it is hard to guarantee that there are no loop holes.
As an extra level of security for sites with external users we are happy to introduce a new security level in which the diagram is rendered in a sandboxed iframe preventing javascript in the code from being executed. This is a great step forward for better security.
_Unfortunately you can not have a cake and eat it at the same time which in this case means that some of the interactive functionality gets blocked along with the possible malicious code._
## Reporting vulnerabilities
To report a vulnerability, please e-mail security@mermaid.live with a description of the issue, the steps you took to create the issue, affected versions, and if known, mitigations for the issue.
## Appreciation
A quick note from Knut Sveidqvist:
> _Many thanks to the [d3](https://d3js.org/) and [dagre-d3](https://github.com/cpettitt/dagre-d3) projects for providing the graphical layout and drawing libraries!_ >_Thanks also to the [js-sequence-diagram](https://bramp.github.io/js-sequence-diagrams) project for usage of the grammar for the sequence diagrams. Thanks to Jessica Peter for inspiration and starting point for gantt rendering._ >_Thank you to [Tyler Long](https://github.com/tylerlong) who has been a collaborator since April 2017._
>
> _Thank you to the ever-growing list of [contributors](https://github.com/knsv/mermaid/graphs/contributors) that brought the project this far!_
---
_Mermaid was created by Knut Sveidqvist for easier documentation._

View File

@ -0,0 +1,334 @@
# mermaid
[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![npm minified gzipped bundle size](https://img.shields.io/bundlephobia/minzip/mermaid)](https://bundlephobia.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
[English](./README.md) | 简体中文
<img src="./img/header.png" alt="" />
:trophy: **Mermaid 被提名并获得了 [JS Open Source Awards (2019)](https://osawards.com/javascript/2019) 的 "The most exciting use of technology" 奖项!!!**
**感谢所有参与进来提交 PR解答疑问的人们! 🙏**
<a href="https://mermaid-js.github.io/mermaid/landing/"><img src="https://github.com/mermaid-js/mermaid/blob/master/docs/img/book-banner-pre-release.jpg" alt="Explore Mermaid.js in depth, with real-world examples, tips & tricks from the creator... The first official book on Mermaid is available for purchase. Check it out!"></a>
## 关于 Mermaid
<!-- <Main description> -->
Mermaid 是一个基于 Javascript 的图表绘制工具,通过解析类 Markdown 的文本语法来实现图表的创建和动态修改。Mermaid 诞生的主要目的是让文档的更新能够及时跟上开发进度。
> Doc-Rot 是 Mermaid 致力于解决的一个难题。
绘图和编写文档花费了开发者宝贵的开发时间,而且随着业务的变更,它很快就会过期。 但是如果缺少了图表或文档,对于生产力和团队新人的业务学习都会产生巨大的阻碍。 <br/>
Mermaid 通过允许用户创建便于修改的图表来解决这一难题,它也可以作为生产脚本(或其他代码)的一部分。<br/>
<br/>
Mermaid 甚至能让非程序员也能通过 [Mermaid Live Editor](https://mermaid.live/) 轻松创建详细的图表。<br/>
你可以访问 [教程](./docs/Tutorials.md) 来查看 Live Editor 的视频教程,也可以查看 [Mermaid 的集成和使用](./docs/integrations.md) 这个清单来检查你的文档工具是否已经集成了 Mermaid 支持。
如果想要查看关于 Mermaid 更详细的介绍及基础使用方式,可以查看 [入门指引](./docs/n00b-overview.md), [用法](./docs/usage.md) 和 [教程](./docs/Tutorials.md).
🌐 [CDN](https://unpkg.com/mermaid/) | 📖 [文档](https://mermaidjs.github.io) | 🙌 [贡献](https://github.com/mermaid-js/mermaid/blob/develop/CONTRIBUTING.md) | 📜 [更新日志](./docs/CHANGELOG.md)
<!-- </Main description> -->
## 示例
**下面是一些可以使用 Mermaid 创建的图表示例。点击 [语法](https://mermaid-js.github.io/mermaid/#/n00b-syntaxReference) 查看详情。**
<table>
<!-- <Flowchart> -->
### 流程图 [<a href="https://mermaid-js.github.io/mermaid/#/flowchart">文档</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ3JhcGggVERcbiAgICBBW0hhcmRdIC0tPnxUZXh0fCBCKFJvdW5kKVxuICAgIEIgLS0-IEN7RGVjaXNpb259XG4gICAgQyAtLT58T25lfCBEW1Jlc3VsdCAxXVxuICAgIEMgLS0-fFR3b3wgRVtSZXN1bHQgMl0iLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9fQ">live editor</a>]
```
flowchart LR
A[Hard] -->|Text| B(Round)
B --> C{Decision}
C -->|One| D[Result 1]
C -->|Two| E[Result 2]
```
```mermaid
flowchart LR
A[Hard] -->|Text| B(Round)
B --> C{Decision}
C -->|One| D[Result 1]
C -->|Two| E[Result 2]
```
### 时序图 [<a href="https://mermaid-js.github.io/mermaid/#/sequenceDiagram">文档</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoic2VxdWVuY2VEaWFncmFtXG5BbGljZS0-PkpvaG46IEhlbGxvIEpvaG4sIGhvdyBhcmUgeW91P1xubG9vcCBIZWFsdGhjaGVja1xuICAgIEpvaG4tPj5Kb2huOiBGaWdodCBhZ2FpbnN0IGh5cG9jaG9uZHJpYVxuZW5kXG5Ob3RlIHJpZ2h0IG9mIEpvaG46IFJhdGlvbmFsIHRob3VnaHRzIVxuSm9obi0tPj5BbGljZTogR3JlYXQhXG5Kb2huLT4-Qm9iOiBIb3cgYWJvdXQgeW91P1xuQm9iLS0-PkpvaG46IEpvbGx5IGdvb2QhIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0">live editor</a>]
```
sequenceDiagram
Alice->>John: Hello John, how are you?
loop Healthcheck
John->>John: Fight against hypochondria
end
Note right of John: Rational thoughts!
John-->>Alice: Great!
John->>Bob: How about you?
Bob-->>John: Jolly good!
```
```mermaid
sequenceDiagram
Alice->>John: Hello John, how are you?
loop Healthcheck
John->>John: Fight against hypochondria
end
Note right of John: Rational thoughts!
John-->>Alice: Great!
John->>Bob: How about you?
Bob-->>John: Jolly good!
```
### 甘特图 [<a href="https://mermaid-js.github.io/mermaid/#/gantt">文档</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ2FudHRcbnNlY3Rpb24gU2VjdGlvblxuQ29tcGxldGVkIDpkb25lLCAgICBkZXMxLCAyMDE0LTAxLTA2LDIwMTQtMDEtMDhcbkFjdGl2ZSAgICAgICAgOmFjdGl2ZSwgIGRlczIsIDIwMTQtMDEtMDcsIDNkXG5QYXJhbGxlbCAxICAgOiAgICAgICAgIGRlczMsIGFmdGVyIGRlczEsIDFkXG5QYXJhbGxlbCAyICAgOiAgICAgICAgIGRlczQsIGFmdGVyIGRlczEsIDFkXG5QYXJhbGxlbCAzICAgOiAgICAgICAgIGRlczUsIGFmdGVyIGRlczMsIDFkXG5QYXJhbGxlbCA0ICAgOiAgICAgICAgIGRlczYsIGFmdGVyIGRlczQsIDFkIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0">live editor</a>]
```
gantt
section Section
Completed :done, des1, 2014-01-06,2014-01-08
Active :active, des2, 2014-01-07, 3d
Parallel 1 : des3, after des1, 1d
Parallel 2 : des4, after des1, 1d
Parallel 3 : des5, after des3, 1d
Parallel 4 : des6, after des4, 1d
```
```mermaid
gantt
section Section
Completed :done, des1, 2014-01-06,2014-01-08
Active :active, des2, 2014-01-07, 3d
Parallel 1 : des3, after des1, 1d
Parallel 2 : des4, after des1, 1d
Parallel 3 : des5, after des3, 1d
Parallel 4 : des6, after des4, 1d
```
### 类图 [<a href="https://mermaid-js.github.io/mermaid/#/classDiagram">文档</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiY2xhc3NEaWFncmFtXG5DbGFzczAxIDx8LS0gQXZlcnlMb25nQ2xhc3MgOiBDb29sXG48PGludGVyZmFjZT4-IENsYXNzMDFcbkNsYXNzMDkgLS0-IEMyIDogV2hlcmUgYW0gaT9cbkNsYXNzMDkgLS0qIEMzXG5DbGFzczA5IC0tfD4gQ2xhc3MwN1xuQ2xhc3MwNyA6IGVxdWFscygpXG5DbGFzczA3IDogT2JqZWN0W10gZWxlbWVudERhdGFcbkNsYXNzMDEgOiBzaXplKClcbkNsYXNzMDEgOiBpbnQgY2hpbXBcbkNsYXNzMDEgOiBpbnQgZ29yaWxsYVxuY2xhc3MgQ2xhc3MxMCB7XG4gID4-c2VydmljZT4-XG4gIGludCBpZFxuICBzaXplKClcbn0iLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9fQ">live editor</a>]
```
classDiagram
Class01 <|-- AveryLongClass : Cool
<<Interface>> Class01
Class09 --> C2 : Where am I?
Class09 --* C3
Class09 --|> Class07
Class07 : equals()
Class07 : Object[] elementData
Class01 : size()
Class01 : int chimp
Class01 : int gorilla
class Class10 {
<<service>>
int id
size()
}
```
```mermaid
classDiagram
Class01 <|-- AveryLongClass : Cool
<<Interface>> Class01
Class09 --> C2 : Where am I?
Class09 --* C3
Class09 --|> Class07
Class07 : equals()
Class07 : Object[] elementData
Class01 : size()
Class01 : int chimp
Class01 : int gorilla
class Class10 {
<<service>>
int id
size()
}
```
### 状态图 [[<a href="https://mermaid-js.github.io/mermaid/#/stateDiagram">docs</a> - <a href="https://mermaid.live/#/edit/eyJjb2RlIjoic3RhdGVEaWFncmFtLXYyXG4gICAgWypdIC0tPiBTdGlsbFxuICAgIFN0aWxsIC0tPiBbKl1cbiAgICBTdGlsbCAtLT4gTW92aW5nXG4gICAgTW92aW5nIC0tPiBTdGlsbFxuICAgIE1vdmluZyAtLT4gQ3Jhc2hcbiAgICBDcmFzaCAtLT4gWypdIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQiLCJ0aGVtZVZhcmlhYmxlcyI6eyJiYWNrZ3JvdW5kIjoid2hpdGUiLCJwcmltYXJ5Q29sb3IiOiIjRUNFQ0ZGIiwic2Vjb25kYXJ5Q29sb3IiOiIjZmZmZmRlIiwidGVydGlhcnlDb2xvciI6ImhzbCg4MCwgMTAwJSwgOTYuMjc0NTA5ODAzOSUpIiwicHJpbWFyeUJvcmRlckNvbG9yIjoiaHNsKDI0MCwgNjAlLCA4Ni4yNzQ1MDk4MDM5JSkiLCJzZWNvbmRhcnlCb3JkZXJDb2xvciI6ImhzbCg2MCwgNjAlLCA4My41Mjk0MTE3NjQ3JSkiLCJ0ZXJ0aWFyeUJvcmRlckNvbG9yIjoiaHNsKDgwLCA2MCUsIDg2LjI3NDUwOTgwMzklKSIsInByaW1hcnlUZXh0Q29sb3IiOiIjMTMxMzAwIiwic2Vjb25kYXJ5VGV4dENvbG9yIjoiIzAwMDAyMSIsInRlcnRpYXJ5VGV4dENvbG9yIjoicmdiKDkuNTAwMDAwMDAwMSwgOS41MDAwMDAwMDAxLCA5LjUwMDAwMDAwMDEpIiwibGluZUNvbG9yIjoiIzMzMzMzMyIsInRleHRDb2xvciI6IiMzMzMiLCJtYWluQmtnIjoiI0VDRUNGRiIsInNlY29uZEJrZyI6IiNmZmZmZGUiLCJib3JkZXIxIjoiIzkzNzBEQiIsImJvcmRlcjIiOiIjYWFhYTMzIiwiYXJyb3doZWFkQ29sb3IiOiIjMzMzMzMzIiwiZm9udEZhbWlseSI6IlwidHJlYnVjaGV0IG1zXCIsIHZlcmRhbmEsIGFyaWFsIiwiZm9udFNpemUiOiIxNnB4IiwibGFiZWxCYWNrZ3JvdW5kIjoiI2U4ZThlOCIsIm5vZGVCa2ciOiIjRUNFQ0ZGIiwibm9kZUJvcmRlciI6IiM5MzcwREIiLCJjbHVzdGVyQmtnIjoiI2ZmZmZkZSIsImNsdXN0ZXJCb3JkZXIiOiIjYWFhYTMzIiwiZGVmYXVsdExpbmtDb2xvciI6IiMzMzMzMzMiLCJ0aXRsZUNvbG9yIjoiIzMzMyIsImVkZ2VMYWJlbEJhY2tncm91bmQiOiIjZThlOGU4IiwiYWN0b3JCb3JkZXIiOiJoc2woMjU5LjYyNjE2ODIyNDMsIDU5Ljc3NjUzNjMxMjglLCA4Ny45MDE5NjA3ODQzJSkiLCJhY3RvckJrZyI6IiNFQ0VDRkYiLCJhY3RvclRleHRDb2xvciI6ImJsYWNrIiwiYWN0b3JMaW5lQ29sb3IiOiJncmV5Iiwic2lnbmFsQ29sb3IiOiIjMzMzIiwic2lnbmFsVGV4dENvbG9yIjoiIzMzMyIsImxhYmVsQm94QmtnQ29sb3IiOiIjRUNFQ0ZGIiwibGFiZWxCb3hCb3JkZXJDb2xvciI6ImhzbCgyNTkuNjI2MTY4MjI0MywgNTkuNzc2NTM2MzEyOCUsIDg3LjkwMTk2MDc4NDMlKSIsImxhYmVsVGV4dENvbG9yIjoiYmxhY2siLCJsb29wVGV4dENvbG9yIjoiYmxhY2siLCJub3RlQm9yZGVyQ29sb3IiOiIjYWFhYTMzIiwibm90ZUJrZ0NvbG9yIjoiI2ZmZjVhZCIsIm5vdGVUZXh0Q29sb3IiOiJibGFjayIsImFjdGl2YXRpb25Cb3JkZXJDb2xvciI6IiM2NjYiLCJhY3RpdmF0aW9uQmtnQ29sb3IiOiIjZjRmNGY0Iiwic2VxdWVuY2VOdW1iZXJDb2xvciI6IndoaXRlIiwic2VjdGlvbkJrZ0NvbG9yIjoicmdiYSgxMDIsIDEwMiwgMjU1LCAwLjQ5KSIsImFsdFNlY3Rpb25Ca2dDb2xvciI6IndoaXRlIiwic2VjdGlvbkJrZ0NvbG9yMiI6IiNmZmY0MDAiLCJ0YXNrQm9yZGVyQ29sb3IiOiIjNTM0ZmJjIiwidGFza0JrZ0NvbG9yIjoiIzhhOTBkZCIsInRhc2tUZXh0TGlnaHRDb2xvciI6IndoaXRlIiwidGFza1RleHRDb2xvciI6IndoaXRlIiwidGFza1RleHREYXJrQ29sb3IiOiJibGFjayIsInRhc2tUZXh0T3V0c2lkZUNvbG9yIjoiYmxhY2siLCJ0YXNrVGV4dENsaWNrYWJsZUNvbG9yIjoiIzAwMzE2MyIsImFjdGl2ZVRhc2tCb3JkZXJDb2xvciI6IiM1MzRmYmMiLCJhY3RpdmVUYXNrQmtnQ29sb3IiOiIjYmZjN2ZmIiwiZ3JpZENvbG9yIjoibGlnaHRncmV5IiwiZG9uZVRhc2tCa2dDb2xvciI6ImxpZ2h0Z3JleSIsImRvbmVUYXNrQm9yZGVyQ29sb3IiOiJncmV5IiwiY3JpdEJvcmRlckNvbG9yIjoiI2ZmODg4OCIsImNyaXRCa2dDb2xvciI6InJlZCIsInRvZGF5TGluZUNvbG9yIjoicmVkIiwibGFiZWxDb2xvciI6ImJsYWNrIiwiZXJyb3JCa2dDb2xvciI6IiM1NTIyMjIiLCJlcnJvclRleHRDb2xvciI6IiM1NTIyMjIiLCJjbGFzc1RleHQiOiIjMTMxMzAwIiwiZmlsbFR5cGUwIjoiI0VDRUNGRiIsImZpbGxUeXBlMSI6IiNmZmZmZGUiLCJmaWxsVHlwZTIiOiJoc2woMzA0LCAxMDAlLCA5Ni4yNzQ1MDk4MDM5JSkiLCJmaWxsVHlwZTMiOiJoc2woMTI0LCAxMDAlLCA5My41Mjk0MTE3NjQ3JSkiLCJmaWxsVHlwZTQiOiJoc2woMTc2LCAxMDAlLCA5Ni4yNzQ1MDk4MDM5JSkiLCJmaWxsVHlwZTUiOiJoc2woLTQsIDEwMCUsIDkzLjUyOTQxMTc2NDclKSIsImZpbGxUeXBlNiI6ImhzbCg4LCAxMDAlLCA5Ni4yNzQ1MDk4MDM5JSkiLCJmaWxsVHlwZTciOiJoc2woMTg4LCAxMDAlLCA5My41Mjk0MTE3NjQ3JSkifX0sInVwZGF0ZUVkaXRvciI6ZmFsc2V9">live editor</a>]
```
stateDiagram-v2
[*] --> Still
Still --> [*]
Still --> Moving
Moving --> Still
Moving --> Crash
Crash --> [*]
```
```mermaid
stateDiagram-v2
[*] --> Still
Still --> [*]
Still --> Moving
Moving --> Still
Moving --> Crash
Crash --> [*]
```
### 饼图 [<a href="https://mermaid-js.github.io/mermaid/#/pie">文档</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoicGllXG5cIkRvZ3NcIiA6IDQyLjk2XG5cIkNhdHNcIiA6IDUwLjA1XG5cIlJhdHNcIiA6IDEwLjAxIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0">live editor</a>]
```
pie
"Dogs" : 386
"Cats" : 85
"Rats" : 15
```
```mermaid
pie
"Dogs" : 386
"Cats" : 85
"Rats" : 15
```
### Git 图 [实验特性 - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ2l0R3JhcGg6XG5vcHRpb25zXG57XG4gICAgXCJub2RlU3BhY2luZ1wiOiAxNTAsXG4gICAgXCJub2RlUmFkaXVzXCI6IDEwXG59XG5lbmRcbmNvbW1pdFxuYnJhbmNoIG5ld2JyYW5jaFxuY2hlY2tvdXQgbmV3YnJhbmNoXG5jb21taXRcbmNvbW1pdFxuY2hlY2tvdXQgbWFzdGVyXG5jb21taXRcbmNvbW1pdFxubWVyZ2UgbmV3YnJhbmNoXG4iLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9fQ">live editor</a>]
### 用户体验旅程图 [<a href="https://mermaid-js.github.io/mermaid/#/user-journey">文档</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoic3RhdGVEaWFncmFtXG4gICAgWypdIC0tPiBTdGlsbFxuICAgIFN0aWxsIC0tPiBbKl1cbiAgICBTdGlsbCAtLT4gTW92aW5nXG4gICAgTW92aW5nIC0tPiBTdGlsbFxuICAgIE1vdmluZyAtLT4gQ3Jhc2hcbiAgICBDcmFzaCAtLT4gWypdIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0">live editor</a>]
```
journey
title My working day
section Go to work
Make tea: 5: Me
Go upstairs: 3: Me
Do work: 1: Me, Cat
section Go home
Go downstairs: 5: Me
Sit down: 3: Me
```
```mermaid
journey
title My working day
section Go to work
Make tea: 5: Me
Go upstairs: 3: Me
Do work: 1: Me, Cat
section Go home
Go downstairs: 5: Me
Sit down: 3: Me
```
### C4 图 [<a href="https://mermaid-js.github.io/mermaid/#/c4c">文档</a>]
```
C4Context
title System Context diagram for Internet Banking System
Person(customerA, "Banking Customer A", "A customer of the bank, with personal bank accounts.")
Person(customerB, "Banking Customer B")
Person_Ext(customerC, "Banking Customer C")
System(SystemAA, "Internet Banking System", "Allows customers to view information about their bank accounts, and make payments.")
Person(customerD, "Banking Customer D", "A customer of the bank, <br/> with personal bank accounts.")
Enterprise_Boundary(b1, "BankBoundary") {
SystemDb_Ext(SystemE, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transactions, etc.")
System_Boundary(b2, "BankBoundary2") {
System(SystemA, "Banking System A")
System(SystemB, "Banking System B", "A system of the bank, with personal bank accounts.")
}
System_Ext(SystemC, "E-mail system", "The internal Microsoft Exchange e-mail system.")
SystemDb(SystemD, "Banking System D Database", "A system of the bank, with personal bank accounts.")
Boundary(b3, "BankBoundary3", "boundary") {
SystemQueue(SystemF, "Banking System F Queue", "A system of the bank, with personal bank accounts.")
SystemQueue_Ext(SystemG, "Banking System G Queue", "A system of the bank, with personal bank accounts.")
}
}
BiRel(customerA, SystemAA, "Uses")
BiRel(SystemAA, SystemE, "Uses")
Rel(SystemAA, SystemC, "Sends e-mails", "SMTP")
Rel(SystemC, customerA, "Sends e-mails to")
```
```mermaid
C4Context
title System Context diagram for Internet Banking System
Person(customerA, "Banking Customer A", "A customer of the bank, with personal bank accounts.")
Person(customerB, "Banking Customer B")
Person_Ext(customerC, "Banking Customer C")
System(SystemAA, "Internet Banking System", "Allows customers to view information about their bank accounts, and make payments.")
Person(customerD, "Banking Customer D", "A customer of the bank, <br/> with personal bank accounts.")
Enterprise_Boundary(b1, "BankBoundary") {
SystemDb_Ext(SystemE, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transactions, etc.")
System_Boundary(b2, "BankBoundary2") {
System(SystemA, "Banking System A")
System(SystemB, "Banking System B", "A system of the bank, with personal bank accounts.")
}
System_Ext(SystemC, "E-mail system", "The internal Microsoft Exchange e-mail system.")
SystemDb(SystemD, "Banking System D Database", "A system of the bank, with personal bank accounts.")
Boundary(b3, "BankBoundary3", "boundary") {
SystemQueue(SystemF, "Banking System F Queue", "A system of the bank, with personal bank accounts.")
SystemQueue_Ext(SystemG, "Banking System G Queue", "A system of the bank, with personal bank accounts.")
}
}
BiRel(customerA, SystemAA, "Uses")
BiRel(SystemAA, SystemE, "Uses")
Rel(SystemAA, SystemC, "Sends e-mails", "SMTP")
Rel(SystemC, customerA, "Sends e-mails to")
```
## 发布
对于有权限的同学来说,你可以通过以下步骤来完成发布操作:
更新 `package.json` 中的版本号,然后执行如下命令:
```sh
npm publish
```
以上的命令会将文件打包到 `dist` 目录并发布至 npmjs.org.
## 相关项目
- [Command Line Interface](https://github.com/mermaid-js/mermaid-cli)
- [Live Editor](https://github.com/mermaid-js/mermaid-live-editor)
- [HTTP Server](https://github.com/TomWright/mermaid-server)
## 贡献者 [![Good first issue](https://img.shields.io/github/labels/mermaid-js/mermaid/Good%20first%20issue%21)](https://github.com/mermaid-js/mermaid/issues?q=is%3Aissue+is%3Aopen+label%3A%22Good+first+issue%21%22) [![Contributors](https://img.shields.io/github/contributors/mermaid-js/mermaid)](https://github.com/mermaid-js/mermaid/graphs/contributors) [![Commits](https://img.shields.io/github/commit-activity/m/mermaid-js/mermaid)](https://github.com/mermaid-js/mermaid/graphs/contributors)
Mermaid 是一个不断发展中的社区,并且还在接收新的贡献者。有很多不同的方式可以参与进来,而且我们还在寻找额外的帮助。如果你想知道如何开始贡献,请查看 [这个 issue](https://github.com/mermaid-js/mermaid/issues/866)。
关于如何贡献的详细信息可以在 [贡献指南](CONTRIBUTING.md) 中找到。
## 安全
对于公开网站来说,从互联网上的用户处检索文本、存储供后续在浏览器中展示的内容可能是不安全的,理由是用户的内容可能嵌入一些数据加载完成之后就会运行的恶意脚本,这些对于 Mermaid 来说毫无疑问是一个风险,尤其是 mermaid 图表还包含了许多在 html 中使用的字符,这意味着我们难以使用常规的手段来过滤不安全代码,因为这些常规手段会造成图表损坏。我们仍然在努力对获取到的代码进行安全过滤并不断完善我们的程序,但很难保证没有漏洞。
作为拥有外部用户的网站的额外安全级别,我们很高兴推出一个新的安全级别,其中的图表在沙盒 iframe 中渲染,防止代码中的 javascript 被执行,这是在安全性方面迈出的一大步。
_很不幸的是鱼与熊掌不可兼得在这个场景下它意味着在可能的恶意代码被阻止时也会损失部分交互能力_。
## 报告漏洞
如果想要报告漏洞,请发送邮件到 security@mermaid.live, 并附上问题的描述、复现问题的步骤、受影响的版本,以及解决问题的方案(如果有的话)。
## 鸣谢
来自 Knut Sveidqvist:
> _特别感谢 [d3](https://d3js.org/) 和 [dagre-d3](https://github.com/cpettitt/dagre-d3) 这两个优秀的项目,它们提供了图形布局和绘图工具库! _ >_同样感谢 [js-sequence-diagram](https://bramp.github.io/js-sequence-diagrams) 提供了时序图语法的使用。 感谢 Jessica Peter 提供了甘特图渲染的灵感。_ >_感谢 [Tyler Long](https://github.com/tylerlong) 从 2017 年四月开始成为了项目的合作者。_
>
> _感谢越来越多的 [贡献者们](https://github.com/knsv/mermaid/graphs/contributors)没有你们就没有这个项目的今天_
---
_Mermaid 是由 Knut Sveidqvist 创建它为了更简单的文档编写而生。_

View File

@ -1,11 +1,11 @@
{
"name": "mermaid",
"version": "9.2.0-rc2",
"version": "9.2.2",
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
"main": "./dist/mermaid.core.mjs",
"main": "./dist/mermaid.min.js",
"module": "./dist/mermaid.core.mjs",
"types": "./dist/mermaid.d.ts",
"type": "module",
"type": "commonjs",
"exports": {
".": {
"require": "./dist/mermaid.min.js",
@ -25,12 +25,6 @@
],
"scripts": {
"clean": "rimraf dist",
"build:code": "node .esbuild/esbuild.cjs",
"build:types": "tsc -p ./tsconfig.json --emitDeclarationOnly",
"build:watch": "pnpm build:code --watch",
"build:esbuild": "concurrently \"pnpm build:code\" \"pnpm build:types\"",
"build": "pnpm clean; pnpm build:esbuild",
"dev": "node .esbuild/serve.cjs",
"docs:code": "typedoc src/defaultConfig.ts src/config.ts src/mermaidAPI.ts && prettier --write ./src/docs/config/setup",
"docs:build": "rimraf ../../docs && pnpm docs:code && ts-node-esm src/docs.mts",
"docs:verify": "pnpm docs:code && ts-node-esm src/docs.mts --verify",
@ -39,14 +33,7 @@
"docs:dev": "pnpm docs:pre:vitepress && concurrently \"vitepress dev src/vitepress\" \"ts-node-esm src/docs.mts --watch --vitepress\"",
"docs:serve": "pnpm docs:build:vitepress && vitepress serve src/vitepress",
"release": "pnpm build",
"lint": "eslint --cache --ignore-path .gitignore . && pnpm lint:jison && prettier --check .",
"lint:fix": "eslint --fix --ignore-path .gitignore . && prettier --write .",
"lint:jison": "ts-node-esm src/jison/lint.mts",
"cypress": "cypress run",
"cypress:open": "cypress open",
"e2e": "start-server-and-test dev http://localhost:9000/ cypress",
"todo-prepare": "concurrently \"husky install\" \"pnpm build\"",
"pre-commit": "lint-staged"
"prepublishOnly": "pnpm -w run build"
},
"repository": {
"type": "git",
@ -67,8 +54,7 @@
"dependencies": {
"@braintree/sanitize-url": "^6.0.0",
"d3": "^7.0.0",
"dagre": "^0.8.5",
"dagre-d3": "^0.6.4",
"dagre-d3-es": "7.0.2",
"dompurify": "2.4.1",
"fast-clone": "^1.5.13",
"graphlib": "^2.1.8",
@ -76,66 +62,43 @@
"lodash": "^4.17.21",
"moment-mini": "^2.24.0",
"non-layered-tidy-tree-layout": "^2.0.2",
"stylis": "^4.1.2"
"stylis": "^4.1.2",
"uuid": "^9.0.0"
},
"devDependencies": {
"@applitools/eyes-cypress": "3.27.6",
"@commitlint/cli": "17.2.0",
"@commitlint/config-conventional": "17.2.0",
"@types/d3": "7.4.0",
"@types/dompurify": "2.4.0",
"@types/eslint": "8.4.10",
"@types/express": "4.17.14",
"@types/jsdom": "20.0.1",
"@types/lodash": "4.14.188",
"@types/micromatch": "4.0.2",
"@types/prettier": "2.7.1",
"@types/stylis": "4.0.2",
"@typescript-eslint/eslint-plugin": "5.42.1",
"@typescript-eslint/parser": "5.42.1",
"chokidar": "3.5.3",
"concurrently": "7.5.0",
"coveralls": "3.1.1",
"cypress": "10.11.0",
"cypress-image-snapshot": "4.0.1",
"documentation": "13.2.5",
"esbuild": "0.15.13",
"eslint": "8.27.0",
"eslint-config-prettier": "8.5.0",
"eslint-plugin-cypress": "2.12.1",
"eslint-plugin-html": "7.1.0",
"eslint-plugin-jest": "27.1.5",
"eslint-plugin-jsdoc": "39.6.2",
"eslint-plugin-json": "3.1.0",
"eslint-plugin-markdown": "3.0.0",
"express": "4.18.2",
"globby": "13.1.2",
"husky": "8.0.2",
"identity-obj-proxy": "3.0.0",
"jison": "0.4.18",
"js-base64": "3.7.2",
"jsdom": "20.0.2",
"lint-staged": "13.0.3",
"@types/d3": "^7.4.0",
"@types/dompurify": "^2.4.0",
"@types/jsdom": "^20.0.1",
"@types/lodash": "^4.14.188",
"@types/micromatch": "^4.0.2",
"@types/prettier": "^2.7.1",
"@types/stylis": "^4.0.2",
"@types/uuid": "^8.3.4",
"@typescript-eslint/eslint-plugin": "^5.42.1",
"@typescript-eslint/parser": "^5.42.1",
"chokidar": "^3.5.3",
"concurrently": "^7.5.0",
"coveralls": "^3.1.1",
"globby": "^13.1.2",
"identity-obj-proxy": "^3.0.0",
"jison": "^0.4.18",
"js-base64": "^3.7.2",
"jsdom": "^20.0.2",
"micromatch": "^4.0.5",
"moment": "2.29.4",
"path-browserify": "1.0.1",
"prettier": "2.7.1",
"prettier-plugin-jsdoc": "0.4.2",
"remark": "14.0.2",
"rimraf": "3.0.2",
"shiki": "^0.11.1",
"start-server-and-test": "1.14.0",
"ts-node": "10.9.1",
"moment": "^2.29.4",
"path-browserify": "^1.0.1",
"prettier": "^2.7.1",
"remark": "^14.0.2",
"rimraf": "^3.0.2",
"start-server-and-test": "^1.14.0",
"typedoc": "^0.23.18",
"typedoc-plugin-markdown": "^3.13.6",
"typescript": "4.8.4",
"unist-util-flatmap": "1.0.0"
},
"resolutions": {
"d3": "^7.0.0"
"typescript": "^4.8.4",
"unist-util-flatmap": "^1.0.0"
},
"files": [
"dist"
"dist",
"README.md"
],
"sideEffects": [
"**/*.css",

View File

@ -2,6 +2,7 @@ import * as configApi from './config';
import { log } from './logger';
import { getDiagram, registerDiagram } from './diagram-api/diagramAPI';
import { detectType, getDiagramLoader } from './diagram-api/detectType';
import { extractFrontMatter } from './diagram-api/frontmatter';
import { isDetailedError, type DetailedError } from './utils';
export type ParseErrorFunction = (err: string | DetailedError, hash?: any) => void;
@ -29,6 +30,16 @@ export class Diagram {
this.db.clear?.();
this.renderer = diagram.renderer;
this.parser = diagram.parser;
const originalParse = this.parser.parse.bind(this.parser);
// Wrap the jison parse() method to handle extracting frontmatter.
//
// This can't be done in this.parse() because some code
// directly calls diagram.parser.parse(), bypassing this.parse().
//
// Similarly, we can't do this in getDiagramFromText() because some code
// calls diagram.db.clear(), which would reset anything set by
// extractFrontMatter().
this.parser.parse = (text: string) => originalParse(extractFrontMatter(text, this.db));
this.parser.parser.yy = this.db;
if (diagram.init) {
diagram.init(cnf);
@ -45,7 +56,7 @@ export class Diagram {
}
try {
text = text + '\n';
this.db.clear();
this.db.clear?.();
this.parser.parse(text);
return true;
} catch (error) {
@ -83,27 +94,30 @@ export class Diagram {
}
}
export const getDiagramFromText = async (
export const getDiagramFromText = (
txt: string,
parseError?: ParseErrorFunction
): Promise<Diagram> => {
): Diagram | Promise<Diagram> => {
const type = detectType(txt, configApi.getConfig());
try {
// Trying to find the diagram
getDiagram(type);
return new Diagram(txt, parseError);
} catch (error) {
const loader = getDiagramLoader(type);
if (!loader) {
throw new Error(`Diagram ${type} not found.`);
}
// Diagram not available, loading it
const { diagram } = await loader();
registerDiagram(type, diagram, undefined, diagram.injectUtils);
// new diagram will try getDiagram again and if fails then it is a valid throw
// TODO: Uncomment for v10
// // Diagram not available, loading it
// const { diagram } = await loader();
// registerDiagram(type, diagram, undefined, diagram.injectUtils);
// // new diagram will try getDiagram again and if fails then it is a valid throw
return loader().then(({ diagram }) => {
registerDiagram(type, diagram, undefined);
return new Diagram(txt, parseError);
});
}
// If either of the above worked, we have the diagram
// logic and can continue
return new Diagram(txt, parseError);
};
export default Diagram;

View File

@ -21,6 +21,7 @@ function parse(text: string, parseError?: ParseErrorFunction): boolean {
// original version cannot be modified since it was frozen with `Object.freeze()`
export const mermaidAPI = {
render: vi.fn(),
renderAsync: vi.fn(),
parse,
parseDirective: vi.fn(),
initialize: vi.fn(),

View File

@ -40,7 +40,8 @@ export const updateCurrentConfig = (siteCfg: MermaidConfig, _directives: any[])
}
currentConfig = cfg;
return cfg;
checkConfig(currentConfig);
return currentConfig;
};
/**
@ -68,7 +69,7 @@ export const setSiteConfig = (conf: MermaidConfig): MermaidConfig => {
siteConfig.themeVariables = theme[conf.theme].getThemeVariables(conf.themeVariables);
}
currentConfig = updateCurrentConfig(siteConfig, directives);
updateCurrentConfig(siteConfig, directives);
return siteConfig;
};
@ -117,6 +118,7 @@ export const setConfig = (conf: MermaidConfig): MermaidConfig => {
// conf[key] = manipulator ? manipulator(conf[key]) : conf[key];
// });
checkConfig(conf);
assignWithDepth(currentConfig, conf);
return getConfig();
@ -225,3 +227,25 @@ export const reset = (config = siteConfig): void => {
directives = [];
updateCurrentConfig(config, directives);
};
enum ConfigWarning {
'LAZY_LOAD_DEPRECATED' = 'The configuration options lazyLoadedDiagrams and loadExternalDiagramsAtStartup are deprecated. Please use registerExternalDiagrams instead.',
}
type ConfigWarningStrings = keyof typeof ConfigWarning;
const issuedWarnings: { [key in ConfigWarningStrings]?: boolean } = {};
const issueWarning = (warning: ConfigWarningStrings) => {
if (issuedWarnings[warning]) {
return;
}
log.warn(ConfigWarning[warning]);
issuedWarnings[warning] = true;
};
const checkConfig = (config: MermaidConfig) => {
if (!config) {
return;
}
if (config.lazyLoadedDiagrams || config.loadExternalDiagramsAtStartup) {
issueWarning('LAZY_LOAD_DEPRECATED');
}
};

View File

@ -3,7 +3,10 @@
import DOMPurify from 'dompurify';
export interface MermaidConfig {
/** @deprecated use mermaid.registerLazyDiagrams instead */
lazyLoadedDiagrams?: string[];
/** @deprecated use mermaid.registerLazyDiagrams instead */
loadExternalDiagramsAtStartup?: boolean;
theme?: string;
themeVariables?: any;
themeCSS?: string;
@ -186,6 +189,7 @@ export interface C4DiagramConfig extends BaseDiagramConfig {
}
export interface GitGraphDiagramConfig extends BaseDiagramConfig {
titleTopMargin?: number;
diagramPadding?: number;
nodeLabel?: NodeLabel;
mainBranchName?: string;
@ -224,6 +228,7 @@ export interface MindmapDiagramConfig extends BaseDiagramConfig {
export type PieDiagramConfig = BaseDiagramConfig;
export interface ErDiagramConfig extends BaseDiagramConfig {
titleTopMargin?: number;
diagramPadding?: number;
layoutDirection?: string;
minEntityWidth?: number;
@ -235,6 +240,7 @@ export interface ErDiagramConfig extends BaseDiagramConfig {
}
export interface StateDiagramConfig extends BaseDiagramConfig {
titleTopMargin?: number;
arrowMarkerAbsolute?: boolean;
dividerMargin?: number;
sizeUnit?: number;
@ -255,6 +261,7 @@ export interface StateDiagramConfig extends BaseDiagramConfig {
}
export interface ClassDiagramConfig extends BaseDiagramConfig {
titleTopMargin?: number;
arrowMarkerAbsolute?: boolean;
dividerMargin?: number;
padding?: number;
@ -340,6 +347,7 @@ export interface SequenceDiagramConfig extends BaseDiagramConfig {
}
export interface FlowchartDiagramConfig extends BaseDiagramConfig {
titleTopMargin?: number;
arrowMarkerAbsolute?: boolean;
diagramPadding?: number;
htmlLabels?: boolean;

View File

@ -1,4 +1,4 @@
import dagre from 'dagre';
import { layout as dagreLayout } from 'dagre-d3-es/src/dagre/index.js';
import graphlib from 'graphlib';
import insertMarkers from './markers';
import { updateNodeBounds } from './shapes/util';
@ -95,7 +95,7 @@ const recursiveRender = (_elem, graph, diagramtype, parentCluster) => {
log.info('### Layout ###');
log.info('#############################################');
log.info(graph);
dagre.layout(graph);
dagreLayout(graph);
log.info('Graph after layout:', graphlib.json.write(graph));
// Move the nodes to the correct place
let diff = 0;

View File

@ -1,5 +1,4 @@
import graphlib from 'graphlib';
import dagre from 'dagre';
import {
validate,
adjustClustersAndEdges,

View File

@ -131,7 +131,6 @@ const config: Partial<MermaidConfig> = {
* Default value: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize']
*/
secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'],
lazyLoadedDiagrams: [],
/**
* This option controls if the generated ids of nodes in the SVG are generated randomly or based
* on a seed. If set to false, the IDs are generated based on the current date and thus are not
@ -155,6 +154,17 @@ const config: Partial<MermaidConfig> = {
/** The object containing configurations specific for flowcharts */
flowchart: {
/**
* ### titleTopMargin
*
* | Parameter | Description | Type | Required | Values |
* | -------------- | ---------------------------------------------- | ------- | -------- | ------------------ |
* | titleTopMargin | Margin top for the text over the flowchart | Integer | Required | Any Positive Value |
*
* **Notes:** Default value: 25
*/
titleTopMargin: 25,
/**
* | Parameter | Description | Type | Required | Values |
* | -------------- | ----------------------------------------------- | ------- | -------- | ------------------ |
@ -852,6 +862,16 @@ const config: Partial<MermaidConfig> = {
sectionColours: ['#fff'],
},
class: {
/**
* ### titleTopMargin
*
* | Parameter | Description | Type | Required | Values |
* | -------------- | ---------------------------------------------- | ------- | -------- | ------------------ |
* | titleTopMargin | Margin top for the text over the class diagram | Integer | Required | Any Positive Value |
*
* **Notes:** Default value: 25
*/
titleTopMargin: 25,
arrowMarkerAbsolute: false,
dividerMargin: 10,
padding: 5,
@ -885,6 +905,16 @@ const config: Partial<MermaidConfig> = {
defaultRenderer: 'dagre-wrapper',
},
state: {
/**
* ### titleTopMargin
*
* | Parameter | Description | Type | Required | Values |
* | -------------- | ---------------------------------------------- | ------- | -------- | ------------------ |
* | titleTopMargin | Margin top for the text over the state diagram | Integer | Required | Any Positive Value |
*
* **Notes:** Default value: 25
*/
titleTopMargin: 25,
dividerMargin: 10,
sizeUnit: 5,
padding: 8,
@ -933,6 +963,17 @@ const config: Partial<MermaidConfig> = {
/** The object containing configurations specific for entity relationship diagrams */
er: {
/**
* ### titleTopMargin
*
* | Parameter | Description | Type | Required | Values |
* | -------------- | ---------------------------------------------- | ------- | -------- | ------------------ |
* | titleTopMargin | Margin top for the text over the diagram | Integer | Required | Any Positive Value |
*
* **Notes:** Default value: 25
*/
titleTopMargin: 25,
/**
* | Parameter | Description | Type | Required | Values |
* | -------------- | ----------------------------------------------- | ------- | -------- | ------------------ |
@ -1086,6 +1127,16 @@ const config: Partial<MermaidConfig> = {
line_height: 20,
},
gitGraph: {
/**
* ### titleTopMargin
*
* | Parameter | Description | Type | Required | Values |
* | -------------- | ---------------------------------------------- | ------- | -------- | ------------------ |
* | titleTopMargin | Margin top for the text over the Git diagram | Integer | Required | Any Positive Value |
*
* **Notes:** Default value: 25
*/
titleTopMargin: 25,
diagramPadding: 8,
nodeLabel: {
width: 75,

View File

@ -1,6 +1,7 @@
import { MermaidConfig } from '../config.type';
import { log } from '../logger';
import { DetectorRecord, DiagramDetector, DiagramLoader } from './types';
import { frontMatterRegex } from './frontmatter';
const directive =
/[%]{2}[{]\s*(?:(?:(\w+)\s*:|(\w+))\s*(?:(?:(\w+))|((?:(?![}][%]{2}).|\r?\n)*))?\s*)(?:[}][%]{2})?/gi;
@ -31,7 +32,7 @@ const detectors: Record<string, DetectorRecord> = {};
* @returns A graph definition key
*/
export const detectType = function (text: string, config?: MermaidConfig): string {
text = text.replace(directive, '').replace(anyComment, '\n');
text = text.replace(frontMatterRegex, '').replace(directive, '').replace(anyComment, '\n');
for (const [key, { detector }] of Object.entries(detectors)) {
const diagram = detector(text, config);
if (diagram) {

View File

@ -22,17 +22,19 @@ export interface Detectors {
[key: string]: DiagramDetector;
}
/**
* Registers the given diagram with Mermaid.
*
* Can be used for third-party custom diagrams.
*
* @param id - A unique ID for the given diagram.
* @param diagram - The diagram definition.
* @param detector - Function that returns `true` if a given mermaid text is this diagram definition.
*/
export const registerDiagram = (
id: string,
diagram: DiagramDefinition,
detector?: DiagramDetector,
callback?: (
_log: any,
_setLogLevel: any,
_getConfig: any,
_sanitizeText: any,
_setupGraphViewbox: any
) => void
detector?: DiagramDetector
) => {
if (diagrams[id]) {
throw new Error(`Diagram ${id} already registered.`);
@ -42,8 +44,9 @@ export const registerDiagram = (
addDetector(id, detector);
}
addStylesForDiagram(id, diagram.styles);
if (typeof callback !== 'undefined') {
callback(log, setLogLevel, getConfig, sanitizeText, setupGraphViewbox);
if (diagram.injectUtils) {
diagram.injectUtils(log, setLogLevel, getConfig, sanitizeText, setupGraphViewbox);
}
};

View File

@ -0,0 +1,78 @@
import { vi } from 'vitest';
import { extractFrontMatter } from './frontmatter';
const dbMock = () => ({ setDiagramTitle: vi.fn() });
describe('extractFrontmatter', () => {
it('returns text unchanged if no frontmatter', () => {
expect(extractFrontMatter('diagram', dbMock())).toEqual('diagram');
});
it('returns text unchanged if frontmatter lacks closing delimiter', () => {
const text = `---\ntitle: foo\ndiagram`;
expect(extractFrontMatter(text, dbMock())).toEqual(text);
});
it('handles empty frontmatter', () => {
const db = dbMock();
const text = `---\n\n---\ndiagram`;
expect(extractFrontMatter(text, db)).toEqual('diagram');
expect(db.setDiagramTitle).not.toHaveBeenCalled();
});
it('handles frontmatter without mappings', () => {
const db = dbMock();
const text = `---\n1\n---\ndiagram`;
expect(extractFrontMatter(text, db)).toEqual('diagram');
expect(db.setDiagramTitle).not.toHaveBeenCalled();
});
it('does not try to parse frontmatter at the end', () => {
const db = dbMock();
const text = `diagram\n---\ntitle: foo\n---\n`;
expect(extractFrontMatter(text, db)).toEqual(text);
expect(db.setDiagramTitle).not.toHaveBeenCalled();
});
it('handles frontmatter with multiple delimiters', () => {
const db = dbMock();
const text = `---\ntitle: foo---bar\n---\ndiagram\n---\ntest`;
expect(extractFrontMatter(text, db)).toEqual('diagram\n---\ntest');
expect(db.setDiagramTitle).toHaveBeenCalledWith('foo---bar');
});
it('handles frontmatter with multi-line string and multiple delimiters', () => {
const db = dbMock();
const text = `---\ntitle: |\n multi-line string\n ---\n---\ndiagram`;
expect(extractFrontMatter(text, db)).toEqual('diagram');
expect(db.setDiagramTitle).toHaveBeenCalledWith('multi-line string\n---\n');
});
it('handles frontmatter with title', () => {
const db = dbMock();
const text = `---\ntitle: foo\n---\ndiagram`;
expect(extractFrontMatter(text, db)).toEqual('diagram');
expect(db.setDiagramTitle).toHaveBeenCalledWith('foo');
});
it('handles booleans in frontmatter properly', () => {
const db = dbMock();
const text = `---\ntitle: true\n---\ndiagram`;
expect(extractFrontMatter(text, db)).toEqual('diagram');
expect(db.setDiagramTitle).toHaveBeenCalledWith('true');
});
it('ignores unspecified frontmatter keys', () => {
const db = dbMock();
const text = `---\ninvalid: true\ntitle: foo\ntest: bar\n---\ndiagram`;
expect(extractFrontMatter(text, db)).toEqual('diagram');
expect(db.setDiagramTitle).toHaveBeenCalledWith('foo');
});
it('throws exception for invalid YAML syntax', () => {
const text = `---\n!!!\n---\ndiagram`;
expect(() => extractFrontMatter(text, dbMock())).toThrow(
'tag suffix cannot contain exclamation marks'
);
});
});

View File

@ -0,0 +1,40 @@
import { DiagramDb } from './types';
// The "* as yaml" part is necessary for tree-shaking
import * as yaml from 'js-yaml';
// Match Jekyll-style front matter blocks (https://jekyllrb.com/docs/front-matter/).
// Based on regex used by Jekyll: https://github.com/jekyll/jekyll/blob/6dd3cc21c40b98054851846425af06c64f9fb466/lib/jekyll/document.rb#L10
// Note that JS doesn't support the "\A" anchor, which means we can't use
// multiline mode.
// Relevant YAML spec: https://yaml.org/spec/1.2.2/#914-explicit-documents
export const frontMatterRegex = /^(?:---\s*[\r\n])(.*?)(?:[\r\n]---\s*[\r\n]+)/s;
type FrontMatterMetadata = {
title?: string;
};
/**
* Extract and parse frontmatter from text, if present, and sets appropriate
* properties in the provided db.
* @param text - The text that may have a YAML frontmatter.
* @param db - Diagram database, could be of any diagram.
* @returns text with frontmatter stripped out
*/
export function extractFrontMatter(text: string, db: DiagramDb): string {
const matches = text.match(frontMatterRegex);
if (matches) {
const parsed: FrontMatterMetadata = yaml.load(matches[1], {
// To keep things simple, only allow strings, arrays, and plain objects.
// https://www.yaml.org/spec/1.2/spec.html#id2802346
schema: yaml.FAILSAFE_SCHEMA,
}) as FrontMatterMetadata;
if (parsed?.title) {
db.setDiagramTitle?.(parsed.title);
}
return text.slice(matches[0].length);
} else {
return text;
}
}

View File

@ -8,13 +8,27 @@ export interface InjectUtils {
_setupGraphViewbox: any;
}
/**
* Generic Diagram DB that may apply to any diagram type.
*/
export interface DiagramDb {
clear?: () => void;
setDiagramTitle?: (title: string) => void;
}
export interface DiagramDefinition {
db: any;
db: DiagramDb;
renderer: any;
parser: any;
styles: any;
init?: (config: MermaidConfig) => void;
injectUtils?: (utils: InjectUtils) => void;
injectUtils?: (
_log: InjectUtils['_log'],
_setLogLevel: InjectUtils['_setLogLevel'],
_getConfig: InjectUtils['_getConfig'],
_sanitizeText: InjectUtils['_sanitizeText'],
_setupGraphViewbox: InjectUtils['_setupGraphViewbox']
) => void;
}
export interface DetectorRecord {
@ -22,5 +36,11 @@ export interface DetectorRecord {
loader?: DiagramLoader;
}
export interface ExternalDiagramDefinition {
id: string;
detector: DiagramDetector;
loader: DiagramLoader;
}
export type DiagramDetector = (text: string, config?: MermaidConfig) => boolean;
export type DiagramLoader = (() => Promise<{ id: string; diagram: DiagramDefinition }>) | null;
export type DiagramLoader = () => Promise<{ id: string; diagram: DiagramDefinition }>;

View File

@ -10,6 +10,8 @@ import {
getAccDescription,
setAccDescription,
clear as commonClear,
setDiagramTitle,
getDiagramTitle,
} from '../../commonDb';
const MERMAID_DOM_ID_PREFIX = 'classid-';
@ -408,4 +410,6 @@ export default {
getTooltip,
setTooltip,
lookUpDomId,
setDiagramTitle,
getDiagramTitle,
};

View File

@ -3,6 +3,7 @@ import graphlib from 'graphlib';
import { log } from '../../logger';
import { getConfig } from '../../config';
import { render } from '../../dagre-wrapper/index.js';
import utils from '../../utils';
import { curveLinear } from 'd3';
import { interpolateToCurve, getStylesFromArray } from '../../utils';
import { setupGraphViewbox } from '../../setupGraphViewbox';
@ -429,6 +430,8 @@ export const draw = function (text, id, _version, diagObj) {
id
);
utils.insertTitle(svg, 'classTitleText', conf.titleTopMargin, diagObj.db.getDiagramTitle());
setupGraphViewbox(g, svg, conf.diagramPadding, conf.useMaxWidth);
// Add label rects for non html labels

View File

@ -1,5 +1,5 @@
import { select } from 'd3';
import dagre from 'dagre';
import { layout as dagreLayout } from 'dagre-d3-es/src/dagre/index.js';
import graphlib from 'graphlib';
import { log } from '../../logger';
import svgDraw from './svgDraw';
@ -238,7 +238,7 @@ export const draw = function (text, id, _version, diagObj) {
}
});
dagre.layout(g);
dagreLayout(g);
g.nodes().forEach(function (v) {
if (typeof v !== 'undefined' && typeof g.node(v) !== 'undefined') {
log.debug('Node ' + v + ': ' + JSON.stringify(g.node(v)));

View File

@ -148,6 +148,11 @@ g.classGroup line {
font-size: 11px;
}
.classTitleText {
text-anchor: middle;
font-size: 18px;
fill: ${options.textColor};
}
`;
export default getStyles;

View File

@ -8,6 +8,8 @@ import {
getAccDescription,
setAccDescription,
clear as commonClear,
setDiagramTitle,
getDiagramTitle,
} from '../../commonDb';
let entities = {};
@ -94,4 +96,6 @@ export default {
getAccTitle,
setAccDescription,
getAccDescription,
setDiagramTitle,
getDiagramTitle,
};

View File

@ -1,8 +1,9 @@
import graphlib from 'graphlib';
import { line, curveBasis, select } from 'd3';
import dagre from 'dagre';
import { layout as dagreLayout } from 'dagre-d3-es/src/dagre/index.js';
import { getConfig } from '../../config';
import { log } from '../../logger';
import utils from '../../utils';
import erMarkers from './erMarkers';
import { configureSvgSize } from '../../setupGraphViewbox';
import addSVGAccessibilityFields from '../../accessibility';
@ -210,9 +211,6 @@ const drawAttributes = (groupNode, entityTextNode, attributes) => {
const typeRect = groupNode
.insert('rect', '#' + attributeNode.tn.node().id)
.classed(`er ${attribStyle}`, true)
.style('fill', conf.fill)
.style('fill-opacity', '100%')
.style('stroke', conf.stroke)
.attr('x', 0)
.attr('y', heightOffset)
.attr('width', maxTypeWidth + widthPadding * 2 + spareColumnWidth)
@ -230,9 +228,6 @@ const drawAttributes = (groupNode, entityTextNode, attributes) => {
const nameRect = groupNode
.insert('rect', '#' + attributeNode.nn.node().id)
.classed(`er ${attribStyle}`, true)
.style('fill', conf.fill)
.style('fill-opacity', '100%')
.style('stroke', conf.stroke)
.attr('x', nameXOffset)
.attr('y', heightOffset)
.attr('width', maxNameWidth + widthPadding * 2 + spareColumnWidth)
@ -252,9 +247,6 @@ const drawAttributes = (groupNode, entityTextNode, attributes) => {
const keyTypeRect = groupNode
.insert('rect', '#' + attributeNode.kn.node().id)
.classed(`er ${attribStyle}`, true)
.style('fill', conf.fill)
.style('fill-opacity', '100%')
.style('stroke', conf.stroke)
.attr('x', keyTypeAndCommentXOffset)
.attr('y', heightOffset)
.attr('width', maxKeyWidth + widthPadding * 2 + spareColumnWidth)
@ -275,9 +267,6 @@ const drawAttributes = (groupNode, entityTextNode, attributes) => {
groupNode
.insert('rect', '#' + attributeNode.cn.node().id)
.classed(`er ${attribStyle}`, 'true')
.style('fill', conf.fill)
.style('fill-opacity', '100%')
.style('stroke', conf.stroke)
.attr('x', keyTypeAndCommentXOffset)
.attr('y', heightOffset)
.attr('width', maxCommentWidth + widthPadding * 2 + spareColumnWidth)
@ -347,9 +336,6 @@ const drawEntities = function (svgNode, entities, graph) {
const rectNode = groupNode
.insert('rect', '#' + textId)
.classed('er entityBox', true)
.style('fill', conf.fill)
.style('fill-opacity', '100%')
.style('stroke', conf.stroke)
.attr('x', 0)
.attr('y', 0)
.attr('width', entityWidth)
@ -547,9 +533,7 @@ const drawRelationshipFromLayout = function (svg, rel, g, insert, diagObj) {
.attr('x', labelPoint.x - labelBBox.width / 2)
.attr('y', labelPoint.y - labelBBox.height / 2)
.attr('width', labelBBox.width)
.attr('height', labelBBox.height)
.style('fill', 'white')
.style('fill-opacity', '85%');
.attr('height', labelBBox.height);
};
/**
@ -637,7 +621,7 @@ export const draw = function (text, id, _version, diagObj) {
// Add all the relationships to the graph
const relationships = addRelationships(diagObj.db.getRelationships(), g);
dagre.layout(g); // Node and edge positions will be updated
dagreLayout(g); // Node and edge positions will be updated
// Adjust the positions of the entities so that they adhere to the layout
adjustEntities(svg, g);
@ -649,6 +633,8 @@ export const draw = function (text, id, _version, diagObj) {
const padding = conf.diagramPadding;
utils.insertTitle(svg, 'entityTitleText', conf.titleTopMargin, diagObj.db.getDiagramTitle());
const svgBounds = svg.node().getBBox();
const width = svgBounds.width + padding * 2;
const height = svgBounds.height + padding * 2;

View File

@ -27,6 +27,12 @@ const getStyles = (options) =>
.relationshipLine {
stroke: ${options.lineColor};
}
.entityTitleText {
text-anchor: middle;
font-size: 18px;
fill: ${options.textColor};
}
`;
export default getStyles;

View File

@ -1,4 +1,5 @@
import dagreD3 from 'dagre-d3';
import { intersectPolygon } from 'dagre-d3-es/src/dagre-js/intersect/intersect-polygon.js';
import { intersectRect } from 'dagre-d3-es/src/dagre-js/intersect/intersect-rect.js';
/**
* @param parent
@ -17,7 +18,7 @@ function question(parent, bbox, node) {
];
const shapeSvg = insertPolygonShape(parent, s, s, points);
node.intersect = function (point) {
return dagreD3.intersect.polygon(node, points, point);
return intersectPolygon(node, points, point);
};
return shapeSvg;
}
@ -42,7 +43,7 @@ function hexagon(parent, bbox, node) {
];
const shapeSvg = insertPolygonShape(parent, w, h, points);
node.intersect = function (point) {
return dagreD3.intersect.polygon(node, points, point);
return intersectPolygon(node, points, point);
};
return shapeSvg;
}
@ -64,7 +65,7 @@ function rect_left_inv_arrow(parent, bbox, node) {
];
const shapeSvg = insertPolygonShape(parent, w, h, points);
node.intersect = function (point) {
return dagreD3.intersect.polygon(node, points, point);
return intersectPolygon(node, points, point);
};
return shapeSvg;
}
@ -85,7 +86,7 @@ function lean_right(parent, bbox, node) {
];
const shapeSvg = insertPolygonShape(parent, w, h, points);
node.intersect = function (point) {
return dagreD3.intersect.polygon(node, points, point);
return intersectPolygon(node, points, point);
};
return shapeSvg;
}
@ -106,7 +107,7 @@ function lean_left(parent, bbox, node) {
];
const shapeSvg = insertPolygonShape(parent, w, h, points);
node.intersect = function (point) {
return dagreD3.intersect.polygon(node, points, point);
return intersectPolygon(node, points, point);
};
return shapeSvg;
}
@ -127,7 +128,7 @@ function trapezoid(parent, bbox, node) {
];
const shapeSvg = insertPolygonShape(parent, w, h, points);
node.intersect = function (point) {
return dagreD3.intersect.polygon(node, points, point);
return intersectPolygon(node, points, point);
};
return shapeSvg;
}
@ -148,7 +149,7 @@ function inv_trapezoid(parent, bbox, node) {
];
const shapeSvg = insertPolygonShape(parent, w, h, points);
node.intersect = function (point) {
return dagreD3.intersect.polygon(node, points, point);
return intersectPolygon(node, points, point);
};
return shapeSvg;
}
@ -170,7 +171,7 @@ function rect_right_inv_arrow(parent, bbox, node) {
];
const shapeSvg = insertPolygonShape(parent, w, h, points);
node.intersect = function (point) {
return dagreD3.intersect.polygon(node, points, point);
return intersectPolygon(node, points, point);
};
return shapeSvg;
}
@ -194,7 +195,7 @@ function stadium(parent, bbox, node) {
.attr('height', h);
node.intersect = function (point) {
return dagreD3.intersect.rect(node, point);
return intersectRect(node, point);
};
return shapeSvg;
}
@ -221,7 +222,7 @@ function subroutine(parent, bbox, node) {
];
const shapeSvg = insertPolygonShape(parent, w, h, points);
node.intersect = function (point) {
return dagreD3.intersect.polygon(node, points, point);
return intersectPolygon(node, points, point);
};
return shapeSvg;
}
@ -270,7 +271,7 @@ function cylinder(parent, bbox, node) {
.attr('transform', 'translate(' + -w / 2 + ',' + -(h / 2 + ry) + ')');
node.intersect = function (point) {
const pos = dagreD3.intersect.rect(node, point);
const pos = intersectRect(node, point);
const x = pos.x - node.x;
if (

View File

@ -10,6 +10,8 @@ import {
getAccDescription,
setAccDescription,
clear as commonClear,
setDiagramTitle,
getDiagramTitle,
} from '../../commonDb';
const MERMAID_DOM_ID_PREFIX = 'flowchart-';
@ -785,4 +787,6 @@ export default {
},
exists,
makeUniq,
setDiagramTitle,
getDiagramTitle,
};

View File

@ -3,9 +3,10 @@ import { select, curveLinear, selectAll } from 'd3';
import flowDb from './flowDb';
import { getConfig } from '../../config';
import utils from '../../utils';
import { render } from '../../dagre-wrapper/index.js';
import addHtmlLabel from 'dagre-d3/lib/label/add-html-label.js';
import { addHtmlLabel } from 'dagre-d3-es/src/dagre-js/label/add-html-label.js';
import { log } from '../../logger';
import common, { evaluate } from '../common/common';
import { interpolateToCurve, getStylesFromArray } from '../../utils';
@ -437,6 +438,8 @@ export const draw = function (text, id, _version, diagObj) {
const element = root.select('#' + id + ' g');
render(element, g, ['point', 'circle', 'cross'], 'flowchart', id);
utils.insertTitle(svg, 'flowchartTitleText', conf.titleTopMargin, diagObj.db.getDiagramTitle());
setupGraphViewbox(g, svg, conf.diagramPadding, conf.useMaxWidth);
// Index nodes

View File

@ -1,8 +1,9 @@
import graphlib from 'graphlib';
import { select, curveLinear, selectAll } from 'd3';
import { getConfig } from '../../config';
import dagreD3 from 'dagre-d3';
import addHtmlLabel from 'dagre-d3/lib/label/add-html-label.js';
import { render as Render } from 'dagre-d3-es';
import { applyStyle } from 'dagre-d3-es/src/dagre-js/util.js';
import { addHtmlLabel } from 'dagre-d3-es/src/dagre-js/label/add-html-label.js';
import { log } from '../../logger';
import common, { evaluate } from '../common/common';
import { interpolateToCurve, getStylesFromArray } from '../../utils';
@ -370,7 +371,6 @@ export const draw = function (text, id, _version, diagObj) {
addEdges(edges, g, diagObj);
// Create the renderer
const Render = dagreD3.render;
const render = new Render();
// Add custom shapes
@ -390,7 +390,7 @@ export const draw = function (text, id, _version, diagObj) {
.attr('orient', 'auto');
const path = marker.append('path').attr('d', 'M 0 0 L 0 0 L 0 0 z');
dagreD3.util.applyStyle(path, edge[type + 'Style']);
applyStyle(path, edge[type + 'Style']);
};
// Override normal arrowhead defined in d3. Remove style & add class to allow css styling.

View File

@ -103,6 +103,12 @@ const getStyles = (options: FlowChartStyleOptions) =>
pointer-events: none;
z-index: 100;
}
.flowchartTitleText {
text-anchor: middle;
font-size: 18px;
fill: ${options.textColor};
}
`;
export default getStyles;

View File

@ -10,6 +10,8 @@ import {
getAccDescription,
setAccDescription,
clear as commonClear,
setDiagramTitle,
getDiagramTitle,
} from '../../commonDb';
let mainBranchName = getConfig().gitGraph.mainBranchName;
@ -529,5 +531,7 @@ export default {
getAccTitle,
getAccDescription,
setAccDescription,
setDiagramTitle,
getDiagramTitle,
commitType,
};

View File

@ -1,6 +1,7 @@
import { select } from 'd3';
import { getConfig, setupGraphViewbox } from '../../diagram-api/diagramAPI';
import { log } from '../../logger';
import utils from '../../utils';
import addSVGAccessibilityFields from '../../accessibility';
let allCommitsDict = {};
@ -521,6 +522,12 @@ export const draw = function (txt, id, ver, diagObj) {
}
drawArrows(diagram, allCommitsDict);
drawCommits(diagram, allCommitsDict, true);
utils.insertTitle(
diagram,
'gitTitleText',
gitGraphConfig.titleTopMargin,
diagObj.db.getDiagramTitle()
);
// Setup the view box and size of the svg element
setupGraphViewbox(

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