mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-01-28 07:03:17 +08:00
commit
fc0902c290
6
.github/workflows/build.yml
vendored
6
.github/workflows/build.yml
vendored
@ -34,6 +34,12 @@ jobs:
|
||||
|
||||
- name: Run Build
|
||||
run: yarn build
|
||||
|
||||
- name: Upload Build as Artifact
|
||||
uses: actions/upload-artifact@v1
|
||||
with:
|
||||
name: dist
|
||||
path: dist
|
||||
|
||||
- name: Run Unit Tests
|
||||
run: |
|
||||
|
@ -474,4 +474,30 @@ describe('Flowchart', () => {
|
||||
{ flowchart: { htmlLabels: false } }
|
||||
);
|
||||
});
|
||||
it('22: Render a simple flowchart with nodeSpacing set to 100', () => {
|
||||
imgSnapshotTest(
|
||||
`graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me think}
|
||||
%% this is a comment
|
||||
C -->|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
`,
|
||||
{ flowchart: { nodeSpacing: 50 } }
|
||||
);
|
||||
});
|
||||
it('23: Render a simple flowchart with rankSpacing set to 100', () => {
|
||||
imgSnapshotTest(
|
||||
`graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me think}
|
||||
%% this is a comment
|
||||
C -->|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
`,
|
||||
{ flowchart: { rankSpacing: '100' } }
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -38,6 +38,42 @@ describe('Sequencediagram', () => {
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('Handle multiline section titles with different line breaks', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
gantt
|
||||
dateFormat YYYY-MM-DD
|
||||
axisFormat %d/%m
|
||||
title GANTT diagram with multiline section titles
|
||||
excludes weekdays 2014-01-10
|
||||
|
||||
section A section<br>multiline
|
||||
Completed task : done, des1, 2014-01-06,2014-01-08
|
||||
Active task : active, des2, 2014-01-09, 3d
|
||||
Future task : des3, after des2, 5d
|
||||
Future task2 : des4, after des3, 5d
|
||||
|
||||
section Critical tasks<br/>multiline
|
||||
Completed task in the critical line : crit, done, 2014-01-06, 24h
|
||||
Implement parser and jison : crit, done, after des1, 2d
|
||||
Create tests for parser : crit, active, 3d
|
||||
Future task in critical line : crit, 5d
|
||||
Create tests for renderer : 2d
|
||||
Add to mermaid : 1d
|
||||
|
||||
section Documentation<br />multiline
|
||||
Describe gantt syntax : active, a1, after des1, 3d
|
||||
Add gantt diagram to demo page : after a1, 20h
|
||||
Add another diagram to demo page : doc1, after a1, 48h
|
||||
|
||||
section Last section<br />multiline
|
||||
Describe gantt syntax : after doc1, 3d
|
||||
Add gantt diagram to demo page : 20h
|
||||
Add another diagram to demo page : 48h
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('Multiple dependencies syntax', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
|
31
dist/index.html
vendored
31
dist/index.html
vendored
@ -430,6 +430,37 @@ Describe gantt syntax :after doc1, 3d
|
||||
Add gantt diagram to demo page : 20h
|
||||
Add another diagram to demo page : 48h
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
gantt
|
||||
dateFormat YYYY-MM-DD
|
||||
axisFormat %d/%m
|
||||
title GANTT diagram with multiline section titles
|
||||
excludes weekdays 2014-01-10
|
||||
|
||||
section A section<br>multiline
|
||||
Completed task : done, des1, 2014-01-06,2014-01-08
|
||||
Active task : active, des2, 2014-01-09, 3d
|
||||
Future task : des3, after des2, 5d
|
||||
Future task2 : des4, after des3, 5d
|
||||
|
||||
section Critical tasks<br/>multiline
|
||||
Completed task in the critical line : crit, done, 2014-01-06, 24h
|
||||
Implement parser and jison : crit, done, after des1, 2d
|
||||
Create tests for parser : crit, active, 3d
|
||||
Future task in critical line : crit, 5d
|
||||
Create tests for renderer : 2d
|
||||
Add to mermaid : 1d
|
||||
|
||||
section Documentation<br />multiline
|
||||
Describe gantt syntax : active, a1, after des1, 3d
|
||||
Add gantt diagram to demo page : after a1, 20h
|
||||
Add another diagram to demo page : doc1, after a1, 48h
|
||||
|
||||
section Last section<br />multiline
|
||||
Describe gantt syntax : after doc1, 3d
|
||||
Add gantt diagram to demo page : 20h
|
||||
Add another diagram to demo page : 48h
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
|
@ -27,7 +27,6 @@ mermaid.initialize({
|
||||
**Example 2:**
|
||||
|
||||
<pre>
|
||||
<script>
|
||||
var config = {
|
||||
startOnLoad:true,
|
||||
flowchart:{
|
||||
@ -39,8 +38,6 @@ mermaid.initialize({
|
||||
securityLevel:'loose',
|
||||
};
|
||||
mermaid.initialize(config);
|
||||
</script>
|
||||
|
||||
</pre>
|
||||
A summary of all options and their defaults is found [here](https://github.com/knsv/mermaid/blob/master/docs/mermaidAPI.md#mermaidapi-configuration-defaults). A description of each option follows below.
|
||||
|
||||
@ -105,6 +102,18 @@ Flag for setting whether or not a html tag should be used for rendering labels
|
||||
on the edges.
|
||||
**Default value true**.
|
||||
|
||||
### nodeSpacing
|
||||
|
||||
Defines the spacing between nodes on the same level (meaning horizontal spacing for
|
||||
TB or BT graphs, and the vertical spacing for LR as well as RL graphs).
|
||||
**Default value 50**.
|
||||
|
||||
### rankSpacing
|
||||
|
||||
Defines the spacing between nodes on different levels (meaning vertical spacing for
|
||||
TB or BT graphs, and the horizontal spacing for LR as well as RL graphs).
|
||||
**Default value 50**.
|
||||
|
||||
### curve
|
||||
|
||||
How mermaid renders curves for flowcharts. Possible values are
|
||||
|
@ -9,6 +9,7 @@ const config = getConfig();
|
||||
|
||||
let relations = [];
|
||||
let classes = {};
|
||||
let classCounter = 0;
|
||||
|
||||
let funs = [];
|
||||
|
||||
@ -41,8 +42,24 @@ export const addClass = function(id) {
|
||||
cssClasses: [],
|
||||
methods: [],
|
||||
members: [],
|
||||
annotations: []
|
||||
annotations: [],
|
||||
domId: MERMAID_DOM_ID_PREFIX + classId.className + '-' + classCounter
|
||||
};
|
||||
classCounter++;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function to lookup domId from id in the graph definition.
|
||||
* @param id
|
||||
* @public
|
||||
*/
|
||||
export const lookUpDomId = function(id) {
|
||||
const classKeys = Object.keys(classes);
|
||||
for (let i = 0; i < classKeys.length; i++) {
|
||||
if (classes[classKeys[i]].id === id) {
|
||||
return classes[classKeys[i]].domId;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const clear = function() {
|
||||
@ -178,9 +195,9 @@ export const setClickEvent = function(ids, functionName, tooltip) {
|
||||
setCssClass(ids, 'clickable');
|
||||
};
|
||||
|
||||
const setClickFunc = function(_id, functionName, tooltip) {
|
||||
let id = _id;
|
||||
let elemId = MERMAID_DOM_ID_PREFIX + id;
|
||||
const setClickFunc = function(domId, functionName, tooltip) {
|
||||
let id = domId;
|
||||
let elemId = lookUpDomId(id);
|
||||
|
||||
if (config.securityLevel !== 'loose') {
|
||||
return;
|
||||
@ -286,5 +303,6 @@ export default {
|
||||
relationType,
|
||||
setClickEvent,
|
||||
setCssClass,
|
||||
setLink
|
||||
setLink,
|
||||
lookUpDomId
|
||||
};
|
||||
|
@ -2,13 +2,12 @@ import * as d3 from 'd3';
|
||||
import dagre from 'dagre';
|
||||
import graphlib from 'graphlib';
|
||||
import { logger } from '../../logger';
|
||||
import classDb from './classDb';
|
||||
import classDb, { lookUpDomId } from './classDb';
|
||||
import utils from '../../utils';
|
||||
import { parser } from './parser/classDiagram';
|
||||
|
||||
parser.yy = classDb;
|
||||
|
||||
const MERMAID_DOM_ID_PREFIX = 'classid-';
|
||||
let idCache = {};
|
||||
|
||||
const conf = {
|
||||
@ -322,7 +321,7 @@ const drawClass = function(elem, classDef) {
|
||||
}
|
||||
};
|
||||
|
||||
const id = MERMAID_DOM_ID_PREFIX + classDef.id;
|
||||
const id = classDef.id;
|
||||
const classInfo = {
|
||||
id: id,
|
||||
label: classDef.id,
|
||||
@ -333,7 +332,7 @@ const drawClass = function(elem, classDef) {
|
||||
// add class group
|
||||
const g = elem
|
||||
.append('g')
|
||||
.attr('id', id)
|
||||
.attr('id', lookUpDomId(id))
|
||||
.attr('class', cssClassStr);
|
||||
|
||||
// add title
|
||||
@ -514,7 +513,7 @@ export const draw = function(text, id) {
|
||||
g.nodes().forEach(function(v) {
|
||||
if (typeof v !== 'undefined' && typeof g.node(v) !== 'undefined') {
|
||||
logger.debug('Node ' + v + ': ' + JSON.stringify(g.node(v)));
|
||||
d3.select('#' + v).attr(
|
||||
d3.select('#' + lookUpDomId(v)).attr(
|
||||
'transform',
|
||||
'translate(' +
|
||||
(g.node(v).x - g.node(v).width / 2) +
|
||||
|
@ -5,10 +5,7 @@ import flowDb from './flowDb';
|
||||
import flow from './parser/flow';
|
||||
import { getConfig } from '../../config';
|
||||
|
||||
const newDagreD3 = true;
|
||||
import dagreD3 from 'dagre-d3';
|
||||
// const newDagreD3 = false;
|
||||
|
||||
import addHtmlLabel from 'dagre-d3/lib/label/add-html-label.js';
|
||||
import { logger } from '../../logger';
|
||||
import { interpolateToCurve } from '../../utils';
|
||||
@ -291,36 +288,25 @@ export const draw = function(text, id) {
|
||||
dir = 'TD';
|
||||
}
|
||||
|
||||
const conf = getConfig().flowchart;
|
||||
const nodeSpacing = conf.nodeSpacing || 50;
|
||||
const rankSpacing = conf.rankSpacing || 50;
|
||||
|
||||
// Create the input mermaid.graph
|
||||
let g;
|
||||
// Todo remove newDagreD3 when properly verified
|
||||
if (newDagreD3) {
|
||||
g = new graphlib.Graph({
|
||||
multigraph: true,
|
||||
compound: true
|
||||
const g = new graphlib.Graph({
|
||||
multigraph: true,
|
||||
compound: true
|
||||
})
|
||||
.setGraph({
|
||||
rankdir: dir,
|
||||
nodesep: nodeSpacing,
|
||||
ranksep: rankSpacing,
|
||||
marginx: 8,
|
||||
marginy: 8
|
||||
})
|
||||
.setGraph({
|
||||
rankdir: dir,
|
||||
marginx: 8,
|
||||
marginy: 8
|
||||
})
|
||||
.setDefaultEdgeLabel(function() {
|
||||
return {};
|
||||
});
|
||||
} else {
|
||||
g = new graphlib.Graph({
|
||||
multigraph: true,
|
||||
compound: true
|
||||
})
|
||||
.setGraph({
|
||||
rankdir: dir,
|
||||
marginx: 20,
|
||||
marginy: 20
|
||||
})
|
||||
.setDefaultEdgeLabel(function() {
|
||||
return {};
|
||||
});
|
||||
}
|
||||
.setDefaultEdgeLabel(function() {
|
||||
return {};
|
||||
});
|
||||
|
||||
let subG;
|
||||
const subGraphs = flowDb.getSubGraphs();
|
||||
@ -403,51 +389,28 @@ export const draw = function(text, id) {
|
||||
return flowDb.getTooltip(this.id);
|
||||
});
|
||||
|
||||
const conf = getConfig().flowchart;
|
||||
const padding = 8;
|
||||
// Todo remove newDagreD3 when properly verified
|
||||
if (newDagreD3) {
|
||||
const svgBounds = svg.node().getBBox();
|
||||
const width = svgBounds.width + 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})`
|
||||
);
|
||||
const svgBounds = svg.node().getBBox();
|
||||
const width = svgBounds.width + 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) {
|
||||
svg.attr('width', '100%');
|
||||
svg.attr('style', `max-width: ${width}px;`);
|
||||
} else {
|
||||
svg.attr('height', height);
|
||||
svg.attr('width', width);
|
||||
}
|
||||
|
||||
svg.attr('viewBox', `0 0 ${width} ${height}`);
|
||||
svg
|
||||
.select('g')
|
||||
.attr('transform', `translate(${padding - g._label.marginx}, ${padding - svgBounds.y})`);
|
||||
if (conf.useMaxWidth) {
|
||||
svg.attr('width', '100%');
|
||||
svg.attr('style', `max-width: ${width}px;`);
|
||||
} else {
|
||||
const width = g.maxX - g.minX + padding * 2;
|
||||
const height = g.maxY - g.minY + padding * 2;
|
||||
|
||||
if (conf.useMaxWidth) {
|
||||
svg.attr('width', '100%');
|
||||
svg.attr('style', `max-width: ${width}px;`);
|
||||
} else {
|
||||
svg.attr('height', height);
|
||||
svg.attr('width', width);
|
||||
}
|
||||
|
||||
logger.debug(
|
||||
`Org ViewBox 0 0 ${width} ${height}`,
|
||||
`translate(${padding - g.minX}, ${padding - g.minY})\n${location.href}`
|
||||
);
|
||||
|
||||
svg.attr('viewBox', `0 0 ${width} ${height}`);
|
||||
svg.select('g').attr('transform', `translate(${padding - g.minX}, ${padding - g.minY})`);
|
||||
// svg.select('g').attr('transform', `translate(${padding - minX}, ${padding - minY})`);
|
||||
svg.attr('height', height);
|
||||
svg.attr('width', width);
|
||||
}
|
||||
|
||||
svg.attr('viewBox', `0 0 ${width} ${height}`);
|
||||
svg
|
||||
.select('g')
|
||||
.attr('transform', `translate(${padding - g._label.marginx}, ${padding - svgBounds.y})`);
|
||||
|
||||
// Index nodes
|
||||
flowDb.indexNodes('subGraph' + i);
|
||||
|
||||
|
@ -357,9 +357,22 @@ export const draw = function(text, id) {
|
||||
.selectAll('text')
|
||||
.data(numOccurances)
|
||||
.enter()
|
||||
.append('text')
|
||||
.text(function(d) {
|
||||
return d[0];
|
||||
.append(function(d) {
|
||||
const rows = d[0].split(/<br\s*\/?>/gi);
|
||||
const dy = -(rows.length - 1) / 2;
|
||||
|
||||
const svgLabel = document.createElementNS('http://www.w3.org/2000/svg', 'text');
|
||||
svgLabel.setAttribute('dy', dy + 'em');
|
||||
|
||||
for (let j = 0; j < rows.length; j++) {
|
||||
const tspan = document.createElementNS('http://www.w3.org/2000/svg', 'tspan');
|
||||
tspan.setAttribute('alignment-baseline', 'central');
|
||||
tspan.setAttribute('x', '10');
|
||||
if (j > 0) tspan.setAttribute('dy', '1em');
|
||||
tspan.textContent = rows[j];
|
||||
svgLabel.appendChild(tspan);
|
||||
}
|
||||
return svgLabel;
|
||||
})
|
||||
.attr('x', 10)
|
||||
.attr('y', function(d, i) {
|
||||
|
@ -47,6 +47,16 @@ describe('when parsing a gantt diagram it', function() {
|
||||
|
||||
expect(parserFnConstructor(str)).not.toThrow();
|
||||
});
|
||||
it('should handle multiline section titles with different line breaks', function() {
|
||||
const str =
|
||||
'gantt\n' +
|
||||
'dateFormat yyyy-mm-dd\n' +
|
||||
'title Adding gantt diagram functionality to mermaid\n' +
|
||||
'excludes weekdays 2019-02-01\n' +
|
||||
'section Line1<br>Line2<br/>Line3</br />Line4<br\t/>Line5';
|
||||
|
||||
expect(parserFnConstructor(str)).not.toThrow();
|
||||
});
|
||||
/**
|
||||
* Beslutsflöde inligt nedan. Obs bla bla bla
|
||||
* ```
|
||||
|
Loading…
x
Reference in New Issue
Block a user