Merge branch 'develop' into feature/1295_generic_rendering_engine
This commit is contained in:
commit
5f4da6e0bc
|
@ -640,4 +640,35 @@ describe('Flowchart', () => {
|
||||||
{ flowchart: { htmlLabels: false } }
|
{ flowchart: { htmlLabels: false } }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('31: should not slice off edges that are to the left of the left-most vertex', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`graph TD
|
||||||
|
work --> sleep
|
||||||
|
sleep --> work
|
||||||
|
eat --> sleep
|
||||||
|
work --> eat
|
||||||
|
`,
|
||||||
|
{ flowchart: { htmlLabels: false } }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('32: Render Subroutine shape', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`graph LR
|
||||||
|
A[[subroutine shape test]]
|
||||||
|
A -->|Get money| B[[Go shopping]]
|
||||||
|
B --> C[[Let me think...<br />Do I want something for work,<br />something to spend every free second with,<br />or something to get around?]]
|
||||||
|
C -->|One| D[[Laptop]]
|
||||||
|
C -->|Two| E[[iPhone]]
|
||||||
|
C -->|Three| F[[Car<br/>wroom wroom]]
|
||||||
|
click A "index.html#link-clicked" "link test"
|
||||||
|
click B testClick "click test"
|
||||||
|
classDef someclass fill:#f96;
|
||||||
|
class A someclass;
|
||||||
|
class C someclass;
|
||||||
|
`,
|
||||||
|
{ flowchart: { htmlLabels: false } }
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* eslint-env jest */
|
/* eslint-env jest */
|
||||||
import { imgSnapshotTest } from '../../helpers/util.js';
|
import { imgSnapshotTest } from '../../helpers/util.js';
|
||||||
|
|
||||||
describe('Sequencediagram', () => {
|
describe('Gantt diagram', () => {
|
||||||
it('should render a gantt chart', () => {
|
it('should render a gantt chart', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
|
@ -130,4 +130,34 @@ describe('Sequencediagram', () => {
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should hide today marker', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
gantt
|
||||||
|
title Hide today marker (vertical line should not be visible)
|
||||||
|
dateFormat YYYY-MM-DD
|
||||||
|
axisFormat %d
|
||||||
|
todayMarker off
|
||||||
|
section Section1
|
||||||
|
Today: 1, -1h
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should style today marker', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
gantt
|
||||||
|
title Style today marker (vertical line should be 5px wide and half-transparent blue)
|
||||||
|
dateFormat YYYY-MM-DD
|
||||||
|
axisFormat %d
|
||||||
|
todayMarker stroke-width:5px,stroke:#00f,opacity:0.5
|
||||||
|
section Section1
|
||||||
|
Today: 1, -1h
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -182,5 +182,18 @@ context('Sequence diagram', () => {
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
it('should render autonumber with different line breaks', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
sequenceDiagram
|
||||||
|
autonumber
|
||||||
|
Alice->>John: Hello John,<br>how are you?
|
||||||
|
Alice->>John: John,<br/>can you hear me?
|
||||||
|
John-->>Alice: Hi Alice,<br />I can hear you!
|
||||||
|
John-->>Alice: I feel great!
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -16,6 +16,9 @@
|
||||||
<div class="mermaid">
|
<div class="mermaid">
|
||||||
info
|
info
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
<div class="mermaid">
|
<div class="mermaid">
|
||||||
gantt
|
gantt
|
||||||
title Exclusive end dates (Manual date should end on 3d)
|
title Exclusive end dates (Manual date should end on 3d)
|
||||||
|
@ -25,7 +28,6 @@
|
||||||
2 Days: 1, 2019-01-01,2d
|
2 Days: 1, 2019-01-01,2d
|
||||||
Manual Date: 2, 2019-01-01,2019-01-03
|
Manual Date: 2, 2019-01-01,2019-01-03
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mermaid">
|
<div class="mermaid">
|
||||||
gantt
|
gantt
|
||||||
title Inclusive end dates (Manual date should end on 4th)
|
title Inclusive end dates (Manual date should end on 4th)
|
||||||
|
@ -36,6 +38,27 @@
|
||||||
2 Days: 1, 2019-01-01,2d
|
2 Days: 1, 2019-01-01,2d
|
||||||
Manual Date: 2, 2019-01-01,2019-01-03
|
Manual Date: 2, 2019-01-01,2019-01-03
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mermaid">
|
||||||
|
gantt
|
||||||
|
title Hide today marker (vertical line should not be visible)
|
||||||
|
dateFormat YYYY-MM-DD
|
||||||
|
axisFormat %d
|
||||||
|
todayMarker off
|
||||||
|
section Section1
|
||||||
|
Today: 1, -1h
|
||||||
|
</div>
|
||||||
|
<div class="mermaid">
|
||||||
|
gantt
|
||||||
|
title Style today marker (vertical line should be 5px wide and half-transparent blue)
|
||||||
|
dateFormat YYYY-MM-DD
|
||||||
|
axisFormat %d
|
||||||
|
todayMarker stroke-width:5px,stroke:#00f,opacity:0.5
|
||||||
|
section Section1
|
||||||
|
Today: 1, -1h
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
<div class="mermaid">
|
<div class="mermaid">
|
||||||
graph LR
|
graph LR
|
||||||
sid-B3655226-6C29-4D00-B685-3D5C734DC7E1["
|
sid-B3655226-6C29-4D00-B685-3D5C734DC7E1["
|
||||||
|
@ -315,6 +338,20 @@ graph TB
|
||||||
class A someclass;
|
class A someclass;
|
||||||
class C someclass;
|
class C someclass;
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mermaid">
|
||||||
|
graph LR
|
||||||
|
A[[subroutine shape test]]
|
||||||
|
A -->|Get money| B[[Go shopping]]
|
||||||
|
B --> C[[Let me think...<br />Do I want something for work,<br />something to spend every free second with,<br />or something to get around?]]
|
||||||
|
C -->|One| D[[Laptop]]
|
||||||
|
C -->|Two| E[[iPhone]]
|
||||||
|
C -->|Three| F[[Car<br/>wroom wroom]]
|
||||||
|
click A "index.html#link-clicked" "link test"
|
||||||
|
click B testClick "click test"
|
||||||
|
classDef someclass fill:#f96;
|
||||||
|
class A someclass;
|
||||||
|
class C someclass;
|
||||||
|
</div>
|
||||||
<div class="mermaid">
|
<div class="mermaid">
|
||||||
graph LR
|
graph LR
|
||||||
A[(cylindrical<br />shape<br />test)]
|
A[(cylindrical<br />shape<br />test)]
|
||||||
|
@ -441,6 +478,14 @@ end
|
||||||
4->>1: multiline<br />using #lt;br /#gt;
|
4->>1: multiline<br />using #lt;br /#gt;
|
||||||
note right of 1: multiline<br />using #lt;br /#gt;
|
note right of 1: multiline<br />using #lt;br /#gt;
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mermaid">
|
||||||
|
sequenceDiagram
|
||||||
|
autonumber
|
||||||
|
Alice->>John: Hello John,<br>how are you?
|
||||||
|
Alice->>John: John,<br/>can you hear me?
|
||||||
|
John-->>Alice: Hi Alice,<br />I can hear you!
|
||||||
|
John-->>Alice: I feel great!
|
||||||
|
</div>
|
||||||
|
|
||||||
<hr/>
|
<hr/>
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
> An entity–relationship model (or ER model) describes interrelated things of interest in a specific domain of knowledge. A basic ER model is composed of entity types (which classify the things of interest) and specifies relationships that can exist between entities (instances of those entity types). Wikipedia.
|
> An entity–relationship model (or ER model) describes interrelated things of interest in a specific domain of knowledge. A basic ER model is composed of entity types (which classify the things of interest) and specifies relationships that can exist between entities (instances of those entity types). Wikipedia.
|
||||||
|
|
||||||
Note that practitioners of ER modelling almost always refer to entity types simply as entities. For example the CUSTOMER entity type would be referred to simply as the CUSTOMER entity. This is so common it would be inadvisable to do anything else, but technically an entity is an abstract *instance* of an entity type, and this is what an ER diagram shows - abstract instances, and the relationships between them. This is why entities are always named using singular nouns.
|
Note that practitioners of ER modelling almost always refer to *entity types* simply as *entities*. For example the CUSTOMER entity type would be referred to simply as the CUSTOMER entity. This is so common it would be inadvisable to do anything else, but technically an entity is an abstract *instance* of an entity type, and this is what an ER diagram shows - abstract instances, and the relationships between them. This is why entities are always named using singular nouns.
|
||||||
|
|
||||||
Mermaid can render ER diagrams
|
Mermaid can render ER diagrams
|
||||||
```
|
```
|
||||||
|
@ -24,7 +24,7 @@ Relationships between entities are represented by lines with end markers represe
|
||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
ER diagrams are a new feature in Mermaid and are **experimental**. There are likely to be a few bugs and constraints, and enhancements will be made in due course.
|
ER diagrams are a new feature in Mermaid and are **experimental**. There are likely to be a few bugs and constraints, and enhancements will be made in due course. Currently you can only define entities and relationships, but not attributes.
|
||||||
|
|
||||||
## Syntax
|
## Syntax
|
||||||
|
|
||||||
|
@ -61,10 +61,10 @@ Cardinality is a property that describes how many elements of another entity can
|
||||||
|
|
||||||
| Value (left) | Value (right) | Meaning |
|
| Value (left) | Value (right) | Meaning |
|
||||||
|:------------:|:-------------:|--------------------------------------------------------|
|
|:------------:|:-------------:|--------------------------------------------------------|
|
||||||
| `|o` | `o|` | Zero or one |
|
| `\|o` | `o\|` | Zero or one |
|
||||||
| `||` | `||` | Exactly one |
|
| `\|\|` | `\|\|` | Exactly one |
|
||||||
| `}o` | `o{` | Zero or more (no upper limit) |
|
| `}o` | `o{` | Zero or more (no upper limit) |
|
||||||
| `}|` | `|{` | One or more (no upper limit) |
|
| `}\|` | `\|{` | One or more (no upper limit) |
|
||||||
|
|
||||||
### Identification
|
### Identification
|
||||||
|
|
||||||
|
|
|
@ -89,6 +89,17 @@ graph LR
|
||||||
id1([This is the text in the box])
|
id1([This is the text in the box])
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### A node in a subroutine shape
|
||||||
|
|
||||||
|
```
|
||||||
|
graph LR
|
||||||
|
id1[[This is the text in the box]]
|
||||||
|
```
|
||||||
|
```mermaid
|
||||||
|
graph LR
|
||||||
|
id1[[This is the text in the box]]
|
||||||
|
```
|
||||||
|
|
||||||
### A node in a cylindrical shape
|
### A node in a cylindrical shape
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<meta name="description" content="Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.">
|
<meta name="description" content="Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.">
|
||||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||||
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/vue.css">
|
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/vue.css">
|
||||||
<script src="//cdn.jsdelivr.net/npm/mermaid@8.4.7/dist/mermaid.min.js"></script>
|
<script src="//cdn.jsdelivr.net/npm/mermaid@8.5.0/dist/mermaid.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||||
|
|
|
@ -263,6 +263,43 @@ The number of alternating section styles.
|
||||||
Datetime format of the axis. This might need adjustment to match your locale and preferences
|
Datetime format of the axis. This might need adjustment to match your locale and preferences
|
||||||
**Default value '%Y-%m-%d'**.
|
**Default value '%Y-%m-%d'**.
|
||||||
|
|
||||||
|
## er
|
||||||
|
|
||||||
|
The object containing configurations specific for entity relationship diagrams
|
||||||
|
|
||||||
|
### diagramPadding
|
||||||
|
|
||||||
|
The amount of padding around the diagram as a whole so that embedded diagrams have margins, expressed in pixels
|
||||||
|
|
||||||
|
### layoutDirection
|
||||||
|
|
||||||
|
Directional bias for layout of entities. Can be either 'TB', 'BT', 'LR', or 'RL',
|
||||||
|
where T = top, B = bottom, L = left, and R = right.
|
||||||
|
|
||||||
|
### minEntityWidth
|
||||||
|
|
||||||
|
The mimimum width of an entity box, expressed in pixels
|
||||||
|
|
||||||
|
### minEntityHeight
|
||||||
|
|
||||||
|
The minimum height of an entity box, expressed in pixels
|
||||||
|
|
||||||
|
### entityPadding
|
||||||
|
|
||||||
|
The minimum internal padding between the text in an entity box and the enclosing box borders, expressed in pixels
|
||||||
|
|
||||||
|
### stroke
|
||||||
|
|
||||||
|
Stroke color of box edges and lines
|
||||||
|
|
||||||
|
### fill
|
||||||
|
|
||||||
|
Fill color of entity boxes
|
||||||
|
|
||||||
|
### fontSize
|
||||||
|
|
||||||
|
Font size
|
||||||
|
|
||||||
## render
|
## render
|
||||||
|
|
||||||
Function that renders an svg with a graph from a chart definition. Usage example below.
|
Function that renders an svg with a graph from a chart definition. Usage example below.
|
||||||
|
@ -318,6 +355,7 @@ mermaidAPI.initialize({
|
||||||
boxTextMargin:5,
|
boxTextMargin:5,
|
||||||
noteMargin:10,
|
noteMargin:10,
|
||||||
messageMargin:35,
|
messageMargin:35,
|
||||||
|
messageAlign:'center',
|
||||||
mirrorActors:true,
|
mirrorActors:true,
|
||||||
bottomMarginAdj:1,
|
bottomMarginAdj:1,
|
||||||
useMaxWidth:true,
|
useMaxWidth:true,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "mermaid",
|
"name": "mermaid",
|
||||||
"version": "8.4.7",
|
"version": "8.5.0",
|
||||||
"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.",
|
||||||
"main": "dist/mermaid.core.js",
|
"main": "dist/mermaid.core.js",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
"git graph"
|
"git graph"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "webpack --progress --colors",
|
"build": "webpack --progress --colors -p",
|
||||||
"postbuild": "documentation build src/mermaidAPI.js --shallow -f md --markdown-toc false -o docs/mermaidAPI.md",
|
"postbuild": "documentation build src/mermaidAPI.js --shallow -f md --markdown-toc false -o docs/mermaidAPI.md",
|
||||||
"build:watch": "yarn build --watch",
|
"build:watch": "yarn build --watch",
|
||||||
"minify": "minify ./dist/mermaid.js > ./dist/mermaid.min.js",
|
"minify": "minify ./dist/mermaid.js > ./dist/mermaid.min.js",
|
||||||
|
|
|
@ -154,6 +154,28 @@ function stadium(parent, bbox, node) {
|
||||||
return shapeSvg;
|
return shapeSvg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function subroutine(parent, bbox, node) {
|
||||||
|
const w = bbox.width;
|
||||||
|
const h = bbox.height;
|
||||||
|
const points = [
|
||||||
|
{ x: 0, y: 0 },
|
||||||
|
{ x: w, y: 0 },
|
||||||
|
{ x: w, y: -h },
|
||||||
|
{ x: 0, y: -h },
|
||||||
|
{ x: 0, y: 0 },
|
||||||
|
{ x: -8, y: 0 },
|
||||||
|
{ x: w + 8, y: 0 },
|
||||||
|
{ x: w + 8, y: -h },
|
||||||
|
{ x: -8, y: -h },
|
||||||
|
{ x: -8, y: 0 }
|
||||||
|
];
|
||||||
|
const shapeSvg = insertPolygonShape(parent, w, h, points);
|
||||||
|
node.intersect = function(point) {
|
||||||
|
return dagreD3.intersect.polygon(node, points, point);
|
||||||
|
};
|
||||||
|
return shapeSvg;
|
||||||
|
}
|
||||||
|
|
||||||
function cylinder(parent, bbox, node) {
|
function cylinder(parent, bbox, node) {
|
||||||
const w = bbox.width;
|
const w = bbox.width;
|
||||||
const rx = w / 2;
|
const rx = w / 2;
|
||||||
|
@ -221,6 +243,7 @@ export function addToRender(render) {
|
||||||
render.shapes().question = question;
|
render.shapes().question = question;
|
||||||
render.shapes().hexagon = hexagon;
|
render.shapes().hexagon = hexagon;
|
||||||
render.shapes().stadium = stadium;
|
render.shapes().stadium = stadium;
|
||||||
|
render.shapes().subroutine = subroutine;
|
||||||
render.shapes().cylinder = cylinder;
|
render.shapes().cylinder = cylinder;
|
||||||
|
|
||||||
// Add custom shape for box with inverted arrow on left side
|
// Add custom shape for box with inverted arrow on left side
|
||||||
|
@ -246,6 +269,7 @@ export function addToRenderV2(addShape) {
|
||||||
addShape({ question });
|
addShape({ question });
|
||||||
addShape({ hexagon });
|
addShape({ hexagon });
|
||||||
addShape({ stadium });
|
addShape({ stadium });
|
||||||
|
addShape({ subroutine });
|
||||||
addShape({ cylinder });
|
addShape({ cylinder });
|
||||||
|
|
||||||
// Add custom shape for box with inverted arrow on left side
|
// Add custom shape for box with inverted arrow on left side
|
||||||
|
|
|
@ -65,7 +65,8 @@ describe('flowchart shapes', function() {
|
||||||
['lean_right', 4, useWidth, useHeight],
|
['lean_right', 4, useWidth, useHeight],
|
||||||
['lean_left', 4, useWidth, useHeight],
|
['lean_left', 4, useWidth, useHeight],
|
||||||
['trapezoid', 4, useWidth, useHeight],
|
['trapezoid', 4, useWidth, useHeight],
|
||||||
['inv_trapezoid', 4, useWidth, useHeight]
|
['inv_trapezoid', 4, useWidth, useHeight],
|
||||||
|
['subroutine', 10, useWidth, useHeight],
|
||||||
].forEach(function([shapeType, expectedPointCount, getW, getH]) {
|
].forEach(function([shapeType, expectedPointCount, getW, getH]) {
|
||||||
it(`should add a ${shapeType} shape that renders a properly translated polygon element`, function() {
|
it(`should add a ${shapeType} shape that renders a properly translated polygon element`, function() {
|
||||||
const mockRender = MockRender();
|
const mockRender = MockRender();
|
||||||
|
|
|
@ -119,6 +119,9 @@ export const addVertices = function(vert, g, svgId) {
|
||||||
case 'stadium':
|
case 'stadium':
|
||||||
_shape = 'stadium';
|
_shape = 'stadium';
|
||||||
break;
|
break;
|
||||||
|
case 'subroutine':
|
||||||
|
_shape = 'subroutine';
|
||||||
|
break;
|
||||||
case 'cylinder':
|
case 'cylinder':
|
||||||
_shape = 'cylinder';
|
_shape = 'cylinder';
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -119,6 +119,9 @@ export const addVertices = function(vert, g, svgId) {
|
||||||
case 'stadium':
|
case 'stadium':
|
||||||
_shape = 'stadium';
|
_shape = 'stadium';
|
||||||
break;
|
break;
|
||||||
|
case 'subroutine':
|
||||||
|
_shape = 'subroutine';
|
||||||
|
break;
|
||||||
case 'cylinder':
|
case 'cylinder':
|
||||||
_shape = 'cylinder';
|
_shape = 'cylinder';
|
||||||
break;
|
break;
|
||||||
|
@ -380,10 +383,6 @@ export const draw = function(text, id) {
|
||||||
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;
|
||||||
logger.debug(
|
|
||||||
`new ViewBox 0 0 ${width} ${height}`,
|
|
||||||
`translate(${padding - g._label.marginx}, ${padding - g._label.marginy})`
|
|
||||||
);
|
|
||||||
|
|
||||||
if (conf.useMaxWidth) {
|
if (conf.useMaxWidth) {
|
||||||
svg.attr('width', '100%');
|
svg.attr('width', '100%');
|
||||||
|
@ -393,10 +392,10 @@ export const draw = function(text, id) {
|
||||||
svg.attr('width', width);
|
svg.attr('width', width);
|
||||||
}
|
}
|
||||||
|
|
||||||
svg.attr('viewBox', `0 0 ${width} ${height}`);
|
// Ensure the viewBox includes the whole svgBounds area with extra space for padding
|
||||||
svg
|
const vBox = `${svgBounds.x - padding} ${svgBounds.y - padding} ${width} ${height}`;
|
||||||
.select('g')
|
logger.debug(`viewBox ${vBox}`);
|
||||||
.attr('transform', `translate(${padding - g._label.marginx}, ${padding - svgBounds.y})`);
|
svg.attr('viewBox', vBox);
|
||||||
|
|
||||||
// Index nodes
|
// Index nodes
|
||||||
flowDb.indexNodes('subGraph' + i);
|
flowDb.indexNodes('subGraph' + i);
|
||||||
|
|
|
@ -23,6 +23,7 @@ describe('the flowchart renderer', function() {
|
||||||
['circle', 'circle'],
|
['circle', 'circle'],
|
||||||
['ellipse', 'ellipse'],
|
['ellipse', 'ellipse'],
|
||||||
['stadium', 'stadium'],
|
['stadium', 'stadium'],
|
||||||
|
['subroutine', 'subroutine'],
|
||||||
['cylinder', 'cylinder'],
|
['cylinder', 'cylinder'],
|
||||||
['group', 'rect']
|
['group', 'rect']
|
||||||
].forEach(function([type, expectedShape, expectedRadios = 0]) {
|
].forEach(function([type, expectedShape, expectedRadios = 0]) {
|
||||||
|
|
|
@ -87,6 +87,8 @@
|
||||||
"-)" return '-)';
|
"-)" return '-)';
|
||||||
"([" return 'STADIUMSTART';
|
"([" return 'STADIUMSTART';
|
||||||
"])" return 'STADIUMEND';
|
"])" return 'STADIUMEND';
|
||||||
|
"[[" return 'SUBROUTINESTART';
|
||||||
|
"]]" return 'SUBROUTINEEND';
|
||||||
"[(" return 'CYLINDERSTART';
|
"[(" return 'CYLINDERSTART';
|
||||||
")]" return 'CYLINDEREND';
|
")]" return 'CYLINDEREND';
|
||||||
\- return 'MINUS';
|
\- return 'MINUS';
|
||||||
|
@ -316,6 +318,8 @@ vertex: idString SQS text SQE
|
||||||
{$$ = $1;yy.addVertex($1,$3,'ellipse');}
|
{$$ = $1;yy.addVertex($1,$3,'ellipse');}
|
||||||
| idString STADIUMSTART text STADIUMEND
|
| idString STADIUMSTART text STADIUMEND
|
||||||
{$$ = $1;yy.addVertex($1,$3,'stadium');}
|
{$$ = $1;yy.addVertex($1,$3,'stadium');}
|
||||||
|
| idString SUBROUTINESTART text SUBROUTINEEND
|
||||||
|
{$$ = $1;yy.addVertex($1,$3,'subroutine');}
|
||||||
| idString CYLINDERSTART text CYLINDEREND
|
| idString CYLINDERSTART text CYLINDEREND
|
||||||
{$$ = $1;yy.addVertex($1,$3,'cylinder');}
|
{$$ = $1;yy.addVertex($1,$3,'cylinder');}
|
||||||
| idString PS text PE
|
| idString PS text PE
|
||||||
|
@ -474,5 +478,5 @@ alphaNumToken : PUNCTUATION | AMP | UNICODE_TEXT | NUM| ALPHA | COLON | COMMA |
|
||||||
|
|
||||||
idStringToken : ALPHA|UNDERSCORE |UNICODE_TEXT | NUM| COLON | COMMA | PLUS | MINUS | DOWN |EQUALS | MULT | BRKT | DOT | PUNCTUATION | AMP;
|
idStringToken : ALPHA|UNDERSCORE |UNICODE_TEXT | NUM| COLON | COMMA | PLUS | MINUS | DOWN |EQUALS | MULT | BRKT | DOT | PUNCTUATION | AMP;
|
||||||
|
|
||||||
graphCodeTokens: STADIUMSTART | STADIUMEND | CYLINDERSTART | CYLINDEREND | TRAPSTART | TRAPEND | INVTRAPSTART | INVTRAPEND | PIPE | PS | PE | SQS | SQE | DIAMOND_START | DIAMOND_STOP | TAGSTART | TAGEND | ARROW_CROSS | ARROW_POINT | ARROW_CIRCLE | ARROW_OPEN | QUOTE | SEMI;
|
graphCodeTokens: STADIUMSTART | STADIUMEND | SUBROUTINESTART | SUBROUTINEEND | CYLINDERSTART | CYLINDEREND | TRAPSTART | TRAPEND | INVTRAPSTART | INVTRAPEND | PIPE | PS | PE | SQS | SQE | DIAMOND_START | DIAMOND_STOP | TAGSTART | TAGEND | ARROW_CROSS | ARROW_POINT | ARROW_CIRCLE | ARROW_OPEN | QUOTE | SEMI;
|
||||||
%%
|
%%
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { getConfig } from '../../config';
|
||||||
const config = getConfig();
|
const config = getConfig();
|
||||||
let dateFormat = '';
|
let dateFormat = '';
|
||||||
let axisFormat = '';
|
let axisFormat = '';
|
||||||
|
let todayMarker = '';
|
||||||
let excludes = [];
|
let excludes = [];
|
||||||
let title = '';
|
let title = '';
|
||||||
let sections = [];
|
let sections = [];
|
||||||
|
@ -27,6 +28,7 @@ export const clear = function() {
|
||||||
rawTasks = [];
|
rawTasks = [];
|
||||||
dateFormat = '';
|
dateFormat = '';
|
||||||
axisFormat = '';
|
axisFormat = '';
|
||||||
|
todayMarker = '';
|
||||||
excludes = [];
|
excludes = [];
|
||||||
inclusiveEndDates = false;
|
inclusiveEndDates = false;
|
||||||
};
|
};
|
||||||
|
@ -39,6 +41,14 @@ export const getAxisFormat = function() {
|
||||||
return axisFormat;
|
return axisFormat;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const setTodayMarker = function(txt) {
|
||||||
|
todayMarker = txt;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getTodayMarker = function() {
|
||||||
|
return todayMarker;
|
||||||
|
};
|
||||||
|
|
||||||
export const setDateFormat = function(txt) {
|
export const setDateFormat = function(txt) {
|
||||||
dateFormat = txt;
|
dateFormat = txt;
|
||||||
};
|
};
|
||||||
|
@ -572,6 +582,8 @@ export default {
|
||||||
endDatesAreInclusive,
|
endDatesAreInclusive,
|
||||||
setAxisFormat,
|
setAxisFormat,
|
||||||
getAxisFormat,
|
getAxisFormat,
|
||||||
|
setTodayMarker,
|
||||||
|
getTodayMarker,
|
||||||
setTitle,
|
setTitle,
|
||||||
getTitle,
|
getTitle,
|
||||||
addSection,
|
addSection,
|
||||||
|
|
|
@ -21,6 +21,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.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');
|
||||||
ganttDb.addTask('test1', 'id1,2019-02-01,1d');
|
ganttDb.addTask('test1', 'id1,2019-02-01,1d');
|
||||||
|
@ -34,6 +35,7 @@ describe('when using the ganttDb', function() {
|
||||||
${'getTitle'} | ${''}
|
${'getTitle'} | ${''}
|
||||||
${'getDateFormat'} | ${''}
|
${'getDateFormat'} | ${''}
|
||||||
${'getAxisFormat'} | ${''}
|
${'getAxisFormat'} | ${''}
|
||||||
|
${'getTodayMarker'} | ${''}
|
||||||
${'getExcludes'} | ${[]}
|
${'getExcludes'} | ${[]}
|
||||||
${'getSections'} | ${[]}
|
${'getSections'} | ${[]}
|
||||||
${'endDatesAreInclusive'} | ${false}
|
${'endDatesAreInclusive'} | ${false}
|
||||||
|
@ -216,4 +218,13 @@ describe('when using the ganttDb', function() {
|
||||||
expect(tasks[1].task).toEqual('test2');
|
expect(tasks[1].task).toEqual('test2');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it.each`
|
||||||
|
type | expected
|
||||||
|
${'hide'} | ${'off'}
|
||||||
|
${'style'} | ${'stoke:stroke-width:5px,stroke:#00f,opacity:0.5'}
|
||||||
|
`('should ${type} today marker', ({ expected }) => {
|
||||||
|
ganttDb.setTodayMarker(expected);
|
||||||
|
expect(ganttDb.getTodayMarker()).toEqual(expected);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -396,17 +396,25 @@ export const draw = function(text, id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawToday(theSidePad, theTopPad, w, h) {
|
function drawToday(theSidePad, theTopPad, w, h) {
|
||||||
|
const todayMarker = ganttDb.getTodayMarker();
|
||||||
|
if (todayMarker === 'off') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const todayG = svg.append('g').attr('class', 'today');
|
const todayG = svg.append('g').attr('class', 'today');
|
||||||
|
|
||||||
const today = new Date();
|
const today = new Date();
|
||||||
|
const todayLine = todayG.append('line');
|
||||||
|
|
||||||
todayG
|
todayLine
|
||||||
.append('line')
|
|
||||||
.attr('x1', timeScale(today) + theSidePad)
|
.attr('x1', timeScale(today) + theSidePad)
|
||||||
.attr('x2', timeScale(today) + theSidePad)
|
.attr('x2', timeScale(today) + theSidePad)
|
||||||
.attr('y1', conf.titleTopMargin)
|
.attr('y1', conf.titleTopMargin)
|
||||||
.attr('y2', h - conf.titleTopMargin)
|
.attr('y2', h - conf.titleTopMargin)
|
||||||
.attr('class', 'today');
|
.attr('class', 'today');
|
||||||
|
|
||||||
|
if (todayMarker !== '') {
|
||||||
|
todayLine.attr('style', todayMarker.replace(/,/g, ';'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// from this stackexchange question: http://stackoverflow.com/questions/1890203/unique-for-arrays-in-javascript
|
// from this stackexchange question: http://stackoverflow.com/questions/1890203/unique-for-arrays-in-javascript
|
||||||
|
|
|
@ -55,13 +55,14 @@ that id.
|
||||||
|
|
||||||
"gantt" return 'gantt';
|
"gantt" return 'gantt';
|
||||||
"dateFormat"\s[^#\n;]+ return 'dateFormat';
|
"dateFormat"\s[^#\n;]+ return 'dateFormat';
|
||||||
"inclusiveEndDates" return 'inclusiveEndDates';
|
"inclusiveEndDates" return 'inclusiveEndDates';
|
||||||
"axisFormat"\s[^#\n;]+ return 'axisFormat';
|
"axisFormat"\s[^#\n;]+ return 'axisFormat';
|
||||||
"excludes"\s[^#\n;]+ return 'excludes';
|
"excludes"\s[^#\n;]+ return 'excludes';
|
||||||
|
"todayMarker"\s[^\n;]+ return 'todayMarker';
|
||||||
\d\d\d\d"-"\d\d"-"\d\d return 'date';
|
\d\d\d\d"-"\d\d"-"\d\d return 'date';
|
||||||
"title"\s[^#\n;]+ return 'title';
|
"title"\s[^#\n;]+ return 'title';
|
||||||
"section"\s[^#:\n;]+ return 'section';
|
"section"\s[^#:\n;]+ return 'section';
|
||||||
[^#:\n;]+ return 'taskTxt';
|
[^#:\n;]+ return 'taskTxt';
|
||||||
":"[^#\n;]+ return 'taskData';
|
":"[^#\n;]+ return 'taskData';
|
||||||
":" return ':';
|
":" return ':';
|
||||||
<<EOF>> return 'EOF';
|
<<EOF>> return 'EOF';
|
||||||
|
@ -93,9 +94,10 @@ line
|
||||||
|
|
||||||
statement
|
statement
|
||||||
: dateFormat {yy.setDateFormat($1.substr(11));$$=$1.substr(11);}
|
: dateFormat {yy.setDateFormat($1.substr(11));$$=$1.substr(11);}
|
||||||
| inclusiveEndDates {yy.enableInclusiveEndDates();$$=$1.substr(18);}
|
| inclusiveEndDates {yy.enableInclusiveEndDates();$$=$1.substr(18);}
|
||||||
| axisFormat {yy.setAxisFormat($1.substr(11));$$=$1.substr(11);}
|
| axisFormat {yy.setAxisFormat($1.substr(11));$$=$1.substr(11);}
|
||||||
| excludes {yy.setExcludes($1.substr(9));$$=$1.substr(9);}
|
| excludes {yy.setExcludes($1.substr(9));$$=$1.substr(9);}
|
||||||
|
| todayMarker {yy.setTodayMarker($1.substr(12));$$=$1.substr(12);}
|
||||||
| title {yy.setTitle($1.substr(6));$$=$1.substr(6);}
|
| title {yy.setTitle($1.substr(6));$$=$1.substr(6);}
|
||||||
| section {yy.addSection($1.substr(8));$$=$1.substr(8);}
|
| section {yy.addSection($1.substr(8));$$=$1.substr(8);}
|
||||||
| clickStatement
|
| clickStatement
|
||||||
|
|
|
@ -37,6 +37,14 @@ describe('when parsing a gantt diagram it', function() {
|
||||||
|
|
||||||
expect(parserFnConstructor(str)).not.toThrow();
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
});
|
});
|
||||||
|
it('should handle a todayMarker definition', function() {
|
||||||
|
spyOn(ganttDb, 'setTodayMarker');
|
||||||
|
const str =
|
||||||
|
'gantt\ndateFormat yyyy-mm-dd\ntitle Adding gantt diagram functionality to mermaid\nexcludes weekdays 2019-02-01\ntodayMarker off';
|
||||||
|
|
||||||
|
expect(parserFnConstructor(str)).not.toThrow();
|
||||||
|
expect(ganttDb.setTodayMarker).toHaveBeenCalledWith('off');
|
||||||
|
});
|
||||||
it('should handle a section definition', function() {
|
it('should handle a section definition', function() {
|
||||||
const str =
|
const str =
|
||||||
'gantt\n' +
|
'gantt\n' +
|
||||||
|
|
|
@ -362,7 +362,7 @@ const drawMessage = function(elem, startx, stopx, verticalPos, msg, sequenceInde
|
||||||
line.attr('marker-start', 'url(' + url + '#sequencenumber)');
|
line.attr('marker-start', 'url(' + url + '#sequencenumber)');
|
||||||
g.append('text')
|
g.append('text')
|
||||||
.attr('x', startx)
|
.attr('x', startx)
|
||||||
.attr('y', verticalPos + 4)
|
.attr('y', verticalPos + 4 + totalOffset)
|
||||||
.attr('font-family', 'sans-serif')
|
.attr('font-family', 'sans-serif')
|
||||||
.attr('font-size', '12px')
|
.attr('font-size', '12px')
|
||||||
.attr('text-anchor', 'middle')
|
.attr('text-anchor', 'middle')
|
||||||
|
|
|
@ -75,8 +75,13 @@ export const draw = function(text, id) {
|
||||||
const width = bounds.width + padding * 2;
|
const width = bounds.width + padding * 2;
|
||||||
const height = bounds.height + padding * 2;
|
const height = bounds.height + padding * 2;
|
||||||
|
|
||||||
// Zoom in a bit
|
if (conf.useMaxWidth) {
|
||||||
diagram.attr('width', width * 1.75);
|
diagram.attr('width', '100%');
|
||||||
|
diagram.attr('style', `max-width: ${width * 1.75}px;`);
|
||||||
|
} else {
|
||||||
|
// Zoom in a bit
|
||||||
|
diagram.attr('width', width * 1.75);
|
||||||
|
}
|
||||||
// diagram.attr('height', bounds.height * 3 + conf.padding * 2);
|
// diagram.attr('height', bounds.height * 3 + conf.padding * 2);
|
||||||
diagram.attr(
|
diagram.attr(
|
||||||
'viewBox',
|
'viewBox',
|
||||||
|
|
Loading…
Reference in New Issue