Merge branch 'develop' into feature/1295_generic_rendering_engine

This commit is contained in:
Knut Sveidqvist 2020-04-11 18:53:47 +02:00
commit 5f4da6e0bc
22 changed files with 275 additions and 29 deletions

View File

@ -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 } }
);
});
}); });

View File

@ -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
`,
{}
);
});
}); });

View File

@ -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!
`,
{}
);
});
}); });
}); });

47
dist/index.html vendored
View File

@ -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/>

View File

@ -2,7 +2,7 @@
> An entityrelationship 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 entityrelationship 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

View File

@ -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
``` ```

View File

@ -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),

View File

@ -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,

View File

@ -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",

View File

@ -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

View File

@ -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();

View File

@ -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;

View File

@ -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);

View File

@ -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]) {

View File

@ -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;
%% %%

View File

@ -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,

View File

@ -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);
});
}); });

View File

@ -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

View File

@ -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

View File

@ -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' +

View File

@ -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')

View File

@ -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',