mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-18 06:49:47 +02:00
Merge branch 'release/8.4.4'
This commit is contained in:
@@ -9,8 +9,27 @@ describe('XSS', () => {
|
|||||||
const url = mermaidUrl(str,{}, true);
|
const url = mermaidUrl(str,{}, true);
|
||||||
|
|
||||||
cy.visit(url);
|
cy.visit(url);
|
||||||
|
cy.wait(1000).then(()=>{
|
||||||
|
cy.get('.mermaid').should('exist');
|
||||||
|
});
|
||||||
cy.get('svg')
|
cy.get('svg')
|
||||||
cy.percySnapshot()
|
// cy.percySnapshot()
|
||||||
|
|
||||||
|
})
|
||||||
|
it('should handle xss in tags in non-html mode', () => {
|
||||||
|
const str = 'eyJjb2RlIjoiXG5ncmFwaCBMUlxuICAgICAgQi0tPkQoPGltZyBvbmVycm9yPWxvY2F0aW9uPWBqYXZhc2NyaXB0XFx1MDAzYXhzc0F0dGFja1xcdTAwMjhkb2N1bWVudC5kb21haW5cXHUwMDI5YCBzcmM9eD4pOyIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0IiwiZmxvd2NoYXJ0Ijp7Imh0bWxMYWJlbHMiOmZhbHNlfX19';
|
||||||
|
|
||||||
|
const url = mermaidUrl(str,{
|
||||||
|
"theme": "default",
|
||||||
|
"flowchart": {
|
||||||
|
"htmlMode": false
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
cy.visit(url);
|
||||||
|
// cy.get('svg')
|
||||||
|
// cy.percySnapshot()
|
||||||
|
cy.get('.malware').should('not.exist');
|
||||||
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@@ -2,19 +2,20 @@
|
|||||||
import { imgSnapshotTest } from '../../helpers/util';
|
import { imgSnapshotTest } from '../../helpers/util';
|
||||||
|
|
||||||
describe('State diagram', () => {
|
describe('State diagram', () => {
|
||||||
it('should render a flowchart full of circles', () => {
|
it('should render a state with states in it', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
stateDiagram
|
stateDiagram
|
||||||
State1: The state with a note
|
state PersonalizedCockpit {
|
||||||
note right of State1
|
Other
|
||||||
Important information! You\ncan write
|
state Parent {
|
||||||
notes with multiple lines...
|
C
|
||||||
Here is another line...
|
}
|
||||||
And another line...
|
}
|
||||||
end note
|
|
||||||
`,
|
`,
|
||||||
{}
|
{
|
||||||
|
logLevel: 0,
|
||||||
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -2,20 +2,20 @@
|
|||||||
import { imgSnapshotTest } from '../../helpers/util.js';
|
import { imgSnapshotTest } from '../../helpers/util.js';
|
||||||
|
|
||||||
describe('Sequencediagram', () => {
|
describe('Sequencediagram', () => {
|
||||||
it('should render a simple git graph', () => {
|
// it('should render a simple git graph', () => {
|
||||||
imgSnapshotTest(
|
// imgSnapshotTest(
|
||||||
`
|
// `
|
||||||
gitGraph:
|
// gitGraph:
|
||||||
commit
|
// commit
|
||||||
branch newbranch
|
// branch newbranch
|
||||||
checkout newbranch
|
// checkout newbranch
|
||||||
commit
|
// commit
|
||||||
commit
|
// commit
|
||||||
checkout master
|
// checkout master
|
||||||
commit
|
// commit
|
||||||
commit
|
// commit
|
||||||
merge newbranch`,
|
// merge newbranch`,
|
||||||
{ logLevel: 0 }
|
// { logLevel: 0 }
|
||||||
);
|
// );
|
||||||
});
|
// });
|
||||||
});
|
});
|
||||||
|
@@ -106,6 +106,22 @@ describe('State diagram', () => {
|
|||||||
);
|
);
|
||||||
cy.get('svg');
|
cy.get('svg');
|
||||||
});
|
});
|
||||||
|
it('should render a note with multiple lines in it', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
stateDiagram
|
||||||
|
State1: The state with a note
|
||||||
|
note right of State1
|
||||||
|
Important information! You\ncan write
|
||||||
|
notes with multiple lines...
|
||||||
|
Here is another line...
|
||||||
|
And another line...
|
||||||
|
end note
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('should render a states with descriptions including multi-line descriptions', () => {
|
it('should render a states with descriptions including multi-line descriptions', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
@@ -276,4 +292,33 @@ describe('State diagram', () => {
|
|||||||
);
|
);
|
||||||
cy.get('svg');
|
cy.get('svg');
|
||||||
});
|
});
|
||||||
|
it('should render a state with states in it', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
stateDiagram
|
||||||
|
state PilotCockpit {
|
||||||
|
state Parent {
|
||||||
|
C
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
{
|
||||||
|
logLevel: 0,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('Simplest compone state', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
stateDiagram
|
||||||
|
state Parent {
|
||||||
|
C
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
{
|
||||||
|
logLevel: 0,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@@ -4,23 +4,33 @@
|
|||||||
href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
|
href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
|
||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
/>
|
/>
|
||||||
|
<style>
|
||||||
|
body {background: black}
|
||||||
|
h1 { color: white;}
|
||||||
|
.arrowheadPath {fill: red;}
|
||||||
|
|
||||||
|
.edgePath .path {stroke: red;}
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>info below</h1>
|
<h1>info below</h1>
|
||||||
<div class="mermaid">graph TB
|
<div style="display: flex;">
|
||||||
a --> b
|
<div class="mermaid">graph TD
|
||||||
a --> c
|
A ==> B
|
||||||
a --> d
|
A --> C
|
||||||
|
A -.-> D
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<script src="./mermaid.js"></script>
|
<script src="./mermaid.js"></script>
|
||||||
<script>
|
<script>
|
||||||
mermaid.initialize({
|
mermaid.initialize({
|
||||||
theme: 'forest',
|
theme: 'dark',
|
||||||
// arrowMarkerAbsolute: true,
|
// arrowMarkerAbsolute: true,
|
||||||
// themeCSS: '.node rect { fill: red; }',
|
// themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
|
||||||
logLevel: 3,
|
logLevel: 3,
|
||||||
flowchart: { curve: 'linear' },
|
flowchart: { curve: 'linear', "htmlLabels": false },
|
||||||
gantt: { axisFormat: '%m/%d/%Y' },
|
gantt: { axisFormat: '%m/%d/%Y' },
|
||||||
sequence: { actorMargin: 50 },
|
sequence: { actorMargin: 50 },
|
||||||
// sequenceDiagram: { actorMargin: 300 } // deprecated
|
// sequenceDiagram: { actorMargin: 300 } // deprecated
|
||||||
|
@@ -31,7 +31,6 @@ const contentLoaded = function() {
|
|||||||
document.getElementsByTagName('body')[0].appendChild(div);
|
document.getElementsByTagName('body')[0].appendChild(div);
|
||||||
}
|
}
|
||||||
global.mermaid.initialize(graphObj.mermaid);
|
global.mermaid.initialize(graphObj.mermaid);
|
||||||
// console.log('graphObj.mermaid', graphObj.mermaid)
|
|
||||||
global.mermaid.init();
|
global.mermaid.init();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -55,7 +54,7 @@ const contentLoadedApi = function() {
|
|||||||
divs[i] = div;
|
divs[i] = div;
|
||||||
}
|
}
|
||||||
|
|
||||||
global.mermaid.initialize(graphObj.mermaid);
|
mermaid2.initialize(graphObj.mermaid);
|
||||||
|
|
||||||
for (let i = 0; i < numCodes; i++) {
|
for (let i = 0; i < numCodes; i++) {
|
||||||
mermaid2.render(
|
mermaid2.render(
|
||||||
@@ -74,8 +73,9 @@ const contentLoadedApi = function() {
|
|||||||
div.id = 'block';
|
div.id = 'block';
|
||||||
div.className = 'mermaid';
|
div.className = 'mermaid';
|
||||||
// div.innerHTML = graphObj.code
|
// div.innerHTML = graphObj.code
|
||||||
|
console.warn('graphObj.mermaid', graphObj.mermaid);
|
||||||
document.getElementsByTagName('body')[0].appendChild(div);
|
document.getElementsByTagName('body')[0].appendChild(div);
|
||||||
global.mermaid.initialize(graphObj.mermaid);
|
mermaid2.initialize(graphObj.mermaid);
|
||||||
|
|
||||||
mermaid2.render(
|
mermaid2.render(
|
||||||
'newid',
|
'newid',
|
||||||
|
@@ -28,7 +28,10 @@
|
|||||||
div.id = 'the-malware'
|
div.id = 'the-malware'
|
||||||
div.className = 'malware'
|
div.className = 'malware'
|
||||||
div.innerHTML = 'XSS Succeeded'
|
div.innerHTML = 'XSS Succeeded'
|
||||||
document.getElementsByTagName('body')[0].appendChild(div)
|
document.getElementsByTagName('body')[0].appendChild(div);
|
||||||
|
// const el = document.querySelector('.mermaid');
|
||||||
|
// el.parentNode.removeChild(el);
|
||||||
|
throw new Error('XSS Succeded');
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
16
package.json
16
package.json
@@ -49,8 +49,8 @@
|
|||||||
"@braintree/sanitize-url": "^3.1.0",
|
"@braintree/sanitize-url": "^3.1.0",
|
||||||
"crypto-random-string": "^3.0.1",
|
"crypto-random-string": "^3.0.1",
|
||||||
"d3": "^5.7.0",
|
"d3": "^5.7.0",
|
||||||
"dagre-d3-unofficial": "0.6.4",
|
|
||||||
"dagre": "^0.8.4",
|
"dagre": "^0.8.4",
|
||||||
|
"dagre-d3": "^0.6.4",
|
||||||
"graphlib": "^2.1.7",
|
"graphlib": "^2.1.7",
|
||||||
"he": "^1.2.0",
|
"he": "^1.2.0",
|
||||||
"lodash": "^4.17.11",
|
"lodash": "^4.17.11",
|
||||||
@@ -59,31 +59,31 @@
|
|||||||
"scope-css": "^1.2.1"
|
"scope-css": "^1.2.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"documentation": "^12.0.1",
|
|
||||||
"prettier": "^1.18.2",
|
|
||||||
"eslint": "^6.3.0",
|
|
||||||
"eslint-config-prettier": "^6.3.0",
|
|
||||||
"eslint-plugin-prettier": "^3.1.0",
|
|
||||||
"@babel/core": "^7.2.2",
|
"@babel/core": "^7.2.2",
|
||||||
"@babel/preset-env": "^7.2.0",
|
"@babel/preset-env": "^7.2.0",
|
||||||
"@babel/register": "^7.0.0",
|
"@babel/register": "^7.0.0",
|
||||||
"@percy/cypress": "^2.0.1",
|
"@percy/cypress": "^2.0.1",
|
||||||
"babel-core": "7.0.0-bridge.0",
|
"babel-core": "7.0.0-bridge.0",
|
||||||
"babel-jest": "^23.6.0",
|
"babel-jest": "^24.9.0",
|
||||||
"babel-loader": "^8.0.4",
|
"babel-loader": "^8.0.4",
|
||||||
"coveralls": "^3.0.2",
|
"coveralls": "^3.0.2",
|
||||||
"css-loader": "^2.0.1",
|
"css-loader": "^2.0.1",
|
||||||
"css-to-string-loader": "^0.1.3",
|
"css-to-string-loader": "^0.1.3",
|
||||||
"cypress": "3.4.0",
|
"cypress": "3.4.0",
|
||||||
|
"documentation": "^12.0.1",
|
||||||
|
"eslint": "^6.3.0",
|
||||||
|
"eslint-config-prettier": "^6.3.0",
|
||||||
|
"eslint-plugin-prettier": "^3.1.0",
|
||||||
"husky": "^1.2.1",
|
"husky": "^1.2.1",
|
||||||
"identity-obj-proxy": "^3.0.0",
|
"identity-obj-proxy": "^3.0.0",
|
||||||
"jest": "^24.9.0",
|
"jest": "^24.9.0",
|
||||||
"jison": "^0.4.18",
|
"jison": "^0.4.18",
|
||||||
"moment": "^2.23.0",
|
"moment": "^2.23.0",
|
||||||
"node-sass": "^4.12.0",
|
"node-sass": "^4.12.0",
|
||||||
|
"prettier": "^1.18.2",
|
||||||
"puppeteer": "^1.17.0",
|
"puppeteer": "^1.17.0",
|
||||||
"sass-loader": "^7.1.0",
|
"sass-loader": "^7.1.0",
|
||||||
"start-server-and-test": "^1.10.0",
|
"start-server-and-test": "^1.10.6",
|
||||||
"webpack": "^4.27.1",
|
"webpack": "^4.27.1",
|
||||||
"webpack-cli": "^3.1.2",
|
"webpack-cli": "^3.1.2",
|
||||||
"webpack-dev-server": "^3.4.1",
|
"webpack-dev-server": "^3.4.1",
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import dagreD3 from 'dagre-d3-unofficial';
|
import dagreD3 from 'dagre-d3';
|
||||||
|
|
||||||
function question(parent, bbox, node) {
|
function question(parent, bbox, node) {
|
||||||
const w = bbox.width;
|
const w = bbox.width;
|
||||||
|
@@ -22,7 +22,13 @@ let funs = [];
|
|||||||
|
|
||||||
const sanitize = text => {
|
const sanitize = text => {
|
||||||
let txt = text;
|
let txt = text;
|
||||||
if (config.securityLevel !== 'loose') {
|
let htmlLabels = true;
|
||||||
|
if (
|
||||||
|
config.flowchart &&
|
||||||
|
(config.flowchart.htmlLabels === false || config.flowchart.htmlLabels === 'false')
|
||||||
|
)
|
||||||
|
htmlLabels = false;
|
||||||
|
if (config.securityLevel !== 'loose' && htmlLabels) { // eslint-disable-line
|
||||||
txt = txt.replace(/<br>/g, '#br#');
|
txt = txt.replace(/<br>/g, '#br#');
|
||||||
txt = txt.replace(/<br\S*?\/>/g, '#br#');
|
txt = txt.replace(/<br\S*?\/>/g, '#br#');
|
||||||
txt = txt.replace(/</g, '<').replace(/>/g, '>');
|
txt = txt.replace(/</g, '<').replace(/>/g, '>');
|
||||||
|
@@ -6,10 +6,10 @@ import flow from './parser/flow';
|
|||||||
import { getConfig } from '../../config';
|
import { getConfig } from '../../config';
|
||||||
|
|
||||||
const newDagreD3 = true;
|
const newDagreD3 = true;
|
||||||
import dagreD3 from 'dagre-d3-unofficial';
|
import dagreD3 from 'dagre-d3';
|
||||||
// const newDagreD3 = false;
|
// const newDagreD3 = false;
|
||||||
|
|
||||||
import addHtmlLabel from 'dagre-d3-unofficial/lib/label/add-html-label.js';
|
import addHtmlLabel from 'dagre-d3/lib/label/add-html-label.js';
|
||||||
import { logger } from '../../logger';
|
import { logger } from '../../logger';
|
||||||
import { interpolateToCurve } from '../../utils';
|
import { interpolateToCurve } from '../../utils';
|
||||||
import flowChartShapes from './flowChartShapes';
|
import flowChartShapes from './flowChartShapes';
|
||||||
@@ -213,10 +213,10 @@ export const addEdges = function(edges, g) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'dotted':
|
case 'dotted':
|
||||||
style = 'stroke: #333; fill:none;stroke-width:2px;stroke-dasharray:3;';
|
style = 'fill:none;stroke-width:2px;stroke-dasharray:3;';
|
||||||
break;
|
break;
|
||||||
case 'thick':
|
case 'thick':
|
||||||
style = 'stroke: #333; stroke-width: 3.5px;fill:none';
|
style = ' stroke-width: 3.5px;fill:none';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -73,7 +73,7 @@ export const drawDescrState = (g, stateDef) => {
|
|||||||
const title = g
|
const title = g
|
||||||
.append('text')
|
.append('text')
|
||||||
.attr('x', 2 * getConfig().state.padding)
|
.attr('x', 2 * getConfig().state.padding)
|
||||||
.attr('y', getConfig().state.textHeight + 1.5 * getConfig().state.padding)
|
.attr('y', getConfig().state.textHeight + 1.3 * getConfig().state.padding)
|
||||||
.attr('font-size', getConfig().state.fontSize)
|
.attr('font-size', getConfig().state.fontSize)
|
||||||
.attr('class', 'state-title')
|
.attr('class', 'state-title')
|
||||||
.text(stateDef.descriptions[0]);
|
.text(stateDef.descriptions[0]);
|
||||||
@@ -87,7 +87,7 @@ export const drawDescrState = (g, stateDef) => {
|
|||||||
.attr(
|
.attr(
|
||||||
'y',
|
'y',
|
||||||
titleHeight +
|
titleHeight +
|
||||||
getConfig().state.padding * 0.2 +
|
getConfig().state.padding * 0.4 +
|
||||||
getConfig().state.dividerMargin +
|
getConfig().state.dividerMargin +
|
||||||
getConfig().state.textHeight
|
getConfig().state.textHeight
|
||||||
)
|
)
|
||||||
@@ -129,71 +129,108 @@ export const drawDescrState = (g, stateDef) => {
|
|||||||
* Adds the creates a box around the existing content and adds a
|
* Adds the creates a box around the existing content and adds a
|
||||||
* panel for the id on top of the content.
|
* panel for the id on top of the content.
|
||||||
*/
|
*/
|
||||||
export const addIdAndBox = (g, stateDef) => {
|
/**
|
||||||
// TODO Move hardcodings to conf
|
* Function that creates an title row and a frame around a substate for a composit state diagram.
|
||||||
// const addTspan = function(textEl, txt, isFirst) {
|
* The function returns a new d3 svg object with updated width and height properties;
|
||||||
// const tSpan = textEl
|
* @param {*} g The d3 svg object for the substate to framed
|
||||||
// .append('tspan')
|
* @param {*} stateDef The info about the
|
||||||
// .attr('x', 2 * getConfig().state.padding)
|
*/
|
||||||
// .text(txt);
|
export const addTitleAndBox = (g, stateDef, altBkg) => {
|
||||||
// if (!isFirst) {
|
const pad = getConfig().state.padding;
|
||||||
// tSpan.attr('dy', getConfig().state.textHeight);
|
const dblPad = 2 * getConfig().state.padding;
|
||||||
// }
|
const orgBox = g.node().getBBox();
|
||||||
// };
|
const orgWidth = orgBox.width;
|
||||||
|
const orgX = orgBox.x;
|
||||||
|
|
||||||
const title = g
|
const title = g
|
||||||
.append('text')
|
.append('text')
|
||||||
.attr('x', 2 * getConfig().state.padding)
|
.attr('x', 0)
|
||||||
.attr('y', getConfig().state.titleShift)
|
.attr('y', getConfig().state.titleShift)
|
||||||
.attr('font-size', getConfig().state.fontSize)
|
.attr('font-size', getConfig().state.fontSize)
|
||||||
.attr('class', 'state-title')
|
.attr('class', 'state-title')
|
||||||
.text(stateDef.id);
|
.text(stateDef.id);
|
||||||
|
|
||||||
const titleBox = title.node().getBBox();
|
const titleBox = title.node().getBBox();
|
||||||
|
const titleWidth = titleBox.width + dblPad;
|
||||||
const lineY = 1 - getConfig().state.textHeight;
|
let width = Math.max(titleWidth, orgWidth); // + dblPad;
|
||||||
const descrLine = g
|
if (width === orgWidth) {
|
||||||
.append('line') // text label for the x axis
|
width = width + dblPad;
|
||||||
.attr('x1', 0)
|
}
|
||||||
.attr('y1', lineY)
|
let startX;
|
||||||
.attr('y2', lineY)
|
// const lineY = 1 - getConfig().state.textHeight;
|
||||||
.attr('class', 'descr-divider');
|
// const descrLine = g
|
||||||
|
// .append('line') // text label for the x axis
|
||||||
|
// .attr('x1', 0)
|
||||||
|
// .attr('y1', lineY)
|
||||||
|
// .attr('y2', lineY)
|
||||||
|
// .attr('class', 'descr-divider');
|
||||||
|
|
||||||
const graphBox = g.node().getBBox();
|
const graphBox = g.node().getBBox();
|
||||||
title.attr('x', graphBox.width / 2 - titleBox.width / 2);
|
// console.warn(width / 2, titleWidth / 2, getConfig().state.padding, orgBox);
|
||||||
descrLine.attr('x2', graphBox.width + getConfig().state.padding);
|
// descrLine.attr('x2', graphBox.width + getConfig().state.padding);
|
||||||
|
|
||||||
|
if (stateDef.doc) {
|
||||||
|
// cnsole.warn(
|
||||||
|
// stateDef.id,
|
||||||
|
// 'orgX: ',
|
||||||
|
// orgX,
|
||||||
|
// 'width: ',
|
||||||
|
// width,
|
||||||
|
// 'titleWidth: ',
|
||||||
|
// titleWidth,
|
||||||
|
// 'orgWidth: ',
|
||||||
|
// orgWidth,
|
||||||
|
// 'width',
|
||||||
|
// width
|
||||||
|
// );
|
||||||
|
}
|
||||||
|
|
||||||
|
startX = orgX - pad;
|
||||||
|
if (titleWidth > orgWidth) {
|
||||||
|
startX = (orgWidth - width) / 2 + pad;
|
||||||
|
}
|
||||||
|
if (Math.abs(orgX - graphBox.x) < pad) {
|
||||||
|
if (titleWidth > orgWidth) {
|
||||||
|
startX = orgX - (titleWidth - orgWidth) / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const lineY = 1 - getConfig().state.textHeight;
|
||||||
// White color
|
// White color
|
||||||
g.insert('rect', ':first-child')
|
g.insert('rect', ':first-child')
|
||||||
.attr('x', graphBox.x)
|
.attr('x', startX)
|
||||||
.attr('y', lineY)
|
.attr('y', lineY)
|
||||||
.attr('class', 'composit')
|
.attr('class', altBkg ? 'alt-composit' : 'composit')
|
||||||
.attr('width', graphBox.width + getConfig().state.padding)
|
.attr('width', width)
|
||||||
.attr(
|
.attr(
|
||||||
'height',
|
'height',
|
||||||
graphBox.height + getConfig().state.textHeight + getConfig().state.titleShift + 1
|
graphBox.height + getConfig().state.textHeight + getConfig().state.titleShift + 1
|
||||||
)
|
)
|
||||||
.attr('rx', '0');
|
.attr('rx', '0');
|
||||||
|
|
||||||
|
title.attr('x', startX + pad);
|
||||||
|
if (titleWidth <= orgWidth) title.attr('x', orgX + (width - dblPad) / 2 - titleWidth / 2 + pad);
|
||||||
|
|
||||||
// Title background
|
// Title background
|
||||||
g.insert('rect', ':first-child')
|
g.insert('rect', ':first-child')
|
||||||
.attr('x', graphBox.x)
|
.attr('x', startX)
|
||||||
.attr(
|
.attr(
|
||||||
'y',
|
'y',
|
||||||
getConfig().state.titleShift - getConfig().state.textHeight - getConfig().state.padding
|
getConfig().state.titleShift - getConfig().state.textHeight - getConfig().state.padding
|
||||||
)
|
)
|
||||||
.attr('width', graphBox.width + getConfig().state.padding)
|
.attr('width', width)
|
||||||
// Just needs to be higher then the descr line, will be clipped by the white color box
|
// Just needs to be higher then the descr line, will be clipped by the white color box
|
||||||
.attr('height', getConfig().state.textHeight * 3)
|
.attr('height', getConfig().state.textHeight * 3)
|
||||||
.attr('rx', getConfig().state.radius);
|
.attr('rx', getConfig().state.radius);
|
||||||
|
|
||||||
// Full background
|
// Full background
|
||||||
g.insert('rect', ':first-child')
|
g.insert('rect', ':first-child')
|
||||||
.attr('x', graphBox.x)
|
.attr('x', startX)
|
||||||
.attr(
|
.attr(
|
||||||
'y',
|
'y',
|
||||||
getConfig().state.titleShift - getConfig().state.textHeight - getConfig().state.padding
|
getConfig().state.titleShift - getConfig().state.textHeight - getConfig().state.padding
|
||||||
)
|
)
|
||||||
.attr('width', graphBox.width + getConfig().state.padding)
|
.attr('width', width)
|
||||||
.attr('height', graphBox.height + 3 + 2 * getConfig().state.textHeight)
|
.attr('height', graphBox.height + 3 + 2 * getConfig().state.textHeight)
|
||||||
.attr('rx', getConfig().state.radius);
|
.attr('rx', getConfig().state.radius);
|
||||||
|
|
||||||
|
@@ -5,40 +5,19 @@ import { logger } from '../../logger';
|
|||||||
import stateDb from './stateDb';
|
import stateDb from './stateDb';
|
||||||
import { parser } from './parser/stateDiagram';
|
import { parser } from './parser/stateDiagram';
|
||||||
// import idCache from './id-cache';
|
// import idCache from './id-cache';
|
||||||
import { drawState, addIdAndBox, drawEdge } from './shapes';
|
import { drawState, addTitleAndBox, drawEdge } from './shapes';
|
||||||
import { getConfig } from '../../config';
|
import { getConfig } from '../../config';
|
||||||
|
|
||||||
parser.yy = stateDb;
|
parser.yy = stateDb;
|
||||||
|
|
||||||
// TODO Move conf object to main conf in mermaidAPI
|
// TODO Move conf object to main conf in mermaidAPI
|
||||||
let conf;
|
let conf;
|
||||||
// {
|
|
||||||
// // Used
|
|
||||||
// padding: 5,
|
|
||||||
// // Font size factor, this is used to guess the width of the edges labels before rendering by dagre
|
|
||||||
// // layout. This might need updating if/when switching font
|
|
||||||
// fontSizeFactor: 5.02,
|
|
||||||
// labelHeight: 16,
|
|
||||||
// edgeLengthFactor: '20',
|
|
||||||
// compositTitleSize: 35
|
|
||||||
// };
|
|
||||||
|
|
||||||
const transformationLog = {};
|
const transformationLog = {};
|
||||||
|
|
||||||
export const setConf = function() {};
|
export const setConf = function() {};
|
||||||
|
|
||||||
// Todo optimize
|
// Todo optimize
|
||||||
// const getGraphId = function(label) {
|
|
||||||
// const keys = idCache.keys();
|
|
||||||
|
|
||||||
// for (let i = 0; i < keys.length; i++) {
|
|
||||||
// if (idCache.get(keys[i]).label === label) {
|
|
||||||
// return keys[i];
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return undefined;
|
|
||||||
// };
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setup arrow head and define the marker. The result is appended to the svg.
|
* Setup arrow head and define the marker. The result is appended to the svg.
|
||||||
@@ -68,11 +47,11 @@ export const draw = function(text, id) {
|
|||||||
parser.parse(text);
|
parser.parse(text);
|
||||||
logger.debug('Rendering diagram ' + text);
|
logger.debug('Rendering diagram ' + text);
|
||||||
|
|
||||||
// /// / Fetch the default direction, use TD if none was found
|
// Fetch the default direction, use TD if none was found
|
||||||
const diagram = d3.select(`[id='${id}']`);
|
const diagram = d3.select(`[id='${id}']`);
|
||||||
insertMarkers(diagram);
|
insertMarkers(diagram);
|
||||||
|
|
||||||
// // Layout graph, Create a new directed graph
|
// Layout graph, Create a new directed graph
|
||||||
const graph = new graphlib.Graph({
|
const graph = new graphlib.Graph({
|
||||||
multigraph: false,
|
multigraph: false,
|
||||||
compound: true,
|
compound: true,
|
||||||
@@ -81,13 +60,13 @@ export const draw = function(text, id) {
|
|||||||
// ranksep: '20'
|
// ranksep: '20'
|
||||||
});
|
});
|
||||||
|
|
||||||
// // Default to assigning a new object as a label for each new edge.
|
// Default to assigning a new object as a label for each new edge.
|
||||||
graph.setDefaultEdgeLabel(function() {
|
graph.setDefaultEdgeLabel(function() {
|
||||||
return {};
|
return {};
|
||||||
});
|
});
|
||||||
|
|
||||||
const rootDoc = stateDb.getRootDoc();
|
const rootDoc = stateDb.getRootDoc();
|
||||||
renderDoc(rootDoc, diagram);
|
renderDoc(rootDoc, diagram, undefined, false);
|
||||||
|
|
||||||
const padding = conf.padding;
|
const padding = conf.padding;
|
||||||
const bounds = diagram.node().getBBox();
|
const bounds = diagram.node().getBBox();
|
||||||
@@ -100,7 +79,7 @@ export const draw = function(text, id) {
|
|||||||
// diagram.attr('height', height);
|
// diagram.attr('height', height);
|
||||||
|
|
||||||
// Zoom in a bit
|
// Zoom in a bit
|
||||||
diagram.attr('width', width * 2);
|
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',
|
||||||
@@ -128,12 +107,21 @@ const getRows = s => {
|
|||||||
return str.split('#br#');
|
return str.split('#br#');
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderDoc = (doc, diagram, parentId) => {
|
const renderDoc = (doc, diagram, parentId, altBkg) => {
|
||||||
// // Layout graph, Create a new directed graph
|
// // Layout graph, Create a new directed graph
|
||||||
const graph = new graphlib.Graph({
|
const graph = new graphlib.Graph({
|
||||||
compound: true
|
compound: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let i;
|
||||||
|
let edgeFreeDoc = true;
|
||||||
|
for (i = 0; i < doc.length; i++) {
|
||||||
|
if (doc[i].stmt === 'relation') {
|
||||||
|
edgeFreeDoc = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Set an object for the graph label
|
// Set an object for the graph label
|
||||||
if (parentId)
|
if (parentId)
|
||||||
graph.setGraph({
|
graph.setGraph({
|
||||||
@@ -142,8 +130,11 @@ const renderDoc = (doc, diagram, parentId) => {
|
|||||||
compound: true,
|
compound: true,
|
||||||
// acyclicer: 'greedy',
|
// acyclicer: 'greedy',
|
||||||
ranker: 'tight-tree',
|
ranker: 'tight-tree',
|
||||||
ranksep: conf.edgeLengthFactor
|
ranksep: edgeFreeDoc ? 1 : conf.edgeLengthFactor,
|
||||||
|
nodeSep: edgeFreeDoc ? 1 : 50
|
||||||
// isMultiGraph: false
|
// isMultiGraph: false
|
||||||
|
// ranksep: 5,
|
||||||
|
// nodesep: 1
|
||||||
});
|
});
|
||||||
else {
|
else {
|
||||||
graph.setGraph({
|
graph.setGraph({
|
||||||
@@ -152,7 +143,8 @@ const renderDoc = (doc, diagram, parentId) => {
|
|||||||
// isCompound: true,
|
// isCompound: true,
|
||||||
// acyclicer: 'greedy',
|
// acyclicer: 'greedy',
|
||||||
// ranker: 'longest-path'
|
// ranker: 'longest-path'
|
||||||
ranksep: conf.edgeLengthFactor,
|
ranksep: edgeFreeDoc ? 1 : conf.edgeLengthFactor,
|
||||||
|
nodeSep: edgeFreeDoc ? 1 : 50,
|
||||||
ranker: 'tight-tree'
|
ranker: 'tight-tree'
|
||||||
// ranker: 'network-simplex'
|
// ranker: 'network-simplex'
|
||||||
// isMultiGraph: false
|
// isMultiGraph: false
|
||||||
@@ -185,14 +177,14 @@ const renderDoc = (doc, diagram, parentId) => {
|
|||||||
.append('g')
|
.append('g')
|
||||||
.attr('id', stateDef.id)
|
.attr('id', stateDef.id)
|
||||||
.attr('class', 'stateGroup');
|
.attr('class', 'stateGroup');
|
||||||
node = renderDoc(stateDef.doc, sub, stateDef.id);
|
node = renderDoc(stateDef.doc, sub, stateDef.id, !altBkg);
|
||||||
|
|
||||||
if (first) {
|
if (first) {
|
||||||
// first = false;
|
// first = false;
|
||||||
sub = addIdAndBox(sub, stateDef);
|
sub = addTitleAndBox(sub, stateDef, altBkg);
|
||||||
let boxBounds = sub.node().getBBox();
|
let boxBounds = sub.node().getBBox();
|
||||||
node.width = boxBounds.width;
|
node.width = boxBounds.width;
|
||||||
node.height = boxBounds.height + 2 * conf.padding;
|
node.height = boxBounds.height + conf.padding / 2;
|
||||||
transformationLog[stateDef.id] = { y: conf.compositTitleSize };
|
transformationLog[stateDef.id] = { y: conf.compositTitleSize };
|
||||||
} else {
|
} else {
|
||||||
// sub = addIdAndBox(sub, stateDef);
|
// sub = addIdAndBox(sub, stateDef);
|
||||||
@@ -278,8 +270,8 @@ const renderDoc = (doc, diagram, parentId) => {
|
|||||||
pShift = 0;
|
pShift = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
divider.setAttribute('x1', 0 - pShift);
|
divider.setAttribute('x1', 0 - pShift + 8);
|
||||||
divider.setAttribute('x2', pWidth - pShift);
|
divider.setAttribute('x2', pWidth - pShift - 8);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
logger.debug('No Node ' + v + ': ' + JSON.stringify(graph.node(v)));
|
logger.debug('No Node ' + v + ': ' + JSON.stringify(graph.node(v)));
|
||||||
|
@@ -37,6 +37,11 @@ g.stateGroup line {
|
|||||||
border-bottom: 1px
|
border-bottom: 1px
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.stateGroup .alt-composit {
|
||||||
|
fill: #e0e0e0;
|
||||||
|
border-bottom: 1px
|
||||||
|
}
|
||||||
|
|
||||||
.state-note {
|
.state-note {
|
||||||
stroke: $noteBorderColor;
|
stroke: $noteBorderColor;
|
||||||
fill: $noteBkgColor;
|
fill: $noteBkgColor;
|
||||||
|
@@ -40,10 +40,7 @@ export const jsConfig = () => {
|
|||||||
mermaid: './src/mermaid.js'
|
mermaid: './src/mermaid.js'
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
extensions: ['.wasm', '.mjs', '.js', '.json', '.jison'],
|
extensions: ['.wasm', '.mjs', '.js', '.json', '.jison']
|
||||||
alias: {
|
|
||||||
'dagre-d3': 'dagre-d3-unofficial'
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
node: {
|
node: {
|
||||||
fs: 'empty' // jison generated code requires 'fs'
|
fs: 'empty' // jison generated code requires 'fs'
|
||||||
|
Reference in New Issue
Block a user