mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-08-22 17:56:43 +02:00
Merge branch 'develop' into fix-node16-module-resolution
This commit is contained in:
1
.npmrc
1
.npmrc
@@ -1,3 +1,2 @@
|
|||||||
auto-install-peers=true
|
auto-install-peers=true
|
||||||
strict-peer-dependencies=false
|
strict-peer-dependencies=false
|
||||||
use-inline-specifiers-lockfile-format=true
|
|
||||||
|
@@ -10,7 +10,6 @@ describe('Entity Relationship Diagram', () => {
|
|||||||
`,
|
`,
|
||||||
{ logLevel: 1 }
|
{ logLevel: 1 }
|
||||||
);
|
);
|
||||||
cy.get('svg');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render an ER diagram with a recursive relationship', () => {
|
it('should render an ER diagram with a recursive relationship', () => {
|
||||||
@@ -23,7 +22,6 @@ describe('Entity Relationship Diagram', () => {
|
|||||||
`,
|
`,
|
||||||
{ logLevel: 1 }
|
{ logLevel: 1 }
|
||||||
);
|
);
|
||||||
cy.get('svg');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render an ER diagram with multiple relationships between the same two entities', () => {
|
it('should render an ER diagram with multiple relationships between the same two entities', () => {
|
||||||
@@ -35,7 +33,6 @@ describe('Entity Relationship Diagram', () => {
|
|||||||
`,
|
`,
|
||||||
{ logLevel: 1 }
|
{ logLevel: 1 }
|
||||||
);
|
);
|
||||||
cy.get('svg');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render a cyclical ER diagram', () => {
|
it('should render a cyclical ER diagram', () => {
|
||||||
@@ -48,7 +45,6 @@ describe('Entity Relationship Diagram', () => {
|
|||||||
`,
|
`,
|
||||||
{ logLevel: 1 }
|
{ logLevel: 1 }
|
||||||
);
|
);
|
||||||
cy.get('svg');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render a not-so-simple ER diagram', () => {
|
it('should render a not-so-simple ER diagram', () => {
|
||||||
@@ -66,7 +62,6 @@ describe('Entity Relationship Diagram', () => {
|
|||||||
`,
|
`,
|
||||||
{ logLevel: 1 }
|
{ logLevel: 1 }
|
||||||
);
|
);
|
||||||
cy.get('svg');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render multiple ER diagrams', () => {
|
it('should render multiple ER diagrams', () => {
|
||||||
@@ -85,7 +80,6 @@ describe('Entity Relationship Diagram', () => {
|
|||||||
],
|
],
|
||||||
{ logLevel: 1 }
|
{ logLevel: 1 }
|
||||||
);
|
);
|
||||||
cy.get('svg');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render an ER diagram with blank or empty labels', () => {
|
it('should render an ER diagram with blank or empty labels', () => {
|
||||||
@@ -98,7 +92,6 @@ describe('Entity Relationship Diagram', () => {
|
|||||||
`,
|
`,
|
||||||
{ logLevel: 1 }
|
{ logLevel: 1 }
|
||||||
);
|
);
|
||||||
cy.get('svg');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render an ER diagrams when useMaxWidth is true (default)', () => {
|
it('should render an ER diagrams when useMaxWidth is true (default)', () => {
|
||||||
@@ -151,7 +144,6 @@ describe('Entity Relationship Diagram', () => {
|
|||||||
`,
|
`,
|
||||||
{ er: { useMaxWidth: false } }
|
{ er: { useMaxWidth: false } }
|
||||||
);
|
);
|
||||||
cy.get('svg');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render entities with and without attributes', () => {
|
it('should render entities with and without attributes', () => {
|
||||||
@@ -164,7 +156,6 @@ describe('Entity Relationship Diagram', () => {
|
|||||||
`,
|
`,
|
||||||
{ logLevel: 1 }
|
{ logLevel: 1 }
|
||||||
);
|
);
|
||||||
cy.get('svg');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render entities with generic and array attributes', () => {
|
it('should render entities with generic and array attributes', () => {
|
||||||
@@ -179,7 +170,6 @@ describe('Entity Relationship Diagram', () => {
|
|||||||
`,
|
`,
|
||||||
{ logLevel: 1 }
|
{ logLevel: 1 }
|
||||||
);
|
);
|
||||||
cy.get('svg');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render entities with length in attributes type', () => {
|
it('should render entities with length in attributes type', () => {
|
||||||
@@ -193,7 +183,6 @@ describe('Entity Relationship Diagram', () => {
|
|||||||
`,
|
`,
|
||||||
{ logLevel: 1 }
|
{ logLevel: 1 }
|
||||||
);
|
);
|
||||||
cy.get('svg');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render entities and attributes with big and small entity names', () => {
|
it('should render entities and attributes with big and small entity names', () => {
|
||||||
@@ -209,7 +198,6 @@ describe('Entity Relationship Diagram', () => {
|
|||||||
`,
|
`,
|
||||||
{ logLevel: 1 }
|
{ logLevel: 1 }
|
||||||
);
|
);
|
||||||
cy.get('svg');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render entities with keys', () => {
|
it('should render entities with keys', () => {
|
||||||
@@ -228,7 +216,6 @@ describe('Entity Relationship Diagram', () => {
|
|||||||
`,
|
`,
|
||||||
{ logLevel: 1 }
|
{ logLevel: 1 }
|
||||||
);
|
);
|
||||||
cy.get('svg');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render entities with comments', () => {
|
it('should render entities with comments', () => {
|
||||||
@@ -247,7 +234,6 @@ describe('Entity Relationship Diagram', () => {
|
|||||||
`,
|
`,
|
||||||
{ logLevel: 1 }
|
{ logLevel: 1 }
|
||||||
);
|
);
|
||||||
cy.get('svg');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render entities with keys and comments', () => {
|
it('should render entities with keys and comments', () => {
|
||||||
@@ -267,7 +253,6 @@ describe('Entity Relationship Diagram', () => {
|
|||||||
`,
|
`,
|
||||||
{ logLevel: 1 }
|
{ logLevel: 1 }
|
||||||
);
|
);
|
||||||
cy.get('svg');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render entities with aliases', () => {
|
it('should render entities with aliases', () => {
|
||||||
@@ -285,7 +270,6 @@ describe('Entity Relationship Diagram', () => {
|
|||||||
`,
|
`,
|
||||||
{ logLevel: 1 }
|
{ logLevel: 1 }
|
||||||
);
|
);
|
||||||
cy.get('svg');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('1433: should render a simple ER diagram with a title', () => {
|
it('1433: should render a simple ER diagram with a title', () => {
|
||||||
|
45
cypress/integration/rendering/errorDiagram.spec.js
Normal file
45
cypress/integration/rendering/errorDiagram.spec.js
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import { imgSnapshotTest } from '../../helpers/util';
|
||||||
|
|
||||||
|
describe('Error Diagrams', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.on('uncaught:exception', (err) => {
|
||||||
|
expect(err.message).to.include('Parse error');
|
||||||
|
// return false to prevent the error from
|
||||||
|
// failing this test
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render a simple ER diagram', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
error
|
||||||
|
`,
|
||||||
|
{ logLevel: 1 }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render error diagram for actual errors', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
flowchart TD
|
||||||
|
A[Christmas] --|Get money| B(Go shopping)
|
||||||
|
`,
|
||||||
|
{ logLevel: 1 }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render error for wrong ER diagram', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
erDiagram
|
||||||
|
ATLAS-ORGANIZATION ||--|{ ATLAS-PROJECTS : "has many"
|
||||||
|
ATLAS-PROJECTS ||--|{ MONGODB-CLUSTERS : "has many"
|
||||||
|
ATLAS-PROJECTS ||--|{ ATLAS-TEAMS : "has many"
|
||||||
|
MONGODB-CLUSTERS ||..|{
|
||||||
|
ATLAS-TEAMS ||..|{
|
||||||
|
`,
|
||||||
|
{ logLevel: 1 }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
@@ -133,6 +133,24 @@ describe('Gantt diagram', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should default to showing today marker', () => {
|
||||||
|
// This test only works if the environment thinks today is 1010-10-10
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
gantt
|
||||||
|
title Show today marker (vertical line should be visible)
|
||||||
|
dateFormat YYYY-MM-DD
|
||||||
|
axisFormat %d
|
||||||
|
%% Should default to being on
|
||||||
|
%% todayMarker on
|
||||||
|
section Section1
|
||||||
|
Yesterday: 1010-10-09, 1d
|
||||||
|
Today: 1010-10-10, 1d
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('should hide today marker', () => {
|
it('should hide today marker', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
@@ -142,7 +160,8 @@ describe('Gantt diagram', () => {
|
|||||||
axisFormat %d
|
axisFormat %d
|
||||||
todayMarker off
|
todayMarker off
|
||||||
section Section1
|
section Section1
|
||||||
Today: 1, -1h
|
Yesterday: 1010-10-09, 1d
|
||||||
|
Today: 1010-10-10, 1d
|
||||||
`,
|
`,
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
@@ -157,7 +176,8 @@ describe('Gantt diagram', () => {
|
|||||||
axisFormat %d
|
axisFormat %d
|
||||||
todayMarker stroke-width:5px,stroke:#00f,opacity:0.5
|
todayMarker stroke-width:5px,stroke:#00f,opacity:0.5
|
||||||
section Section1
|
section Section1
|
||||||
Today: 1, -1h
|
Yesterday: 1010-10-09, 1d
|
||||||
|
Today: 1010-10-10, 1d
|
||||||
`,
|
`,
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
@@ -435,4 +455,39 @@ describe('Gantt diagram', () => {
|
|||||||
{ gantt: { topAxis: true } }
|
{ gantt: { topAxis: true } }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should render when compact is true', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
---
|
||||||
|
displayMode: compact
|
||||||
|
---
|
||||||
|
gantt
|
||||||
|
title GANTT compact
|
||||||
|
dateFormat HH:mm:ss
|
||||||
|
axisFormat %Hh%M
|
||||||
|
|
||||||
|
section DB Clean
|
||||||
|
Clean: 12:00:00, 10m
|
||||||
|
Clean: 12:30:00, 12m
|
||||||
|
Clean: 13:00:00, 8m
|
||||||
|
Clean: 13:30:00, 9m
|
||||||
|
Clean: 14:00:00, 13m
|
||||||
|
Clean: 14:30:00, 10m
|
||||||
|
Clean: 15:00:00, 11m
|
||||||
|
|
||||||
|
section Sessions
|
||||||
|
A: 12:00:00, 63m
|
||||||
|
B: 12:30:00, 12m
|
||||||
|
C: 13:05:00, 12m
|
||||||
|
D: 13:06:00, 33m
|
||||||
|
E: 13:15:00, 55m
|
||||||
|
F: 13:20:00, 12m
|
||||||
|
G: 13:32:00, 18m
|
||||||
|
H: 13:50:00, 20m
|
||||||
|
I: 14:10:00, 10m
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@@ -47,7 +47,6 @@ const contentLoaded = async function () {
|
|||||||
await mermaid2.registerExternalDiagrams([externalExample]);
|
await mermaid2.registerExternalDiagrams([externalExample]);
|
||||||
mermaid2.initialize(graphObj.mermaid);
|
mermaid2.initialize(graphObj.mermaid);
|
||||||
await mermaid2.run();
|
await mermaid2.run();
|
||||||
markRendered();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -123,7 +122,6 @@ const contentLoadedApi = async function () {
|
|||||||
bindFunctions(div);
|
bindFunctions(div);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
markRendered();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (typeof document !== 'undefined') {
|
if (typeof document !== 'undefined') {
|
||||||
@@ -135,10 +133,10 @@ if (typeof document !== 'undefined') {
|
|||||||
function () {
|
function () {
|
||||||
if (this.location.href.match('xss.html')) {
|
if (this.location.href.match('xss.html')) {
|
||||||
this.console.log('Using api');
|
this.console.log('Using api');
|
||||||
void contentLoadedApi();
|
void contentLoadedApi().finally(markRendered);
|
||||||
} else {
|
} else {
|
||||||
this.console.log('Not using api');
|
this.console.log('Not using api');
|
||||||
void contentLoaded();
|
void contentLoaded().finally(markRendered);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
false
|
false
|
||||||
|
38
demos/error.html
Normal file
38
demos/error.html
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<title>Error | Mermaid Quick Test Page</title>
|
||||||
|
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<pre class="mermaid">
|
||||||
|
erDiagram
|
||||||
|
ATLAS-ORGANIZATION ||--|{ ATLAS-PROJECTS : "has many"
|
||||||
|
ATLAS-PROJECTS ||--|{ MONGODB-CLUSTERS : "has many"
|
||||||
|
ATLAS-PROJECTS ||--|{ ATLAS-TEAMS : "has many"
|
||||||
|
</pre>
|
||||||
|
<pre class="mermaid">
|
||||||
|
erDiagram
|
||||||
|
ATLAS-ORGANIZATION ||--|{ ATLAS-PROJECTS : "has many"
|
||||||
|
ATLAS-PROJECTS ||--|{ MONGODB-CLUSTERS : "has many"
|
||||||
|
ATLAS-PROJECTS ||--|{ ATLAS-TEAMS : "has many"
|
||||||
|
MONGODB-CLUSTERS ||..|{
|
||||||
|
ATLAS-TEAMS ||..|{
|
||||||
|
</pre>
|
||||||
|
<hr />
|
||||||
|
<pre class="mermaid">
|
||||||
|
flowchart TD
|
||||||
|
A[Christmas] -->|Get money| B(Go shopping)
|
||||||
|
</pre>
|
||||||
|
<pre class="mermaid">
|
||||||
|
flowchart TD
|
||||||
|
A[Christmas] --|Get money| B(Go shopping)
|
||||||
|
</pre>
|
||||||
|
<script type="module">
|
||||||
|
import mermaid from './mermaid.esm.mjs';
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@@ -78,7 +78,7 @@
|
|||||||
axisFormat %d/%m
|
axisFormat %d/%m
|
||||||
todayMarker off
|
todayMarker off
|
||||||
section Section1
|
section Section1
|
||||||
Today: 1, -01:00, 5min
|
Today: 1, 08-08-09-01:00, 5min
|
||||||
</pre>
|
</pre>
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
@@ -89,7 +89,7 @@
|
|||||||
axisFormat %d/%m
|
axisFormat %d/%m
|
||||||
todayMarker stroke-width:5px,stroke:#00f,opacity:0.5
|
todayMarker stroke-width:5px,stroke:#00f,opacity:0.5
|
||||||
section Section1
|
section Section1
|
||||||
Today: 1, -01:00, 5min
|
Today: 1, 08-08-09-01:00, 5min
|
||||||
</pre>
|
</pre>
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
@@ -166,6 +166,37 @@
|
|||||||
</pre>
|
</pre>
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
|
<pre class="mermaid">
|
||||||
|
---
|
||||||
|
displayMode: compact
|
||||||
|
---
|
||||||
|
gantt
|
||||||
|
title GANTT compact
|
||||||
|
dateFormat HH:mm:ss
|
||||||
|
axisFormat %Hh%M
|
||||||
|
|
||||||
|
section DB Clean
|
||||||
|
Clean: 12:00:00, 10m
|
||||||
|
Clean: 12:30:00, 12m
|
||||||
|
Clean: 13:00:00, 8m
|
||||||
|
Clean: 13:30:00, 9m
|
||||||
|
Clean: 14:00:00, 13m
|
||||||
|
Clean: 14:30:00, 10m
|
||||||
|
Clean: 15:00:00, 11m
|
||||||
|
|
||||||
|
section Sessions
|
||||||
|
A: 12:00:00, 63m
|
||||||
|
B: 12:30:00, 12m
|
||||||
|
C: 13:05:00, 12m
|
||||||
|
D: 13:06:00, 33m
|
||||||
|
E: 13:15:00, 55m
|
||||||
|
F: 13:20:00, 12m
|
||||||
|
G: 13:32:00, 18m
|
||||||
|
H: 13:50:00, 20m
|
||||||
|
I: 14:10:00, 10m
|
||||||
|
</pre>
|
||||||
|
<hr />
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
function ganttTestClick(a, b, c) {
|
function ganttTestClick(a, b, c) {
|
||||||
console.log('a:', a);
|
console.log('a:', a);
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[defaultConfig.ts:2093](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L2093)
|
[defaultConfig.ts:2103](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L2103)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@@ -88,6 +88,7 @@ const config = {
|
|||||||
numberSectionStyles: 4,
|
numberSectionStyles: 4,
|
||||||
axisFormat: '%Y-%m-%d',
|
axisFormat: '%Y-%m-%d',
|
||||||
topAxis: false,
|
topAxis: false,
|
||||||
|
displayMode: '',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
mermaid.initialize(config);
|
mermaid.initialize(config);
|
||||||
@@ -95,7 +96,7 @@ mermaid.initialize(config);
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:659](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L659)
|
[mermaidAPI.ts:660](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L660)
|
||||||
|
|
||||||
## Functions
|
## Functions
|
||||||
|
|
||||||
|
@@ -183,8 +183,6 @@ flowchart LR
|
|||||||
|
|
||||||
### A hexagon node
|
### A hexagon node
|
||||||
|
|
||||||
Code:
|
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
flowchart LR
|
flowchart LR
|
||||||
id1{{This is the text in the box}}
|
id1{{This is the text in the box}}
|
||||||
|
@@ -257,9 +257,41 @@ The pattern is:
|
|||||||
|
|
||||||
More info in: <https://github.com/d3/d3-time#interval_every>
|
More info in: <https://github.com/d3/d3-time#interval_every>
|
||||||
|
|
||||||
|
## Output in compact mode
|
||||||
|
|
||||||
|
The compact mode allows you to display multiple tasks in the same row. Compact mode can be enabled for a gantt chart by setting the display mode of the graph via preceeding YAML settings.
|
||||||
|
|
||||||
|
```mermaid-example
|
||||||
|
---
|
||||||
|
displayMode: compact
|
||||||
|
---
|
||||||
|
gantt
|
||||||
|
title A Gantt Diagram
|
||||||
|
dateFormat YYYY-MM-DD
|
||||||
|
|
||||||
|
section Section
|
||||||
|
A task :a1, 2014-01-01, 30d
|
||||||
|
Another task :a2, 2014-01-20, 25d
|
||||||
|
Another one :a3, 2014-02-10, 20d
|
||||||
|
```
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
---
|
||||||
|
displayMode: compact
|
||||||
|
---
|
||||||
|
gantt
|
||||||
|
title A Gantt Diagram
|
||||||
|
dateFormat YYYY-MM-DD
|
||||||
|
|
||||||
|
section Section
|
||||||
|
A task :a1, 2014-01-01, 30d
|
||||||
|
Another task :a2, 2014-01-20, 25d
|
||||||
|
Another one :a3, 2014-02-10, 20d
|
||||||
|
```
|
||||||
|
|
||||||
## Comments
|
## Comments
|
||||||
|
|
||||||
Comments can be entered within a gantt chart, which will be ignored by the parser. Comments need to be on their own line and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any diagram syntax
|
Comments can be entered within a gantt chart, which will be ignored by the parser. Comments need to be on their own line and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any diagram syntax.
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
gantt
|
gantt
|
||||||
|
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
> Timeline: This is an experimental diagram for now. The syntax and properties can change in future releases. The syntax is stable except for the icon integration which is the experimental part.
|
> Timeline: This is an experimental diagram for now. The syntax and properties can change in future releases. The syntax is stable except for the icon integration which is the experimental part.
|
||||||
|
|
||||||
"A timeline is a type of diagram used to illustrate a chronology of events, dates, or periods of time. It is usually presented graphically to indicate the passing of time, and it is usually organized chronologically. A basic timeline presents a list of events in chronological order, usually using dates as markers. A timeline can also be used to show the relationship between events, such as the relationship between the events of a person's life. A timeline can also be used to show the relationship between events, such as the relationship between the events of a person's life." Wikipedia
|
"A timeline is a type of diagram used to illustrate a chronology of events, dates, or periods of time. It is usually presented graphically to indicate the passing of time, and it is usually organized chronologically. A basic timeline presents a list of events in chronological order, usually using dates as markers. A timeline can also be used to show the relationship between events, such as the relationship between the events of a person's life." Wikipedia
|
||||||
|
|
||||||
### An example of a timeline.
|
### An example of a timeline.
|
||||||
|
|
||||||
@@ -213,7 +213,7 @@ However, if there is no section defined, then we have two possibilities:
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that this is no, section defined, and each time period and its corresponding events will have its own color scheme.
|
Note that there are no sections defined, and each time period and its corresponding events will have its own color scheme.
|
||||||
|
|
||||||
2. Disable the multiColor option using the `disableMultiColor` option. This will make all time periods and events follow the same color scheme.
|
2. Disable the multiColor option using the `disableMultiColor` option. This will make all time periods and events follow the same color scheme.
|
||||||
|
|
||||||
@@ -257,7 +257,7 @@ let us look at same example, where we have disabled the multiColor option.
|
|||||||
|
|
||||||
### Customizing Color scheme
|
### Customizing Color scheme
|
||||||
|
|
||||||
You can customize the color scheme using the `cScale0` to `cScale11` theme variables. Mermaid allows you to set unique colors for up-to 12, where `cScale0` variable will drive the value of the first section or time-period, `cScale1` will drive the value of the second section and so on.
|
You can customize the color scheme using the `cScale0` to `cScale11` theme variables. Mermaid allows you to set unique colors for up-to 12 sections, where `cScale0` variable will drive the value of the first section or time-period, `cScale1` will drive the value of the second section and so on.
|
||||||
In case you have more than 12 sections, the color scheme will start to repeat.
|
In case you have more than 12 sections, the color scheme will start to repeat.
|
||||||
|
|
||||||
NOTE: Default values for these theme variables are picked from the selected theme. If you want to override the default values, you can use the `initialize` call to add your custom theme variable values.
|
NOTE: Default values for these theme variables are picked from the selected theme. If you want to override the default values, you can use the `initialize` call to add your custom theme variable values.
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
"version": "10.0.2",
|
"version": "10.0.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.30.0",
|
"packageManager": "pnpm@7.30.1",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"diagram",
|
"diagram",
|
||||||
"markdown",
|
"markdown",
|
||||||
|
@@ -5,6 +5,7 @@ import { detectType, getDiagramLoader } from './diagram-api/detectType.js';
|
|||||||
import { extractFrontMatter } from './diagram-api/frontmatter.js';
|
import { extractFrontMatter } from './diagram-api/frontmatter.js';
|
||||||
import { UnknownDiagramError } from './errors.js';
|
import { UnknownDiagramError } from './errors.js';
|
||||||
import { DetailedError } from './utils.js';
|
import { DetailedError } from './utils.js';
|
||||||
|
import { cleanupComments } from './diagram-api/comments.js';
|
||||||
|
|
||||||
export type ParseErrorFunction = (err: string | DetailedError | unknown, hash?: any) => void;
|
export type ParseErrorFunction = (err: string | DetailedError | unknown, hash?: any) => void;
|
||||||
|
|
||||||
@@ -43,7 +44,8 @@ export class Diagram {
|
|||||||
// Similarly, we can't do this in getDiagramFromText() because some code
|
// Similarly, we can't do this in getDiagramFromText() because some code
|
||||||
// calls diagram.db.clear(), which would reset anything set by
|
// calls diagram.db.clear(), which would reset anything set by
|
||||||
// extractFrontMatter().
|
// extractFrontMatter().
|
||||||
this.parser.parse = (text: string) => originalParse(extractFrontMatter(text, this.db));
|
this.parser.parse = (text: string) =>
|
||||||
|
originalParse(cleanupComments(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);
|
||||||
|
@@ -3,6 +3,7 @@ import { getConfig } from './config.js';
|
|||||||
let title = '';
|
let title = '';
|
||||||
let diagramTitle = '';
|
let diagramTitle = '';
|
||||||
let description = '';
|
let description = '';
|
||||||
|
|
||||||
const sanitizeText = (txt: string): string => _sanitizeText(txt, getConfig());
|
const sanitizeText = (txt: string): string => _sanitizeText(txt, getConfig());
|
||||||
|
|
||||||
export const clear = function (): void {
|
export const clear = function (): void {
|
||||||
@@ -36,10 +37,10 @@ export const getDiagramTitle = function (): string {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
setAccTitle,
|
|
||||||
getAccTitle,
|
getAccTitle,
|
||||||
|
setAccTitle,
|
||||||
|
getDiagramTitle,
|
||||||
setDiagramTitle,
|
setDiagramTitle,
|
||||||
getDiagramTitle: getDiagramTitle,
|
|
||||||
getAccDescription,
|
getAccDescription,
|
||||||
setAccDescription,
|
setAccDescription,
|
||||||
clear,
|
clear,
|
||||||
|
@@ -335,6 +335,7 @@ export interface GanttDiagramConfig extends BaseDiagramConfig {
|
|||||||
axisFormat?: string;
|
axisFormat?: string;
|
||||||
tickInterval?: string;
|
tickInterval?: string;
|
||||||
topAxis?: boolean;
|
topAxis?: boolean;
|
||||||
|
displayMode?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SequenceDiagramConfig extends BaseDiagramConfig {
|
export interface SequenceDiagramConfig extends BaseDiagramConfig {
|
||||||
|
@@ -659,6 +659,17 @@ const config: Partial<MermaidConfig> = {
|
|||||||
*/
|
*/
|
||||||
numberSectionStyles: 4,
|
numberSectionStyles: 4,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* | Parameter | Description | Type | Required | Values |
|
||||||
|
* | ----------- | ------------------------- | ------ | -------- | --------- |
|
||||||
|
* | displayMode | Controls the display mode | string | 4 | 'compact' |
|
||||||
|
*
|
||||||
|
* **Notes**:
|
||||||
|
*
|
||||||
|
* - **compact**: Enables displaying multiple tasks on the same row.
|
||||||
|
*/
|
||||||
|
displayMode: '',
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* | Parameter | Description | Type | Required | Values |
|
* | Parameter | Description | Type | Required | Values |
|
||||||
* | ---------- | ---------------------------- | ---- | -------- | ---------------- |
|
* | ---------- | ---------------------------- | ---- | -------- | ---------------- |
|
||||||
@@ -684,7 +695,6 @@ const config: Partial<MermaidConfig> = {
|
|||||||
* Default value: undefined
|
* Default value: undefined
|
||||||
*/
|
*/
|
||||||
tickInterval: undefined,
|
tickInterval: undefined,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* | Parameter | Description | Type | Required | Values |
|
* | Parameter | Description | Type | Required | Values |
|
||||||
* | ----------- | ----------- | ------- | -------- | ----------- |
|
* | ----------- | ----------- | ------- | -------- | ----------- |
|
||||||
|
94
packages/mermaid/src/diagram-api/comments.spec.ts
Normal file
94
packages/mermaid/src/diagram-api/comments.spec.ts
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
// tests to check that comments are removed
|
||||||
|
|
||||||
|
import { cleanupComments } from './comments.js';
|
||||||
|
import { describe, it, expect } from 'vitest';
|
||||||
|
|
||||||
|
describe('comments', () => {
|
||||||
|
it('should remove comments', () => {
|
||||||
|
const text = `
|
||||||
|
|
||||||
|
%% This is a comment
|
||||||
|
%% This is another comment
|
||||||
|
graph TD
|
||||||
|
A-->B
|
||||||
|
%% This is a comment
|
||||||
|
`;
|
||||||
|
expect(cleanupComments(text)).toMatchInlineSnapshot(`
|
||||||
|
"graph TD
|
||||||
|
A-->B
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should keep init statements when removing comments', () => {
|
||||||
|
const text = `
|
||||||
|
%% This is a comment
|
||||||
|
|
||||||
|
%% This is another comment
|
||||||
|
%%{init: {'theme': 'forest'}}%%
|
||||||
|
%%{ init: {'theme': 'space before init'}}%%
|
||||||
|
%%{init: {'theme': 'space after ending'}}%%
|
||||||
|
graph TD
|
||||||
|
A-->B
|
||||||
|
|
||||||
|
B-->C
|
||||||
|
%% This is a comment
|
||||||
|
`;
|
||||||
|
expect(cleanupComments(text)).toMatchInlineSnapshot(`
|
||||||
|
"%%{init: {'theme': 'forest'}}%%
|
||||||
|
%%{ init: {'theme': 'space before init'}}%%
|
||||||
|
%%{init: {'theme': 'space after ending'}}%%
|
||||||
|
graph TD
|
||||||
|
A-->B
|
||||||
|
|
||||||
|
B-->C
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should remove indented comments', () => {
|
||||||
|
const text = `
|
||||||
|
%% This is a comment
|
||||||
|
graph TD
|
||||||
|
A-->B
|
||||||
|
%% This is a comment
|
||||||
|
C-->D
|
||||||
|
`;
|
||||||
|
expect(cleanupComments(text)).toMatchInlineSnapshot(`
|
||||||
|
"graph TD
|
||||||
|
A-->B
|
||||||
|
C-->D
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should remove empty newlines from start', () => {
|
||||||
|
const text = `
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
%% This is a comment
|
||||||
|
graph TD
|
||||||
|
A-->B
|
||||||
|
`;
|
||||||
|
expect(cleanupComments(text)).toMatchInlineSnapshot(`
|
||||||
|
"graph TD
|
||||||
|
A-->B
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should remove comments at end of text with no newline', () => {
|
||||||
|
const text = `
|
||||||
|
graph TD
|
||||||
|
A-->B
|
||||||
|
%% This is a comment`;
|
||||||
|
|
||||||
|
expect(cleanupComments(text)).toMatchInlineSnapshot(`
|
||||||
|
"graph TD
|
||||||
|
A-->B
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
});
|
8
packages/mermaid/src/diagram-api/comments.ts
Normal file
8
packages/mermaid/src/diagram-api/comments.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
/**
|
||||||
|
* Remove all lines starting with `%%` from the text that don't contain a `%%{`
|
||||||
|
* @param text - The text to remove comments from
|
||||||
|
* @returns cleaned text
|
||||||
|
*/
|
||||||
|
export const cleanupComments = (text: string): string => {
|
||||||
|
return text.trimStart().replace(/^\s*%%(?!{)[^\n]+\n?/gm, '');
|
||||||
|
};
|
@@ -13,7 +13,7 @@ import classDiagramV2 from '../diagrams/class/classDetector-V2.js';
|
|||||||
import state from '../diagrams/state/stateDetector.js';
|
import state from '../diagrams/state/stateDetector.js';
|
||||||
import stateV2 from '../diagrams/state/stateDetector-V2.js';
|
import stateV2 from '../diagrams/state/stateDetector-V2.js';
|
||||||
import journey from '../diagrams/user-journey/journeyDetector.js';
|
import journey from '../diagrams/user-journey/journeyDetector.js';
|
||||||
import error from '../diagrams/error/errorDetector.js';
|
import errorDiagram from '../diagrams/error/errorDiagram.js';
|
||||||
import flowchartElk from '../diagrams/flowchart/elk/detector.js';
|
import flowchartElk from '../diagrams/flowchart/elk/detector.js';
|
||||||
import timeline from '../diagrams/timeline/detector.js';
|
import timeline from '../diagrams/timeline/detector.js';
|
||||||
import mindmap from '../diagrams/mindmap/detector.js';
|
import mindmap from '../diagrams/mindmap/detector.js';
|
||||||
@@ -28,6 +28,9 @@ export const addDiagrams = () => {
|
|||||||
// This is added here to avoid race-conditions.
|
// This is added here to avoid race-conditions.
|
||||||
// We could optimize the loading logic somehow.
|
// We could optimize the loading logic somehow.
|
||||||
hasLoadedDiagrams = true;
|
hasLoadedDiagrams = true;
|
||||||
|
registerDiagram('error', errorDiagram, (text) => {
|
||||||
|
return text.toLowerCase().trim() === 'error';
|
||||||
|
});
|
||||||
registerDiagram(
|
registerDiagram(
|
||||||
'---',
|
'---',
|
||||||
// --- diagram type may appear if YAML front-matter is not parsed correctly
|
// --- diagram type may appear if YAML front-matter is not parsed correctly
|
||||||
@@ -57,7 +60,6 @@ export const addDiagrams = () => {
|
|||||||
);
|
);
|
||||||
// Ordering of detectors is important. The first one to return true will be used.
|
// Ordering of detectors is important. The first one to return true will be used.
|
||||||
registerLazyLoadedDiagrams(
|
registerLazyLoadedDiagrams(
|
||||||
error,
|
|
||||||
c4,
|
c4,
|
||||||
classDiagramV2,
|
classDiagramV2,
|
||||||
classDiagram,
|
classDiagram,
|
||||||
|
@@ -11,6 +11,8 @@ export const frontMatterRegex = /^-{3}\s*[\n\r](.*?)[\n\r]-{3}\s*[\n\r]+/s;
|
|||||||
|
|
||||||
type FrontMatterMetadata = {
|
type FrontMatterMetadata = {
|
||||||
title?: string;
|
title?: string;
|
||||||
|
// Allows custom display modes. Currently used for compact mode in gantt charts.
|
||||||
|
displayMode?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -33,6 +35,10 @@ export function extractFrontMatter(text: string, db: DiagramDb): string {
|
|||||||
db.setDiagramTitle?.(parsed.title);
|
db.setDiagramTitle?.(parsed.title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parsed?.displayMode) {
|
||||||
|
db.setDisplayMode?.(parsed.displayMode);
|
||||||
|
}
|
||||||
|
|
||||||
return text.slice(matches[0].length);
|
return text.slice(matches[0].length);
|
||||||
} else {
|
} else {
|
||||||
return text;
|
return text;
|
||||||
|
@@ -16,6 +16,7 @@ export interface InjectUtils {
|
|||||||
export interface DiagramDb {
|
export interface DiagramDb {
|
||||||
clear?: () => void;
|
clear?: () => void;
|
||||||
setDiagramTitle?: (title: string) => void;
|
setDiagramTitle?: (title: string) => void;
|
||||||
|
setDisplayMode?: (title: string) => void;
|
||||||
getAccTitle?: () => string;
|
getAccTitle?: () => string;
|
||||||
getAccDescription?: () => string;
|
getAccDescription?: () => string;
|
||||||
bindFunctions?: (element: Element) => void;
|
bindFunctions?: (element: Element) => void;
|
||||||
|
@@ -19,8 +19,6 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multili
|
|||||||
<type_directive>":" { this.popState(); this.begin('arg_directive'); return ':'; }
|
<type_directive>":" { this.popState(); this.begin('arg_directive'); return ':'; }
|
||||||
<type_directive,arg_directive>\}\%\% { this.popState(); this.popState(); return 'close_directive'; }
|
<type_directive,arg_directive>\}\%\% { this.popState(); this.popState(); return 'close_directive'; }
|
||||||
<arg_directive>((?:(?!\}\%\%).|\n)*) return 'arg_directive';
|
<arg_directive>((?:(?!\}\%\%).|\n)*) return 'arg_directive';
|
||||||
\%%(?!\{)[^\n]* /* skip comments */
|
|
||||||
[^\}]\%\%[^\n]* /* skip comments */
|
|
||||||
[\n]+ return 'NEWLINE';
|
[\n]+ return 'NEWLINE';
|
||||||
\s+ /* skip whitespace */
|
\s+ /* skip whitespace */
|
||||||
[\s]+ return 'SPACE';
|
[\s]+ return 'SPACE';
|
||||||
@@ -35,8 +33,6 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multili
|
|||||||
<block>[A-Za-z_][A-Za-z0-9\-_\[\]\(\)]* return 'ATTRIBUTE_WORD'
|
<block>[A-Za-z_][A-Za-z0-9\-_\[\]\(\)]* return 'ATTRIBUTE_WORD'
|
||||||
<block>\"[^"]*\" return 'COMMENT';
|
<block>\"[^"]*\" return 'COMMENT';
|
||||||
<block>[\n]+ /* nothing */
|
<block>[\n]+ /* nothing */
|
||||||
<block>\%%(?!\{)[^\n]* /* skip comments in attribute block */
|
|
||||||
<block>[^\}]\%\%[^\n]* /* skip comments in attribute block */
|
|
||||||
<block>"}" { this.popState(); return 'BLOCK_STOP'; }
|
<block>"}" { this.popState(); return 'BLOCK_STOP'; }
|
||||||
<block>. return yytext[0];
|
<block>. return yytext[0];
|
||||||
|
|
||||||
|
@@ -1,20 +0,0 @@
|
|||||||
import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-api/types.js';
|
|
||||||
|
|
||||||
const id = 'error';
|
|
||||||
|
|
||||||
const detector: DiagramDetector = (text) => {
|
|
||||||
return text.toLowerCase().trim() === 'error';
|
|
||||||
};
|
|
||||||
|
|
||||||
const loader = async () => {
|
|
||||||
const { diagram } = await import('./errorDiagram.js');
|
|
||||||
return { id, diagram };
|
|
||||||
};
|
|
||||||
|
|
||||||
const plugin: ExternalDiagramDefinition = {
|
|
||||||
id,
|
|
||||||
detector,
|
|
||||||
loader,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default plugin;
|
|
@@ -19,3 +19,5 @@ export const diagram: DiagramDefinition = {
|
|||||||
// no op
|
// no op
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default diagram;
|
||||||
|
@@ -4,15 +4,13 @@ import { select } from 'd3';
|
|||||||
import { log } from '../../logger.js';
|
import { log } from '../../logger.js';
|
||||||
import { getErrorMessage } from '../../utils.js';
|
import { getErrorMessage } from '../../utils.js';
|
||||||
|
|
||||||
let conf = {};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merges the value of `conf` with the passed `cnf`
|
* Merges the value of `conf` with the passed `cnf`
|
||||||
*
|
*
|
||||||
* @param cnf - Config to merge
|
* @param cnf - Config to merge
|
||||||
*/
|
*/
|
||||||
export const setConf = function (cnf: any) {
|
export const setConf = function () {
|
||||||
conf = { ...conf, ...cnf };
|
// no-op
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -78,7 +76,7 @@ export const draw = (_text: string, id: string, mermaidVersion: string) => {
|
|||||||
.attr('y', 250)
|
.attr('y', 250)
|
||||||
.attr('font-size', '150px')
|
.attr('font-size', '150px')
|
||||||
.style('text-anchor', 'middle')
|
.style('text-anchor', 'middle')
|
||||||
.text('Syntax error in graph');
|
.text('Syntax error in text');
|
||||||
g.append('text') // text label for the x axis
|
g.append('text') // text label for the x axis
|
||||||
.attr('class', 'error-text')
|
.attr('class', 'error-text')
|
||||||
.attr('x', 1250)
|
.attr('x', 1250)
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
import flowDb from '../flowDb.js';
|
import flowDb from '../flowDb.js';
|
||||||
import flow from './flow.jison';
|
import flow from './flow.jison';
|
||||||
import { setConfig } from '../../../config.js';
|
import { setConfig } from '../../../config.js';
|
||||||
|
import { cleanupComments } from '../../../diagram-api/comments.js';
|
||||||
|
|
||||||
setConfig({
|
setConfig({
|
||||||
securityLevel: 'strict',
|
securityLevel: 'strict',
|
||||||
@@ -13,7 +14,7 @@ describe('[Comments] when parsing', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should handle comments', function () {
|
it('should handle comments', function () {
|
||||||
const res = flow.parser.parse('graph TD;\n%% Comment\n A-->B;');
|
const res = flow.parser.parse(cleanupComments('graph TD;\n%% Comment\n A-->B;'));
|
||||||
|
|
||||||
const vert = flow.parser.yy.getVertices();
|
const vert = flow.parser.yy.getVertices();
|
||||||
const edges = flow.parser.yy.getEdges();
|
const edges = flow.parser.yy.getEdges();
|
||||||
@@ -28,7 +29,7 @@ describe('[Comments] when parsing', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should handle comments at the start', function () {
|
it('should handle comments at the start', function () {
|
||||||
const res = flow.parser.parse('%% Comment\ngraph TD;\n A-->B;');
|
const res = flow.parser.parse(cleanupComments('%% Comment\ngraph TD;\n A-->B;'));
|
||||||
|
|
||||||
const vert = flow.parser.yy.getVertices();
|
const vert = flow.parser.yy.getVertices();
|
||||||
const edges = flow.parser.yy.getEdges();
|
const edges = flow.parser.yy.getEdges();
|
||||||
@@ -43,7 +44,7 @@ describe('[Comments] when parsing', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should handle comments at the end', function () {
|
it('should handle comments at the end', function () {
|
||||||
const res = flow.parser.parse('graph TD;\n A-->B\n %% Comment at the end\n');
|
const res = flow.parser.parse(cleanupComments('graph TD;\n A-->B\n %% Comment at the end\n'));
|
||||||
|
|
||||||
const vert = flow.parser.yy.getVertices();
|
const vert = flow.parser.yy.getVertices();
|
||||||
const edges = flow.parser.yy.getEdges();
|
const edges = flow.parser.yy.getEdges();
|
||||||
@@ -58,7 +59,7 @@ describe('[Comments] when parsing', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should handle comments at the end no trailing newline', function () {
|
it('should handle comments at the end no trailing newline', function () {
|
||||||
const res = flow.parser.parse('graph TD;\n A-->B\n%% Comment');
|
const res = flow.parser.parse(cleanupComments('graph TD;\n A-->B\n%% Comment'));
|
||||||
|
|
||||||
const vert = flow.parser.yy.getVertices();
|
const vert = flow.parser.yy.getVertices();
|
||||||
const edges = flow.parser.yy.getEdges();
|
const edges = flow.parser.yy.getEdges();
|
||||||
@@ -73,7 +74,7 @@ describe('[Comments] when parsing', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should handle comments at the end many trailing newlines', function () {
|
it('should handle comments at the end many trailing newlines', function () {
|
||||||
const res = flow.parser.parse('graph TD;\n A-->B\n%% Comment\n\n\n');
|
const res = flow.parser.parse(cleanupComments('graph TD;\n A-->B\n%% Comment\n\n\n'));
|
||||||
|
|
||||||
const vert = flow.parser.yy.getVertices();
|
const vert = flow.parser.yy.getVertices();
|
||||||
const edges = flow.parser.yy.getEdges();
|
const edges = flow.parser.yy.getEdges();
|
||||||
@@ -88,7 +89,7 @@ describe('[Comments] when parsing', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should handle no trailing newlines', function () {
|
it('should handle no trailing newlines', function () {
|
||||||
const res = flow.parser.parse('graph TD;\n A-->B');
|
const res = flow.parser.parse(cleanupComments('graph TD;\n A-->B'));
|
||||||
|
|
||||||
const vert = flow.parser.yy.getVertices();
|
const vert = flow.parser.yy.getVertices();
|
||||||
const edges = flow.parser.yy.getEdges();
|
const edges = flow.parser.yy.getEdges();
|
||||||
@@ -103,7 +104,7 @@ describe('[Comments] when parsing', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should handle many trailing newlines', function () {
|
it('should handle many trailing newlines', function () {
|
||||||
const res = flow.parser.parse('graph TD;\n A-->B\n\n');
|
const res = flow.parser.parse(cleanupComments('graph TD;\n A-->B\n\n'));
|
||||||
|
|
||||||
const vert = flow.parser.yy.getVertices();
|
const vert = flow.parser.yy.getVertices();
|
||||||
const edges = flow.parser.yy.getEdges();
|
const edges = flow.parser.yy.getEdges();
|
||||||
@@ -118,7 +119,7 @@ describe('[Comments] when parsing', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should handle a comment with blank rows in-between', function () {
|
it('should handle a comment with blank rows in-between', function () {
|
||||||
const res = flow.parser.parse('graph TD;\n\n\n %% Comment\n A-->B;');
|
const res = flow.parser.parse(cleanupComments('graph TD;\n\n\n %% Comment\n A-->B;'));
|
||||||
|
|
||||||
const vert = flow.parser.yy.getVertices();
|
const vert = flow.parser.yy.getVertices();
|
||||||
const edges = flow.parser.yy.getEdges();
|
const edges = flow.parser.yy.getEdges();
|
||||||
@@ -134,7 +135,9 @@ describe('[Comments] when parsing', () => {
|
|||||||
|
|
||||||
it('should handle a comment with mermaid flowchart code in them', function () {
|
it('should handle a comment with mermaid flowchart code in them', function () {
|
||||||
const res = flow.parser.parse(
|
const res = flow.parser.parse(
|
||||||
'graph TD;\n\n\n %% Test od>Odd shape]-->|Two line<br>edge comment|ro;\n A-->B;'
|
cleanupComments(
|
||||||
|
'graph TD;\n\n\n %% Test od>Odd shape]-->|Two line<br>edge comment|ro;\n A-->B;'
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
const vert = flow.parser.yy.getVertices();
|
const vert = flow.parser.yy.getVertices();
|
||||||
|
@@ -27,8 +27,6 @@
|
|||||||
<type_directive>":" { this.popState(); this.begin('arg_directive'); return ':'; }
|
<type_directive>":" { this.popState(); this.begin('arg_directive'); return ':'; }
|
||||||
<type_directive,arg_directive>\}\%\% { this.popState(); this.popState(); return 'close_directive'; }
|
<type_directive,arg_directive>\}\%\% { this.popState(); this.popState(); return 'close_directive'; }
|
||||||
<arg_directive>((?:(?!\}\%\%).|\n)*) return 'arg_directive';
|
<arg_directive>((?:(?!\}\%\%).|\n)*) return 'arg_directive';
|
||||||
\%\%(?!\{)[^\n]* /* skip comments */
|
|
||||||
[^\}]\%\%[^\n]* /* skip comments */
|
|
||||||
accTitle\s*":"\s* { this.begin("acc_title");return 'acc_title'; }
|
accTitle\s*":"\s* { this.begin("acc_title");return 'acc_title'; }
|
||||||
<acc_title>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_title_value"; }
|
<acc_title>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_title_value"; }
|
||||||
accDescr\s*":"\s* { this.begin("acc_descr");return 'acc_descr'; }
|
accDescr\s*":"\s* { this.begin("acc_descr");return 'acc_descr'; }
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
import flowDb from '../flowDb.js';
|
import flowDb from '../flowDb.js';
|
||||||
import flow from './flow.jison';
|
import flow from './flow.jison';
|
||||||
import { setConfig } from '../../../config.js';
|
import { setConfig } from '../../../config.js';
|
||||||
|
import { cleanupComments } from '../../../diagram-api/comments.js';
|
||||||
|
|
||||||
setConfig({
|
setConfig({
|
||||||
securityLevel: 'strict',
|
securityLevel: 'strict',
|
||||||
@@ -13,7 +14,7 @@ describe('parsing a flow chart', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should handle a trailing whitespaces after statements', function () {
|
it('should handle a trailing whitespaces after statements', function () {
|
||||||
const res = flow.parser.parse('graph TD;\n\n\n %% Comment\n A-->B; \n B-->C;');
|
const res = flow.parser.parse(cleanupComments('graph TD;\n\n\n %% Comment\n A-->B; \n B-->C;'));
|
||||||
|
|
||||||
const vert = flow.parser.yy.getVertices();
|
const vert = flow.parser.yy.getVertices();
|
||||||
const edges = flow.parser.yy.getEdges();
|
const edges = flow.parser.yy.getEdges();
|
||||||
|
@@ -32,6 +32,7 @@ let links = {};
|
|||||||
let sections = [];
|
let sections = [];
|
||||||
let tasks = [];
|
let tasks = [];
|
||||||
let currentSection = '';
|
let currentSection = '';
|
||||||
|
let displayMode = '';
|
||||||
const tags = ['active', 'done', 'crit', 'milestone'];
|
const tags = ['active', 'done', 'crit', 'milestone'];
|
||||||
let funs = [];
|
let funs = [];
|
||||||
let inclusiveEndDates = false;
|
let inclusiveEndDates = false;
|
||||||
@@ -55,6 +56,7 @@ export const clear = function () {
|
|||||||
rawTasks = [];
|
rawTasks = [];
|
||||||
dateFormat = '';
|
dateFormat = '';
|
||||||
axisFormat = '';
|
axisFormat = '';
|
||||||
|
displayMode = '';
|
||||||
tickInterval = undefined;
|
tickInterval = undefined;
|
||||||
todayMarker = '';
|
todayMarker = '';
|
||||||
includes = [];
|
includes = [];
|
||||||
@@ -110,6 +112,14 @@ export const topAxisEnabled = function () {
|
|||||||
return topAxis;
|
return topAxis;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const setDisplayMode = function (txt) {
|
||||||
|
displayMode = txt;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getDisplayMode = function () {
|
||||||
|
return displayMode;
|
||||||
|
};
|
||||||
|
|
||||||
export const getDateFormat = function () {
|
export const getDateFormat = function () {
|
||||||
return dateFormat;
|
return dateFormat;
|
||||||
};
|
};
|
||||||
@@ -143,11 +153,11 @@ export const getSections = function () {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getTasks = function () {
|
export const getTasks = function () {
|
||||||
let allItemsPricessed = compileTasks();
|
let allItemsProcessed = compileTasks();
|
||||||
const maxDepth = 10;
|
const maxDepth = 10;
|
||||||
let iterationCount = 0;
|
let iterationCount = 0;
|
||||||
while (!allItemsPricessed && iterationCount < maxDepth) {
|
while (!allItemsProcessed && iterationCount < maxDepth) {
|
||||||
allItemsPricessed = compileTasks();
|
allItemsProcessed = compileTasks();
|
||||||
iterationCount++;
|
iterationCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -719,6 +729,8 @@ export default {
|
|||||||
getAccTitle,
|
getAccTitle,
|
||||||
setDiagramTitle,
|
setDiagramTitle,
|
||||||
getDiagramTitle,
|
getDiagramTitle,
|
||||||
|
setDisplayMode,
|
||||||
|
getDisplayMode,
|
||||||
setAccDescription,
|
setAccDescription,
|
||||||
getAccDescription,
|
getAccDescription,
|
||||||
addSection,
|
addSection,
|
||||||
|
@@ -34,6 +34,7 @@ describe('when using the ganttDb', function () {
|
|||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
ganttDb.setDateFormat('YYYY-MM-DD');
|
ganttDb.setDateFormat('YYYY-MM-DD');
|
||||||
ganttDb.enableInclusiveEndDates();
|
ganttDb.enableInclusiveEndDates();
|
||||||
|
ganttDb.setDisplayMode('compact');
|
||||||
ganttDb.setTodayMarker('off');
|
ganttDb.setTodayMarker('off');
|
||||||
ganttDb.setExcludes('weekends 2019-02-06,friday');
|
ganttDb.setExcludes('weekends 2019-02-06,friday');
|
||||||
ganttDb.addSection('weekends skip test');
|
ganttDb.addSection('weekends skip test');
|
||||||
@@ -53,6 +54,7 @@ describe('when using the ganttDb', function () {
|
|||||||
${'getExcludes'} | ${[]}
|
${'getExcludes'} | ${[]}
|
||||||
${'getSections'} | ${[]}
|
${'getSections'} | ${[]}
|
||||||
${'endDatesAreInclusive'} | ${false}
|
${'endDatesAreInclusive'} | ${false}
|
||||||
|
${'getDisplayMode'} | ${''}
|
||||||
`)('should clear $fn', ({ fn, expected }) => {
|
`)('should clear $fn', ({ fn, expected }) => {
|
||||||
expect(ganttDb[fn]()).toEqual(expected);
|
expect(ganttDb[fn]()).toEqual(expected);
|
||||||
});
|
});
|
||||||
|
@@ -24,12 +24,43 @@ export const setConf = function () {
|
|||||||
log.debug('Something is calling, setConf, remove the call');
|
log.debug('Something is calling, setConf, remove the call');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For this issue:
|
||||||
|
* https://github.com/mermaid-js/mermaid/issues/1618
|
||||||
|
*
|
||||||
|
* Finds the number of intersections between tasks that happen at any point in time.
|
||||||
|
* Used to figure out how many rows are needed to display the tasks when the display
|
||||||
|
* mode is set to 'compact'.
|
||||||
|
*
|
||||||
|
* @param tasks
|
||||||
|
* @param orderOffset
|
||||||
|
*/
|
||||||
|
const getMaxIntersections = (tasks, orderOffset) => {
|
||||||
|
let timeline = [...tasks].map(() => -Infinity);
|
||||||
|
let sorted = [...tasks].sort((a, b) => a.startTime - b.startTime || a.order - b.order);
|
||||||
|
let maxIntersections = 0;
|
||||||
|
for (const element of sorted) {
|
||||||
|
for (let j = 0; j < timeline.length; j++) {
|
||||||
|
if (element.startTime >= timeline[j]) {
|
||||||
|
timeline[j] = element.endTime;
|
||||||
|
element.order = j + orderOffset;
|
||||||
|
if (j > maxIntersections) {
|
||||||
|
maxIntersections = j;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return maxIntersections;
|
||||||
|
};
|
||||||
|
|
||||||
let w;
|
let w;
|
||||||
export const draw = function (text, id, version, diagObj) {
|
export const draw = function (text, id, version, diagObj) {
|
||||||
const conf = getConfig().gantt;
|
const conf = getConfig().gantt;
|
||||||
|
|
||||||
// diagObj.db.clear();
|
// diagObj.db.clear();
|
||||||
// parser.parse(text);
|
// parser.parse(text);
|
||||||
|
|
||||||
const securityLevel = getConfig().securityLevel;
|
const securityLevel = getConfig().securityLevel;
|
||||||
// Handle root and Document for when rendering in sandbox mode
|
// Handle root and Document for when rendering in sandbox mode
|
||||||
let sandboxElement;
|
let sandboxElement;
|
||||||
@@ -56,7 +87,40 @@ export const draw = function (text, id, version, diagObj) {
|
|||||||
const taskArray = diagObj.db.getTasks();
|
const taskArray = diagObj.db.getTasks();
|
||||||
|
|
||||||
// Set height based on number of tasks
|
// Set height based on number of tasks
|
||||||
const h = taskArray.length * (conf.barHeight + conf.barGap) + 2 * conf.topPadding;
|
|
||||||
|
let categories = [];
|
||||||
|
|
||||||
|
for (const element of taskArray) {
|
||||||
|
categories.push(element.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
categories = checkUnique(categories);
|
||||||
|
const categoryHeights = {};
|
||||||
|
|
||||||
|
let h = 2 * conf.topPadding;
|
||||||
|
if (diagObj.db.getDisplayMode() === 'compact' || conf.displayMode === 'compact') {
|
||||||
|
const categoryElements = {};
|
||||||
|
for (const element of taskArray) {
|
||||||
|
if (categoryElements[element.section] === undefined) {
|
||||||
|
categoryElements[element.section] = [element];
|
||||||
|
} else {
|
||||||
|
categoryElements[element.section].push(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let intersections = 0;
|
||||||
|
for (const category of Object.keys(categoryElements)) {
|
||||||
|
const categoryHeight = getMaxIntersections(categoryElements[category], intersections) + 1;
|
||||||
|
intersections += categoryHeight;
|
||||||
|
h += categoryHeight * (conf.barHeight + conf.barGap);
|
||||||
|
categoryHeights[category] = categoryHeight;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
h += taskArray.length * (conf.barHeight + conf.barGap);
|
||||||
|
for (const category of categories) {
|
||||||
|
categoryHeights[category] = taskArray.filter((task) => task.type === category).length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Set viewBox
|
// Set viewBox
|
||||||
elem.setAttribute('viewBox', '0 0 ' + w + ' ' + h);
|
elem.setAttribute('viewBox', '0 0 ' + w + ' ' + h);
|
||||||
@@ -74,16 +138,6 @@ export const draw = function (text, id, version, diagObj) {
|
|||||||
])
|
])
|
||||||
.rangeRound([0, w - conf.leftPadding - conf.rightPadding]);
|
.rangeRound([0, w - conf.leftPadding - conf.rightPadding]);
|
||||||
|
|
||||||
let categories = [];
|
|
||||||
|
|
||||||
for (const element of taskArray) {
|
|
||||||
categories.push(element.type);
|
|
||||||
}
|
|
||||||
|
|
||||||
const catsUnfiltered = categories; // for vert labels
|
|
||||||
|
|
||||||
categories = checkUnique(categories);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param a
|
* @param a
|
||||||
* @param b
|
* @param b
|
||||||
@@ -157,11 +211,15 @@ export const draw = function (text, id, version, diagObj) {
|
|||||||
* @param w
|
* @param w
|
||||||
*/
|
*/
|
||||||
function drawRects(theArray, theGap, theTopPad, theSidePad, theBarHeight, theColorScale, w) {
|
function drawRects(theArray, theGap, theTopPad, theSidePad, theBarHeight, theColorScale, w) {
|
||||||
|
// Get unique task orders. Required to draw the background rects when display mode is compact.
|
||||||
|
const uniqueTaskOrderIds = [...new Set(theArray.map((item) => item.order))];
|
||||||
|
const uniqueTasks = uniqueTaskOrderIds.map((id) => theArray.find((item) => item.order === id));
|
||||||
|
|
||||||
// Draw background rects covering the entire width of the graph, these form the section rows.
|
// Draw background rects covering the entire width of the graph, these form the section rows.
|
||||||
svg
|
svg
|
||||||
.append('g')
|
.append('g')
|
||||||
.selectAll('rect')
|
.selectAll('rect')
|
||||||
.data(theArray)
|
.data(uniqueTasks)
|
||||||
.enter()
|
.enter()
|
||||||
.append('rect')
|
.append('rect')
|
||||||
.attr('x', 0)
|
.attr('x', 0)
|
||||||
@@ -582,12 +640,9 @@ export const draw = function (text, id, version, diagObj) {
|
|||||||
* @param theTopPad
|
* @param theTopPad
|
||||||
*/
|
*/
|
||||||
function vertLabels(theGap, theTopPad) {
|
function vertLabels(theGap, theTopPad) {
|
||||||
const numOccurances = [];
|
|
||||||
let prevGap = 0;
|
let prevGap = 0;
|
||||||
|
|
||||||
for (const [i, category] of categories.entries()) {
|
const numOccurances = Object.keys(categoryHeights).map((d) => [d, categoryHeights[d]]);
|
||||||
numOccurances[i] = [category, getCount(category, catsUnfiltered)];
|
|
||||||
}
|
|
||||||
|
|
||||||
svg
|
svg
|
||||||
.append('g') // without doing this, impossible to put grid lines behind text
|
.append('g') // without doing this, impossible to put grid lines behind text
|
||||||
@@ -625,7 +680,6 @@ export const draw = function (text, id, version, diagObj) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.attr('font-size', conf.sectionFontSize)
|
.attr('font-size', conf.sectionFontSize)
|
||||||
.attr('font-size', conf.sectionFontSize)
|
|
||||||
.attr('class', function (d) {
|
.attr('class', function (d) {
|
||||||
for (const [i, category] of categories.entries()) {
|
for (const [i, category] of categories.entries()) {
|
||||||
if (d[0] === category) {
|
if (d[0] === category) {
|
||||||
@@ -682,31 +736,6 @@ export const draw = function (text, id, version, diagObj) {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* From this stack exchange question:
|
|
||||||
* http://stackoverflow.com/questions/14227981/count-how-many-strings-in-an-array-have-duplicates-in-the-same-array
|
|
||||||
*
|
|
||||||
* @param arr
|
|
||||||
*/
|
|
||||||
function getCounts(arr) {
|
|
||||||
let i = arr.length; // const to loop over
|
|
||||||
const obj = {}; // obj to store results
|
|
||||||
while (i) {
|
|
||||||
obj[arr[--i]] = (obj[arr[i]] || 0) + 1; // count occurrences
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get specific from everything
|
|
||||||
*
|
|
||||||
* @param word
|
|
||||||
* @param arr
|
|
||||||
*/
|
|
||||||
function getCount(word, arr) {
|
|
||||||
return getCounts(arr)[word] || 0;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@@ -131,9 +131,10 @@ statement
|
|||||||
| includes {yy.setIncludes($1.substr(9));$$=$1.substr(9);}
|
| includes {yy.setIncludes($1.substr(9));$$=$1.substr(9);}
|
||||||
| todayMarker {yy.setTodayMarker($1.substr(12));$$=$1.substr(12);}
|
| todayMarker {yy.setTodayMarker($1.substr(12));$$=$1.substr(12);}
|
||||||
| title {yy.setDiagramTitle($1.substr(6));$$=$1.substr(6);}
|
| title {yy.setDiagramTitle($1.substr(6));$$=$1.substr(6);}
|
||||||
| acc_title acc_title_value { $$=$2.trim();yy.setAccTitle($$); }
|
| acc_title acc_title_value { $$=$2.trim();yy.setAccTitle($$); }
|
||||||
| acc_descr acc_descr_value { $$=$2.trim();yy.setAccDescription($$); }
|
| acc_descr acc_descr_value { $$=$2.trim();yy.setAccDescription($$); }
|
||||||
| acc_descr_multiline_value { $$=$1.trim();yy.setAccDescription($$); } | section {yy.addSection($1.substr(8));$$=$1.substr(8);}
|
| acc_descr_multiline_value { $$=$1.trim();yy.setAccDescription($$); }
|
||||||
|
| section { yy.addSection($1.substr(8));$$=$1.substr(8); }
|
||||||
| clickStatement
|
| clickStatement
|
||||||
| taskTxt taskData {yy.addTask($1,$2);$$='task';}
|
| taskTxt taskData {yy.addTask($1,$2);$$='task';}
|
||||||
| directive
|
| directive
|
||||||
|
@@ -122,9 +122,7 @@ flowchart LR
|
|||||||
|
|
||||||
### A hexagon node
|
### A hexagon node
|
||||||
|
|
||||||
Code:
|
```mermaid-example
|
||||||
|
|
||||||
```mmd
|
|
||||||
flowchart LR
|
flowchart LR
|
||||||
id1{{This is the text in the box}}
|
id1{{This is the text in the box}}
|
||||||
```
|
```
|
||||||
|
@@ -189,9 +189,27 @@ The pattern is:
|
|||||||
|
|
||||||
More info in: [https://github.com/d3/d3-time#interval_every](https://github.com/d3/d3-time#interval_every)
|
More info in: [https://github.com/d3/d3-time#interval_every](https://github.com/d3/d3-time#interval_every)
|
||||||
|
|
||||||
|
## Output in compact mode
|
||||||
|
|
||||||
|
The compact mode allows you to display multiple tasks in the same row. Compact mode can be enabled for a gantt chart by setting the display mode of the graph via preceeding YAML settings.
|
||||||
|
|
||||||
|
```mmd
|
||||||
|
---
|
||||||
|
displayMode: compact
|
||||||
|
---
|
||||||
|
gantt
|
||||||
|
title A Gantt Diagram
|
||||||
|
dateFormat YYYY-MM-DD
|
||||||
|
|
||||||
|
section Section
|
||||||
|
A task :a1, 2014-01-01, 30d
|
||||||
|
Another task :a2, 2014-01-20, 25d
|
||||||
|
Another one :a3, 2014-02-10, 20d
|
||||||
|
```
|
||||||
|
|
||||||
## Comments
|
## Comments
|
||||||
|
|
||||||
Comments can be entered within a gantt chart, which will be ignored by the parser. Comments need to be on their own line and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any diagram syntax
|
Comments can be entered within a gantt chart, which will be ignored by the parser. Comments need to be on their own line and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any diagram syntax.
|
||||||
|
|
||||||
```mmd
|
```mmd
|
||||||
gantt
|
gantt
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
> Timeline: This is an experimental diagram for now. The syntax and properties can change in future releases. The syntax is stable except for the icon integration which is the experimental part.
|
> Timeline: This is an experimental diagram for now. The syntax and properties can change in future releases. The syntax is stable except for the icon integration which is the experimental part.
|
||||||
|
|
||||||
"A timeline is a type of diagram used to illustrate a chronology of events, dates, or periods of time. It is usually presented graphically to indicate the passing of time, and it is usually organized chronologically. A basic timeline presents a list of events in chronological order, usually using dates as markers. A timeline can also be used to show the relationship between events, such as the relationship between the events of a person's life. A timeline can also be used to show the relationship between events, such as the relationship between the events of a person's life." Wikipedia
|
"A timeline is a type of diagram used to illustrate a chronology of events, dates, or periods of time. It is usually presented graphically to indicate the passing of time, and it is usually organized chronologically. A basic timeline presents a list of events in chronological order, usually using dates as markers. A timeline can also be used to show the relationship between events, such as the relationship between the events of a person's life." Wikipedia
|
||||||
|
|
||||||
### An example of a timeline.
|
### An example of a timeline.
|
||||||
|
|
||||||
@@ -139,7 +139,7 @@ However, if there is no section defined, then we have two possibilities:
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that this is no, section defined, and each time period and its corresponding events will have its own color scheme.
|
Note that there are no sections defined, and each time period and its corresponding events will have its own color scheme.
|
||||||
|
|
||||||
2. Disable the multiColor option using the `disableMultiColor` option. This will make all time periods and events follow the same color scheme.
|
2. Disable the multiColor option using the `disableMultiColor` option. This will make all time periods and events follow the same color scheme.
|
||||||
|
|
||||||
@@ -172,7 +172,7 @@ let us look at same example, where we have disabled the multiColor option.
|
|||||||
|
|
||||||
### Customizing Color scheme
|
### Customizing Color scheme
|
||||||
|
|
||||||
You can customize the color scheme using the `cScale0` to `cScale11` theme variables. Mermaid allows you to set unique colors for up-to 12, where `cScale0` variable will drive the value of the first section or time-period, `cScale1` will drive the value of the second section and so on.
|
You can customize the color scheme using the `cScale0` to `cScale11` theme variables. Mermaid allows you to set unique colors for up-to 12 sections, where `cScale0` variable will drive the value of the first section or time-period, `cScale1` will drive the value of the second section and so on.
|
||||||
In case you have more than 12 sections, the color scheme will start to repeat.
|
In case you have more than 12 sections, the color scheme will start to repeat.
|
||||||
|
|
||||||
NOTE: Default values for these theme variables are picked from the selected theme. If you want to override the default values, you can use the `initialize` call to add your custom theme variable values.
|
NOTE: Default values for these theme variables are picked from the selected theme. If you want to override the default values, you can use the `initialize` call to add your custom theme variable values.
|
||||||
|
@@ -392,7 +392,7 @@ const render = (id: string, text: string, container?: Element): Promise<RenderRe
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const mermaid: {
|
export interface Mermaid {
|
||||||
startOnLoad: boolean;
|
startOnLoad: boolean;
|
||||||
parseError?: ParseErrorFunction;
|
parseError?: ParseErrorFunction;
|
||||||
mermaidAPI: typeof mermaidAPI;
|
mermaidAPI: typeof mermaidAPI;
|
||||||
@@ -405,7 +405,9 @@ const mermaid: {
|
|||||||
contentLoaded: typeof contentLoaded;
|
contentLoaded: typeof contentLoaded;
|
||||||
setParseErrorHandler: typeof setParseErrorHandler;
|
setParseErrorHandler: typeof setParseErrorHandler;
|
||||||
detectType: typeof detectType;
|
detectType: typeof detectType;
|
||||||
} = {
|
}
|
||||||
|
|
||||||
|
const mermaid: Mermaid = {
|
||||||
startOnLoad: true,
|
startOnLoad: true,
|
||||||
mermaidAPI,
|
mermaidAPI,
|
||||||
parse,
|
parse,
|
||||||
|
@@ -531,6 +531,10 @@ const render = async function (
|
|||||||
|
|
||||||
attachFunctions();
|
attachFunctions();
|
||||||
|
|
||||||
|
if (parseEncounteredException) {
|
||||||
|
throw parseEncounteredException;
|
||||||
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
// Remove the temporary HTML element if appropriate
|
// Remove the temporary HTML element if appropriate
|
||||||
const tmpElementSelector = isSandboxed ? iFrameID_selector : enclosingDivID_selector;
|
const tmpElementSelector = isSandboxed ? iFrameID_selector : enclosingDivID_selector;
|
||||||
@@ -539,10 +543,6 @@ const render = async function (
|
|||||||
node.remove();
|
node.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parseEncounteredException) {
|
|
||||||
throw parseEncounteredException;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
svg: svgCode,
|
svg: svgCode,
|
||||||
bindFunctions: diag.db.bindFunctions,
|
bindFunctions: diag.db.bindFunctions,
|
||||||
@@ -650,6 +650,7 @@ function addA11yInfo(
|
|||||||
* numberSectionStyles: 4,
|
* numberSectionStyles: 4,
|
||||||
* axisFormat: '%Y-%m-%d',
|
* axisFormat: '%Y-%m-%d',
|
||||||
* topAxis: false,
|
* topAxis: false,
|
||||||
|
* displayMode: '',
|
||||||
* },
|
* },
|
||||||
* };
|
* };
|
||||||
* mermaid.initialize(config);
|
* mermaid.initialize(config);
|
||||||
|
Reference in New Issue
Block a user