mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-10-05 15:19:36 +02:00
Merge branch 'develop' into sidv/esbuildV10
* develop: (57 commits) fix Lint Update CHANGELOG.md Update CHANGELOG.md fix: fix exports Fix readme link Regenerate mermaid docs Add deepdwn to cspell Add Deepdwn to native integrations list docs: Fix changelog docs: v10 breaking changes Remove `null` from diagrams before render fix docs diagram Updated version Minor cleanup to trigger build. Fix spellings Wrap option working in test case Fix typos Minor cleanup Removed the deprecated use of mindmap in Demo Minor cleanup ...
This commit is contained in:
2
.github/ISSUE_TEMPLATE/config.yml
vendored
2
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,4 +1,4 @@
|
||||
blank_issues_enabled: false
|
||||
blank_issues_enabled: true
|
||||
contact_links:
|
||||
- name: GitHub Discussions
|
||||
url: https://github.com/mermaid-js/mermaid/discussions
|
||||
|
103
CHANGELOG.md
103
CHANGELOG.md
@@ -1,6 +1,105 @@
|
||||
# Change Log
|
||||
# Changelog
|
||||
|
||||
// TODO: Populate changelog
|
||||
## [10.0.0](https://github.com/mermaid-js/mermaid/releases/tag/v10.0.0)
|
||||
|
||||
### Mermaid is ESM only!
|
||||
|
||||
We've dropped CJS support. So, you will have to update your import scripts as follows.
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
</script>
|
||||
```
|
||||
|
||||
You can keep using v9 by adding the `@9` in the CDN URL.
|
||||
|
||||
```diff
|
||||
- <script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.js"></script>
|
||||
+ <script src="https://cdn.jsdelivr.net/npm/mermaid@9/dist/mermaid.js"></script>
|
||||
```
|
||||
|
||||
### mermaid.render is async and doesn't accept callbacks
|
||||
|
||||
```js
|
||||
// < v10
|
||||
mermaid.render('id', 'graph TD;\nA-->B', (svg, bindFunctions) => {
|
||||
element.innerHTML = svg;
|
||||
if (bindFunctions) {
|
||||
bindFunctions(element);
|
||||
}
|
||||
});
|
||||
|
||||
// Shorter syntax
|
||||
if (bindFunctions) {
|
||||
bindFunctions(element);
|
||||
}
|
||||
// can be replaced with the `?.` shorthand
|
||||
bindFunctions?.(element);
|
||||
|
||||
// >= v10 with async/await
|
||||
const { svg, bindFunctions } = await mermaid.render('id', 'graph TD;\nA-->B');
|
||||
element.innerHTML = svg;
|
||||
bindFunctions?.(element);
|
||||
|
||||
// >= v10 with promise.then
|
||||
mermaid.render('id', 'graph TD;A-->B').then(({ svg, bindFunctions }) => {
|
||||
element.innerHTML = svg;
|
||||
bindFunctions?.(element);
|
||||
});
|
||||
```
|
||||
|
||||
### mermaid.parse is async and ParseError is removed
|
||||
|
||||
```js
|
||||
// < v10
|
||||
mermaid.parse(text, parseError);
|
||||
|
||||
//>= v10
|
||||
await mermaid.parse(text).catch(parseError);
|
||||
// or
|
||||
try {
|
||||
await mermaid.parse(text);
|
||||
} catch (err) {
|
||||
parseError(err);
|
||||
}
|
||||
```
|
||||
|
||||
### Init deprecated and InitThrowsErrors removed
|
||||
|
||||
The config passed to `init` was not being used eariler.
|
||||
It will now be used.
|
||||
The `init` function is deprecated and will be removed in the next major release.
|
||||
init currently works as a wrapper to `initialize` and `run`.
|
||||
|
||||
```js
|
||||
// < v10
|
||||
mermaid.init(config, selector, cb);
|
||||
|
||||
//>= v10
|
||||
mermaid.initialize(config);
|
||||
mermaid.run({
|
||||
querySelector: selector,
|
||||
postRenderCallback: cb,
|
||||
suppressErrors: true,
|
||||
});
|
||||
```
|
||||
|
||||
```js
|
||||
// < v10
|
||||
mermaid.initThrowsErrors(config, selector, cb);
|
||||
|
||||
//>= v10
|
||||
mermaid.initialize(config);
|
||||
mermaid.run({
|
||||
querySelector: selector,
|
||||
postRenderCallback: cb,
|
||||
suppressErrors: false,
|
||||
});
|
||||
```
|
||||
|
||||
// TODO: Populate changelog pre v10
|
||||
|
||||
- Config has a lot of changes
|
||||
- globalReset resets to `defaultConfig` instead of current config. Use `reset` instead.
|
||||
|
@@ -8,7 +8,7 @@ Mermaid
|
||||
Generate diagrams from markdown-like text.
|
||||
<p>
|
||||
<p align="center">
|
||||
<a href="https://www.npmjs.com/package/vitest"><img src="https://img.shields.io/npm/v/mermaid?color=ff3670&label="></a>
|
||||
<a href="https://www.npmjs.com/package/mermaid"><img src="https://img.shields.io/npm/v/mermaid?color=ff3670&label="></a>
|
||||
<p>
|
||||
|
||||
<p align="center">
|
||||
|
@@ -8,7 +8,7 @@ Mermaid
|
||||
通过解析类 Markdown 的文本语法来实现图表的创建和动态修改。
|
||||
<p>
|
||||
<p align="center">
|
||||
<a href="https://www.npmjs.com/package/vitest"><img src="https://img.shields.io/npm/v/mermaid?color=ff3670&label="></a>
|
||||
<a href="https://www.npmjs.com/package/mermaid"><img src="https://img.shields.io/npm/v/mermaid?color=ff3670&label="></a>
|
||||
<p>
|
||||
|
||||
<p align="center">
|
||||
|
@@ -1,58 +0,0 @@
|
||||
# A collection of updates that change the behavior
|
||||
|
||||
## Async
|
||||
|
||||
`parse`, `render` are now async.
|
||||
|
||||
## Lazy loading and asynchronisity
|
||||
|
||||
- Invalid dates are rendered as syntax error instead of returning best guess or the current date
|
||||
|
||||
## ParseError is removed
|
||||
|
||||
```js
|
||||
//< v10.0.0
|
||||
mermaid.parse(text, parseError);
|
||||
|
||||
//>= v10.0.0
|
||||
await mermaid.parse(text).catch(parseError);
|
||||
// or
|
||||
try {
|
||||
await mermaid.parse(text);
|
||||
} catch (err) {
|
||||
parseError(err);
|
||||
}
|
||||
```
|
||||
|
||||
## Init deprecated and InitThrowsErrors removed
|
||||
|
||||
The config passed to `init` was not being used eariler.
|
||||
It will now be used.
|
||||
The `init` function is deprecated and will be removed in the next major release.
|
||||
init currently works as a wrapper to `initialize` and `run`.
|
||||
|
||||
```js
|
||||
//< v10.0.0
|
||||
mermaid.init(config, selector, cb);
|
||||
|
||||
//>= v10.0.0
|
||||
mermaid.initialize(config);
|
||||
mermaid.run({
|
||||
querySelector: selector,
|
||||
postRenderCallback: cb,
|
||||
suppressErrors: true,
|
||||
});
|
||||
```
|
||||
|
||||
```js
|
||||
//< v10.0.0
|
||||
mermaid.initThrowsErrors(config, selector, cb);
|
||||
|
||||
//>= v10.0.0
|
||||
mermaid.initialize(config);
|
||||
mermaid.run({
|
||||
querySelector: selector,
|
||||
postRenderCallback: cb,
|
||||
suppressErrors: false,
|
||||
});
|
||||
```
|
@@ -27,6 +27,7 @@
|
||||
"cuzon",
|
||||
"cytoscape",
|
||||
"dagre",
|
||||
"deepdwn",
|
||||
"descr",
|
||||
"docsify",
|
||||
"docsy",
|
||||
|
@@ -188,7 +188,7 @@ describe('Entity Relationship Diagram', () => {
|
||||
erDiagram
|
||||
CLUSTER {
|
||||
varchar(99) name
|
||||
string(255) description
|
||||
string(255) description
|
||||
}
|
||||
`,
|
||||
{ logLevel: 1 }
|
||||
|
@@ -670,6 +670,17 @@ title: Simple flowchart
|
||||
---
|
||||
flowchart TD
|
||||
A --> B
|
||||
`,
|
||||
{ titleTopMargin: 0 }
|
||||
);
|
||||
});
|
||||
it('3192: It should be possieble to render flowcharts with invisible edges', () => {
|
||||
imgSnapshotTest(
|
||||
`---
|
||||
title: Simple flowchart with invisible edges
|
||||
---
|
||||
flowchart TD
|
||||
A ~~~ B
|
||||
`,
|
||||
{ titleTopMargin: 0 }
|
||||
);
|
||||
|
@@ -116,7 +116,11 @@ context('Sequence diagram', () => {
|
||||
loop Loopy
|
||||
Bob->>Alice: Pasten
|
||||
end `,
|
||||
{ wrap: true }
|
||||
{
|
||||
sequence: {
|
||||
wrap: true,
|
||||
},
|
||||
}
|
||||
);
|
||||
});
|
||||
context('font settings', () => {
|
||||
|
46
cypress/platform/flow2.html
Normal file
46
cypress/platform/flow2.html
Normal file
@@ -0,0 +1,46 @@
|
||||
<html>
|
||||
<head>
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet" />
|
||||
<style>
|
||||
body {
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<pre class="mermaid">
|
||||
graph TB
|
||||
subgraph One
|
||||
a1-->a2-->a3
|
||||
end
|
||||
</pre>
|
||||
<pre class="mermaid">
|
||||
graph TB
|
||||
a_a --> b_b:::apa --> c_c:::apa
|
||||
classDef apa fill:#f9f,stroke:#333,stroke-width:4px;
|
||||
class a_a apa;
|
||||
</pre>
|
||||
<pre class="mermaid">
|
||||
graph TB
|
||||
a_a(Aftonbladet) --> b_b[gorilla]:::apa --> c_c{chimp}:::apa -->a_a
|
||||
a_a --> c --> d_d --> c_c
|
||||
classDef apa fill:#f9f,stroke:#333,stroke-width:4px;
|
||||
class a_a apa;
|
||||
click a_a "http://www.aftonbladet.se" "apa"
|
||||
</pre>
|
||||
|
||||
<script type="module">
|
||||
import mermaid from '../../packages/mermaid/src/mermaid';
|
||||
|
||||
mermaid.initialize({
|
||||
theme: 'forest',
|
||||
// themeCSS: '.node rect { fill: red; }',
|
||||
logLevel: 3,
|
||||
flowchart: { curve: 'linear' },
|
||||
gantt: { axisFormat: '%m/%d/%Y' },
|
||||
sequence: { actorMargin: 50 },
|
||||
// sequenceDiagram: { actorMargin: 300 } // deprecated
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@@ -46,7 +46,7 @@ const contentLoaded = async function () {
|
||||
|
||||
await mermaid2.registerExternalDiagrams([externalExample]);
|
||||
mermaid2.initialize(graphObj.mermaid);
|
||||
await mermaid2.init();
|
||||
await mermaid2.run();
|
||||
markRendered();
|
||||
}
|
||||
};
|
||||
|
@@ -17,7 +17,7 @@
|
||||
<h1>Journey diagram demo</h1>
|
||||
<pre class="mermaid">
|
||||
---
|
||||
title: My working day
|
||||
title: My working day
|
||||
---
|
||||
journey
|
||||
accTitle: Very simple journey demo
|
||||
|
@@ -8,41 +8,6 @@
|
||||
|
||||
[mermaidAPI](../modules/mermaidAPI.md).RenderResult
|
||||
|
||||
Function that renders an svg with a graph from a chart definition. Usage example below.
|
||||
|
||||
```javascript
|
||||
mermaidAPI.initialize({
|
||||
startOnLoad: true,
|
||||
});
|
||||
$(function () {
|
||||
const graphDefinition = 'graph TB\na-->b';
|
||||
const cb = function (svgGraph) {
|
||||
console.log(svgGraph);
|
||||
};
|
||||
mermaidAPI.render('id1', graphDefinition, cb);
|
||||
});
|
||||
```
|
||||
|
||||
**`Param`**
|
||||
|
||||
The id for the SVG element (the element to be rendered)
|
||||
|
||||
**`Param`**
|
||||
|
||||
The text for the graph definition
|
||||
|
||||
**`Param`**
|
||||
|
||||
Callback which is called after rendering is finished with the svg code as in param.
|
||||
|
||||
**`Param`**
|
||||
|
||||
HTML element where the svg will be inserted. (Is usually element with the .mermaid class)
|
||||
If no svgContainingElement is provided then the SVG element will be appended to the body.
|
||||
Selector to element in which a div with the graph temporarily will be
|
||||
inserted. If one is provided a hidden div will be inserted in the body of the page instead. The
|
||||
element will be removed when rendering is completed.
|
||||
|
||||
## Properties
|
||||
|
||||
### bindFunctions
|
||||
@@ -53,6 +18,15 @@ element will be removed when rendering is completed.
|
||||
|
||||
▸ (`element`): `void`
|
||||
|
||||
Bind function to be called after the svg has been inserted into the DOM.
|
||||
This is necessary for adding event listeners to the elements in the svg.
|
||||
|
||||
```js
|
||||
const { svg, bindFunctions } = mermaidAPI.render('id1', 'graph TD;A-->B');
|
||||
div.innerHTML = svg;
|
||||
bindFunctions?.(div); // To call bindFunctions only if it's present.
|
||||
```
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Type |
|
||||
@@ -65,7 +39,7 @@ element will be removed when rendering is completed.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:384](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L384)
|
||||
[mermaidAPI.ts:91](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L91)
|
||||
|
||||
---
|
||||
|
||||
@@ -73,6 +47,8 @@ element will be removed when rendering is completed.
|
||||
|
||||
• **svg**: `string`
|
||||
|
||||
The svg code for the rendered graph.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:383](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L383)
|
||||
[mermaidAPI.ts:81](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L81)
|
||||
|
@@ -95,7 +95,7 @@ mermaid.initialize(config);
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:668](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L668)
|
||||
[mermaidAPI.ts:680](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L680)
|
||||
|
||||
## Functions
|
||||
|
||||
@@ -126,7 +126,7 @@ Return the last node appended
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:291](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L291)
|
||||
[mermaidAPI.ts:308](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L308)
|
||||
|
||||
---
|
||||
|
||||
@@ -152,7 +152,7 @@ the cleaned up svgCode
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:242](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L242)
|
||||
[mermaidAPI.ts:259](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L259)
|
||||
|
||||
---
|
||||
|
||||
@@ -178,7 +178,7 @@ the string with all the user styles
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:171](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L171)
|
||||
[mermaidAPI.ts:188](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L188)
|
||||
|
||||
---
|
||||
|
||||
@@ -201,7 +201,7 @@ the string with all the user styles
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:219](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L219)
|
||||
[mermaidAPI.ts:236](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L236)
|
||||
|
||||
---
|
||||
|
||||
@@ -228,7 +228,7 @@ with an enclosing block that has each of the cssClasses followed by !important;
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:155](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L155)
|
||||
[mermaidAPI.ts:172](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L172)
|
||||
|
||||
---
|
||||
|
||||
@@ -248,7 +248,7 @@ with an enclosing block that has each of the cssClasses followed by !important;
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:135](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L135)
|
||||
[mermaidAPI.ts:152](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L152)
|
||||
|
||||
---
|
||||
|
||||
@@ -268,7 +268,7 @@ with an enclosing block that has each of the cssClasses followed by !important;
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:106](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L106)
|
||||
[mermaidAPI.ts:123](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L123)
|
||||
|
||||
---
|
||||
|
||||
@@ -294,7 +294,7 @@ Put the svgCode into an iFrame. Return the iFrame code
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:270](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L270)
|
||||
[mermaidAPI.ts:287](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L287)
|
||||
|
||||
---
|
||||
|
||||
@@ -319,4 +319,4 @@ Remove any existing elements from the given document
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:341](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L341)
|
||||
[mermaidAPI.ts:358](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L358)
|
||||
|
@@ -20,21 +20,24 @@ Please note that you can switch versions through the dropdown box at the top rig
|
||||
|
||||
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.
|
||||
We have compiled some Video [Tutorials](./Tutorials.md) on how to use the Mermaid Live Editor.
|
||||
|
||||
### Installing and Hosting Mermaid on a Webpage
|
||||
|
||||
**Using the npm package:**
|
||||
|
||||
1. You will need to install `node v16`, which would have npm.
|
||||
Requirements:
|
||||
|
||||
2. Download `yarn` using npm.
|
||||
- Node >= 16
|
||||
|
||||
3. Enter the following command: `yarn add mermaid`.
|
||||
|
||||
4. At this point, you can add mermaid as a dev dependency using this command: `yarn add --dev mermaid`.
|
||||
|
||||
5. Alternatively, you can also deploy mermaid using the script tag in an HTML file with mermaid diagram descriptions as is shown in the example below.
|
||||
```bash
|
||||
# NPM
|
||||
npm install mermaid
|
||||
# Yarn
|
||||
yarn add mermaid
|
||||
# PNPM
|
||||
pnpm add mermaid
|
||||
```
|
||||
|
||||
**Hosting mermaid on a web page:**
|
||||
|
||||
@@ -42,7 +45,9 @@ We have compiled some Video [Tutorials](./Tutorials.md) on how to use the mermai
|
||||
|
||||
The easiest way to integrate mermaid on a web page requires two elements:
|
||||
|
||||
- A graph definition, inside `<pre>` tags labeled `class=mermaid`. Example:
|
||||
- A graph definition, inside `<pre>` tags labeled `class=mermaid`.
|
||||
|
||||
Example:
|
||||
|
||||
```html
|
||||
<pre class="mermaid">
|
||||
@@ -53,14 +58,13 @@ The easiest way to integrate mermaid on a web page requires two elements:
|
||||
</pre>
|
||||
```
|
||||
|
||||
- Inclusion of the mermaid address in the html page body using a `script` tag as an ESM import, and the `mermaidAPI` call.
|
||||
- The mermaid js script. Added using a `script` tag as an ESM import.
|
||||
|
||||
Example:
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
</script>
|
||||
```
|
||||
|
||||
@@ -71,9 +75,6 @@ Example:
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
</head>
|
||||
<body>
|
||||
<pre class="mermaid">
|
||||
graph LR
|
||||
@@ -83,7 +84,6 @@ Example:
|
||||
</pre>
|
||||
<script type="module">
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -95,11 +95,12 @@ An id attribute is also added to mermaid tags without one.
|
||||
|
||||
Mermaid can load multiple diagrams, in the same page.
|
||||
|
||||
> Try it out, save this code as HTML and load it using any browser.(Except Internet Explorer, please don't use Internet Explorer.)
|
||||
> Try it out, save this code as HTML and load it using any browser.
|
||||
> (Except Internet Explorer, please don't use Internet Explorer.)
|
||||
|
||||
## Enabling Click Event and Tags in Nodes
|
||||
|
||||
A `securityLevel` configuration has to first be cleared, `securityLevel` sets the level of trust for the parsed diagrams and limits click functionality. This was introduce in version 8.2 as a security improvement, aimed at preventing malicious use.
|
||||
A `securityLevel` configuration has to first be cleared. `securityLevel` sets the level of trust for the parsed diagrams and limits click functionality. This was introduce in version 8.2 as a security improvement, aimed at preventing malicious use.
|
||||
|
||||
**It is the site owner's responsibility to discriminate between trustworthy and untrustworthy user-bases and we encourage the use of discretion.**
|
||||
|
||||
@@ -107,7 +108,7 @@ A `securityLevel` configuration has to first be cleared, `securityLevel` sets th
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ------------- | --------------------------------- | ------ | -------- | ------------------------------------------ |
|
||||
| securityLevel | Level of trust for parsed diagram | String | Required | 'sandbox', 'strict', 'loose', 'antiscript' |
|
||||
| securityLevel | Level of trust for parsed diagram | String | Optional | 'sandbox', 'strict', 'loose', 'antiscript' |
|
||||
|
||||
Values:
|
||||
|
||||
@@ -122,26 +123,17 @@ Values:
|
||||
|
||||
**If you are taking responsibility for the diagram source security you can set the `securityLevel` to a value of your choosing . This allows clicks and tags are allowed.**
|
||||
|
||||
**To change `securityLevel`, you have to call `mermaidAPI.initialize`:**
|
||||
**To change `securityLevel`, you have to call `mermaid.initialize`:**
|
||||
|
||||
```javascript
|
||||
mermaidAPI.initialize({
|
||||
mermaid.initialize({
|
||||
securityLevel: 'loose',
|
||||
});
|
||||
```
|
||||
|
||||
### Labels out of bounds
|
||||
|
||||
If you use dynamically loaded fonts that are loaded through CSS, such as Google fonts, mermaid should wait for the
|
||||
whole page to load (dom + assets, particularly the fonts file).
|
||||
|
||||
```javascript
|
||||
$(document).load(function () {
|
||||
mermaid.initialize();
|
||||
});
|
||||
```
|
||||
|
||||
or
|
||||
If you use dynamically loaded fonts that are loaded through CSS, such as fonts, mermaid should wait for the whole page to load (dom + assets, particularly the fonts file).
|
||||
|
||||
```javascript
|
||||
$(document).ready(function () {
|
||||
@@ -154,12 +146,54 @@ Not doing so will most likely result in mermaid rendering graphs that have label
|
||||
If your page has other fonts in its body those might be used instead of the mermaid font. Specifying the font in your styling is a workaround for this.
|
||||
|
||||
```css
|
||||
div.mermaid {
|
||||
pre.mermaid {
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
}
|
||||
```
|
||||
|
||||
### Calling `mermaid.init`
|
||||
### Using `mermaid.run`
|
||||
|
||||
mermaid.run was added in v10 and is the preferred way of handling more complex integration.
|
||||
By default, `mermaid.run` will be called when the document is ready, rendering all elements with `class="mermaid"`.
|
||||
|
||||
You can customize that behavior by calling `await mermaid.run(<config>)`.
|
||||
|
||||
`mermaid.initialize({startOnLoad: false})` will prevent `mermaid.run` from being called automatically after load.
|
||||
|
||||
Render all elements with querySelector ".someOtherClass"
|
||||
|
||||
```js
|
||||
mermaid.initialize({ startOnLoad: false });
|
||||
await mermaid.run({
|
||||
querySelector: '.someOtherClass',
|
||||
});
|
||||
```
|
||||
|
||||
Render all elements passed as an array
|
||||
|
||||
```js
|
||||
mermaid.initialize({ startOnLoad: false });
|
||||
await mermaid.run({
|
||||
nodes: [document.getElementById('someId'), document.getElementById('anotherId')],
|
||||
});
|
||||
await mermaid.run({
|
||||
nodes: document.querySelectorAll('.yetAnotherClass'),
|
||||
});
|
||||
```
|
||||
|
||||
Render all `.mermaid` elements while suppressing any error
|
||||
|
||||
```js
|
||||
mermaid.initialize({ startOnLoad: false });
|
||||
await mermaid.run({
|
||||
suppressErrors: true,
|
||||
});
|
||||
```
|
||||
|
||||
### Calling `mermaid.init` - Deprecated
|
||||
|
||||
> **Warning**
|
||||
> mermaid.init is deprecated in v10 and will be removed in v11. Please use mermaid.run instead.
|
||||
|
||||
By default, `mermaid.init` will be called when the document is ready, finding all elements with
|
||||
`class="mermaid"`. If you are adding content after mermaid is loaded, or otherwise need
|
||||
@@ -192,25 +226,24 @@ mermaid fully supports webpack. Here is a [working demo](https://github.com/merm
|
||||
|
||||
## API usage
|
||||
|
||||
The main idea of the API is to be able to call a render function with the graph definition as a string. The render function
|
||||
will render the graph and call a callback with the resulting SVG code. With this approach it is up to the site creator to
|
||||
fetch the graph definition from the site (perhaps from a textarea), render it and place the graph somewhere in the site.
|
||||
The main idea of the API is to be able to call a render function with the graph definition as a string. The render function will render the graph and call a callback with the resulting SVG code. With this approach it is up to the site creator to fetch the graph definition from the site (perhaps from a textarea), render it and place the graph somewhere in the site.
|
||||
|
||||
The example below show an outline of how this could be used. The example just logs the resulting SVG to the JavaScript console.
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
import mermaid from './mermaid.mjs';
|
||||
mermaid.mermaidAPI.initialize({ startOnLoad: false });
|
||||
$(async function () {
|
||||
// Example of using the API var
|
||||
import mermaid from './mermaid.esm.mjs';
|
||||
mermaid.initialize({ startOnLoad: false });
|
||||
|
||||
// Example of using the render function
|
||||
const drawDiagram = async function () {
|
||||
element = document.querySelector('#graphDiv');
|
||||
const insertSvg = function (svgCode, bindFunctions) {
|
||||
element.innerHTML = svgCode;
|
||||
};
|
||||
const graphDefinition = 'graph TB\na-->b';
|
||||
const graph = await mermaid.mermaidAPI.render('graphDiv', graphDefinition, insertSvg);
|
||||
});
|
||||
const { svg } = await mermaid.render('graphDiv', graphDefinition);
|
||||
element.innerHTML = svg;
|
||||
};
|
||||
|
||||
await drawDiagram();
|
||||
</script>
|
||||
```
|
||||
|
||||
@@ -223,17 +256,17 @@ The example code below is an extract of what mermaid does when using the API. Th
|
||||
bind events to an SVG when using the API for rendering.
|
||||
|
||||
```javascript
|
||||
const insertSvg = function (svgCode, bindFunctions) {
|
||||
element.innerHTML = svgCode;
|
||||
if (typeof callback !== 'undefined') {
|
||||
callback(id);
|
||||
// Example of using the bindFunctions
|
||||
const drawDiagram = async function () {
|
||||
element = document.querySelector('#graphDiv');
|
||||
const graphDefinition = 'graph TB\na-->b';
|
||||
const { svg, bindFunctions } = await mermaid.render('graphDiv', graphDefinition);
|
||||
element.innerHTML = svg;
|
||||
// This can also be written as `bindFunctions?.(element);` using the `?` shorthand.
|
||||
if (bindFunctions) {
|
||||
bindFunctions(element);
|
||||
}
|
||||
bindFunctions(element);
|
||||
};
|
||||
|
||||
const id = 'theGraph';
|
||||
|
||||
mermaidAPI.render(id, txt, insertSvg, element);
|
||||
```
|
||||
|
||||
1. The graph is generated using the render call.
|
||||
|
@@ -20,6 +20,7 @@ They also serve as proof of concept, for the variety of things that can be built
|
||||
- [Gitea](https://gitea.io) (**Native support**)
|
||||
- [Azure Devops](https://docs.microsoft.com/en-us/azure/devops/project/wiki/wiki-markdown-guidance?view=azure-devops#add-mermaid-diagrams-to-a-wiki-page) (**Native support**)
|
||||
- [Tuleap](https://docs.tuleap.org/user-guide/writing-in-tuleap.html#graphs) (**Native support**)
|
||||
- [Deepdwn](https://billiam.itch.io/deepdwn) (**Native support**)
|
||||
- [Joplin](https://joplinapp.org) (**Native support**)
|
||||
- [Swimm](https://swimm.io) (**Native support**)
|
||||
- [Notion](https://notion.so) (**Native support**)
|
||||
@@ -188,3 +189,6 @@ They also serve as proof of concept, for the variety of things that can be built
|
||||
- [mermaid-server: Generate diagrams using a HTTP request](https://github.com/TomWright/mermaid-server)
|
||||
- [ExDoc](https://github.com/elixir-lang/ex_doc)
|
||||
- [Rendering Mermaid graphs](https://github.com/elixir-lang/ex_doc#rendering-mermaid-graphs)
|
||||
- [NiceGUI: Let any browser be the frontend of your Python code](https://nicegui.io)
|
||||
- [ui.mermaid(...)](https://nicegui.io/reference#mermaid_diagrams)
|
||||
- [ui.markdown(..., extras=\['mermaid'\])](https://nicegui.io/reference#markdown_element)
|
||||
|
@@ -103,7 +103,7 @@ When writing the .html file, we give two instructions inside the html code to th
|
||||
|
||||
a. The mermaid code for the diagram we want to create.
|
||||
|
||||
b. The importing of mermaid library through the `mermaid.esm.js` or `mermaid.esm.min.mjs` and the `mermaid.initialize()` call, which dictates the appearance of diagrams and also starts the rendering process .
|
||||
b. The importing of mermaid library through the `mermaid.esm.mjs` or `mermaid.esm.min.mjs` and the `mermaid.initialize()` call, which dictates the appearance of diagrams and also starts the rendering process .
|
||||
|
||||
**a. The embedded mermaid diagram definition inside a `<pre class="mermaid">`:**
|
||||
|
||||
@@ -135,7 +135,7 @@ b. The importing of mermaid library through the `mermaid.esm.js` or `mermaid.esm
|
||||
```
|
||||
|
||||
**Notes**:
|
||||
Rendering in Mermaid is initialized by `mermaid.initialize()` call. You can place `mermaid.initialize()` inside `mermaid.esm.min.mjs` for brevity. However, doing the opposite lets you control when it starts looking for `<div>`tags inside the web page with `mermaid.initialize()`. This is useful when you think that not all `<div>` tags may have loaded on the execution of `mermaid.esm.min.mjs` file.
|
||||
Rendering in Mermaid is initialized by `mermaid.initialize()` call. However, doing the opposite lets you control when it starts looking for `<pre>` tags inside the web page with `mermaid.initialize()`. This is useful when you think that not all `<pre>` tags may have loaded on the execution of `mermaid.esm.min.mjs` file.
|
||||
|
||||
`startOnLoad` is one of the parameters that can be defined by `mermaid.initialize()`
|
||||
|
||||
@@ -143,10 +143,6 @@ Rendering in Mermaid is initialized by `mermaid.initialize()` call. You can plac
|
||||
| ----------- | --------------------------------- | ------- | ----------- |
|
||||
| startOnLoad | Toggle for Rendering upon loading | Boolean | true, false |
|
||||
|
||||
### Adding external diagrams to mermaid
|
||||
|
||||
Please refer to the [Mindmap](../syntax/mindmap.md?id=integrating-with-your-librarywebsite) section for more information.
|
||||
|
||||
### Working Examples
|
||||
|
||||
**Here is a full working example of the mermaidAPI being called through the CDN:**
|
||||
|
@@ -391,6 +391,20 @@ flowchart LR
|
||||
A == text ==> B
|
||||
```
|
||||
|
||||
### An invisible link
|
||||
|
||||
This can be a useful tool in some instances where you want to alter the default positioning of a node.
|
||||
|
||||
```mermaid-example
|
||||
flowchart LR
|
||||
A ~~~ B
|
||||
```
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A ~~~ B
|
||||
```
|
||||
|
||||
### Chaining of links
|
||||
|
||||
It is possible declare many links in the same line as per below:
|
||||
|
@@ -1,14 +1,14 @@
|
||||
{
|
||||
"name": "mermaid",
|
||||
"version": "10.0.0-rc.4",
|
||||
"version": "10.0.1-rc.1",
|
||||
"description": "Markdown-ish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
|
||||
"type": "module",
|
||||
"module": "./dist/mermaid.core.mjs",
|
||||
"types": "./dist/mermaid.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./dist/mermaid.core.mjs",
|
||||
"types": "./dist/mermaid.d.ts"
|
||||
"types": "./dist/mermaid.d.ts",
|
||||
"import": "./dist/mermaid.core.mjs"
|
||||
},
|
||||
"./*": "./*"
|
||||
},
|
||||
|
@@ -68,8 +68,8 @@ export class Diagram {
|
||||
}
|
||||
}
|
||||
|
||||
export const getDiagramFromText = async (txt: string): Promise<Diagram> => {
|
||||
const type = detectType(txt, configApi.getConfig());
|
||||
export const getDiagramFromText = async (text: string): Promise<Diagram> => {
|
||||
const type = detectType(text, configApi.getConfig());
|
||||
try {
|
||||
// Trying to find the diagram
|
||||
getDiagram(type);
|
||||
@@ -83,5 +83,5 @@ export const getDiagramFromText = async (txt: string): Promise<Diagram> => {
|
||||
const { id, diagram } = await loader();
|
||||
registerDiagram(id, diagram);
|
||||
}
|
||||
return new Diagram(txt);
|
||||
return new Diagram(text);
|
||||
};
|
||||
|
@@ -243,6 +243,7 @@ const checkConfig = (config: MermaidConfig) => {
|
||||
if (!config) {
|
||||
return;
|
||||
}
|
||||
// @ts-expect-error Properties were removed in v10. Warning should exist.
|
||||
if (config.lazyLoadedDiagrams || config.loadExternalDiagramsAtStartup) {
|
||||
issueWarning('LAZY_LOAD_DEPRECATED');
|
||||
}
|
||||
|
@@ -3,10 +3,6 @@
|
||||
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;
|
||||
|
@@ -453,6 +453,9 @@ export const insertEdge = function (elem, e, edge, clusterDb, diagramType, graph
|
||||
case 'thick':
|
||||
strokeClasses = 'edge-thickness-thick';
|
||||
break;
|
||||
case 'invisible':
|
||||
strokeClasses = 'edge-thickness-thick';
|
||||
break;
|
||||
default:
|
||||
strokeClasses = '';
|
||||
}
|
||||
|
@@ -7,6 +7,7 @@ import type {
|
||||
ExternalDiagramDefinition,
|
||||
} from './types';
|
||||
import { frontMatterRegex } from './frontmatter';
|
||||
import { getDiagram, registerDiagram } from './diagramAPI';
|
||||
import { UnknownDiagramError } from '../errors';
|
||||
|
||||
const directive = /%{2}{\s*(?:(\w+)\s*:|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi;
|
||||
@@ -54,6 +55,39 @@ export const registerLazyLoadedDiagrams = (...diagrams: ExternalDiagramDefinitio
|
||||
}
|
||||
};
|
||||
|
||||
export const loadRegisteredDiagrams = async () => {
|
||||
log.debug(`Loading registered diagrams`);
|
||||
// Load all lazy loaded diagrams in parallel
|
||||
const results = await Promise.allSettled(
|
||||
Object.entries(detectors).map(async ([key, { detector, loader }]) => {
|
||||
if (loader) {
|
||||
try {
|
||||
getDiagram(key);
|
||||
} catch (error) {
|
||||
try {
|
||||
// Register diagram if it is not already registered
|
||||
const { diagram, id } = await loader();
|
||||
registerDiagram(id, diagram, detector);
|
||||
} catch (err) {
|
||||
// Remove failed diagram from detectors
|
||||
log.error(`Failed to load external diagram with key ${key}. Removing from detectors.`);
|
||||
delete detectors[key];
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
const failed = results.filter((result) => result.status === 'rejected');
|
||||
if (failed.length > 0) {
|
||||
log.error(`Failed to load ${failed.length} external diagrams`);
|
||||
for (const res of failed) {
|
||||
log.error(res);
|
||||
}
|
||||
throw new Error(`Failed to load ${failed.length} external diagrams`);
|
||||
}
|
||||
};
|
||||
|
||||
export const addDetector = (key: string, detector: DiagramDetector, loader?: DiagramLoader) => {
|
||||
if (detectors[key]) {
|
||||
log.error(`Detector with key ${key} already exists`);
|
||||
|
@@ -1,104 +1,24 @@
|
||||
import { registerDiagram } from './diagramAPI';
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import gitGraphParser from '../diagrams/git/parser/gitGraph';
|
||||
import { gitGraphDetector } from '../diagrams/git/gitGraphDetector';
|
||||
import gitGraphDb from '../diagrams/git/gitGraphAst';
|
||||
import gitGraphRenderer from '../diagrams/git/gitGraphRenderer';
|
||||
import gitGraphStyles from '../diagrams/git/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import c4Parser from '../diagrams/c4/parser/c4Diagram';
|
||||
import { c4Detector } from '../diagrams/c4/c4Detector';
|
||||
import c4Db from '../diagrams/c4/c4Db';
|
||||
import c4Renderer from '../diagrams/c4/c4Renderer';
|
||||
import c4Styles from '../diagrams/c4/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import classParser from '../diagrams/class/parser/classDiagram';
|
||||
import { classDetector } from '../diagrams/class/classDetector';
|
||||
import { classDetectorV2 } from '../diagrams/class/classDetector-V2';
|
||||
import classDb from '../diagrams/class/classDb';
|
||||
import classRenderer from '../diagrams/class/classRenderer';
|
||||
import classRendererV2 from '../diagrams/class/classRenderer-v2';
|
||||
import classStyles from '../diagrams/class/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import erParser from '../diagrams/er/parser/erDiagram';
|
||||
import { erDetector } from '../diagrams/er/erDetector';
|
||||
import erDb from '../diagrams/er/erDb';
|
||||
import erRenderer from '../diagrams/er/erRenderer';
|
||||
import erStyles from '../diagrams/er/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import flowParser from '../diagrams/flowchart/parser/flow';
|
||||
import { flowDetector } from '../diagrams/flowchart/flowDetector';
|
||||
import { flowDetectorV2 } from '../diagrams/flowchart/flowDetector-v2';
|
||||
import flowDb from '../diagrams/flowchart/flowDb';
|
||||
import flowRenderer from '../diagrams/flowchart/flowRenderer';
|
||||
import flowRendererV2 from '../diagrams/flowchart/flowRenderer-v2';
|
||||
import flowStyles from '../diagrams/flowchart/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import ganttParser from '../diagrams/gantt/parser/gantt';
|
||||
import { ganttDetector } from '../diagrams/gantt/ganttDetector';
|
||||
import ganttDb from '../diagrams/gantt/ganttDb';
|
||||
import ganttRenderer from '../diagrams/gantt/ganttRenderer';
|
||||
import ganttStyles from '../diagrams/gantt/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import infoParser from '../diagrams/info/parser/info';
|
||||
import infoDb from '../diagrams/info/infoDb';
|
||||
import infoRenderer from '../diagrams/info/infoRenderer';
|
||||
import { infoDetector } from '../diagrams/info/infoDetector';
|
||||
import infoStyles from '../diagrams/info/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import pieParser from '../diagrams/pie/parser/pie';
|
||||
import { pieDetector } from '../diagrams/pie/pieDetector';
|
||||
import pieDb from '../diagrams/pie/pieDb';
|
||||
import pieRenderer from '../diagrams/pie/pieRenderer';
|
||||
import pieStyles from '../diagrams/pie/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import requirementParser from '../diagrams/requirement/parser/requirementDiagram';
|
||||
import { requirementDetector } from '../diagrams/requirement/requirementDetector';
|
||||
import requirementDb from '../diagrams/requirement/requirementDb';
|
||||
import requirementRenderer from '../diagrams/requirement/requirementRenderer';
|
||||
import requirementStyles from '../diagrams/requirement/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import sequenceParser from '../diagrams/sequence/parser/sequenceDiagram';
|
||||
import { sequenceDetector } from '../diagrams/sequence/sequenceDetector';
|
||||
import sequenceDb from '../diagrams/sequence/sequenceDb';
|
||||
import sequenceRenderer from '../diagrams/sequence/sequenceRenderer';
|
||||
import sequenceStyles from '../diagrams/sequence/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import stateParser from '../diagrams/state/parser/stateDiagram';
|
||||
import { stateDetector } from '../diagrams/state/stateDetector';
|
||||
import { stateDetectorV2 } from '../diagrams/state/stateDetector-V2';
|
||||
import stateDb from '../diagrams/state/stateDb';
|
||||
import stateRenderer from '../diagrams/state/stateRenderer';
|
||||
import stateRendererV2 from '../diagrams/state/stateRenderer-v2';
|
||||
import stateStyles from '../diagrams/state/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import journeyParser from '../diagrams/user-journey/parser/journey';
|
||||
import { journeyDetector } from '../diagrams/user-journey/journeyDetector';
|
||||
import journeyDb from '../diagrams/user-journey/journeyDb';
|
||||
import journeyRenderer from '../diagrams/user-journey/journeyRenderer';
|
||||
import journeyStyles from '../diagrams/user-journey/styles';
|
||||
import { setConfig } from '../config';
|
||||
|
||||
import errorRenderer from '../diagrams/error/errorRenderer';
|
||||
import errorStyles from '../diagrams/error/styles';
|
||||
|
||||
import c4 from '../diagrams/c4/c4Detector';
|
||||
import flowchart from '../diagrams/flowchart/flowDetector';
|
||||
import flowchartV2 from '../diagrams/flowchart/flowDetector-v2';
|
||||
import er from '../diagrams/er/erDetector';
|
||||
import git from '../diagrams/git/gitGraphDetector';
|
||||
import gantt from '../diagrams/gantt/ganttDetector';
|
||||
import info from '../diagrams/info/infoDetector';
|
||||
import pie from '../diagrams/pie/pieDetector';
|
||||
import requirement from '../diagrams/requirement/requirementDetector';
|
||||
import sequence from '../diagrams/sequence/sequenceDetector';
|
||||
import classDiagram from '../diagrams/class/classDetector';
|
||||
import classDiagramV2 from '../diagrams/class/classDetector-V2';
|
||||
import state from '../diagrams/state/stateDetector';
|
||||
import stateV2 from '../diagrams/state/stateDetector-V2';
|
||||
import journey from '../diagrams/user-journey/journeyDetector';
|
||||
import error from '../diagrams/error/errorDetector';
|
||||
import flowchartElk from '../diagrams/flowchart/elk/detector';
|
||||
import timeline from '../diagrams/timeline/detector';
|
||||
import mindmap from '../diagrams/mindmap/detector';
|
||||
import { registerLazyLoadedDiagrams } from './detectType';
|
||||
|
||||
// Lazy loaded diagrams
|
||||
import timelineDetector from '../diagrams/timeline/detector';
|
||||
import mindmapDetector from '../diagrams/mindmap/detector';
|
||||
import { registerDiagram } from './diagramAPI';
|
||||
|
||||
let hasLoadedDiagrams = false;
|
||||
export const addDiagrams = () => {
|
||||
@@ -108,31 +28,6 @@ export const addDiagrams = () => {
|
||||
// This is added here to avoid race-conditions.
|
||||
// We could optimize the loading logic somehow.
|
||||
hasLoadedDiagrams = true;
|
||||
registerLazyLoadedDiagrams(flowchartElk, timelineDetector, mindmapDetector);
|
||||
|
||||
registerDiagram(
|
||||
'error',
|
||||
// Special diagram with error messages but setup as a regular diagram
|
||||
{
|
||||
db: {
|
||||
clear: () => {
|
||||
// Quite ok, clear needs to be there for error to work as a regular diagram
|
||||
},
|
||||
},
|
||||
styles: errorStyles,
|
||||
renderer: errorRenderer,
|
||||
parser: {
|
||||
parser: { yy: {} },
|
||||
parse: () => {
|
||||
// no op
|
||||
},
|
||||
},
|
||||
init: () => {
|
||||
// no op
|
||||
},
|
||||
},
|
||||
(text) => text.toLowerCase().trim() === 'error'
|
||||
);
|
||||
registerDiagram(
|
||||
'---',
|
||||
// --- diagram type may appear if YAML front-matter is not parsed correctly
|
||||
@@ -142,8 +37,8 @@ export const addDiagrams = () => {
|
||||
// Quite ok, clear needs to be there for --- to work as a regular diagram
|
||||
},
|
||||
},
|
||||
styles: errorStyles, // should never be used
|
||||
renderer: errorRenderer, // should never be used
|
||||
styles: {}, // should never be used
|
||||
renderer: {}, // should never be used
|
||||
parser: {
|
||||
parser: { yy: {} },
|
||||
parse: () => {
|
||||
@@ -160,220 +55,25 @@ export const addDiagrams = () => {
|
||||
return text.toLowerCase().trimStart().startsWith('---');
|
||||
}
|
||||
);
|
||||
|
||||
registerDiagram(
|
||||
'c4',
|
||||
{
|
||||
parser: c4Parser,
|
||||
db: c4Db,
|
||||
renderer: c4Renderer,
|
||||
styles: c4Styles,
|
||||
init: (cnf) => {
|
||||
c4Renderer.setConf(cnf.c4);
|
||||
},
|
||||
},
|
||||
c4Detector
|
||||
);
|
||||
registerDiagram(
|
||||
'class',
|
||||
{
|
||||
parser: classParser,
|
||||
db: classDb,
|
||||
renderer: classRenderer,
|
||||
styles: classStyles,
|
||||
init: (cnf) => {
|
||||
if (!cnf.class) {
|
||||
cnf.class = {};
|
||||
}
|
||||
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
classDb.clear();
|
||||
},
|
||||
},
|
||||
classDetector
|
||||
);
|
||||
registerDiagram(
|
||||
'classDiagram',
|
||||
{
|
||||
parser: classParser,
|
||||
db: classDb,
|
||||
renderer: classRendererV2,
|
||||
styles: classStyles,
|
||||
init: (cnf) => {
|
||||
if (!cnf.class) {
|
||||
cnf.class = {};
|
||||
}
|
||||
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
classDb.clear();
|
||||
},
|
||||
},
|
||||
classDetectorV2
|
||||
);
|
||||
registerDiagram(
|
||||
'er',
|
||||
{
|
||||
parser: erParser,
|
||||
db: erDb,
|
||||
renderer: erRenderer,
|
||||
styles: erStyles,
|
||||
},
|
||||
erDetector
|
||||
);
|
||||
registerDiagram(
|
||||
'gantt',
|
||||
{
|
||||
parser: ganttParser,
|
||||
db: ganttDb,
|
||||
renderer: ganttRenderer,
|
||||
styles: ganttStyles,
|
||||
},
|
||||
ganttDetector
|
||||
);
|
||||
registerDiagram(
|
||||
'info',
|
||||
{
|
||||
parser: infoParser,
|
||||
db: infoDb,
|
||||
renderer: infoRenderer,
|
||||
styles: infoStyles,
|
||||
},
|
||||
infoDetector
|
||||
);
|
||||
registerDiagram(
|
||||
'pie',
|
||||
{
|
||||
parser: pieParser,
|
||||
db: pieDb,
|
||||
renderer: pieRenderer,
|
||||
styles: pieStyles,
|
||||
},
|
||||
pieDetector
|
||||
);
|
||||
registerDiagram(
|
||||
'requirement',
|
||||
{
|
||||
parser: requirementParser,
|
||||
db: requirementDb,
|
||||
renderer: requirementRenderer,
|
||||
styles: requirementStyles,
|
||||
},
|
||||
requirementDetector
|
||||
);
|
||||
registerDiagram(
|
||||
'sequence',
|
||||
{
|
||||
parser: sequenceParser,
|
||||
db: sequenceDb,
|
||||
renderer: sequenceRenderer,
|
||||
styles: sequenceStyles,
|
||||
init: (cnf) => {
|
||||
if (!cnf.sequence) {
|
||||
cnf.sequence = {};
|
||||
}
|
||||
cnf.sequence.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
if ('sequenceDiagram' in cnf) {
|
||||
throw new Error(
|
||||
'`mermaid config.sequenceDiagram` has been renamed to `config.sequence`. Please update your mermaid config.'
|
||||
);
|
||||
}
|
||||
sequenceDb.setWrap(cnf.wrap);
|
||||
sequenceRenderer.setConf(cnf.sequence);
|
||||
},
|
||||
},
|
||||
sequenceDetector
|
||||
);
|
||||
registerDiagram(
|
||||
'state',
|
||||
{
|
||||
parser: stateParser,
|
||||
db: stateDb,
|
||||
renderer: stateRenderer,
|
||||
styles: stateStyles,
|
||||
init: (cnf) => {
|
||||
if (!cnf.state) {
|
||||
cnf.state = {};
|
||||
}
|
||||
cnf.state.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
stateDb.clear();
|
||||
},
|
||||
},
|
||||
stateDetector
|
||||
);
|
||||
registerDiagram(
|
||||
'stateDiagram',
|
||||
{
|
||||
parser: stateParser,
|
||||
db: stateDb,
|
||||
renderer: stateRendererV2,
|
||||
styles: stateStyles,
|
||||
init: (cnf) => {
|
||||
if (!cnf.state) {
|
||||
cnf.state = {};
|
||||
}
|
||||
cnf.state.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
stateDb.clear();
|
||||
},
|
||||
},
|
||||
stateDetectorV2
|
||||
);
|
||||
registerDiagram(
|
||||
'journey',
|
||||
{
|
||||
parser: journeyParser,
|
||||
db: journeyDb,
|
||||
renderer: journeyRenderer,
|
||||
styles: journeyStyles,
|
||||
init: (cnf) => {
|
||||
journeyRenderer.setConf(cnf.journey);
|
||||
journeyDb.clear();
|
||||
},
|
||||
},
|
||||
journeyDetector
|
||||
);
|
||||
|
||||
registerDiagram(
|
||||
'flowchart',
|
||||
{
|
||||
parser: flowParser,
|
||||
db: flowDb,
|
||||
renderer: flowRendererV2,
|
||||
styles: flowStyles,
|
||||
init: (cnf) => {
|
||||
if (!cnf.flowchart) {
|
||||
cnf.flowchart = {};
|
||||
}
|
||||
// TODO, broken as of 2022-09-14 (13809b50251845475e6dca65cc395761be38fbd2)
|
||||
cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
flowRenderer.setConf(cnf.flowchart);
|
||||
flowDb.clear();
|
||||
flowDb.setGen('gen-1');
|
||||
},
|
||||
},
|
||||
flowDetector
|
||||
);
|
||||
registerDiagram(
|
||||
'flowchart-v2',
|
||||
{
|
||||
parser: flowParser,
|
||||
db: flowDb,
|
||||
renderer: flowRendererV2,
|
||||
styles: flowStyles,
|
||||
init: (cnf) => {
|
||||
if (!cnf.flowchart) {
|
||||
cnf.flowchart = {};
|
||||
}
|
||||
cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
// flowchart-v2 uses dagre-wrapper, which doesn't have access to flowchart cnf
|
||||
setConfig({ flowchart: { arrowMarkerAbsolute: cnf.arrowMarkerAbsolute } });
|
||||
flowRendererV2.setConf(cnf.flowchart);
|
||||
flowDb.clear();
|
||||
flowDb.setGen('gen-2');
|
||||
},
|
||||
},
|
||||
flowDetectorV2
|
||||
);
|
||||
registerDiagram(
|
||||
'gitGraph',
|
||||
{ parser: gitGraphParser, db: gitGraphDb, renderer: gitGraphRenderer, styles: gitGraphStyles },
|
||||
gitGraphDetector
|
||||
registerLazyLoadedDiagrams(
|
||||
error,
|
||||
c4,
|
||||
classDiagram,
|
||||
classDiagramV2,
|
||||
er,
|
||||
gantt,
|
||||
info,
|
||||
pie,
|
||||
requirement,
|
||||
sequence,
|
||||
flowchart,
|
||||
flowchartV2,
|
||||
flowchartElk,
|
||||
mindmap,
|
||||
timeline,
|
||||
git,
|
||||
state,
|
||||
stateV2,
|
||||
journey
|
||||
);
|
||||
};
|
||||
|
@@ -2,8 +2,12 @@ import { detectType } from './detectType';
|
||||
import { getDiagram, registerDiagram } from './diagramAPI';
|
||||
import { addDiagrams } from './diagram-orchestration';
|
||||
import { DiagramDetector } from './types';
|
||||
import { getDiagramFromText } from '../Diagram';
|
||||
|
||||
addDiagrams();
|
||||
beforeAll(async () => {
|
||||
await getDiagramFromText('sequenceDiagram');
|
||||
});
|
||||
|
||||
describe('DiagramAPI', () => {
|
||||
it('should return default diagrams', () => {
|
||||
|
@@ -71,3 +71,9 @@ export const getDiagram = (name: string): DiagramDefinition => {
|
||||
}
|
||||
throw new Error(`Diagram ${name} not found.`);
|
||||
};
|
||||
|
||||
export class DiagramNotFoundError extends Error {
|
||||
constructor(message: string) {
|
||||
super(`Diagram ${message} not found.`);
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,20 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/types';
|
||||
import type { ExternalDiagramDefinition } from '../../diagram-api/types';
|
||||
|
||||
export const c4Detector: DiagramDetector = (txt) => {
|
||||
const id = 'c4';
|
||||
|
||||
const detector = (txt: string) => {
|
||||
return txt.match(/^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/) !== null;
|
||||
};
|
||||
|
||||
const loader = async () => {
|
||||
const { diagram } = await import('./c4Diagram');
|
||||
return { id, diagram };
|
||||
};
|
||||
|
||||
const plugin: ExternalDiagramDefinition = {
|
||||
id,
|
||||
detector,
|
||||
loader,
|
||||
};
|
||||
|
||||
export default plugin;
|
||||
|
17
packages/mermaid/src/diagrams/c4/c4Diagram.ts
Normal file
17
packages/mermaid/src/diagrams/c4/c4Diagram.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import c4Parser from './parser/c4Diagram';
|
||||
import c4Db from './c4Db';
|
||||
import c4Renderer from './c4Renderer';
|
||||
import c4Styles from './styles';
|
||||
import { MermaidConfig } from '../../config.type';
|
||||
import { DiagramDefinition } from '../../diagram-api/types';
|
||||
|
||||
export const diagram: DiagramDefinition = {
|
||||
parser: c4Parser,
|
||||
db: c4Db,
|
||||
renderer: c4Renderer,
|
||||
styles: c4Styles,
|
||||
init: (cnf: MermaidConfig) => {
|
||||
c4Renderer.setConf(cnf.c4);
|
||||
},
|
||||
};
|
@@ -1,6 +1,8 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/types';
|
||||
import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-api/types';
|
||||
|
||||
export const classDetectorV2: DiagramDetector = (txt, config) => {
|
||||
const id = 'classDiagram';
|
||||
|
||||
const detector: DiagramDetector = (txt, config) => {
|
||||
// If we have configured to use dagre-wrapper then we should return true in this function for classDiagram code thus making it use the new class diagram
|
||||
if (
|
||||
txt.match(/^\s*classDiagram/) !== null &&
|
||||
@@ -11,3 +13,16 @@ export const classDetectorV2: DiagramDetector = (txt, config) => {
|
||||
// We have not opted to use the new renderer so we should return true if we detect a class diagram
|
||||
return txt.match(/^\s*classDiagram-v2/) !== null;
|
||||
};
|
||||
|
||||
const loader = async () => {
|
||||
const { diagram } = await import('./classDiagram-v2');
|
||||
return { id, diagram };
|
||||
};
|
||||
|
||||
const plugin: ExternalDiagramDefinition = {
|
||||
id,
|
||||
detector,
|
||||
loader,
|
||||
};
|
||||
|
||||
export default plugin;
|
||||
|
@@ -1,6 +1,8 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/types';
|
||||
import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-api/types';
|
||||
|
||||
export const classDetector: DiagramDetector = (txt, config) => {
|
||||
const id = 'class';
|
||||
|
||||
const detector: DiagramDetector = (txt, config) => {
|
||||
// If we have configured to use dagre-wrapper then we should never return true in this function
|
||||
if (config?.class?.defaultRenderer === 'dagre-wrapper') {
|
||||
return false;
|
||||
@@ -8,3 +10,16 @@ export const classDetector: DiagramDetector = (txt, config) => {
|
||||
// We have not opted to use the new renderer so we should return true if we detect a class diagram
|
||||
return txt.match(/^\s*classDiagram/) !== null;
|
||||
};
|
||||
|
||||
const loader = async () => {
|
||||
const { diagram } = await import('./classDiagram');
|
||||
return { id, diagram };
|
||||
};
|
||||
|
||||
const plugin: ExternalDiagramDefinition = {
|
||||
id,
|
||||
detector,
|
||||
loader,
|
||||
};
|
||||
|
||||
export default plugin;
|
||||
|
20
packages/mermaid/src/diagrams/class/classDiagram-v2.ts
Normal file
20
packages/mermaid/src/diagrams/class/classDiagram-v2.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { DiagramDefinition } from '../../diagram-api/types';
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import parser from './parser/classDiagram';
|
||||
import db from './classDb';
|
||||
import styles from './styles';
|
||||
import renderer from './classRenderer-v2';
|
||||
|
||||
export const diagram: DiagramDefinition = {
|
||||
parser,
|
||||
db,
|
||||
renderer,
|
||||
styles,
|
||||
init: (cnf) => {
|
||||
if (!cnf.class) {
|
||||
cnf.class = {};
|
||||
}
|
||||
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
db.clear();
|
||||
},
|
||||
};
|
20
packages/mermaid/src/diagrams/class/classDiagram.ts
Normal file
20
packages/mermaid/src/diagrams/class/classDiagram.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { DiagramDefinition } from '../../diagram-api/types';
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import parser from './parser/classDiagram';
|
||||
import db from './classDb';
|
||||
import styles from './styles';
|
||||
import renderer from './classRenderer';
|
||||
|
||||
export const diagram: DiagramDefinition = {
|
||||
parser,
|
||||
db,
|
||||
renderer,
|
||||
styles,
|
||||
init: (cnf) => {
|
||||
if (!cnf.class) {
|
||||
cnf.class = {};
|
||||
}
|
||||
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
db.clear();
|
||||
},
|
||||
};
|
@@ -1,5 +1,20 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/types';
|
||||
import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-api/types';
|
||||
|
||||
export const erDetector: DiagramDetector = (txt) => {
|
||||
const id = 'er';
|
||||
|
||||
const detector: DiagramDetector = (txt) => {
|
||||
return txt.match(/^\s*erDiagram/) !== null;
|
||||
};
|
||||
|
||||
const loader = async () => {
|
||||
const { diagram } = await import('./erDiagram');
|
||||
return { id, diagram };
|
||||
};
|
||||
|
||||
const plugin: ExternalDiagramDefinition = {
|
||||
id,
|
||||
detector,
|
||||
loader,
|
||||
};
|
||||
|
||||
export default plugin;
|
||||
|
12
packages/mermaid/src/diagrams/er/erDiagram.ts
Normal file
12
packages/mermaid/src/diagrams/er/erDiagram.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import erParser from './parser/erDiagram';
|
||||
import erDb from './erDb';
|
||||
import erRenderer from './erRenderer';
|
||||
import erStyles from './styles';
|
||||
|
||||
export const diagram = {
|
||||
parser: erParser,
|
||||
db: erDb,
|
||||
renderer: erRenderer,
|
||||
styles: erStyles,
|
||||
};
|
@@ -81,7 +81,7 @@ start
|
||||
|
||||
document
|
||||
: /* empty */ { $$ = [] }
|
||||
| document line {$1.push($2);$$ = $1}
|
||||
| document line {$1.push($2);$$ = $1}
|
||||
;
|
||||
|
||||
line
|
||||
|
20
packages/mermaid/src/diagrams/error/errorDetector.ts
Normal file
20
packages/mermaid/src/diagrams/error/errorDetector.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-api/types';
|
||||
|
||||
const id = 'error';
|
||||
|
||||
const detector: DiagramDetector = (text) => {
|
||||
return text.toLowerCase().trim() === 'error';
|
||||
};
|
||||
|
||||
const loader = async () => {
|
||||
const { diagram } = await import('./errorDiagram');
|
||||
return { id, diagram };
|
||||
};
|
||||
|
||||
const plugin: ExternalDiagramDefinition = {
|
||||
id,
|
||||
detector,
|
||||
loader,
|
||||
};
|
||||
|
||||
export default plugin;
|
21
packages/mermaid/src/diagrams/error/errorDiagram.ts
Normal file
21
packages/mermaid/src/diagrams/error/errorDiagram.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { DiagramDefinition } from '../../diagram-api/types';
|
||||
import styles from './styles';
|
||||
import renderer from './errorRenderer';
|
||||
export const diagram: DiagramDefinition = {
|
||||
db: {
|
||||
clear: () => {
|
||||
// Quite ok, clear needs to be there for error to work as a regular diagram
|
||||
},
|
||||
},
|
||||
styles,
|
||||
renderer,
|
||||
parser: {
|
||||
parser: { yy: {} },
|
||||
parse: () => {
|
||||
// no op
|
||||
},
|
||||
},
|
||||
init: () => {
|
||||
// no op
|
||||
},
|
||||
};
|
@@ -677,6 +677,10 @@ const destructEndLink = (_str) => {
|
||||
stroke = 'thick';
|
||||
}
|
||||
|
||||
if (line[0] === '~') {
|
||||
stroke = 'invisible';
|
||||
}
|
||||
|
||||
let dots = countChar('.', line);
|
||||
|
||||
if (dots) {
|
||||
|
@@ -1,6 +1,9 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/types';
|
||||
import type { ExternalDiagramDefinition } from '../../diagram-api/types';
|
||||
|
||||
export const flowDetectorV2: DiagramDetector = (txt, config) => {
|
||||
const id = 'flowchart-v2';
|
||||
|
||||
const detector: DiagramDetector = (txt, config) => {
|
||||
if (config?.flowchart?.defaultRenderer === 'dagre-d3') {
|
||||
return false;
|
||||
}
|
||||
@@ -14,3 +17,16 @@ export const flowDetectorV2: DiagramDetector = (txt, config) => {
|
||||
}
|
||||
return txt.match(/^\s*flowchart/) !== null;
|
||||
};
|
||||
|
||||
const loader = async () => {
|
||||
const { diagram } = await import('./flowDiagram-v2');
|
||||
return { id, diagram };
|
||||
};
|
||||
|
||||
const plugin: ExternalDiagramDefinition = {
|
||||
id,
|
||||
detector,
|
||||
loader,
|
||||
};
|
||||
|
||||
export default plugin;
|
||||
|
@@ -1,6 +1,8 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/types';
|
||||
import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-api/types';
|
||||
|
||||
export const flowDetector: DiagramDetector = (txt, config) => {
|
||||
const id = 'flowchart';
|
||||
|
||||
const detector: DiagramDetector = (txt, config) => {
|
||||
// If we have conferred to only use new flow charts this function should always return false
|
||||
// as in not signalling true for a legacy flowchart
|
||||
if (config?.flowchart?.defaultRenderer === 'dagre-wrapper') {
|
||||
@@ -11,3 +13,16 @@ export const flowDetector: DiagramDetector = (txt, config) => {
|
||||
}
|
||||
return txt.match(/^\s*graph/) !== null;
|
||||
};
|
||||
|
||||
const loader = async () => {
|
||||
const { diagram } = await import('./flowDiagram');
|
||||
return { id, diagram };
|
||||
};
|
||||
|
||||
const plugin: ExternalDiagramDefinition = {
|
||||
id,
|
||||
detector,
|
||||
loader,
|
||||
};
|
||||
|
||||
export default plugin;
|
||||
|
25
packages/mermaid/src/diagrams/flowchart/flowDiagram-v2.ts
Normal file
25
packages/mermaid/src/diagrams/flowchart/flowDiagram-v2.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import flowParser from './parser/flow';
|
||||
import flowDb from './flowDb';
|
||||
import flowRendererV2 from './flowRenderer-v2';
|
||||
import flowStyles from './styles';
|
||||
import { MermaidConfig } from '../../config.type';
|
||||
import { setConfig } from '../../config';
|
||||
|
||||
export const diagram = {
|
||||
parser: flowParser,
|
||||
db: flowDb,
|
||||
renderer: flowRendererV2,
|
||||
styles: flowStyles,
|
||||
init: (cnf: MermaidConfig) => {
|
||||
if (!cnf.flowchart) {
|
||||
cnf.flowchart = {};
|
||||
}
|
||||
cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
// flowchart-v2 uses dagre-wrapper, which doesn't have access to flowchart cnf
|
||||
setConfig({ flowchart: { arrowMarkerAbsolute: cnf.arrowMarkerAbsolute } });
|
||||
flowRendererV2.setConf(cnf.flowchart);
|
||||
flowDb.clear();
|
||||
flowDb.setGen('gen-2');
|
||||
},
|
||||
};
|
24
packages/mermaid/src/diagrams/flowchart/flowDiagram.ts
Normal file
24
packages/mermaid/src/diagrams/flowchart/flowDiagram.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import flowParser from './parser/flow';
|
||||
import flowDb from './flowDb';
|
||||
import flowRenderer from './flowRenderer';
|
||||
import flowRendererV2 from './flowRenderer-v2';
|
||||
import flowStyles from './styles';
|
||||
import { MermaidConfig } from '../../config.type';
|
||||
|
||||
export const diagram = {
|
||||
parser: flowParser,
|
||||
db: flowDb,
|
||||
renderer: flowRendererV2,
|
||||
styles: flowStyles,
|
||||
init: (cnf: MermaidConfig) => {
|
||||
if (!cnf.flowchart) {
|
||||
cnf.flowchart = {};
|
||||
}
|
||||
// TODO, broken as of 2022-09-14 (13809b50251845475e6dca65cc395761be38fbd2)
|
||||
cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
flowRenderer.setConf(cnf.flowchart);
|
||||
flowDb.clear();
|
||||
flowDb.setGen('gen-1');
|
||||
},
|
||||
};
|
@@ -280,6 +280,11 @@ export const addEdges = function (edges, g, diagObj) {
|
||||
edgeData.pattern = 'solid';
|
||||
edgeData.style = 'stroke-width: 3.5px;fill:none;';
|
||||
break;
|
||||
case 'invisible':
|
||||
edgeData.thickness = 'invisible';
|
||||
edgeData.pattern = 'solid';
|
||||
edgeData.style = 'stroke-width: 0;fill:none;';
|
||||
break;
|
||||
}
|
||||
if (edge.style !== undefined) {
|
||||
const styles = getStylesFromArray(edge.style);
|
||||
|
@@ -1,21 +1,24 @@
|
||||
import flowDb from './flowDb';
|
||||
import flowParser from './parser/flow';
|
||||
import { parser } from './parser/flow';
|
||||
import flowRenderer from './flowRenderer';
|
||||
import { Diagram } from '../../Diagram';
|
||||
import { addDiagrams } from '../../diagram-api/diagram-orchestration';
|
||||
|
||||
const diag = {
|
||||
db: flowDb,
|
||||
};
|
||||
addDiagrams();
|
||||
|
||||
describe('when using mermaid and ', function () {
|
||||
describe('when calling addEdges ', function () {
|
||||
beforeEach(function () {
|
||||
flowParser.parser.yy = flowDb;
|
||||
parser.yy = flowDb;
|
||||
flowDb.clear();
|
||||
flowDb.setGen('gen-2');
|
||||
});
|
||||
it('should handle edges with text', function () {
|
||||
const diag = new Diagram('graph TD;A-->|text ex|B;');
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
it('should handle edges with text', () => {
|
||||
parser.parse('graph TD;A-->|text ex|B;');
|
||||
flowDb.getVertices();
|
||||
const edges = flowDb.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
@@ -29,10 +32,10 @@ describe('when using mermaid and ', function () {
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
|
||||
it('should handle edges without text', function () {
|
||||
const diag = new Diagram('graph TD;A-->B;');
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
it('should handle edges without text', async function () {
|
||||
parser.parse('graph TD;A-->B;');
|
||||
flowDb.getVertices();
|
||||
const edges = flowDb.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
@@ -45,10 +48,10 @@ describe('when using mermaid and ', function () {
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
|
||||
it('should handle open-ended edges', function () {
|
||||
const diag = new Diagram('graph TD;A---B;');
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
it('should handle open-ended edges', () => {
|
||||
parser.parse('graph TD;A---B;');
|
||||
flowDb.getVertices();
|
||||
const edges = flowDb.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
@@ -61,10 +64,10 @@ describe('when using mermaid and ', function () {
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
|
||||
it('should handle edges with styles defined', function () {
|
||||
const diag = new Diagram('graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2;');
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
it('should handle edges with styles defined', () => {
|
||||
parser.parse('graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2;');
|
||||
flowDb.getVertices();
|
||||
const edges = flowDb.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
@@ -77,10 +80,10 @@ describe('when using mermaid and ', function () {
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
it('should handle edges with interpolation defined', function () {
|
||||
const diag = new Diagram('graph TD;A---B; linkStyle 0 interpolate basis');
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
it('should handle edges with interpolation defined', () => {
|
||||
parser.parse('graph TD;A---B; linkStyle 0 interpolate basis');
|
||||
flowDb.getVertices();
|
||||
const edges = flowDb.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
@@ -93,12 +96,10 @@ describe('when using mermaid and ', function () {
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
it('should handle edges with text and styles defined', function () {
|
||||
const diag = new Diagram(
|
||||
'graph TD;A---|the text|B; linkStyle 0 stroke:val1,stroke-width:val2;'
|
||||
);
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
it('should handle edges with text and styles defined', () => {
|
||||
parser.parse('graph TD;A---|the text|B; linkStyle 0 stroke:val1,stroke-width:val2;');
|
||||
flowDb.getVertices();
|
||||
const edges = flowDb.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
@@ -113,10 +114,10 @@ describe('when using mermaid and ', function () {
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
|
||||
it('should set fill to "none" by default when handling edges', function () {
|
||||
const diag = new Diagram('graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2;');
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
it('should set fill to "none" by default when handling edges', () => {
|
||||
parser.parse('graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2;');
|
||||
flowDb.getVertices();
|
||||
const edges = flowDb.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
@@ -130,12 +131,10 @@ describe('when using mermaid and ', function () {
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
|
||||
it('should not set fill to none if fill is set in linkStyle', function () {
|
||||
const diag = new Diagram(
|
||||
'graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2,fill:blue;'
|
||||
);
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
it('should not set fill to none if fill is set in linkStyle', () => {
|
||||
parser.parse('graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2,fill:blue;');
|
||||
flowDb.getVertices();
|
||||
const edges = flowDb.getEdges();
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
expect(start).toContain('flowchart-A-');
|
||||
|
@@ -121,6 +121,7 @@ that id.
|
||||
\s*[xo<]?\-\-+[-xo>]\s* return 'LINK';
|
||||
\s*[xo<]?\=\=+[=xo>]\s* return 'LINK';
|
||||
\s*[xo<]?\-?\.+\-[xo>]?\s* return 'LINK';
|
||||
\s*\~\~[\~]+\s* return 'LINK';
|
||||
\s*[xo<]?\-\-\s* return 'START_LINK';
|
||||
\s*[xo<]?\=\=\s* return 'START_LINK';
|
||||
\s*[xo<]?\-\.\s* return 'START_LINK';
|
||||
|
@@ -1,5 +1,20 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/types';
|
||||
import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-api/types';
|
||||
|
||||
export const ganttDetector: DiagramDetector = (txt) => {
|
||||
const id = 'gantt';
|
||||
|
||||
const detector: DiagramDetector = (txt) => {
|
||||
return txt.match(/^\s*gantt/) !== null;
|
||||
};
|
||||
|
||||
const loader = async () => {
|
||||
const { diagram } = await import('./ganttDiagram');
|
||||
return { id, diagram };
|
||||
};
|
||||
|
||||
const plugin: ExternalDiagramDefinition = {
|
||||
id,
|
||||
detector,
|
||||
loader,
|
||||
};
|
||||
|
||||
export default plugin;
|
||||
|
13
packages/mermaid/src/diagrams/gantt/ganttDiagram.ts
Normal file
13
packages/mermaid/src/diagrams/gantt/ganttDiagram.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import ganttParser from './parser/gantt';
|
||||
import ganttDb from './ganttDb';
|
||||
import ganttRenderer from './ganttRenderer';
|
||||
import ganttStyles from './styles';
|
||||
import { DiagramDefinition } from '../../diagram-api/types';
|
||||
|
||||
export const diagram: DiagramDefinition = {
|
||||
parser: ganttParser,
|
||||
db: ganttDb,
|
||||
renderer: ganttRenderer,
|
||||
styles: ganttStyles,
|
||||
};
|
@@ -1,5 +1,21 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/types';
|
||||
import type { ExternalDiagramDefinition } from '../../diagram-api/types';
|
||||
|
||||
export const gitGraphDetector: DiagramDetector = (txt) => {
|
||||
const id = 'gitGraph';
|
||||
|
||||
const detector: DiagramDetector = (txt) => {
|
||||
return txt.match(/^\s*gitGraph/) !== null;
|
||||
};
|
||||
|
||||
const loader = async () => {
|
||||
const { diagram } = await import('./gitGraphDiagram');
|
||||
return { id, diagram };
|
||||
};
|
||||
|
||||
const plugin: ExternalDiagramDefinition = {
|
||||
id,
|
||||
detector,
|
||||
loader,
|
||||
};
|
||||
|
||||
export default plugin;
|
||||
|
13
packages/mermaid/src/diagrams/git/gitGraphDiagram.ts
Normal file
13
packages/mermaid/src/diagrams/git/gitGraphDiagram.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import gitGraphParser from './parser/gitGraph';
|
||||
import gitGraphDb from './gitGraphAst';
|
||||
import gitGraphRenderer from './gitGraphRenderer';
|
||||
import gitGraphStyles from './styles';
|
||||
import { DiagramDefinition } from '../../diagram-api/types';
|
||||
|
||||
export const diagram: DiagramDefinition = {
|
||||
parser: gitGraphParser,
|
||||
db: gitGraphDb,
|
||||
renderer: gitGraphRenderer,
|
||||
styles: gitGraphStyles,
|
||||
};
|
@@ -1,5 +1,20 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/types';
|
||||
import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-api/types';
|
||||
|
||||
export const infoDetector: DiagramDetector = (txt) => {
|
||||
const id = 'info';
|
||||
|
||||
const detector: DiagramDetector = (txt) => {
|
||||
return txt.match(/^\s*info/) !== null;
|
||||
};
|
||||
|
||||
const loader = async () => {
|
||||
const { diagram } = await import('./infoDiagram');
|
||||
return { id, diagram };
|
||||
};
|
||||
|
||||
const plugin: ExternalDiagramDefinition = {
|
||||
id,
|
||||
detector,
|
||||
loader,
|
||||
};
|
||||
|
||||
export default plugin;
|
||||
|
13
packages/mermaid/src/diagrams/info/infoDiagram.ts
Normal file
13
packages/mermaid/src/diagrams/info/infoDiagram.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { DiagramDefinition } from '../../diagram-api/types';
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import parser from './parser/info';
|
||||
import db from './infoDb';
|
||||
import styles from './styles';
|
||||
import renderer from './infoRenderer';
|
||||
|
||||
export const diagram: DiagramDefinition = {
|
||||
parser,
|
||||
db,
|
||||
renderer,
|
||||
styles,
|
||||
};
|
@@ -1,6 +1,20 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/types';
|
||||
import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-api/types';
|
||||
|
||||
export const pieDetector: DiagramDetector = (txt) => {
|
||||
const logOutput = txt.match(/^\s*pie/) !== null || txt.match(/^\s*bar/) !== null;
|
||||
return logOutput;
|
||||
const id = 'pie';
|
||||
|
||||
const detector: DiagramDetector = (txt) => {
|
||||
return txt.match(/^\s*pie/) !== null;
|
||||
};
|
||||
|
||||
const loader = async () => {
|
||||
const { diagram } = await import('./pieDiagram');
|
||||
return { id, diagram };
|
||||
};
|
||||
|
||||
const plugin: ExternalDiagramDefinition = {
|
||||
id,
|
||||
detector,
|
||||
loader,
|
||||
};
|
||||
|
||||
export default plugin;
|
||||
|
13
packages/mermaid/src/diagrams/pie/pieDiagram.ts
Normal file
13
packages/mermaid/src/diagrams/pie/pieDiagram.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { DiagramDefinition } from '../../diagram-api/types';
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import parser from './parser/pie';
|
||||
import db from './pieDb';
|
||||
import styles from './styles';
|
||||
import renderer from './pieRenderer';
|
||||
|
||||
export const diagram: DiagramDefinition = {
|
||||
parser,
|
||||
db,
|
||||
renderer,
|
||||
styles,
|
||||
};
|
@@ -1,5 +1,20 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/types';
|
||||
import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-api/types';
|
||||
|
||||
export const requirementDetector: DiagramDetector = (txt) => {
|
||||
const id = 'requirement';
|
||||
|
||||
const detector: DiagramDetector = (txt) => {
|
||||
return txt.match(/^\s*requirement(Diagram)?/) !== null;
|
||||
};
|
||||
|
||||
const loader = async () => {
|
||||
const { diagram } = await import('./requirementDiagram');
|
||||
return { id, diagram };
|
||||
};
|
||||
|
||||
const plugin: ExternalDiagramDefinition = {
|
||||
id,
|
||||
detector,
|
||||
loader,
|
||||
};
|
||||
|
||||
export default plugin;
|
||||
|
@@ -0,0 +1,13 @@
|
||||
import { DiagramDefinition } from '../../diagram-api/types';
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import parser from './parser/requirementDiagram';
|
||||
import db from './requirementDb';
|
||||
import styles from './styles';
|
||||
import renderer from './requirementRenderer';
|
||||
|
||||
export const diagram: DiagramDefinition = {
|
||||
parser,
|
||||
db,
|
||||
renderer,
|
||||
styles,
|
||||
};
|
@@ -1,5 +1,20 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/types';
|
||||
import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-api/types';
|
||||
|
||||
export const sequenceDetector: DiagramDetector = (txt) => {
|
||||
const id = 'sequence';
|
||||
|
||||
const detector: DiagramDetector = (txt) => {
|
||||
return txt.match(/^\s*sequenceDiagram/) !== null;
|
||||
};
|
||||
|
||||
const loader = async () => {
|
||||
const { diagram } = await import('./sequenceDiagram');
|
||||
return { id, diagram };
|
||||
};
|
||||
|
||||
const plugin: ExternalDiagramDefinition = {
|
||||
id,
|
||||
detector,
|
||||
loader,
|
||||
};
|
||||
|
||||
export default plugin;
|
||||
|
@@ -2,9 +2,14 @@ import { vi } from 'vitest';
|
||||
|
||||
import * as configApi from '../../config';
|
||||
import mermaidAPI from '../../mermaidAPI';
|
||||
import { Diagram } from '../../Diagram';
|
||||
import { Diagram, getDiagramFromText } from '../../Diagram';
|
||||
import { addDiagrams } from '../../diagram-api/diagram-orchestration';
|
||||
|
||||
beforeAll(async () => {
|
||||
// Is required to load the sequence diagram
|
||||
await getDiagramFromText('sequenceDiagram');
|
||||
});
|
||||
|
||||
/**
|
||||
* Sequence diagrams require their own very special version of a mocked d3 module
|
||||
* diagrams/sequence/svgDraw uses statements like this with d3 nodes: (note the [0][0])
|
||||
@@ -183,7 +188,7 @@ Alice->Bob:Hello Bob, how are you?
|
||||
Note right of Bob: Bob thinks
|
||||
Bob-->Alice: I am good thanks!`;
|
||||
|
||||
await mermaidAPI.parse(str, diagram);
|
||||
await mermaidAPI.parse(str);
|
||||
const actors = diagram.db.getActors();
|
||||
expect(actors.Alice.description).toBe('Alice');
|
||||
actors.Bob.description = 'Bob';
|
||||
|
13
packages/mermaid/src/diagrams/sequence/sequenceDiagram.ts
Normal file
13
packages/mermaid/src/diagrams/sequence/sequenceDiagram.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { DiagramDefinition } from '../../diagram-api/types';
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import parser from './parser/sequenceDiagram';
|
||||
import db from './sequenceDb';
|
||||
import styles from './styles';
|
||||
import renderer from './sequenceRenderer';
|
||||
|
||||
export const diagram: DiagramDefinition = {
|
||||
parser,
|
||||
db,
|
||||
renderer,
|
||||
styles,
|
||||
};
|
@@ -117,7 +117,7 @@ describe('state parser can parse...', () => {
|
||||
state "Big State 1" as bigState1 {
|
||||
state "inner state 1" as inner1
|
||||
inner2: inner state 2
|
||||
inner1 --> inner2
|
||||
inner1 --> inner2
|
||||
}`;
|
||||
stateDiagram.parser.parse(diagramText);
|
||||
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
|
||||
|
@@ -1,11 +1,29 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/types';
|
||||
import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-api/types';
|
||||
|
||||
export const stateDetectorV2: DiagramDetector = (text, config) => {
|
||||
const id = 'stateDiagram';
|
||||
|
||||
const detector: DiagramDetector = (text, config) => {
|
||||
if (text.match(/^\s*stateDiagram-v2/) !== null) {
|
||||
return true;
|
||||
}
|
||||
if (text.match(/^\s*stateDiagram/) && config?.state?.defaultRenderer === 'dagre-wrapper') {
|
||||
return true;
|
||||
}
|
||||
if (text.match(/^\s*stateDiagram/) && config?.state?.defaultRenderer === 'dagre-wrapper') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const loader = async () => {
|
||||
const { diagram } = await import('./stateDiagram-v2');
|
||||
return { id, diagram };
|
||||
};
|
||||
|
||||
const plugin: ExternalDiagramDefinition = {
|
||||
id,
|
||||
detector,
|
||||
loader,
|
||||
};
|
||||
|
||||
export default plugin;
|
||||
|
@@ -1,6 +1,8 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/types';
|
||||
import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-api/types';
|
||||
|
||||
export const stateDetector: DiagramDetector = (txt, config) => {
|
||||
const id = 'state';
|
||||
|
||||
const detector: DiagramDetector = (txt, config) => {
|
||||
// If we have confirmed to only use new state diagrams this function should always return false
|
||||
// as in not signalling true for a legacy state diagram
|
||||
if (config?.state?.defaultRenderer === 'dagre-wrapper') {
|
||||
@@ -8,3 +10,16 @@ export const stateDetector: DiagramDetector = (txt, config) => {
|
||||
}
|
||||
return txt.match(/^\s*stateDiagram/) !== null;
|
||||
};
|
||||
|
||||
const loader = async () => {
|
||||
const { diagram } = await import('./stateDiagram');
|
||||
return { id, diagram };
|
||||
};
|
||||
|
||||
const plugin: ExternalDiagramDefinition = {
|
||||
id,
|
||||
detector,
|
||||
loader,
|
||||
};
|
||||
|
||||
export default plugin;
|
||||
|
20
packages/mermaid/src/diagrams/state/stateDiagram-v2.ts
Normal file
20
packages/mermaid/src/diagrams/state/stateDiagram-v2.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { DiagramDefinition } from '../../diagram-api/types';
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import parser from './parser/stateDiagram';
|
||||
import db from './stateDb';
|
||||
import styles from './styles';
|
||||
import renderer from './stateRenderer-v2';
|
||||
|
||||
export const diagram: DiagramDefinition = {
|
||||
parser,
|
||||
db,
|
||||
renderer,
|
||||
styles,
|
||||
init: (cnf) => {
|
||||
if (!cnf.state) {
|
||||
cnf.state = {};
|
||||
}
|
||||
cnf.state.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
db.clear();
|
||||
},
|
||||
};
|
20
packages/mermaid/src/diagrams/state/stateDiagram.ts
Normal file
20
packages/mermaid/src/diagrams/state/stateDiagram.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { DiagramDefinition } from '../../diagram-api/types';
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import parser from './parser/stateDiagram';
|
||||
import db from './stateDb';
|
||||
import styles from './styles';
|
||||
import renderer from './stateRenderer';
|
||||
|
||||
export const diagram: DiagramDefinition = {
|
||||
parser,
|
||||
db,
|
||||
renderer,
|
||||
styles,
|
||||
init: (cnf) => {
|
||||
if (!cnf.state) {
|
||||
cnf.state = {};
|
||||
}
|
||||
cnf.state.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
db.clear();
|
||||
},
|
||||
};
|
@@ -1,5 +1,20 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/types';
|
||||
import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-api/types';
|
||||
|
||||
export const journeyDetector: DiagramDetector = (txt) => {
|
||||
const id = 'journey';
|
||||
|
||||
const detector: DiagramDetector = (txt) => {
|
||||
return txt.match(/^\s*journey/) !== null;
|
||||
};
|
||||
|
||||
const loader = async () => {
|
||||
const { diagram } = await import('./journeyDiagram');
|
||||
return { id, diagram };
|
||||
};
|
||||
|
||||
const plugin: ExternalDiagramDefinition = {
|
||||
id,
|
||||
detector,
|
||||
loader,
|
||||
};
|
||||
|
||||
export default plugin;
|
||||
|
17
packages/mermaid/src/diagrams/user-journey/journeyDiagram.ts
Normal file
17
packages/mermaid/src/diagrams/user-journey/journeyDiagram.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { DiagramDefinition } from '../../diagram-api/types';
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import parser from './parser/journey';
|
||||
import db from './journeyDb';
|
||||
import styles from './styles';
|
||||
import renderer from './journeyRenderer';
|
||||
|
||||
export const diagram: DiagramDefinition = {
|
||||
parser,
|
||||
db,
|
||||
renderer,
|
||||
styles,
|
||||
init: (cnf) => {
|
||||
renderer.setConf(cnf.journey);
|
||||
db.clear();
|
||||
},
|
||||
};
|
@@ -17,7 +17,7 @@ const props = defineProps({
|
||||
},
|
||||
});
|
||||
|
||||
const svg = ref(null);
|
||||
const svg = ref('');
|
||||
let mut = null;
|
||||
|
||||
onMounted(async () => {
|
||||
|
@@ -2,6 +2,6 @@ import mermaid, { type MermaidConfig } from 'mermaid';
|
||||
|
||||
export const render = async (id: string, code: string, config: MermaidConfig): Promise<string> => {
|
||||
mermaid.initialize(config);
|
||||
const svg = await mermaid.render(id, code);
|
||||
const { svg } = await mermaid.render(id, code);
|
||||
return svg;
|
||||
};
|
||||
|
@@ -14,21 +14,24 @@ Please note that you can switch versions through the dropdown box at the top rig
|
||||
|
||||
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.
|
||||
We have compiled some Video [Tutorials](./Tutorials.md) on how to use the Mermaid Live Editor.
|
||||
|
||||
### Installing and Hosting Mermaid on a Webpage
|
||||
|
||||
**Using the npm package:**
|
||||
|
||||
1. You will need to install `node v16`, which would have npm.
|
||||
Requirements:
|
||||
|
||||
2. Download `yarn` using npm.
|
||||
- Node >= 16
|
||||
|
||||
3. Enter the following command: `yarn add mermaid`.
|
||||
|
||||
4. At this point, you can add mermaid as a dev dependency using this command: `yarn add --dev mermaid`.
|
||||
|
||||
5. Alternatively, you can also deploy mermaid using the script tag in an HTML file with mermaid diagram descriptions as is shown in the example below.
|
||||
```bash
|
||||
# NPM
|
||||
npm install mermaid
|
||||
# Yarn
|
||||
yarn add mermaid
|
||||
# PNPM
|
||||
pnpm add mermaid
|
||||
```
|
||||
|
||||
**Hosting mermaid on a web page:**
|
||||
|
||||
@@ -36,7 +39,9 @@ We have compiled some Video [Tutorials](./Tutorials.md) on how to use the mermai
|
||||
|
||||
The easiest way to integrate mermaid on a web page requires two elements:
|
||||
|
||||
- A graph definition, inside `<pre>` tags labeled `class=mermaid`. Example:
|
||||
- A graph definition, inside `<pre>` tags labeled `class=mermaid`.
|
||||
|
||||
Example:
|
||||
|
||||
```html
|
||||
<pre class="mermaid">
|
||||
@@ -47,14 +52,13 @@ The easiest way to integrate mermaid on a web page requires two elements:
|
||||
</pre>
|
||||
```
|
||||
|
||||
- Inclusion of the mermaid address in the html page body using a `script` tag as an ESM import, and the `mermaidAPI` call.
|
||||
- The mermaid js script. Added using a `script` tag as an ESM import.
|
||||
|
||||
Example:
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
import mermaid from '<CDN_URL>/mermaid@<MERMAID_VERSION>/dist/mermaid.esm.min.mjs';
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
</script>
|
||||
```
|
||||
|
||||
@@ -65,9 +69,6 @@ Example:
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
</head>
|
||||
<body>
|
||||
<pre class="mermaid">
|
||||
graph LR
|
||||
@@ -77,7 +78,6 @@ Example:
|
||||
</pre>
|
||||
<script type="module">
|
||||
import mermaid from '<CDN_URL>/mermaid@<MERMAID_VERSION>/dist/mermaid.esm.min.mjs';
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -89,11 +89,12 @@ An id attribute is also added to mermaid tags without one.
|
||||
|
||||
Mermaid can load multiple diagrams, in the same page.
|
||||
|
||||
> Try it out, save this code as HTML and load it using any browser.(Except Internet Explorer, please don't use Internet Explorer.)
|
||||
> Try it out, save this code as HTML and load it using any browser.
|
||||
> (Except Internet Explorer, please don't use Internet Explorer.)
|
||||
|
||||
## Enabling Click Event and Tags in Nodes
|
||||
|
||||
A `securityLevel` configuration has to first be cleared, `securityLevel` sets the level of trust for the parsed diagrams and limits click functionality. This was introduce in version 8.2 as a security improvement, aimed at preventing malicious use.
|
||||
A `securityLevel` configuration has to first be cleared. `securityLevel` sets the level of trust for the parsed diagrams and limits click functionality. This was introduce in version 8.2 as a security improvement, aimed at preventing malicious use.
|
||||
|
||||
**It is the site owner's responsibility to discriminate between trustworthy and untrustworthy user-bases and we encourage the use of discretion.**
|
||||
|
||||
@@ -101,7 +102,7 @@ A `securityLevel` configuration has to first be cleared, `securityLevel` sets th
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ------------- | --------------------------------- | ------ | -------- | ------------------------------------------ |
|
||||
| securityLevel | Level of trust for parsed diagram | String | Required | 'sandbox', 'strict', 'loose', 'antiscript' |
|
||||
| securityLevel | Level of trust for parsed diagram | String | Optional | 'sandbox', 'strict', 'loose', 'antiscript' |
|
||||
|
||||
Values:
|
||||
|
||||
@@ -117,26 +118,17 @@ This changes the default behaviour of mermaid so that after upgrade to 8.2, unle
|
||||
|
||||
**If you are taking responsibility for the diagram source security you can set the `securityLevel` to a value of your choosing . This allows clicks and tags are allowed.**
|
||||
|
||||
**To change `securityLevel`, you have to call `mermaidAPI.initialize`:**
|
||||
**To change `securityLevel`, you have to call `mermaid.initialize`:**
|
||||
|
||||
```javascript
|
||||
mermaidAPI.initialize({
|
||||
mermaid.initialize({
|
||||
securityLevel: 'loose',
|
||||
});
|
||||
```
|
||||
|
||||
### Labels out of bounds
|
||||
|
||||
If you use dynamically loaded fonts that are loaded through CSS, such as Google fonts, mermaid should wait for the
|
||||
whole page to load (dom + assets, particularly the fonts file).
|
||||
|
||||
```javascript
|
||||
$(document).load(function () {
|
||||
mermaid.initialize();
|
||||
});
|
||||
```
|
||||
|
||||
or
|
||||
If you use dynamically loaded fonts that are loaded through CSS, such as fonts, mermaid should wait for the whole page to load (dom + assets, particularly the fonts file).
|
||||
|
||||
```javascript
|
||||
$(document).ready(function () {
|
||||
@@ -149,12 +141,55 @@ Not doing so will most likely result in mermaid rendering graphs that have label
|
||||
If your page has other fonts in its body those might be used instead of the mermaid font. Specifying the font in your styling is a workaround for this.
|
||||
|
||||
```css
|
||||
div.mermaid {
|
||||
pre.mermaid {
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
}
|
||||
```
|
||||
|
||||
### Calling `mermaid.init`
|
||||
### Using `mermaid.run`
|
||||
|
||||
mermaid.run was added in v10 and is the preferred way of handling more complex integration.
|
||||
By default, `mermaid.run` will be called when the document is ready, rendering all elements with `class="mermaid"`.
|
||||
|
||||
You can customize that behavior by calling `await mermaid.run(<config>)`.
|
||||
|
||||
`mermaid.initialize({startOnLoad: false})` will prevent `mermaid.run` from being called automatically after load.
|
||||
|
||||
Render all elements with querySelector ".someOtherClass"
|
||||
|
||||
```js
|
||||
mermaid.initialize({ startOnLoad: false });
|
||||
await mermaid.run({
|
||||
querySelector: '.someOtherClass',
|
||||
});
|
||||
```
|
||||
|
||||
Render all elements passed as an array
|
||||
|
||||
```js
|
||||
mermaid.initialize({ startOnLoad: false });
|
||||
await mermaid.run({
|
||||
nodes: [document.getElementById('someId'), document.getElementById('anotherId')],
|
||||
});
|
||||
await mermaid.run({
|
||||
nodes: document.querySelectorAll('.yetAnotherClass'),
|
||||
});
|
||||
```
|
||||
|
||||
Render all `.mermaid` elements while suppressing any error
|
||||
|
||||
```js
|
||||
mermaid.initialize({ startOnLoad: false });
|
||||
await mermaid.run({
|
||||
suppressErrors: true,
|
||||
});
|
||||
```
|
||||
|
||||
### Calling `mermaid.init` - Deprecated
|
||||
|
||||
```warning
|
||||
mermaid.init is deprecated in v10 and will be removed in v11. Please use mermaid.run instead.
|
||||
```
|
||||
|
||||
By default, `mermaid.init` will be called when the document is ready, finding all elements with
|
||||
`class="mermaid"`. If you are adding content after mermaid is loaded, or otherwise need
|
||||
@@ -188,25 +223,24 @@ mermaid fully supports webpack. Here is a [working demo](https://github.com/merm
|
||||
|
||||
## API usage
|
||||
|
||||
The main idea of the API is to be able to call a render function with the graph definition as a string. The render function
|
||||
will render the graph and call a callback with the resulting SVG code. With this approach it is up to the site creator to
|
||||
fetch the graph definition from the site (perhaps from a textarea), render it and place the graph somewhere in the site.
|
||||
The main idea of the API is to be able to call a render function with the graph definition as a string. The render function will render the graph and call a callback with the resulting SVG code. With this approach it is up to the site creator to fetch the graph definition from the site (perhaps from a textarea), render it and place the graph somewhere in the site.
|
||||
|
||||
The example below show an outline of how this could be used. The example just logs the resulting SVG to the JavaScript console.
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
import mermaid from './mermaid.mjs';
|
||||
mermaid.mermaidAPI.initialize({ startOnLoad: false });
|
||||
$(async function () {
|
||||
// Example of using the API var
|
||||
import mermaid from './mermaid.esm.mjs';
|
||||
mermaid.initialize({ startOnLoad: false });
|
||||
|
||||
// Example of using the render function
|
||||
const drawDiagram = async function () {
|
||||
element = document.querySelector('#graphDiv');
|
||||
const insertSvg = function (svgCode, bindFunctions) {
|
||||
element.innerHTML = svgCode;
|
||||
};
|
||||
const graphDefinition = 'graph TB\na-->b';
|
||||
const graph = await mermaid.mermaidAPI.render('graphDiv', graphDefinition, insertSvg);
|
||||
});
|
||||
const { svg } = await mermaid.render('graphDiv', graphDefinition);
|
||||
element.innerHTML = svg;
|
||||
};
|
||||
|
||||
await drawDiagram();
|
||||
</script>
|
||||
```
|
||||
|
||||
@@ -219,17 +253,17 @@ The example code below is an extract of what mermaid does when using the API. Th
|
||||
bind events to an SVG when using the API for rendering.
|
||||
|
||||
```javascript
|
||||
const insertSvg = function (svgCode, bindFunctions) {
|
||||
element.innerHTML = svgCode;
|
||||
if (typeof callback !== 'undefined') {
|
||||
callback(id);
|
||||
// Example of using the bindFunctions
|
||||
const drawDiagram = async function () {
|
||||
element = document.querySelector('#graphDiv');
|
||||
const graphDefinition = 'graph TB\na-->b';
|
||||
const { svg, bindFunctions } = await mermaid.render('graphDiv', graphDefinition);
|
||||
element.innerHTML = svg;
|
||||
// This can also be written as `bindFunctions?.(element);` using the `?` shorthand.
|
||||
if (bindFunctions) {
|
||||
bindFunctions(element);
|
||||
}
|
||||
bindFunctions(element);
|
||||
};
|
||||
|
||||
const id = 'theGraph';
|
||||
|
||||
mermaidAPI.render(id, txt, insertSvg, element);
|
||||
```
|
||||
|
||||
1. The graph is generated using the render call.
|
||||
|
@@ -14,6 +14,7 @@ They also serve as proof of concept, for the variety of things that can be built
|
||||
- [Gitea](https://gitea.io) (**Native support**)
|
||||
- [Azure Devops](https://docs.microsoft.com/en-us/azure/devops/project/wiki/wiki-markdown-guidance?view=azure-devops#add-mermaid-diagrams-to-a-wiki-page) (**Native support**)
|
||||
- [Tuleap](https://docs.tuleap.org/user-guide/writing-in-tuleap.html#graphs) (**Native support**)
|
||||
- [Deepdwn](https://billiam.itch.io/deepdwn) (**Native support**)
|
||||
- [Joplin](https://joplinapp.org) (**Native support**)
|
||||
- [Swimm](https://swimm.io) (**Native support**)
|
||||
- [Notion](https://notion.so) (**Native support**)
|
||||
@@ -182,3 +183,6 @@ They also serve as proof of concept, for the variety of things that can be built
|
||||
- [mermaid-server: Generate diagrams using a HTTP request](https://github.com/TomWright/mermaid-server)
|
||||
- [ExDoc](https://github.com/elixir-lang/ex_doc)
|
||||
- [Rendering Mermaid graphs](https://github.com/elixir-lang/ex_doc#rendering-mermaid-graphs)
|
||||
- [NiceGUI: Let any browser be the frontend of your Python code](https://nicegui.io)
|
||||
- [ui.mermaid(...)](https://nicegui.io/reference#mermaid_diagrams)
|
||||
- [ui.markdown(..., extras=['mermaid'])](https://nicegui.io/reference#markdown_element)
|
||||
|
@@ -86,7 +86,7 @@ When writing the .html file, we give two instructions inside the html code to th
|
||||
|
||||
a. The mermaid code for the diagram we want to create.
|
||||
|
||||
b. The importing of mermaid library through the `mermaid.esm.js` or `mermaid.esm.min.mjs` and the `mermaid.initialize()` call, which dictates the appearance of diagrams and also starts the rendering process .
|
||||
b. The importing of mermaid library through the `mermaid.esm.mjs` or `mermaid.esm.min.mjs` and the `mermaid.initialize()` call, which dictates the appearance of diagrams and also starts the rendering process .
|
||||
|
||||
**a. The embedded mermaid diagram definition inside a `<pre class="mermaid">`:**
|
||||
|
||||
@@ -118,7 +118,7 @@ b. The importing of mermaid library through the `mermaid.esm.js` or `mermaid.esm
|
||||
```
|
||||
|
||||
**Notes**:
|
||||
Rendering in Mermaid is initialized by `mermaid.initialize()` call. You can place `mermaid.initialize()` inside `mermaid.esm.min.mjs` for brevity. However, doing the opposite lets you control when it starts looking for `<div>`tags inside the web page with `mermaid.initialize()`. This is useful when you think that not all `<div>` tags may have loaded on the execution of `mermaid.esm.min.mjs` file.
|
||||
Rendering in Mermaid is initialized by `mermaid.initialize()` call. However, doing the opposite lets you control when it starts looking for `<pre>` tags inside the web page with `mermaid.initialize()`. This is useful when you think that not all `<pre>` tags may have loaded on the execution of `mermaid.esm.min.mjs` file.
|
||||
|
||||
`startOnLoad` is one of the parameters that can be defined by `mermaid.initialize()`
|
||||
|
||||
@@ -126,10 +126,6 @@ Rendering in Mermaid is initialized by `mermaid.initialize()` call. You can plac
|
||||
| ----------- | --------------------------------- | ------- | ----------- |
|
||||
| startOnLoad | Toggle for Rendering upon loading | Boolean | true, false |
|
||||
|
||||
### Adding external diagrams to mermaid
|
||||
|
||||
Please refer to the [Mindmap](../syntax/mindmap.md?id=integrating-with-your-librarywebsite) section for more information.
|
||||
|
||||
### Working Examples
|
||||
|
||||
**Here is a full working example of the mermaidAPI being called through the CDN:**
|
||||
|
@@ -245,6 +245,15 @@ flowchart LR
|
||||
A == text ==> B
|
||||
```
|
||||
|
||||
### An invisible link
|
||||
|
||||
This can be a useful tool in some instances where you want to alter the default positioning of a node.
|
||||
|
||||
```mermaid-example
|
||||
flowchart LR
|
||||
A ~~~ B
|
||||
```
|
||||
|
||||
### Chaining of links
|
||||
|
||||
It is possible declare many links in the same line as per below:
|
||||
|
@@ -1,6 +1,11 @@
|
||||
import mermaid from './mermaid';
|
||||
import { mermaidAPI } from './mermaidAPI';
|
||||
import './diagram-api/diagram-orchestration';
|
||||
import { addDiagrams } from './diagram-api/diagram-orchestration';
|
||||
|
||||
beforeAll(async () => {
|
||||
addDiagrams();
|
||||
});
|
||||
const spyOn = vi.spyOn;
|
||||
|
||||
vi.mock('./mermaidAPI');
|
||||
@@ -66,9 +71,9 @@ describe('when using mermaid and ', () => {
|
||||
mermaid.registerExternalDiagrams(
|
||||
[
|
||||
{
|
||||
id: 'dummy',
|
||||
detector: (text) => /dummy/.test(text),
|
||||
loader: () => Promise.reject('error'),
|
||||
id: 'dummyError',
|
||||
detector: (text) => /dummyError/.test(text),
|
||||
loader: () => Promise.reject('dummyError'),
|
||||
},
|
||||
],
|
||||
{ lazyLoad: false }
|
||||
|
@@ -7,11 +7,10 @@ import { MermaidConfig } from './config.type';
|
||||
import { log } from './logger';
|
||||
import utils from './utils';
|
||||
import { mermaidAPI, ParseOptions, RenderResult } from './mermaidAPI';
|
||||
import { registerLazyLoadedDiagrams } from './diagram-api/detectType';
|
||||
import { registerLazyLoadedDiagrams, loadRegisteredDiagrams } from './diagram-api/detectType';
|
||||
import type { ParseErrorFunction } from './Diagram';
|
||||
import { isDetailedError } from './utils';
|
||||
import type { DetailedError } from './utils';
|
||||
import { registerDiagram } from './diagram-api/diagramAPI';
|
||||
import { ExternalDiagramDefinition } from './diagram-api/types';
|
||||
|
||||
export type {
|
||||
@@ -23,19 +22,22 @@ export type {
|
||||
ParseOptions,
|
||||
};
|
||||
|
||||
/**
|
||||
* The options used when running mermaid.
|
||||
*
|
||||
* @param querySelector - The query selector to use when finding elements to render. Default: .mermaid
|
||||
* @param nodes - The nodes to render. If this is set, querySelector will be ignored.
|
||||
* @param postRenderCallback - A callback to call after each diagram is rendered.
|
||||
* @param suppressErrors - If true, errors will be logged to the console, but not thrown. Default: false
|
||||
*/
|
||||
export interface RunOptions {
|
||||
// Default: .mermaid
|
||||
/**
|
||||
* The query selector to use when finding elements to render. Default: `".mermaid"`.
|
||||
*/
|
||||
querySelector?: string;
|
||||
/**
|
||||
* The nodes to render. If this is set, `querySelector` will be ignored.
|
||||
*/
|
||||
nodes?: ArrayLike<HTMLElement>;
|
||||
/**
|
||||
* A callback to call after each diagram is rendered.
|
||||
*/
|
||||
postRenderCallback?: (id: string) => unknown;
|
||||
/**
|
||||
* If `true`, errors will be logged to the console, but not thrown. Default: `false`
|
||||
*/
|
||||
suppressErrors?: boolean;
|
||||
}
|
||||
|
||||
@@ -64,30 +66,6 @@ const handleError = (error: unknown, errors: DetailedError[], parseError?: Parse
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This is an internal function and should not be made public, as it will likely change.
|
||||
* @internal
|
||||
* @param diagrams - Array of {@link ExternalDiagramDefinition}.
|
||||
*/
|
||||
const loadExternalDiagrams = async (...diagrams: ExternalDiagramDefinition[]) => {
|
||||
log.debug(`Loading ${diagrams.length} external diagrams`);
|
||||
// Load all lazy loaded diagrams in parallel
|
||||
const results = await Promise.allSettled(
|
||||
diagrams.map(async ({ id, detector, loader }) => {
|
||||
const { diagram } = await loader();
|
||||
registerDiagram(id, diagram, detector);
|
||||
})
|
||||
);
|
||||
const failed = results.filter((result) => result.status === 'rejected');
|
||||
if (failed.length > 0) {
|
||||
log.error(`Failed to load ${failed.length} external diagrams`);
|
||||
for (const res of failed) {
|
||||
log.error(res);
|
||||
}
|
||||
throw new Error(`Failed to load ${failed.length} external diagrams`);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* ## run
|
||||
*
|
||||
@@ -251,7 +229,7 @@ const init = async function (
|
||||
/**
|
||||
* Used to register external diagram types.
|
||||
* @param diagrams - Array of {@link ExternalDiagramDefinition}.
|
||||
* @param opts - If opts.lazyLoad is true, the diagram will be loaded on demand.
|
||||
* @param opts - If opts.lazyLoad is false, the diagrams will be loaded immediately.
|
||||
*/
|
||||
const registerExternalDiagrams = async (
|
||||
diagrams: ExternalDiagramDefinition[],
|
||||
@@ -261,10 +239,9 @@ const registerExternalDiagrams = async (
|
||||
lazyLoad?: boolean;
|
||||
} = {}
|
||||
) => {
|
||||
if (lazyLoad) {
|
||||
registerLazyLoadedDiagrams(...diagrams);
|
||||
} else {
|
||||
await loadExternalDiagrams(...diagrams);
|
||||
registerLazyLoadedDiagrams(...diagrams);
|
||||
if (lazyLoad === false) {
|
||||
await loadRegisteredDiagrams();
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -74,6 +74,23 @@ export interface ParseOptions {
|
||||
// @ts-ignore Could replicate the type definition in d3. This also makes it possible to use the untyped info from the js diagram files.
|
||||
export type D3Element = any;
|
||||
|
||||
export interface RenderResult {
|
||||
/**
|
||||
* The svg code for the rendered graph.
|
||||
*/
|
||||
svg: string;
|
||||
/**
|
||||
* Bind function to be called after the svg has been inserted into the DOM.
|
||||
* This is necessary for adding event listeners to the elements in the svg.
|
||||
* ```js
|
||||
* const { svg, bindFunctions } = mermaidAPI.render('id1', 'graph TD;A-->B');
|
||||
* div.innerHTML = svg;
|
||||
* bindFunctions?.(div); // To call bindFunctions only if it's present.
|
||||
* ```
|
||||
*/
|
||||
bindFunctions?: (element: Element) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the text and validate the syntax.
|
||||
* @param text - The mermaid diagram definition.
|
||||
@@ -379,11 +396,6 @@ export const removeExistingElements = (
|
||||
* @returns Returns the rendered element as a string containing the SVG definition.
|
||||
*/
|
||||
|
||||
export interface RenderResult {
|
||||
svg: string;
|
||||
bindFunctions?: (element: Element) => void;
|
||||
}
|
||||
|
||||
const render = async function (
|
||||
id: string,
|
||||
text: string,
|
||||
|
@@ -1,39 +1,7 @@
|
||||
import classDiagram from './diagrams/class/styles';
|
||||
import er from './diagrams/er/styles';
|
||||
import error from './diagrams/error/styles';
|
||||
import flowchart from './diagrams/flowchart/styles';
|
||||
import gantt from './diagrams/gantt/styles';
|
||||
// import gitGraph from './diagrams/git/styles';
|
||||
import info from './diagrams/info/styles';
|
||||
import pie from './diagrams/pie/styles';
|
||||
import requirement from './diagrams/requirement/styles';
|
||||
import sequence from './diagrams/sequence/styles';
|
||||
import stateDiagram from './diagrams/state/styles';
|
||||
import journey from './diagrams/user-journey/styles';
|
||||
import c4 from './diagrams/c4/styles';
|
||||
import { FlowChartStyleOptions } from './diagrams/flowchart/styles';
|
||||
import type { FlowChartStyleOptions } from './diagrams/flowchart/styles';
|
||||
import { log } from './logger';
|
||||
|
||||
// TODO @knut: Inject from registerDiagram.
|
||||
const themes: Record<string, any> = {
|
||||
flowchart,
|
||||
'flowchart-v2': flowchart,
|
||||
sequence,
|
||||
gantt,
|
||||
classDiagram,
|
||||
'classDiagram-v2': classDiagram,
|
||||
class: classDiagram,
|
||||
stateDiagram,
|
||||
state: stateDiagram,
|
||||
// gitGraph,
|
||||
info,
|
||||
pie,
|
||||
er,
|
||||
error,
|
||||
journey,
|
||||
requirement,
|
||||
c4,
|
||||
};
|
||||
const themes: Record<string, any> = {};
|
||||
|
||||
const getStyles = (
|
||||
type: string,
|
||||
|
45
pnpm-lock.yaml
generated
45
pnpm-lock.yaml
generated
@@ -1166,7 +1166,6 @@ packages:
|
||||
|
||||
/@braintree/sanitize-url/6.0.0:
|
||||
resolution: {integrity: sha512-mgmE7XBYY/21erpzhexk4Cj1cyTQ9LzvnTxtzM17BJ7ERMNE6W72mQRo0I1Ud8eFJ+RVVIcBNhLFZ3GX4XFz5w==}
|
||||
dev: false
|
||||
|
||||
/@colors/colors/1.5.0:
|
||||
resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==}
|
||||
@@ -2983,6 +2982,10 @@ packages:
|
||||
resolution: {integrity: sha512-zmEmF5OIM3rb7SbLCFYoQhO4dGt2FRM9AMkxvA3LaADOF1n8in/zGJlWji9fmafLoNyz+FoL6FE0SLtGIArD7w==}
|
||||
dev: true
|
||||
|
||||
/@types/lodash/4.14.189:
|
||||
resolution: {integrity: sha512-kb9/98N6X8gyME9Cf7YaqIMvYGnBSWqEci6tiettE6iJWH1XdJz/PO8LB0GtLCG7x8dU3KWhZT+lA1a35127tA==}
|
||||
dev: true
|
||||
|
||||
/@types/markdown-it/12.2.3:
|
||||
resolution: {integrity: sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==}
|
||||
dependencies:
|
||||
@@ -5424,12 +5427,10 @@ packages:
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
internmap: 2.0.3
|
||||
dev: false
|
||||
|
||||
/d3-axis/3.0.0:
|
||||
resolution: {integrity: sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==}
|
||||
engines: {node: '>=12'}
|
||||
dev: false
|
||||
|
||||
/d3-brush/3.0.0:
|
||||
resolution: {integrity: sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==}
|
||||
@@ -5440,38 +5441,32 @@ packages:
|
||||
d3-interpolate: 3.0.1
|
||||
d3-selection: 3.0.0
|
||||
d3-transition: 3.0.1_d3-selection@3.0.0
|
||||
dev: false
|
||||
|
||||
/d3-chord/3.0.1:
|
||||
resolution: {integrity: sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
d3-path: 3.0.1
|
||||
dev: false
|
||||
|
||||
/d3-color/3.1.0:
|
||||
resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==}
|
||||
engines: {node: '>=12'}
|
||||
dev: false
|
||||
|
||||
/d3-contour/4.0.0:
|
||||
resolution: {integrity: sha512-7aQo0QHUTu/Ko3cP9YK9yUTxtoDEiDGwnBHyLxG5M4vqlBkO/uixMRele3nfsfj6UXOcuReVpVXzAboGraYIJw==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
d3-array: 3.2.0
|
||||
dev: false
|
||||
|
||||
/d3-delaunay/6.0.2:
|
||||
resolution: {integrity: sha512-IMLNldruDQScrcfT+MWnazhHbDJhcRJyOEBAJfwQnHle1RPh6WDuLvxNArUju2VSMSUuKlY5BGHRJ2cYyoFLQQ==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
delaunator: 5.0.0
|
||||
dev: false
|
||||
|
||||
/d3-dispatch/3.0.1:
|
||||
resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==}
|
||||
engines: {node: '>=12'}
|
||||
dev: false
|
||||
|
||||
/d3-drag/3.0.0:
|
||||
resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==}
|
||||
@@ -5479,7 +5474,6 @@ packages:
|
||||
dependencies:
|
||||
d3-dispatch: 3.0.1
|
||||
d3-selection: 3.0.0
|
||||
dev: false
|
||||
|
||||
/d3-dsv/3.0.1:
|
||||
resolution: {integrity: sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==}
|
||||
@@ -5489,19 +5483,16 @@ packages:
|
||||
commander: 7.2.0
|
||||
iconv-lite: 0.6.3
|
||||
rw: 1.3.3
|
||||
dev: false
|
||||
|
||||
/d3-ease/3.0.1:
|
||||
resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==}
|
||||
engines: {node: '>=12'}
|
||||
dev: false
|
||||
|
||||
/d3-fetch/3.0.1:
|
||||
resolution: {integrity: sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
d3-dsv: 3.0.1
|
||||
dev: false
|
||||
|
||||
/d3-force/3.0.0:
|
||||
resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==}
|
||||
@@ -5510,51 +5501,42 @@ packages:
|
||||
d3-dispatch: 3.0.1
|
||||
d3-quadtree: 3.0.1
|
||||
d3-timer: 3.0.1
|
||||
dev: false
|
||||
|
||||
/d3-format/3.1.0:
|
||||
resolution: {integrity: sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==}
|
||||
engines: {node: '>=12'}
|
||||
dev: false
|
||||
|
||||
/d3-geo/3.0.1:
|
||||
resolution: {integrity: sha512-Wt23xBych5tSy9IYAM1FR2rWIBFWa52B/oF/GYe5zbdHrg08FU8+BuI6X4PvTwPDdqdAdq04fuWJpELtsaEjeA==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
d3-array: 3.2.0
|
||||
dev: false
|
||||
|
||||
/d3-hierarchy/3.1.2:
|
||||
resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==}
|
||||
engines: {node: '>=12'}
|
||||
dev: false
|
||||
|
||||
/d3-interpolate/3.0.1:
|
||||
resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
d3-color: 3.1.0
|
||||
dev: false
|
||||
|
||||
/d3-path/3.0.1:
|
||||
resolution: {integrity: sha512-gq6gZom9AFZby0YLduxT1qmrp4xpBA1YZr19OI717WIdKE2OM5ETq5qrHLb301IgxhLwcuxvGZVLeeWc/k1I6w==}
|
||||
engines: {node: '>=12'}
|
||||
dev: false
|
||||
|
||||
/d3-polygon/3.0.1:
|
||||
resolution: {integrity: sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==}
|
||||
engines: {node: '>=12'}
|
||||
dev: false
|
||||
|
||||
/d3-quadtree/3.0.1:
|
||||
resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==}
|
||||
engines: {node: '>=12'}
|
||||
dev: false
|
||||
|
||||
/d3-random/3.0.1:
|
||||
resolution: {integrity: sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==}
|
||||
engines: {node: '>=12'}
|
||||
dev: false
|
||||
|
||||
/d3-scale-chromatic/3.0.0:
|
||||
resolution: {integrity: sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==}
|
||||
@@ -5562,7 +5544,6 @@ packages:
|
||||
dependencies:
|
||||
d3-color: 3.1.0
|
||||
d3-interpolate: 3.0.1
|
||||
dev: false
|
||||
|
||||
/d3-scale/4.0.2:
|
||||
resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==}
|
||||
@@ -5573,38 +5554,32 @@ packages:
|
||||
d3-interpolate: 3.0.1
|
||||
d3-time: 3.0.0
|
||||
d3-time-format: 4.1.0
|
||||
dev: false
|
||||
|
||||
/d3-selection/3.0.0:
|
||||
resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==}
|
||||
engines: {node: '>=12'}
|
||||
dev: false
|
||||
|
||||
/d3-shape/3.1.0:
|
||||
resolution: {integrity: sha512-tGDh1Muf8kWjEDT/LswZJ8WF85yDZLvVJpYU9Nq+8+yW1Z5enxrmXOhTArlkaElU+CTn0OTVNli+/i+HP45QEQ==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
d3-path: 3.0.1
|
||||
dev: false
|
||||
|
||||
/d3-time-format/4.1.0:
|
||||
resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
d3-time: 3.0.0
|
||||
dev: false
|
||||
|
||||
/d3-time/3.0.0:
|
||||
resolution: {integrity: sha512-zmV3lRnlaLI08y9IMRXSDshQb5Nj77smnfpnd2LrBa/2K281Jijactokeak14QacHs/kKq0AQ121nidNYlarbQ==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
d3-array: 3.2.0
|
||||
dev: false
|
||||
|
||||
/d3-timer/3.0.1:
|
||||
resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==}
|
||||
engines: {node: '>=12'}
|
||||
dev: false
|
||||
|
||||
/d3-transition/3.0.1_d3-selection@3.0.0:
|
||||
resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==}
|
||||
@@ -5618,7 +5593,6 @@ packages:
|
||||
d3-interpolate: 3.0.1
|
||||
d3-selection: 3.0.0
|
||||
d3-timer: 3.0.1
|
||||
dev: false
|
||||
|
||||
/d3-zoom/3.0.0:
|
||||
resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==}
|
||||
@@ -5629,7 +5603,6 @@ packages:
|
||||
d3-interpolate: 3.0.1
|
||||
d3-selection: 3.0.0
|
||||
d3-transition: 3.0.1_d3-selection@3.0.0
|
||||
dev: false
|
||||
|
||||
/d3/7.8.2:
|
||||
resolution: {integrity: sha512-WXty7qOGSHb7HR7CfOzwN1Gw04MUOzN8qh9ZUsvwycIMb4DYMpY9xczZ6jUorGtO6bR9BPMPaueIKwiDxu9uiQ==}
|
||||
@@ -5665,7 +5638,6 @@ packages:
|
||||
d3-timer: 3.0.1
|
||||
d3-transition: 3.0.1_d3-selection@3.0.0
|
||||
d3-zoom: 3.0.0
|
||||
dev: false
|
||||
|
||||
/dagre-d3-es/7.0.8:
|
||||
resolution: {integrity: sha512-eykdoYQ4FwCJinEYS0gPL2f2w+BPbSLvnQSJ3Ye1vAoPjdkq6xIMKBv+UkICd3qZE26wBKIn3p+6n0QC7R1LyA==}
|
||||
@@ -5859,7 +5831,6 @@ packages:
|
||||
resolution: {integrity: sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw==}
|
||||
dependencies:
|
||||
robust-predicates: 3.0.1
|
||||
dev: false
|
||||
|
||||
/delayed-stream/1.0.0:
|
||||
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
|
||||
@@ -7496,7 +7467,6 @@ packages:
|
||||
/internmap/2.0.3:
|
||||
resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==}
|
||||
engines: {node: '>=12'}
|
||||
dev: false
|
||||
|
||||
/interpret/2.2.0:
|
||||
resolution: {integrity: sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==}
|
||||
@@ -8453,7 +8423,6 @@ packages:
|
||||
|
||||
/khroma/2.0.0:
|
||||
resolution: {integrity: sha512-2J8rDNlQWbtiNYThZRvmMv5yt44ZakX+Tz5ZIp/mN1pt4snn+m030Va5Z4v8xA0cQFDXBwO/8i42xL4QPsVk3g==}
|
||||
dev: false
|
||||
|
||||
/kind-of/6.0.3:
|
||||
resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==}
|
||||
@@ -9327,7 +9296,6 @@ packages:
|
||||
|
||||
/moment-mini/2.29.4:
|
||||
resolution: {integrity: sha512-uhXpYwHFeiTbY9KSgPPRoo1nt8OxNVdMVoTBYHfSEKeRkIkwGpO+gERmhuhBtzfaeOyTkykSrm2+noJBgqt3Hg==}
|
||||
dev: false
|
||||
|
||||
/mri/1.2.0:
|
||||
resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==}
|
||||
@@ -9430,7 +9398,6 @@ packages:
|
||||
|
||||
/non-layered-tidy-tree-layout/2.0.2:
|
||||
resolution: {integrity: sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw==}
|
||||
dev: false
|
||||
|
||||
/normalize-package-data/2.5.0:
|
||||
resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==}
|
||||
@@ -10439,7 +10406,6 @@ packages:
|
||||
|
||||
/robust-predicates/3.0.1:
|
||||
resolution: {integrity: sha512-ndEIpszUHiG4HtDsQLeIuMvRsDnn8c8rYStabochtUeCvfuvNptb5TUbVD68LRAILPX7p9nqQGh4xJgn3EHS/g==}
|
||||
dev: false
|
||||
|
||||
/rollup/3.15.0:
|
||||
resolution: {integrity: sha512-F9hrCAhnp5/zx/7HYmftvsNBkMfLfk/dXUh73hPSM2E3CRgap65orDNJbLetoiUFwSAk6iHPLvBrZ5iHYvzqsg==}
|
||||
@@ -10457,7 +10423,6 @@ packages:
|
||||
|
||||
/rw/1.3.3:
|
||||
resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==}
|
||||
dev: false
|
||||
|
||||
/rxjs/7.5.6:
|
||||
resolution: {integrity: sha512-dnyv2/YsXhnm461G+R/Pe5bWP41Nm6LBXEYWI6eiFP4fiwx6WRI/CD0zbdVAudd9xwLEF2IDcKXLHit0FYjUzw==}
|
||||
@@ -11086,7 +11051,6 @@ packages:
|
||||
|
||||
/stylis/4.1.2:
|
||||
resolution: {integrity: sha512-Nn2CCrG2ZaFziDxaZPN43CXqn+j7tcdjPFCkRBkFue8QYXC2HdEwnw5TCBo4yQZ2WxKYeSi0fdoOrtEqgDrXbA==}
|
||||
dev: false
|
||||
|
||||
/supports-color/2.0.0:
|
||||
resolution: {integrity: sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==}
|
||||
@@ -11655,7 +11619,6 @@ packages:
|
||||
/uuid/9.0.0:
|
||||
resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==}
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/uvu/0.5.6:
|
||||
resolution: {integrity: sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==}
|
||||
|
Reference in New Issue
Block a user