mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-01-28 07:03:17 +08:00
Merge branch 'develop' into sidv/optimizeSize
* develop: chore(deps): update pnpm to v7.17.0 docs: Remove warning in readme chore(deps): update lycheeverse/lychee-action action to v1.5.4 chore: Add size shield in readme Fix example for Git diagrams Fix TS errors Add interface for DiagramDb and other minor changes Disallow leading whitespace before delimiter Add title support using YAML frontmatter
This commit is contained in:
commit
a686255d9e
2
.github/workflows/link-checker.yml
vendored
2
.github/workflows/link-checker.yml
vendored
@ -36,7 +36,7 @@ jobs:
|
|||||||
restore-keys: cache-lychee-
|
restore-keys: cache-lychee-
|
||||||
|
|
||||||
- name: Link Checker
|
- name: Link Checker
|
||||||
uses: lycheeverse/lychee-action@v1.5.2
|
uses: lycheeverse/lychee-action@v1.5.4
|
||||||
with:
|
with:
|
||||||
args: --verbose --no-progress --cache --max-cache-age 1d packages/mermaid/src/docs/**/*.md README.md README.zh-CN.md
|
args: --verbose --no-progress --cache --max-cache-age 1d packages/mermaid/src/docs/**/*.md README.md README.zh-CN.md
|
||||||
fail: true
|
fail: true
|
||||||
|
19
README.md
19
README.md
@ -1,23 +1,6 @@
|
|||||||
# mermaid
|
# mermaid
|
||||||
|
|
||||||
[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
|
[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![npm minified gzipped bundle size](https://img.shields.io/bundlephobia/minzip/mermaid)](https://bundlephobia.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
|
||||||
|
|
||||||
# Whoa, what's going on here?
|
|
||||||
|
|
||||||
We are transforming the Mermaid repository to a so called mono-repo. This is a part of the effort to decouple the diagrams from the core of mermaid. This will:
|
|
||||||
|
|
||||||
- Make it possible to select which diagrams to include on your site
|
|
||||||
- Open up for lazy loading
|
|
||||||
- Make it possible to add diagrams from outside of the Mermaid repository
|
|
||||||
- Separate the release flow between different diagrams and the Mermaid core
|
|
||||||
|
|
||||||
As such be aware of some changes..
|
|
||||||
|
|
||||||
# We use pnpm now
|
|
||||||
|
|
||||||
# The source code has moved
|
|
||||||
|
|
||||||
It is now located in the src folder for each respective package located as subfolders in packages.
|
|
||||||
|
|
||||||
English | [简体中文](./README.zh-CN.md)
|
English | [简体中文](./README.zh-CN.md)
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# mermaid
|
# mermaid
|
||||||
|
|
||||||
[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
|
[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![npm minified gzipped bundle size](https://img.shields.io/bundlephobia/minzip/mermaid)](https://bundlephobia.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
|
||||||
|
|
||||||
[English](./README.md) | 简体中文
|
[English](./README.md) | 简体中文
|
||||||
|
|
||||||
|
@ -53,6 +53,18 @@ export const MockD3 = (name, parent) => {
|
|||||||
get __parent() {
|
get __parent() {
|
||||||
return parent;
|
return parent;
|
||||||
},
|
},
|
||||||
|
node() {
|
||||||
|
return {
|
||||||
|
getBBox() {
|
||||||
|
return {
|
||||||
|
x: 5,
|
||||||
|
y: 10,
|
||||||
|
height: 15,
|
||||||
|
width: 20,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
};
|
};
|
||||||
elem.append = (name) => {
|
elem.append = (name) => {
|
||||||
const mockElem = MockD3(name, elem);
|
const mockElem = MockD3(name, elem);
|
||||||
|
@ -496,4 +496,16 @@ describe('Class diagram V2', () => {
|
|||||||
);
|
);
|
||||||
cy.get('svg');
|
cy.get('svg');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('1433: should render a simple class with a title', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`---
|
||||||
|
title: simple class diagram
|
||||||
|
---
|
||||||
|
classDiagram-v2
|
||||||
|
class Class10
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -273,4 +273,17 @@ describe('Entity Relationship Diagram', () => {
|
|||||||
);
|
);
|
||||||
cy.get('svg');
|
cy.get('svg');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('1433: should render a simple ER diagram with a title', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`---
|
||||||
|
title: simple ER diagram
|
||||||
|
---
|
||||||
|
erDiagram
|
||||||
|
CUSTOMER ||--o{ ORDER : places
|
||||||
|
ORDER ||--|{ LINE-ITEM : contains
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -663,4 +663,15 @@ flowchart RL
|
|||||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
it('1433: should render a titled flowchart with titleTopMargin set to 0', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`---
|
||||||
|
title: Simple flowchart
|
||||||
|
---
|
||||||
|
flowchart TD
|
||||||
|
A --> B
|
||||||
|
`,
|
||||||
|
{ titleTopMargin: 0 }
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -322,4 +322,15 @@ describe('Git Graph diagram', () => {
|
|||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
it('1433: should render a simple gitgraph with a title', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`---
|
||||||
|
title: simple gitGraph
|
||||||
|
---
|
||||||
|
gitGraph
|
||||||
|
commit
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -559,4 +559,16 @@ stateDiagram-v2
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
it('1433: should render a simple state diagram with a title', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`---
|
||||||
|
title: simple state diagram
|
||||||
|
---
|
||||||
|
stateDiagram-v2
|
||||||
|
[*] --> State1
|
||||||
|
State1 --> [*]
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
<h1>Class diagram demos</h1>
|
<h1>Class diagram demos</h1>
|
||||||
|
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
|
---
|
||||||
|
title: Demo Class Diagram
|
||||||
|
---
|
||||||
classDiagram
|
classDiagram
|
||||||
accTitle: Demo Class Diagram
|
accTitle: Demo Class Diagram
|
||||||
accDescr: This class diagram show the abstract Animal class, and 3 classes that inherit from it: Duck, Fish, and Zebra.
|
accDescr: This class diagram show the abstract Animal class, and 3 classes that inherit from it: Duck, Fish, and Zebra.
|
||||||
|
@ -20,6 +20,9 @@
|
|||||||
<body>
|
<body>
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
|
|
||||||
|
---
|
||||||
|
title: This is a title
|
||||||
|
---
|
||||||
erDiagram
|
erDiagram
|
||||||
%% title This is a title
|
%% title This is a title
|
||||||
%% accDescription Test a description
|
%% accDescription Test a description
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
<h2>Sample 1</h2>
|
<h2>Sample 1</h2>
|
||||||
<h3>graph</h3>
|
<h3>graph</h3>
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
|
---
|
||||||
|
title: This is a complicated flow
|
||||||
|
---
|
||||||
graph LR
|
graph LR
|
||||||
accTitle: This is a complicated flow
|
accTitle: This is a complicated flow
|
||||||
accDescr: This is the descriptoin for the complicated flow.
|
accDescr: This is the descriptoin for the complicated flow.
|
||||||
@ -221,6 +224,9 @@
|
|||||||
<h2>Sample 2</h2>
|
<h2>Sample 2</h2>
|
||||||
<h3>graph</h3>
|
<h3>graph</h3>
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
|
---
|
||||||
|
title: What to buy
|
||||||
|
---
|
||||||
graph TD
|
graph TD
|
||||||
accTitle: What to buy
|
accTitle: What to buy
|
||||||
accDescr: Options of what to buy with Christmas money
|
accDescr: Options of what to buy with Christmas money
|
||||||
|
@ -16,6 +16,9 @@
|
|||||||
<body>
|
<body>
|
||||||
<h1>Git diagram demo</h1>
|
<h1>Git diagram demo</h1>
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
|
---
|
||||||
|
title: Simple Git diagram
|
||||||
|
---
|
||||||
gitGraph:
|
gitGraph:
|
||||||
options
|
options
|
||||||
{
|
{
|
||||||
|
@ -16,8 +16,10 @@
|
|||||||
<body>
|
<body>
|
||||||
<h1>Journey diagram demo</h1>
|
<h1>Journey diagram demo</h1>
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
journey
|
---
|
||||||
title My working day
|
title: My working day
|
||||||
|
---
|
||||||
|
journey
|
||||||
accTitle: Very simple journey demo
|
accTitle: Very simple journey demo
|
||||||
accDescr: 2 main sections: work and home, each with just a few tasks
|
accDescr: 2 main sections: work and home, each with just a few tasks
|
||||||
|
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
<h1>State diagram demos</h1>
|
<h1>State diagram demos</h1>
|
||||||
<h2>Very simple showing change from State1 to State2</h2>
|
<h2>Very simple showing change from State1 to State2</h2>
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
|
---
|
||||||
|
title: Very simple diagram
|
||||||
|
---
|
||||||
stateDiagram
|
stateDiagram
|
||||||
accTitle: This is the accessible title
|
accTitle: This is the accessible title
|
||||||
accDescr:This is an accessible description
|
accDescr:This is an accessible description
|
||||||
@ -43,6 +46,9 @@
|
|||||||
</code>
|
</code>
|
||||||
</p>
|
</p>
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
|
---
|
||||||
|
title: Very simple diagram
|
||||||
|
---
|
||||||
stateDiagram-v2
|
stateDiagram-v2
|
||||||
accTitle: This is the accessible title
|
accTitle: This is the accessible title
|
||||||
accDescr: This is an accessible description
|
accDescr: This is an accessible description
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[defaultConfig.ts:1881](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L1881)
|
[defaultConfig.ts:1933](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L1933)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ It is a JavaScript based diagramming and charting tool that renders Markdown-ins
|
|||||||
|
|
||||||
<img src="/header.png" alt="" />
|
<img src="/header.png" alt="" />
|
||||||
|
|
||||||
[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
|
[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![npm minified gzipped bundle size](https://img.shields.io/bundlephobia/minzip/mermaid)](https://bundlephobia.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
|
||||||
|
|
||||||
<!-- Mermaid book banner -->
|
<!-- Mermaid book banner -->
|
||||||
|
|
||||||
|
@ -14,6 +14,9 @@ The class diagram is the main building block of object-oriented modeling. It is
|
|||||||
Mermaid can render class diagrams.
|
Mermaid can render class diagrams.
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
|
---
|
||||||
|
title: Animal example
|
||||||
|
---
|
||||||
classDiagram
|
classDiagram
|
||||||
note "From Duck till Zebra"
|
note "From Duck till Zebra"
|
||||||
Animal <|-- Duck
|
Animal <|-- Duck
|
||||||
@ -40,6 +43,9 @@ classDiagram
|
|||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
|
---
|
||||||
|
title: Animal example
|
||||||
|
---
|
||||||
classDiagram
|
classDiagram
|
||||||
note "From Duck till Zebra"
|
note "From Duck till Zebra"
|
||||||
Animal <|-- Duck
|
Animal <|-- Duck
|
||||||
@ -77,6 +83,9 @@ A single instance of a class in the diagram contains three compartments:
|
|||||||
- The bottom compartment contains the operations the class can execute. They are also left-aligned and the first letter is lowercase.
|
- The bottom compartment contains the operations the class can execute. They are also left-aligned and the first letter is lowercase.
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
|
---
|
||||||
|
title: Bank example
|
||||||
|
---
|
||||||
classDiagram
|
classDiagram
|
||||||
class BankAccount
|
class BankAccount
|
||||||
BankAccount : +String owner
|
BankAccount : +String owner
|
||||||
@ -87,6 +96,9 @@ classDiagram
|
|||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
|
---
|
||||||
|
title: Bank example
|
||||||
|
---
|
||||||
classDiagram
|
classDiagram
|
||||||
class BankAccount
|
class BankAccount
|
||||||
BankAccount : +String owner
|
BankAccount : +String owner
|
||||||
|
@ -13,6 +13,9 @@ Note that practitioners of ER modelling almost always refer to _entity types_ si
|
|||||||
Mermaid can render ER diagrams
|
Mermaid can render ER diagrams
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
|
---
|
||||||
|
title: Order example
|
||||||
|
---
|
||||||
erDiagram
|
erDiagram
|
||||||
CUSTOMER ||--o{ ORDER : places
|
CUSTOMER ||--o{ ORDER : places
|
||||||
ORDER ||--|{ LINE-ITEM : contains
|
ORDER ||--|{ LINE-ITEM : contains
|
||||||
@ -20,6 +23,9 @@ erDiagram
|
|||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
|
---
|
||||||
|
title: Order example
|
||||||
|
---
|
||||||
erDiagram
|
erDiagram
|
||||||
CUSTOMER ||--o{ ORDER : places
|
CUSTOMER ||--o{ ORDER : places
|
||||||
ORDER ||--|{ LINE-ITEM : contains
|
ORDER ||--|{ LINE-ITEM : contains
|
||||||
|
@ -15,11 +15,17 @@ It can also accommodate different arrow types, multi directional arrows, and lin
|
|||||||
### A node (default)
|
### A node (default)
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
|
---
|
||||||
|
title: Node
|
||||||
|
---
|
||||||
flowchart LR
|
flowchart LR
|
||||||
id
|
id
|
||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
|
---
|
||||||
|
title: Node
|
||||||
|
---
|
||||||
flowchart LR
|
flowchart LR
|
||||||
id
|
id
|
||||||
```
|
```
|
||||||
@ -33,11 +39,17 @@ found for the node that will be used. Also if you define edges for the node late
|
|||||||
one previously defined will be used when rendering the box.
|
one previously defined will be used when rendering the box.
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
|
---
|
||||||
|
title: Node with text
|
||||||
|
---
|
||||||
flowchart LR
|
flowchart LR
|
||||||
id1[This is the text in the box]
|
id1[This is the text in the box]
|
||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
|
---
|
||||||
|
title: Node with text
|
||||||
|
---
|
||||||
flowchart LR
|
flowchart LR
|
||||||
id1[This is the text in the box]
|
id1[This is the text in the box]
|
||||||
```
|
```
|
||||||
|
@ -13,31 +13,37 @@ These kind of diagram are particularly helpful to developers and devops teams to
|
|||||||
Mermaid can render Git diagrams
|
Mermaid can render Git diagrams
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
gitGraph
|
---
|
||||||
commit
|
title: Example Git diagram
|
||||||
commit
|
---
|
||||||
branch develop
|
gitGraph
|
||||||
checkout develop
|
commit
|
||||||
commit
|
commit
|
||||||
commit
|
branch develop
|
||||||
checkout main
|
checkout develop
|
||||||
merge develop
|
commit
|
||||||
commit
|
commit
|
||||||
commit
|
checkout main
|
||||||
|
merge develop
|
||||||
|
commit
|
||||||
|
commit
|
||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
gitGraph
|
---
|
||||||
commit
|
title: Example Git diagram
|
||||||
commit
|
---
|
||||||
branch develop
|
gitGraph
|
||||||
checkout develop
|
commit
|
||||||
commit
|
commit
|
||||||
commit
|
branch develop
|
||||||
checkout main
|
checkout develop
|
||||||
merge develop
|
commit
|
||||||
commit
|
commit
|
||||||
commit
|
checkout main
|
||||||
|
merge develop
|
||||||
|
commit
|
||||||
|
commit
|
||||||
```
|
```
|
||||||
|
|
||||||
In Mermaid, we support the basic git operations like:
|
In Mermaid, we support the basic git operations like:
|
||||||
|
@ -11,6 +11,9 @@
|
|||||||
Mermaid can render state diagrams. The syntax tries to be compliant with the syntax used in plantUml as this will make it easier for users to share diagrams between mermaid and plantUml.
|
Mermaid can render state diagrams. The syntax tries to be compliant with the syntax used in plantUml as this will make it easier for users to share diagrams between mermaid and plantUml.
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
|
---
|
||||||
|
title: Simple sample
|
||||||
|
---
|
||||||
stateDiagram-v2
|
stateDiagram-v2
|
||||||
[*] --> Still
|
[*] --> Still
|
||||||
Still --> [*]
|
Still --> [*]
|
||||||
@ -22,6 +25,9 @@ stateDiagram-v2
|
|||||||
```
|
```
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
|
---
|
||||||
|
title: Simple sample
|
||||||
|
---
|
||||||
stateDiagram-v2
|
stateDiagram-v2
|
||||||
[*] --> Still
|
[*] --> Still
|
||||||
Still --> [*]
|
Still --> [*]
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"version": "9.2.2",
|
"version": "9.2.2",
|
||||||
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
|
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"packageManager": "pnpm@7.15.0",
|
"packageManager": "pnpm@7.17.0",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"diagram",
|
"diagram",
|
||||||
"markdown",
|
"markdown",
|
||||||
@ -61,6 +61,7 @@
|
|||||||
"@types/eslint": "^8.4.10",
|
"@types/eslint": "^8.4.10",
|
||||||
"@types/express": "^4.17.14",
|
"@types/express": "^4.17.14",
|
||||||
"@types/jsdom": "^20.0.1",
|
"@types/jsdom": "^20.0.1",
|
||||||
|
"@types/js-yaml": "^4.0.5",
|
||||||
"@types/lodash": "^4.14.188",
|
"@types/lodash": "^4.14.188",
|
||||||
"@types/mdast": "^3.0.10",
|
"@types/mdast": "^3.0.10",
|
||||||
"@types/node": "^18.11.9",
|
"@types/node": "^18.11.9",
|
||||||
@ -92,6 +93,7 @@
|
|||||||
"jest": "^29.3.1",
|
"jest": "^29.3.1",
|
||||||
"jison": "^0.4.18",
|
"jison": "^0.4.18",
|
||||||
"jsdom": "^20.0.2",
|
"jsdom": "^20.0.2",
|
||||||
|
"js-yaml": "^4.1.0",
|
||||||
"lint-staged": "^13.0.3",
|
"lint-staged": "^13.0.3",
|
||||||
"path-browserify": "^1.0.1",
|
"path-browserify": "^1.0.1",
|
||||||
"pnpm": "^7.15.0",
|
"pnpm": "^7.15.0",
|
||||||
|
@ -1,23 +1,6 @@
|
|||||||
# mermaid
|
# mermaid
|
||||||
|
|
||||||
[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
|
[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![npm minified gzipped bundle size](https://img.shields.io/bundlephobia/minzip/mermaid)](https://bundlephobia.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
|
||||||
|
|
||||||
# Whoa, what's going on here?
|
|
||||||
|
|
||||||
We are transforming the Mermaid repository to a so called mono-repo. This is a part of the effort to decouple the diagrams from the core of mermaid. This will:
|
|
||||||
|
|
||||||
- Make it possible to select which diagrams to include on your site
|
|
||||||
- Open up for lazy loading
|
|
||||||
- Make it possible to add diagrams from outside of the Mermaid repository
|
|
||||||
- Separate the release flow between different diagrams and the Mermaid core
|
|
||||||
|
|
||||||
As such be aware of some changes..
|
|
||||||
|
|
||||||
# We use pnpm now
|
|
||||||
|
|
||||||
# The source code has moved
|
|
||||||
|
|
||||||
It is now located in the src folder for each respective package located as subfolders in packages.
|
|
||||||
|
|
||||||
English | [简体中文](./README.zh-CN.md)
|
English | [简体中文](./README.zh-CN.md)
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# mermaid
|
# mermaid
|
||||||
|
|
||||||
[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
|
[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![npm minified gzipped bundle size](https://img.shields.io/bundlephobia/minzip/mermaid)](https://bundlephobia.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
|
||||||
|
|
||||||
[English](./README.md) | 简体中文
|
[English](./README.md) | 简体中文
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ import * as configApi from './config';
|
|||||||
import { log } from './logger';
|
import { log } from './logger';
|
||||||
import { getDiagram, registerDiagram } from './diagram-api/diagramAPI';
|
import { getDiagram, registerDiagram } from './diagram-api/diagramAPI';
|
||||||
import { detectType, getDiagramLoader } from './diagram-api/detectType';
|
import { detectType, getDiagramLoader } from './diagram-api/detectType';
|
||||||
|
import { extractFrontMatter } from './diagram-api/frontmatter';
|
||||||
import { isDetailedError, type DetailedError } from './utils';
|
import { isDetailedError, type DetailedError } from './utils';
|
||||||
|
|
||||||
export type ParseErrorFunction = (err: string | DetailedError, hash?: any) => void;
|
export type ParseErrorFunction = (err: string | DetailedError, hash?: any) => void;
|
||||||
@ -29,6 +30,16 @@ export class Diagram {
|
|||||||
this.db.clear?.();
|
this.db.clear?.();
|
||||||
this.renderer = diagram.renderer;
|
this.renderer = diagram.renderer;
|
||||||
this.parser = diagram.parser;
|
this.parser = diagram.parser;
|
||||||
|
const originalParse = this.parser.parse.bind(this.parser);
|
||||||
|
// Wrap the jison parse() method to handle extracting frontmatter.
|
||||||
|
//
|
||||||
|
// This can't be done in this.parse() because some code
|
||||||
|
// directly calls diagram.parser.parse(), bypassing this.parse().
|
||||||
|
//
|
||||||
|
// Similarly, we can't do this in getDiagramFromText() because some code
|
||||||
|
// calls diagram.db.clear(), which would reset anything set by
|
||||||
|
// extractFrontMatter().
|
||||||
|
this.parser.parse = (text: string) => originalParse(extractFrontMatter(text, this.db));
|
||||||
this.parser.parser.yy = this.db;
|
this.parser.parser.yy = this.db;
|
||||||
if (diagram.init) {
|
if (diagram.init) {
|
||||||
diagram.init(cnf);
|
diagram.init(cnf);
|
||||||
@ -45,7 +56,7 @@ export class Diagram {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
text = text + '\n';
|
text = text + '\n';
|
||||||
this.db.clear();
|
this.db.clear?.();
|
||||||
this.parser.parse(text);
|
this.parser.parse(text);
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -189,6 +189,7 @@ export interface C4DiagramConfig extends BaseDiagramConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface GitGraphDiagramConfig extends BaseDiagramConfig {
|
export interface GitGraphDiagramConfig extends BaseDiagramConfig {
|
||||||
|
titleTopMargin?: number;
|
||||||
diagramPadding?: number;
|
diagramPadding?: number;
|
||||||
nodeLabel?: NodeLabel;
|
nodeLabel?: NodeLabel;
|
||||||
mainBranchName?: string;
|
mainBranchName?: string;
|
||||||
@ -227,6 +228,7 @@ export interface MindmapDiagramConfig extends BaseDiagramConfig {
|
|||||||
export type PieDiagramConfig = BaseDiagramConfig;
|
export type PieDiagramConfig = BaseDiagramConfig;
|
||||||
|
|
||||||
export interface ErDiagramConfig extends BaseDiagramConfig {
|
export interface ErDiagramConfig extends BaseDiagramConfig {
|
||||||
|
titleTopMargin?: number;
|
||||||
diagramPadding?: number;
|
diagramPadding?: number;
|
||||||
layoutDirection?: string;
|
layoutDirection?: string;
|
||||||
minEntityWidth?: number;
|
minEntityWidth?: number;
|
||||||
@ -238,6 +240,7 @@ export interface ErDiagramConfig extends BaseDiagramConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface StateDiagramConfig extends BaseDiagramConfig {
|
export interface StateDiagramConfig extends BaseDiagramConfig {
|
||||||
|
titleTopMargin?: number;
|
||||||
arrowMarkerAbsolute?: boolean;
|
arrowMarkerAbsolute?: boolean;
|
||||||
dividerMargin?: number;
|
dividerMargin?: number;
|
||||||
sizeUnit?: number;
|
sizeUnit?: number;
|
||||||
@ -258,6 +261,7 @@ export interface StateDiagramConfig extends BaseDiagramConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ClassDiagramConfig extends BaseDiagramConfig {
|
export interface ClassDiagramConfig extends BaseDiagramConfig {
|
||||||
|
titleTopMargin?: number;
|
||||||
arrowMarkerAbsolute?: boolean;
|
arrowMarkerAbsolute?: boolean;
|
||||||
dividerMargin?: number;
|
dividerMargin?: number;
|
||||||
padding?: number;
|
padding?: number;
|
||||||
@ -343,6 +347,7 @@ export interface SequenceDiagramConfig extends BaseDiagramConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface FlowchartDiagramConfig extends BaseDiagramConfig {
|
export interface FlowchartDiagramConfig extends BaseDiagramConfig {
|
||||||
|
titleTopMargin?: number;
|
||||||
arrowMarkerAbsolute?: boolean;
|
arrowMarkerAbsolute?: boolean;
|
||||||
diagramPadding?: number;
|
diagramPadding?: number;
|
||||||
htmlLabels?: boolean;
|
htmlLabels?: boolean;
|
||||||
|
@ -154,6 +154,17 @@ const config: Partial<MermaidConfig> = {
|
|||||||
|
|
||||||
/** The object containing configurations specific for flowcharts */
|
/** The object containing configurations specific for flowcharts */
|
||||||
flowchart: {
|
flowchart: {
|
||||||
|
/**
|
||||||
|
* ### titleTopMargin
|
||||||
|
*
|
||||||
|
* | Parameter | Description | Type | Required | Values |
|
||||||
|
* | -------------- | ---------------------------------------------- | ------- | -------- | ------------------ |
|
||||||
|
* | titleTopMargin | Margin top for the text over the flowchart | Integer | Required | Any Positive Value |
|
||||||
|
*
|
||||||
|
* **Notes:** Default value: 25
|
||||||
|
*/
|
||||||
|
titleTopMargin: 25,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* | Parameter | Description | Type | Required | Values |
|
* | Parameter | Description | Type | Required | Values |
|
||||||
* | -------------- | ----------------------------------------------- | ------- | -------- | ------------------ |
|
* | -------------- | ----------------------------------------------- | ------- | -------- | ------------------ |
|
||||||
@ -851,6 +862,16 @@ const config: Partial<MermaidConfig> = {
|
|||||||
sectionColours: ['#fff'],
|
sectionColours: ['#fff'],
|
||||||
},
|
},
|
||||||
class: {
|
class: {
|
||||||
|
/**
|
||||||
|
* ### titleTopMargin
|
||||||
|
*
|
||||||
|
* | Parameter | Description | Type | Required | Values |
|
||||||
|
* | -------------- | ---------------------------------------------- | ------- | -------- | ------------------ |
|
||||||
|
* | titleTopMargin | Margin top for the text over the class diagram | Integer | Required | Any Positive Value |
|
||||||
|
*
|
||||||
|
* **Notes:** Default value: 25
|
||||||
|
*/
|
||||||
|
titleTopMargin: 25,
|
||||||
arrowMarkerAbsolute: false,
|
arrowMarkerAbsolute: false,
|
||||||
dividerMargin: 10,
|
dividerMargin: 10,
|
||||||
padding: 5,
|
padding: 5,
|
||||||
@ -884,6 +905,16 @@ const config: Partial<MermaidConfig> = {
|
|||||||
defaultRenderer: 'dagre-wrapper',
|
defaultRenderer: 'dagre-wrapper',
|
||||||
},
|
},
|
||||||
state: {
|
state: {
|
||||||
|
/**
|
||||||
|
* ### titleTopMargin
|
||||||
|
*
|
||||||
|
* | Parameter | Description | Type | Required | Values |
|
||||||
|
* | -------------- | ---------------------------------------------- | ------- | -------- | ------------------ |
|
||||||
|
* | titleTopMargin | Margin top for the text over the state diagram | Integer | Required | Any Positive Value |
|
||||||
|
*
|
||||||
|
* **Notes:** Default value: 25
|
||||||
|
*/
|
||||||
|
titleTopMargin: 25,
|
||||||
dividerMargin: 10,
|
dividerMargin: 10,
|
||||||
sizeUnit: 5,
|
sizeUnit: 5,
|
||||||
padding: 8,
|
padding: 8,
|
||||||
@ -932,6 +963,17 @@ const config: Partial<MermaidConfig> = {
|
|||||||
|
|
||||||
/** The object containing configurations specific for entity relationship diagrams */
|
/** The object containing configurations specific for entity relationship diagrams */
|
||||||
er: {
|
er: {
|
||||||
|
/**
|
||||||
|
* ### titleTopMargin
|
||||||
|
*
|
||||||
|
* | Parameter | Description | Type | Required | Values |
|
||||||
|
* | -------------- | ---------------------------------------------- | ------- | -------- | ------------------ |
|
||||||
|
* | titleTopMargin | Margin top for the text over the diagram | Integer | Required | Any Positive Value |
|
||||||
|
*
|
||||||
|
* **Notes:** Default value: 25
|
||||||
|
*/
|
||||||
|
titleTopMargin: 25,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* | Parameter | Description | Type | Required | Values |
|
* | Parameter | Description | Type | Required | Values |
|
||||||
* | -------------- | ----------------------------------------------- | ------- | -------- | ------------------ |
|
* | -------------- | ----------------------------------------------- | ------- | -------- | ------------------ |
|
||||||
@ -1085,6 +1127,16 @@ const config: Partial<MermaidConfig> = {
|
|||||||
line_height: 20,
|
line_height: 20,
|
||||||
},
|
},
|
||||||
gitGraph: {
|
gitGraph: {
|
||||||
|
/**
|
||||||
|
* ### titleTopMargin
|
||||||
|
*
|
||||||
|
* | Parameter | Description | Type | Required | Values |
|
||||||
|
* | -------------- | ---------------------------------------------- | ------- | -------- | ------------------ |
|
||||||
|
* | titleTopMargin | Margin top for the text over the Git diagram | Integer | Required | Any Positive Value |
|
||||||
|
*
|
||||||
|
* **Notes:** Default value: 25
|
||||||
|
*/
|
||||||
|
titleTopMargin: 25,
|
||||||
diagramPadding: 8,
|
diagramPadding: 8,
|
||||||
nodeLabel: {
|
nodeLabel: {
|
||||||
width: 75,
|
width: 75,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { MermaidConfig } from '../config.type';
|
import { MermaidConfig } from '../config.type';
|
||||||
import { log } from '../logger';
|
import { log } from '../logger';
|
||||||
import { DetectorRecord, DiagramDetector, DiagramLoader } from './types';
|
import { DetectorRecord, DiagramDetector, DiagramLoader } from './types';
|
||||||
|
import { frontMatterRegex } from './frontmatter';
|
||||||
|
|
||||||
const directive =
|
const directive =
|
||||||
/[%]{2}[{]\s*(?:(?:(\w+)\s*:|(\w+))\s*(?:(?:(\w+))|((?:(?![}][%]{2}).|\r?\n)*))?\s*)(?:[}][%]{2})?/gi;
|
/[%]{2}[{]\s*(?:(?:(\w+)\s*:|(\w+))\s*(?:(?:(\w+))|((?:(?![}][%]{2}).|\r?\n)*))?\s*)(?:[}][%]{2})?/gi;
|
||||||
@ -31,7 +32,7 @@ const detectors: Record<string, DetectorRecord> = {};
|
|||||||
* @returns A graph definition key
|
* @returns A graph definition key
|
||||||
*/
|
*/
|
||||||
export const detectType = function (text: string, config?: MermaidConfig): string {
|
export const detectType = function (text: string, config?: MermaidConfig): string {
|
||||||
text = text.replace(directive, '').replace(anyComment, '\n');
|
text = text.replace(frontMatterRegex, '').replace(directive, '').replace(anyComment, '\n');
|
||||||
for (const [key, { detector }] of Object.entries(detectors)) {
|
for (const [key, { detector }] of Object.entries(detectors)) {
|
||||||
const diagram = detector(text, config);
|
const diagram = detector(text, config);
|
||||||
if (diagram) {
|
if (diagram) {
|
||||||
|
78
packages/mermaid/src/diagram-api/frontmatter.spec.ts
Normal file
78
packages/mermaid/src/diagram-api/frontmatter.spec.ts
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
import { vi } from 'vitest';
|
||||||
|
import { extractFrontMatter } from './frontmatter';
|
||||||
|
|
||||||
|
const dbMock = () => ({ setDiagramTitle: vi.fn() });
|
||||||
|
|
||||||
|
describe('extractFrontmatter', () => {
|
||||||
|
it('returns text unchanged if no frontmatter', () => {
|
||||||
|
expect(extractFrontMatter('diagram', dbMock())).toEqual('diagram');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns text unchanged if frontmatter lacks closing delimiter', () => {
|
||||||
|
const text = `---\ntitle: foo\ndiagram`;
|
||||||
|
expect(extractFrontMatter(text, dbMock())).toEqual(text);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles empty frontmatter', () => {
|
||||||
|
const db = dbMock();
|
||||||
|
const text = `---\n\n---\ndiagram`;
|
||||||
|
expect(extractFrontMatter(text, db)).toEqual('diagram');
|
||||||
|
expect(db.setDiagramTitle).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles frontmatter without mappings', () => {
|
||||||
|
const db = dbMock();
|
||||||
|
const text = `---\n1\n---\ndiagram`;
|
||||||
|
expect(extractFrontMatter(text, db)).toEqual('diagram');
|
||||||
|
expect(db.setDiagramTitle).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not try to parse frontmatter at the end', () => {
|
||||||
|
const db = dbMock();
|
||||||
|
const text = `diagram\n---\ntitle: foo\n---\n`;
|
||||||
|
expect(extractFrontMatter(text, db)).toEqual(text);
|
||||||
|
expect(db.setDiagramTitle).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles frontmatter with multiple delimiters', () => {
|
||||||
|
const db = dbMock();
|
||||||
|
const text = `---\ntitle: foo---bar\n---\ndiagram\n---\ntest`;
|
||||||
|
expect(extractFrontMatter(text, db)).toEqual('diagram\n---\ntest');
|
||||||
|
expect(db.setDiagramTitle).toHaveBeenCalledWith('foo---bar');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles frontmatter with multi-line string and multiple delimiters', () => {
|
||||||
|
const db = dbMock();
|
||||||
|
const text = `---\ntitle: |\n multi-line string\n ---\n---\ndiagram`;
|
||||||
|
expect(extractFrontMatter(text, db)).toEqual('diagram');
|
||||||
|
expect(db.setDiagramTitle).toHaveBeenCalledWith('multi-line string\n---\n');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles frontmatter with title', () => {
|
||||||
|
const db = dbMock();
|
||||||
|
const text = `---\ntitle: foo\n---\ndiagram`;
|
||||||
|
expect(extractFrontMatter(text, db)).toEqual('diagram');
|
||||||
|
expect(db.setDiagramTitle).toHaveBeenCalledWith('foo');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles booleans in frontmatter properly', () => {
|
||||||
|
const db = dbMock();
|
||||||
|
const text = `---\ntitle: true\n---\ndiagram`;
|
||||||
|
expect(extractFrontMatter(text, db)).toEqual('diagram');
|
||||||
|
expect(db.setDiagramTitle).toHaveBeenCalledWith('true');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('ignores unspecified frontmatter keys', () => {
|
||||||
|
const db = dbMock();
|
||||||
|
const text = `---\ninvalid: true\ntitle: foo\ntest: bar\n---\ndiagram`;
|
||||||
|
expect(extractFrontMatter(text, db)).toEqual('diagram');
|
||||||
|
expect(db.setDiagramTitle).toHaveBeenCalledWith('foo');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws exception for invalid YAML syntax', () => {
|
||||||
|
const text = `---\n!!!\n---\ndiagram`;
|
||||||
|
expect(() => extractFrontMatter(text, dbMock())).toThrow(
|
||||||
|
'tag suffix cannot contain exclamation marks'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
40
packages/mermaid/src/diagram-api/frontmatter.ts
Normal file
40
packages/mermaid/src/diagram-api/frontmatter.ts
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import { DiagramDb } from './types';
|
||||||
|
// The "* as yaml" part is necessary for tree-shaking
|
||||||
|
import * as yaml from 'js-yaml';
|
||||||
|
|
||||||
|
// Match Jekyll-style front matter blocks (https://jekyllrb.com/docs/front-matter/).
|
||||||
|
// Based on regex used by Jekyll: https://github.com/jekyll/jekyll/blob/6dd3cc21c40b98054851846425af06c64f9fb466/lib/jekyll/document.rb#L10
|
||||||
|
// Note that JS doesn't support the "\A" anchor, which means we can't use
|
||||||
|
// multiline mode.
|
||||||
|
// Relevant YAML spec: https://yaml.org/spec/1.2.2/#914-explicit-documents
|
||||||
|
export const frontMatterRegex = /^(?:---\s*[\r\n])(.*?)(?:[\r\n]---\s*[\r\n]+)/s;
|
||||||
|
|
||||||
|
type FrontMatterMetadata = {
|
||||||
|
title?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract and parse frontmatter from text, if present, and sets appropriate
|
||||||
|
* properties in the provided db.
|
||||||
|
* @param text - The text that may have a YAML frontmatter.
|
||||||
|
* @param db - Diagram database, could be of any diagram.
|
||||||
|
* @returns text with frontmatter stripped out
|
||||||
|
*/
|
||||||
|
export function extractFrontMatter(text: string, db: DiagramDb): string {
|
||||||
|
const matches = text.match(frontMatterRegex);
|
||||||
|
if (matches) {
|
||||||
|
const parsed: FrontMatterMetadata = yaml.load(matches[1], {
|
||||||
|
// To keep things simple, only allow strings, arrays, and plain objects.
|
||||||
|
// https://www.yaml.org/spec/1.2/spec.html#id2802346
|
||||||
|
schema: yaml.FAILSAFE_SCHEMA,
|
||||||
|
}) as FrontMatterMetadata;
|
||||||
|
|
||||||
|
if (parsed?.title) {
|
||||||
|
db.setDiagramTitle?.(parsed.title);
|
||||||
|
}
|
||||||
|
|
||||||
|
return text.slice(matches[0].length);
|
||||||
|
} else {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
}
|
@ -8,8 +8,16 @@ export interface InjectUtils {
|
|||||||
_setupGraphViewbox: any;
|
_setupGraphViewbox: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic Diagram DB that may apply to any diagram type.
|
||||||
|
*/
|
||||||
|
export interface DiagramDb {
|
||||||
|
clear?: () => void;
|
||||||
|
setDiagramTitle?: (title: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
export interface DiagramDefinition {
|
export interface DiagramDefinition {
|
||||||
db: any;
|
db: DiagramDb;
|
||||||
renderer: any;
|
renderer: any;
|
||||||
parser: any;
|
parser: any;
|
||||||
styles: any;
|
styles: any;
|
||||||
|
@ -10,6 +10,8 @@ import {
|
|||||||
getAccDescription,
|
getAccDescription,
|
||||||
setAccDescription,
|
setAccDescription,
|
||||||
clear as commonClear,
|
clear as commonClear,
|
||||||
|
setDiagramTitle,
|
||||||
|
getDiagramTitle,
|
||||||
} from '../../commonDb';
|
} from '../../commonDb';
|
||||||
|
|
||||||
const MERMAID_DOM_ID_PREFIX = 'classid-';
|
const MERMAID_DOM_ID_PREFIX = 'classid-';
|
||||||
@ -408,4 +410,6 @@ export default {
|
|||||||
getTooltip,
|
getTooltip,
|
||||||
setTooltip,
|
setTooltip,
|
||||||
lookUpDomId,
|
lookUpDomId,
|
||||||
|
setDiagramTitle,
|
||||||
|
getDiagramTitle,
|
||||||
};
|
};
|
||||||
|
@ -3,6 +3,7 @@ import * as graphlib from 'dagre-d3-es/src/graphlib';
|
|||||||
import { log } from '../../logger';
|
import { log } from '../../logger';
|
||||||
import { getConfig } from '../../config';
|
import { getConfig } from '../../config';
|
||||||
import { render } from '../../dagre-wrapper/index.js';
|
import { render } from '../../dagre-wrapper/index.js';
|
||||||
|
import utils from '../../utils';
|
||||||
import { curveLinear } from 'd3';
|
import { curveLinear } from 'd3';
|
||||||
import { interpolateToCurve, getStylesFromArray } from '../../utils';
|
import { interpolateToCurve, getStylesFromArray } from '../../utils';
|
||||||
import { setupGraphViewbox } from '../../setupGraphViewbox';
|
import { setupGraphViewbox } from '../../setupGraphViewbox';
|
||||||
@ -429,6 +430,8 @@ export const draw = function (text, id, _version, diagObj) {
|
|||||||
id
|
id
|
||||||
);
|
);
|
||||||
|
|
||||||
|
utils.insertTitle(svg, 'classTitleText', conf.titleTopMargin, diagObj.db.getDiagramTitle());
|
||||||
|
|
||||||
setupGraphViewbox(g, svg, conf.diagramPadding, conf.useMaxWidth);
|
setupGraphViewbox(g, svg, conf.diagramPadding, conf.useMaxWidth);
|
||||||
|
|
||||||
// Add label rects for non html labels
|
// Add label rects for non html labels
|
||||||
|
@ -148,6 +148,11 @@ g.classGroup line {
|
|||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.classTitleText {
|
||||||
|
text-anchor: middle;
|
||||||
|
font-size: 18px;
|
||||||
|
fill: ${options.textColor};
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default getStyles;
|
export default getStyles;
|
||||||
|
@ -8,6 +8,8 @@ import {
|
|||||||
getAccDescription,
|
getAccDescription,
|
||||||
setAccDescription,
|
setAccDescription,
|
||||||
clear as commonClear,
|
clear as commonClear,
|
||||||
|
setDiagramTitle,
|
||||||
|
getDiagramTitle,
|
||||||
} from '../../commonDb';
|
} from '../../commonDb';
|
||||||
|
|
||||||
let entities = {};
|
let entities = {};
|
||||||
@ -94,4 +96,6 @@ export default {
|
|||||||
getAccTitle,
|
getAccTitle,
|
||||||
setAccDescription,
|
setAccDescription,
|
||||||
getAccDescription,
|
getAccDescription,
|
||||||
|
setDiagramTitle,
|
||||||
|
getDiagramTitle,
|
||||||
};
|
};
|
||||||
|
@ -3,6 +3,7 @@ import { line, curveBasis, select } from 'd3';
|
|||||||
import { layout as dagreLayout } from 'dagre-d3-es/src/dagre/index.js';
|
import { layout as dagreLayout } from 'dagre-d3-es/src/dagre/index.js';
|
||||||
import { getConfig } from '../../config';
|
import { getConfig } from '../../config';
|
||||||
import { log } from '../../logger';
|
import { log } from '../../logger';
|
||||||
|
import utils from '../../utils';
|
||||||
import erMarkers from './erMarkers';
|
import erMarkers from './erMarkers';
|
||||||
import { configureSvgSize } from '../../setupGraphViewbox';
|
import { configureSvgSize } from '../../setupGraphViewbox';
|
||||||
import addSVGAccessibilityFields from '../../accessibility';
|
import addSVGAccessibilityFields from '../../accessibility';
|
||||||
@ -649,6 +650,8 @@ export const draw = function (text, id, _version, diagObj) {
|
|||||||
|
|
||||||
const padding = conf.diagramPadding;
|
const padding = conf.diagramPadding;
|
||||||
|
|
||||||
|
utils.insertTitle(svg, 'entityTitleText', conf.titleTopMargin, diagObj.db.getDiagramTitle());
|
||||||
|
|
||||||
const svgBounds = svg.node().getBBox();
|
const svgBounds = svg.node().getBBox();
|
||||||
const width = svgBounds.width + padding * 2;
|
const width = svgBounds.width + padding * 2;
|
||||||
const height = svgBounds.height + padding * 2;
|
const height = svgBounds.height + padding * 2;
|
||||||
|
@ -27,6 +27,12 @@ const getStyles = (options) =>
|
|||||||
.relationshipLine {
|
.relationshipLine {
|
||||||
stroke: ${options.lineColor};
|
stroke: ${options.lineColor};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.entityTitleText {
|
||||||
|
text-anchor: middle;
|
||||||
|
font-size: 18px;
|
||||||
|
fill: ${options.textColor};
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default getStyles;
|
export default getStyles;
|
||||||
|
@ -10,6 +10,8 @@ import {
|
|||||||
getAccDescription,
|
getAccDescription,
|
||||||
setAccDescription,
|
setAccDescription,
|
||||||
clear as commonClear,
|
clear as commonClear,
|
||||||
|
setDiagramTitle,
|
||||||
|
getDiagramTitle,
|
||||||
} from '../../commonDb';
|
} from '../../commonDb';
|
||||||
|
|
||||||
const MERMAID_DOM_ID_PREFIX = 'flowchart-';
|
const MERMAID_DOM_ID_PREFIX = 'flowchart-';
|
||||||
@ -785,4 +787,6 @@ export default {
|
|||||||
},
|
},
|
||||||
exists,
|
exists,
|
||||||
makeUniq,
|
makeUniq,
|
||||||
|
setDiagramTitle,
|
||||||
|
getDiagramTitle,
|
||||||
};
|
};
|
||||||
|
@ -3,6 +3,7 @@ import { select, curveLinear, selectAll } from 'd3';
|
|||||||
|
|
||||||
import flowDb from './flowDb';
|
import flowDb from './flowDb';
|
||||||
import { getConfig } from '../../config';
|
import { getConfig } from '../../config';
|
||||||
|
import utils from '../../utils';
|
||||||
|
|
||||||
import { render } from '../../dagre-wrapper/index.js';
|
import { render } from '../../dagre-wrapper/index.js';
|
||||||
import { addHtmlLabel } from 'dagre-d3-es/src/dagre-js/label/add-html-label.js';
|
import { addHtmlLabel } from 'dagre-d3-es/src/dagre-js/label/add-html-label.js';
|
||||||
@ -437,6 +438,8 @@ export const draw = function (text, id, _version, diagObj) {
|
|||||||
const element = root.select('#' + id + ' g');
|
const element = root.select('#' + id + ' g');
|
||||||
render(element, g, ['point', 'circle', 'cross'], 'flowchart', id);
|
render(element, g, ['point', 'circle', 'cross'], 'flowchart', id);
|
||||||
|
|
||||||
|
utils.insertTitle(svg, 'flowchartTitleText', conf.titleTopMargin, diagObj.db.getDiagramTitle());
|
||||||
|
|
||||||
setupGraphViewbox(g, svg, conf.diagramPadding, conf.useMaxWidth);
|
setupGraphViewbox(g, svg, conf.diagramPadding, conf.useMaxWidth);
|
||||||
|
|
||||||
// Index nodes
|
// Index nodes
|
||||||
|
@ -103,6 +103,12 @@ const getStyles = (options: FlowChartStyleOptions) =>
|
|||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.flowchartTitleText {
|
||||||
|
text-anchor: middle;
|
||||||
|
font-size: 18px;
|
||||||
|
fill: ${options.textColor};
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default getStyles;
|
export default getStyles;
|
||||||
|
@ -10,6 +10,8 @@ import {
|
|||||||
getAccDescription,
|
getAccDescription,
|
||||||
setAccDescription,
|
setAccDescription,
|
||||||
clear as commonClear,
|
clear as commonClear,
|
||||||
|
setDiagramTitle,
|
||||||
|
getDiagramTitle,
|
||||||
} from '../../commonDb';
|
} from '../../commonDb';
|
||||||
|
|
||||||
let mainBranchName = getConfig().gitGraph.mainBranchName;
|
let mainBranchName = getConfig().gitGraph.mainBranchName;
|
||||||
@ -529,5 +531,7 @@ export default {
|
|||||||
getAccTitle,
|
getAccTitle,
|
||||||
getAccDescription,
|
getAccDescription,
|
||||||
setAccDescription,
|
setAccDescription,
|
||||||
|
setDiagramTitle,
|
||||||
|
getDiagramTitle,
|
||||||
commitType,
|
commitType,
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { select } from 'd3';
|
import { select } from 'd3';
|
||||||
import { getConfig, setupGraphViewbox } from '../../diagram-api/diagramAPI';
|
import { getConfig, setupGraphViewbox } from '../../diagram-api/diagramAPI';
|
||||||
import { log } from '../../logger';
|
import { log } from '../../logger';
|
||||||
|
import utils from '../../utils';
|
||||||
import addSVGAccessibilityFields from '../../accessibility';
|
import addSVGAccessibilityFields from '../../accessibility';
|
||||||
|
|
||||||
let allCommitsDict = {};
|
let allCommitsDict = {};
|
||||||
@ -521,6 +522,12 @@ export const draw = function (txt, id, ver, diagObj) {
|
|||||||
}
|
}
|
||||||
drawArrows(diagram, allCommitsDict);
|
drawArrows(diagram, allCommitsDict);
|
||||||
drawCommits(diagram, allCommitsDict, true);
|
drawCommits(diagram, allCommitsDict, true);
|
||||||
|
utils.insertTitle(
|
||||||
|
diagram,
|
||||||
|
'gitTitleText',
|
||||||
|
gitGraphConfig.titleTopMargin,
|
||||||
|
diagObj.db.getDiagramTitle()
|
||||||
|
);
|
||||||
|
|
||||||
// Setup the view box and size of the svg element
|
// Setup the view box and size of the svg element
|
||||||
setupGraphViewbox(
|
setupGraphViewbox(
|
||||||
|
@ -51,6 +51,11 @@ const getStyles = (options) =>
|
|||||||
}
|
}
|
||||||
|
|
||||||
.arrow { stroke-width: 8; stroke-linecap: round; fill: none}
|
.arrow { stroke-width: 8; stroke-linecap: round; fill: none}
|
||||||
|
.gitTitleText {
|
||||||
|
text-anchor: middle;
|
||||||
|
font-size: 18px;
|
||||||
|
fill: ${options.textColor};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -9,6 +9,8 @@ import {
|
|||||||
getAccDescription,
|
getAccDescription,
|
||||||
setAccDescription,
|
setAccDescription,
|
||||||
clear as commonClear,
|
clear as commonClear,
|
||||||
|
setDiagramTitle,
|
||||||
|
getDiagramTitle,
|
||||||
} from '../../commonDb';
|
} from '../../commonDb';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -571,4 +573,6 @@ export default {
|
|||||||
addStyleClass,
|
addStyleClass,
|
||||||
setCssClass,
|
setCssClass,
|
||||||
addDescription,
|
addDescription,
|
||||||
|
setDiagramTitle,
|
||||||
|
getDiagramTitle,
|
||||||
};
|
};
|
||||||
|
@ -5,6 +5,7 @@ import { render } from '../../dagre-wrapper/index.js';
|
|||||||
import { log } from '../../logger';
|
import { log } from '../../logger';
|
||||||
import { configureSvgSize } from '../../setupGraphViewbox';
|
import { configureSvgSize } from '../../setupGraphViewbox';
|
||||||
import common from '../common/common';
|
import common from '../common/common';
|
||||||
|
import utils from '../../utils';
|
||||||
import addSVGAccessibilityFields from '../../accessibility';
|
import addSVGAccessibilityFields from '../../accessibility';
|
||||||
import {
|
import {
|
||||||
DEFAULT_DIAGRAM_DIRECTION,
|
DEFAULT_DIAGRAM_DIRECTION,
|
||||||
@ -437,8 +438,9 @@ export const draw = function (text, id, _version, diag) {
|
|||||||
|
|
||||||
const padding = 8;
|
const padding = 8;
|
||||||
|
|
||||||
const bounds = svg.node().getBBox();
|
utils.insertTitle(svg, 'statediagramTitleText', conf.titleTopMargin, diag.db.getDiagramTitle());
|
||||||
|
|
||||||
|
const bounds = svg.node().getBBox();
|
||||||
const width = bounds.width + padding * 2;
|
const width = bounds.width + padding * 2;
|
||||||
const height = bounds.height + padding * 2;
|
const height = bounds.height + padding * 2;
|
||||||
|
|
||||||
|
@ -194,6 +194,12 @@ g.stateGroup line {
|
|||||||
stroke: ${options.lineColor};
|
stroke: ${options.lineColor};
|
||||||
stroke-width: 1;
|
stroke-width: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.statediagramTitleText {
|
||||||
|
text-anchor: middle;
|
||||||
|
font-size: 18px;
|
||||||
|
fill: ${options.textColor};
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default getStyles;
|
export default getStyles;
|
||||||
|
@ -8,7 +8,7 @@ It is a JavaScript based diagramming and charting tool that renders Markdown-ins
|
|||||||
|
|
||||||
<img src="/header.png" alt="" />
|
<img src="/header.png" alt="" />
|
||||||
|
|
||||||
[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
|
[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![npm minified gzipped bundle size](https://img.shields.io/bundlephobia/minzip/mermaid)](https://bundlephobia.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
|
||||||
|
|
||||||
<!-- Mermaid book banner -->
|
<!-- Mermaid book banner -->
|
||||||
|
|
||||||
|
@ -8,6 +8,9 @@ The class diagram is the main building block of object-oriented modeling. It is
|
|||||||
Mermaid can render class diagrams.
|
Mermaid can render class diagrams.
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
|
---
|
||||||
|
title: Animal example
|
||||||
|
---
|
||||||
classDiagram
|
classDiagram
|
||||||
note "From Duck till Zebra"
|
note "From Duck till Zebra"
|
||||||
Animal <|-- Duck
|
Animal <|-- Duck
|
||||||
@ -45,6 +48,9 @@ A single instance of a class in the diagram contains three compartments:
|
|||||||
- The bottom compartment contains the operations the class can execute. They are also left-aligned and the first letter is lowercase.
|
- The bottom compartment contains the operations the class can execute. They are also left-aligned and the first letter is lowercase.
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
|
---
|
||||||
|
title: Bank example
|
||||||
|
---
|
||||||
classDiagram
|
classDiagram
|
||||||
class BankAccount
|
class BankAccount
|
||||||
BankAccount : +String owner
|
BankAccount : +String owner
|
||||||
|
@ -7,6 +7,9 @@ Note that practitioners of ER modelling almost always refer to _entity types_ si
|
|||||||
Mermaid can render ER diagrams
|
Mermaid can render ER diagrams
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
|
---
|
||||||
|
title: Order example
|
||||||
|
---
|
||||||
erDiagram
|
erDiagram
|
||||||
CUSTOMER ||--o{ ORDER : places
|
CUSTOMER ||--o{ ORDER : places
|
||||||
ORDER ||--|{ LINE-ITEM : contains
|
ORDER ||--|{ LINE-ITEM : contains
|
||||||
|
@ -9,6 +9,9 @@ It can also accommodate different arrow types, multi directional arrows, and lin
|
|||||||
### A node (default)
|
### A node (default)
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
|
---
|
||||||
|
title: Node
|
||||||
|
---
|
||||||
flowchart LR
|
flowchart LR
|
||||||
id
|
id
|
||||||
```
|
```
|
||||||
@ -22,6 +25,9 @@ found for the node that will be used. Also if you define edges for the node late
|
|||||||
one previously defined will be used when rendering the box.
|
one previously defined will be used when rendering the box.
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
|
---
|
||||||
|
title: Node with text
|
||||||
|
---
|
||||||
flowchart LR
|
flowchart LR
|
||||||
id1[This is the text in the box]
|
id1[This is the text in the box]
|
||||||
```
|
```
|
||||||
|
@ -7,17 +7,20 @@ These kind of diagram are particularly helpful to developers and devops teams to
|
|||||||
Mermaid can render Git diagrams
|
Mermaid can render Git diagrams
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
gitGraph
|
---
|
||||||
commit
|
title: Example Git diagram
|
||||||
commit
|
---
|
||||||
branch develop
|
gitGraph
|
||||||
checkout develop
|
commit
|
||||||
commit
|
commit
|
||||||
commit
|
branch develop
|
||||||
checkout main
|
checkout develop
|
||||||
merge develop
|
commit
|
||||||
commit
|
commit
|
||||||
commit
|
checkout main
|
||||||
|
merge develop
|
||||||
|
commit
|
||||||
|
commit
|
||||||
```
|
```
|
||||||
|
|
||||||
In Mermaid, we support the basic git operations like:
|
In Mermaid, we support the basic git operations like:
|
||||||
|
@ -5,6 +5,9 @@
|
|||||||
Mermaid can render state diagrams. The syntax tries to be compliant with the syntax used in plantUml as this will make it easier for users to share diagrams between mermaid and plantUml.
|
Mermaid can render state diagrams. The syntax tries to be compliant with the syntax used in plantUml as this will make it easier for users to share diagrams between mermaid and plantUml.
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
|
---
|
||||||
|
title: Simple sample
|
||||||
|
---
|
||||||
stateDiagram-v2
|
stateDiagram-v2
|
||||||
[*] --> Still
|
[*] --> Still
|
||||||
Still --> [*]
|
Still --> [*]
|
||||||
|
@ -3,7 +3,8 @@ import utils from './utils';
|
|||||||
import assignWithDepth from './assignWithDepth';
|
import assignWithDepth from './assignWithDepth';
|
||||||
import { detectType } from './diagram-api/detectType';
|
import { detectType } from './diagram-api/detectType';
|
||||||
import { addDiagrams } from './diagram-api/diagram-orchestration';
|
import { addDiagrams } from './diagram-api/diagram-orchestration';
|
||||||
import memoize from 'lodash-es/memoize';
|
import memoize from 'lodash/memoize';
|
||||||
|
import { MockD3 } from 'd3';
|
||||||
addDiagrams();
|
addDiagrams();
|
||||||
|
|
||||||
describe('when assignWithDepth: should merge objects within objects', function () {
|
describe('when assignWithDepth: should merge objects within objects', function () {
|
||||||
@ -232,6 +233,15 @@ Alice->Bob: hi`;
|
|||||||
const type = detectType(str);
|
const type = detectType(str);
|
||||||
expect(type).toBe('gitGraph');
|
expect(type).toBe('gitGraph');
|
||||||
});
|
});
|
||||||
|
it('should handle frontmatter', function () {
|
||||||
|
const str = '---\ntitle: foo\n---\n gitGraph TB:\nbfs1:queue';
|
||||||
|
const type = detectType(str);
|
||||||
|
expect(type).toBe('gitGraph');
|
||||||
|
});
|
||||||
|
it('should not allow frontmatter with leading spaces', function () {
|
||||||
|
const str = ' ---\ntitle: foo\n---\n gitGraph TB:\nbfs1:queue';
|
||||||
|
expect(() => detectType(str)).toThrow('No diagram type detected for text');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
describe('when finding substring in array ', function () {
|
describe('when finding substring in array ', function () {
|
||||||
it('should return the array index that contains the substring', function () {
|
it('should return the array index that contains the substring', function () {
|
||||||
@ -340,3 +350,23 @@ describe('when initializing the id generator', function () {
|
|||||||
expect(idGenerator.next()).toEqual(lastId + 1);
|
expect(idGenerator.next()).toEqual(lastId + 1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('when inserting titles', function () {
|
||||||
|
it('should do nothing when title is empty', function () {
|
||||||
|
const svg = MockD3('svg');
|
||||||
|
utils.insertTitle(svg, 'testClass', 0, '');
|
||||||
|
expect(svg.__children.length).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should insert title centered', function () {
|
||||||
|
const svg = MockD3('svg');
|
||||||
|
utils.insertTitle(svg, 'testClass', 5, 'test title');
|
||||||
|
expect(svg.__children.length).toBe(1);
|
||||||
|
const text = svg.__children[0];
|
||||||
|
expect(text.__name).toBe('text');
|
||||||
|
expect(text.text).toHaveBeenCalledWith('test title');
|
||||||
|
expect(text.attr).toHaveBeenCalledWith('x', 15);
|
||||||
|
expect(text.attr).toHaveBeenCalledWith('y', -5);
|
||||||
|
expect(text.attr).toHaveBeenCalledWith('class', 'testClass');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -914,6 +914,32 @@ export function getErrorMessage(error: unknown): string {
|
|||||||
return String(error);
|
return String(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends <text> element with the given title, centered.
|
||||||
|
*
|
||||||
|
* @param parent - d3 svg object to append title to
|
||||||
|
* @param cssClass - CSS class for the <text> element containing the title
|
||||||
|
* @param titleTopMargin - Margin in pixels between title and rest of the graph
|
||||||
|
* @param title - The title. If empty, returns immediately.
|
||||||
|
*/
|
||||||
|
export const insertTitle = (
|
||||||
|
parent,
|
||||||
|
cssClass: string,
|
||||||
|
titleTopMargin: number,
|
||||||
|
title?: string
|
||||||
|
): void => {
|
||||||
|
if (!title) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const bounds = parent.node().getBBox();
|
||||||
|
parent
|
||||||
|
.append('text')
|
||||||
|
.text(title)
|
||||||
|
.attr('x', bounds.x + bounds.width / 2)
|
||||||
|
.attr('y', -titleTopMargin)
|
||||||
|
.attr('class', cssClass);
|
||||||
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
assignWithDepth,
|
assignWithDepth,
|
||||||
wrapLabel,
|
wrapLabel,
|
||||||
@ -936,4 +962,5 @@ export default {
|
|||||||
initIdGenerator: initIdGenerator,
|
initIdGenerator: initIdGenerator,
|
||||||
directiveSanitizer,
|
directiveSanitizer,
|
||||||
sanitizeCss,
|
sanitizeCss,
|
||||||
|
insertTitle,
|
||||||
};
|
};
|
||||||
|
10
pnpm-lock.yaml
generated
10
pnpm-lock.yaml
generated
@ -22,6 +22,9 @@ importers:
|
|||||||
'@types/express':
|
'@types/express':
|
||||||
specifier: ^4.17.14
|
specifier: ^4.17.14
|
||||||
version: 4.17.14
|
version: 4.17.14
|
||||||
|
'@types/js-yaml':
|
||||||
|
specifier: ^4.0.5
|
||||||
|
version: 4.0.5
|
||||||
'@types/jsdom':
|
'@types/jsdom':
|
||||||
specifier: ^20.0.1
|
specifier: ^20.0.1
|
||||||
version: 20.0.1
|
version: 20.0.1
|
||||||
@ -115,6 +118,9 @@ importers:
|
|||||||
jison:
|
jison:
|
||||||
specifier: ^0.4.18
|
specifier: ^0.4.18
|
||||||
version: 0.4.18
|
version: 0.4.18
|
||||||
|
js-yaml:
|
||||||
|
specifier: ^4.1.0
|
||||||
|
version: 4.1.0
|
||||||
jsdom:
|
jsdom:
|
||||||
specifier: ^20.0.2
|
specifier: ^20.0.2
|
||||||
version: 20.0.2
|
version: 20.0.2
|
||||||
@ -2466,6 +2472,10 @@ packages:
|
|||||||
'@types/istanbul-lib-report': 3.0.0
|
'@types/istanbul-lib-report': 3.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@types/js-yaml/4.0.5:
|
||||||
|
resolution: {integrity: sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@types/jsdom/20.0.1:
|
/@types/jsdom/20.0.1:
|
||||||
resolution: {integrity: sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==}
|
resolution: {integrity: sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user