Merge branch 'develop'

Conflicts:
	cypress/platform/knsv.html
This commit is contained in:
Knut Sveidqvist 2022-08-28 14:22:56 +02:00
commit 6ab0eef6f3
18 changed files with 155 additions and 97 deletions

5
.gitignore vendored
View File

@ -22,4 +22,7 @@ Gemfile.lock
/.vs
cypress/screenshots/
cypress/snapshots/
cypress/snapshots/
# eslint --cache file
.eslintcache

View File

@ -112,7 +112,7 @@ describe('Entity Relationship Diagram', () => {
);
cy.get('svg').should((svg) => {
expect(svg).to.have.attr('width', '100%');
expect(svg).to.have.attr('height', '465');
// expect(svg).to.have.attr('height', '465');
const style = svg.attr('style');
expect(style).to.match(/^max-width: [\d.]+px;$/);
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
@ -134,7 +134,7 @@ describe('Entity Relationship Diagram', () => {
const width = parseFloat(svg.attr('width'));
// use within because the absolute value can be slightly different depending on the environment ±5%
expect(width).to.be.within(140 * 0.95, 140 * 1.05);
expect(svg).to.have.attr('height', '465');
// expect(svg).to.have.attr('height', '465');
expect(svg).to.not.have.attr('style');
});
});
@ -186,7 +186,7 @@ describe('Entity Relationship Diagram', () => {
renderGraph(
`
erDiagram
PRIVATE_FINANCIAL_INSTITUTION {
PRIVATE_FINANCIAL_INSTITUTION {
string name
int turnover
}
@ -206,9 +206,9 @@ describe('Entity Relationship Diagram', () => {
string name PK
}
AUTHOR_WITH_LONG_ENTITY_NAME }|..|{ BOOK : writes
BOOK {
BOOK {
float price
string author FK
string author FK
string title PK
}
`,
@ -225,8 +225,8 @@ describe('Entity Relationship Diagram', () => {
string name "comment"
}
AUTHOR_WITH_LONG_ENTITY_NAME }|..|{ BOOK : writes
BOOK {
string author
BOOK {
string author
string title "author comment"
float price "price comment"
}
@ -244,11 +244,11 @@ describe('Entity Relationship Diagram', () => {
string name PK "comment"
}
AUTHOR_WITH_LONG_ENTITY_NAME }|..|{ BOOK : writes
BOOK {
BOOK {
string description
float price "price comment"
string title PK "title comment"
string author FK
string author FK
}
`,
{ logLevel: 1 }

View File

@ -42,7 +42,7 @@ describe('Flowchart v2', () => {
P3 --> P6
P1.5 --> P5
`,
{ flowchart: { diagramPadding: 0 } }
{}
);
});
@ -60,7 +60,7 @@ describe('Flowchart v2', () => {
C <-...-> E4
C ======> E5
`,
{ flowchart: { diagramPadding: 0 } }
{}
);
});
it('5: should render escaped without html labels', () => {
@ -92,10 +92,10 @@ describe('Flowchart v2', () => {
);
cy.get('svg').should((svg) => {
expect(svg).to.have.attr('width', '100%');
expect(svg).to.have.attr('height');
// expect(svg).to.have.attr('height');
// use within because the absolute value can be slightly different depending on the environment ±5%
const height = parseFloat(svg.attr('height'));
expect(height).to.be.within(446 * 0.95, 446 * 1.05);
// const height = parseFloat(svg.attr('height'));
// expect(height).to.be.within(446 * 0.95, 446 * 1.05);
const style = svg.attr('style');
expect(style).to.match(/^max-width: [\d.]+px;$/);
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
@ -114,10 +114,10 @@ describe('Flowchart v2', () => {
{ flowchart: { useMaxWidth: false } }
);
cy.get('svg').should((svg) => {
const height = parseFloat(svg.attr('height'));
// const height = parseFloat(svg.attr('height'));
const width = parseFloat(svg.attr('width'));
// use within because the absolute value can be slightly different depending on the environment ±5%
expect(height).to.be.within(446 * 0.95, 446 * 1.05);
// expect(height).to.be.within(446 * 0.95, 446 * 1.05);
expect(width).to.be.within(290 * 0.95 - 1, 290 * 1.05);
expect(svg).to.not.have.attr('style');
});
@ -652,4 +652,15 @@ flowchart RL
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
it('2824: Clipping of edges', () => {
imgSnapshotTest(
`
flowchart TD
A --> B
A --> C
B --> C
`,
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
});

View File

@ -744,10 +744,10 @@ describe('Graph', () => {
);
cy.get('svg').should((svg) => {
expect(svg).to.have.attr('width', '100%');
expect(svg).to.have.attr('height');
// expect(svg).to.have.attr('height');
// use within because the absolute value can be slightly different depending on the environment ±5%
const height = parseFloat(svg.attr('height'));
expect(height).to.be.within(446 * 0.95, 446 * 1.05);
// const height = parseFloat(svg.attr('height'));
// expect(height).to.be.within(446 * 0.95, 446 * 1.05);
const style = svg.attr('style');
expect(style).to.match(/^max-width: [\d.]+px;$/);
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
@ -766,10 +766,10 @@ describe('Graph', () => {
{ flowchart: { useMaxWidth: false } }
);
cy.get('svg').should((svg) => {
const height = parseFloat(svg.attr('height'));
// const height = parseFloat(svg.attr('height'));
const width = parseFloat(svg.attr('width'));
// use within because the absolute value can be slightly different depending on the environment ±5%
expect(height).to.be.within(446 * 0.95, 446 * 1.05);
// expect(height).to.be.within(446 * 0.95, 446 * 1.05);
expect(width).to.be.within(300 * 0.95, 300 * 1.05);
expect(svg).to.not.have.attr('style');
});

View File

@ -218,10 +218,10 @@ describe('Gantt diagram', () => {
);
cy.get('svg').should((svg) => {
expect(svg).to.have.attr('width', '100%');
expect(svg).to.have.attr('height');
// expect(svg).to.have.attr('height');
// use within because the absolute value can be slightly different depending on the environment ±5%
const height = parseFloat(svg.attr('height'));
expect(height).to.be.within(484 * 0.95, 484 * 1.05);
// const height = parseFloat(svg.attr('height'));
// expect(height).to.be.within(484 * 0.95, 484 * 1.05);
const style = svg.attr('style');
expect(style).to.match(/^max-width: [\d.]+px;$/);
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
@ -265,10 +265,10 @@ describe('Gantt diagram', () => {
{ gantt: { useMaxWidth: false } }
);
cy.get('svg').should((svg) => {
const height = parseFloat(svg.attr('height'));
// const height = parseFloat(svg.attr('height'));
const width = parseFloat(svg.attr('width'));
// use within because the absolute value can be slightly different depending on the environment ±5%
expect(height).to.be.within(484 * 0.95, 484 * 1.05);
// expect(height).to.be.within(484 * 0.95, 484 * 1.05);
expect(width).to.be.within(984 * 0.95, 984 * 1.05);
expect(svg).to.not.have.attr('style');
});

View File

@ -42,8 +42,8 @@ section Checkout from website
cy.get('svg').should((svg) => {
expect(svg).to.have.attr('width', '100%');
expect(svg).to.have.attr('height');
const height = parseFloat(svg.attr('height'));
expect(height).to.eq(565);
// const height = parseFloat(svg.attr('height'));
// expect(height).to.eq(565);
const style = svg.attr('style');
expect(style).to.match(/^max-width: [\d.]+px;$/);
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));

View File

@ -48,9 +48,9 @@ describe('Pie Chart', () => {
);
cy.get('svg').should((svg) => {
expect(svg).to.have.attr('width', '100%');
expect(svg).to.have.attr('height');
const height = parseFloat(svg.attr('height'));
expect(height).to.eq(450);
// expect(svg).to.have.attr('height');
// const height = parseFloat(svg.attr('height'));
// expect(height).to.eq(450);
const style = svg.attr('style');
expect(style).to.match(/^max-width: [\d.]+px;$/);
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
@ -68,9 +68,9 @@ describe('Pie Chart', () => {
{ pie: { useMaxWidth: false } }
);
cy.get('svg').should((svg) => {
const height = parseFloat(svg.attr('height'));
// const height = parseFloat(svg.attr('height'));
const width = parseFloat(svg.attr('width'));
expect(height).to.eq(450);
// expect(height).to.eq(450);
expect(width).to.eq(984);
expect(svg).to.not.have.attr('style');
});

View File

@ -734,9 +734,9 @@ context('Sequence diagram', () => {
);
cy.get('svg').should((svg) => {
expect(svg).to.have.attr('width', '100%');
expect(svg).to.have.attr('height');
const height = parseFloat(svg.attr('height'));
expect(height).to.be.within(920, 971);
// expect(svg).to.have.attr('height');
// const height = parseFloat(svg.attr('height'));
// expect(height).to.be.within(920, 971);
const style = svg.attr('style');
expect(style).to.match(/^max-width: [\d.]+px;$/);
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
@ -773,9 +773,9 @@ context('Sequence diagram', () => {
{ sequence: { useMaxWidth: false } }
);
cy.get('svg').should((svg) => {
const height = parseFloat(svg.attr('height'));
// const height = parseFloat(svg.attr('height'));
const width = parseFloat(svg.attr('width'));
expect(height).to.be.within(920, 971);
// expect(height).to.be.within(920, 971);
// use within because the absolute value can be slightly different depending on the environment ±5%
expect(width).to.be.within(820 * 0.95, 820 * 1.05);
expect(svg).to.not.have.attr('style');

View File

@ -480,14 +480,14 @@ stateDiagram-v2
);
cy.get('svg').should((svg) => {
expect(svg).to.have.attr('width', '100%');
expect(svg).to.have.attr('height');
const height = parseFloat(svg.attr('height'));
expect(height).to.be.within(177, 178);
// expect(svg).to.have.attr('height');
// const height = parseFloat(svg.attr('height'));
// expect(height).to.be.within(177, 178);
const style = svg.attr('style');
expect(style).to.match(/^max-width: [\d.]+px;$/);
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
// use within because the absolute value can be slightly different depending on the environment ±5%
expect(maxWidthValue).to.be.within(135 * 0.95, 135 * 1.05);
expect(maxWidthValue).to.be.within(65, 85);
});
});
it('v2 should render a state diagram when useMaxWidth is false', () => {
@ -501,11 +501,11 @@ stateDiagram-v2
{ state: { useMaxWidth: false } }
);
cy.get('svg').should((svg) => {
const height = parseFloat(svg.attr('height'));
// const height = parseFloat(svg.attr('height'));
const width = parseFloat(svg.attr('width'));
expect(height).to.be.within(177, 178);
// expect(height).to.be.within(177, 178);
// use within because the absolute value can be slightly different depending on the environment ±5%
expect(width).to.be.within(135 * 0.95, 135 * 1.05);
expect(width).to.be.within(65, 85);
expect(svg).to.not.have.attr('style');
});
});

View File

@ -357,16 +357,16 @@ describe('State diagram', () => {
);
cy.get('svg').should((svg) => {
expect(svg).to.have.attr('width', '100%');
expect(svg).to.have.attr('height');
const height = parseFloat(svg.attr('height'));
expect(height).to.be.within(176, 178);
// expect(svg).to.have.attr('height');
// const height = parseFloat(svg.attr('height'));
// expect(height).to.be.within(176, 178);
const style = svg.attr('style');
expect(style).to.match(/^max-width: [\d.]+px;$/);
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
// use within because the absolute value can be slightly different depending on the environment ±5%
// Todo investigate difference
// expect(maxWidthValue).to.be.within(112 * .95, 112 * 1.05);
expect(maxWidthValue).to.be.within(130, 140);
expect(maxWidthValue).to.be.within(65, 85);
});
});
it('should render a state diagram when useMaxWidth is false', () => {
@ -379,13 +379,13 @@ describe('State diagram', () => {
{ state: { useMaxWidth: false } }
);
cy.get('svg').should((svg) => {
const height = parseFloat(svg.attr('height'));
// const height = parseFloat(svg.attr('height'));
const width = parseFloat(svg.attr('width'));
expect(height).to.be.within(176, 178);
// expect(height).to.be.within(176, 178);
// use within because the absolute value can be slightly different depending on the environment ±5%
// Todo investigate difference
// expect(width).to.be.within(112 * .95, 112 * 1.05);
expect(width).to.be.within(130, 140);
expect(width).to.be.within(65, 85);
expect(svg).to.not.have.attr('style');
});

View File

@ -23,12 +23,11 @@
.mermaid2,.mermaid3 {
display: none;
}
.mermaid {
border: 1px solid purple;
}
.mermaid svg {
border: 1px solid purple;
/* font-size: 18px !important; */
border: 1px solid red;
fontFamily: 'courier'
}
</style>
</head>
@ -56,7 +55,7 @@ flowchart LR
O0 -- has type -->O2["Bug"]
click O0 function "Lots of great info about Joe<br>Lots of great info about Joe<br>burt<br>fred";
</div>
<div class="mermaid" style="width: 50%;">
<div class="mermaid2" style="width: 50%;">
flowchart TD
subgraph test
direction TB
@ -152,7 +151,6 @@ mindmap
GrandChild2
Child5((Child5))
:::disabled
GrandChild7
sc1
sc2
@ -160,6 +158,17 @@ mindmap
GrandChild7
</div>
<div class="mermaid" style="width: 50%;">
flowchart TD
id
</div>
<div class="mermaid2" style="width: 50%;">
flowchart LR
a["<strong>Haiya</strong>"]===>b
</div>
<div class="mermaid2" style="width: 50%;">
flowchart TD
</div>
<div class="mermaid2" style="width: 50%;">
pie
accTitle: My Pie Chart Accessibility Title
@ -168,9 +177,20 @@ mindmap
A --> B
A --> C
B --> C
</div>
<div class="mermaid2" style="width: 50%;">
flowchart TD
A([stadium 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;
gitGraph TB
commit
commit
@ -415,16 +435,17 @@ flowchart TD
// console.error('Mermaid error: ', err);
};
mermaid.initialize({
// theme: 'dark',
theme: 'base',
// arrowMarkerAbsolute: true,
// themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
maxTextSize: 900000,
startOnLoad: true,
securityLevel: 'loose',
logLevel: 0,
fontFamily: 'courier',
flowchart: {
curve: 'curveLinear',
// curve: 'curveLinear',
useMaxWidth: true,
htmlLabels: true,
htmlLabels: false,
fontFamily: 'courier',
},
logLevel: 1,
fontSize: 18,
curve: 'cardinal',
// securityLevel: 'sandbox',

View File

@ -522,6 +522,22 @@ In the example below the style defined in the linkStyle statement will belong to
linkStyle 3 stroke:#ff3,stroke-width:4px,color:red;
```
### Styling line curves
It is possible to style the type of curve used for lines between items, if the default method does not meet your needs.
Available curve styles include `basis`, `bump`, `linear`, `monotoneX`, `monotoneY`, `natural`, `step`, `stepAfter`,
and `stepBefore`.
In this example, a left-to-right graph uses the `stepBefore` curve style:
```
%%{ init: { 'flowchart': { 'curve': 'stepBefore' } } }%%
graph LR
```
For a full list of available curves, including an explanation of custom curves, refer to
the [Shapes](https://github.com/d3/d3-shape/blob/main/README.md#curves) documentation in the
[d3-shape](https://github.com/d3/d3-shape/) project.
### Styling a node

View File

@ -18,7 +18,7 @@
<!-- <link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/vue.css"> -->
<link rel="stylesheet" href="theme.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/all.min.css">
<script src="//cdn.jsdelivr.net/npm/mermaid@9.1.5/dist/mermaid.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/mermaid@9.1.6/dist/mermaid.min.js"></script>
<!-- <script src="http://localhost:9000/mermaid.js"></script> -->
<script>
// prettier-ignore

View File

@ -27,7 +27,7 @@
"postbuild": "documentation build src/mermaidAPI.js src/config.js src/defaultConfig.js --shallow -f md --markdown-toc false > docs/Setup.md",
"build:watch": "yarn build:development --watch",
"release": "yarn build",
"lint": "eslint ./ --ext .js,.json,.html,.md",
"lint": "eslint --cache ./ --ext .js,.json,.html,.md",
"lint:fix": "yarn lint --fix",
"e2e:depr": "yarn lint && jest e2e --config e2e/jest.config.js",
"cypress": "cypress run",

View File

@ -388,8 +388,8 @@ export const draw = function (text, id, _version, diagObj) {
rankdir: dir,
nodesep: nodeSpacing,
ranksep: rankSpacing,
marginx: 8,
marginy: 8,
marginx: 0,
marginy: 0,
})
.setDefaultEdgeLabel(function () {
return {};

View File

@ -305,7 +305,7 @@ export const draw = function (text, id, _version, diag) {
const svgBounds = svg.node().getBBox();
configureSvgSize(svg, height, width * 1.75, conf.useMaxWidth);
configureSvgSize(svg, height, width, conf.useMaxWidth);
// Ensure the viewBox includes the whole svgBounds area with extra space for padding
const vBox = `${svgBounds.x - padding} ${svgBounds.y - padding} ${width} ${height}`;

View File

@ -742,7 +742,7 @@ const d3Attrs = function (d3Elem, attrs) {
*/
export const calculateSvgSizeAttrs = function (height, width, useMaxWidth) {
let attrs = new Map();
attrs.set('height', height);
// attrs.set('height', height);
if (useMaxWidth) {
attrs.set('width', '100%');
attrs.set('style', `max-width: ${width}px;`);
@ -761,7 +761,7 @@ export const calculateSvgSizeAttrs = function (height, width, useMaxWidth) {
* @param {boolean} useMaxWidth Whether or not to use max-width and set width to 100%
*/
export const configureSvgSize = function (svgElem, height, width, useMaxWidth) {
const attrs = calculateSvgSizeAttrs(height, width, useMaxWidth);
const attrs = calculateSvgSizeAttrs(height, 1 * width, useMaxWidth);
d3Attrs(svgElem, attrs);
};
export const setupGraphViewbox = function (graph, svgElem, padding, useMaxWidth) {
@ -769,27 +769,37 @@ export const setupGraphViewbox = function (graph, svgElem, padding, useMaxWidth)
const sWidth = svgBounds.width;
const sHeight = svgBounds.height;
log.info(`SVG bounds: ${sWidth}x${sHeight}`, svgBounds);
let width = graph._label.width;
let height = graph._label.height;
let tx = 0;
let ty = 0;
if (sWidth > width) {
tx = (sWidth - width) / 2 + padding;
width = sWidth + padding * 2;
} else {
if (Math.abs(sWidth - width) >= 2 * padding + 1) {
width = width - padding;
}
}
if (sHeight > height) {
ty = (sHeight - height) / 2 + padding;
height = sHeight + padding * 2;
}
log.info(`Graph bounds: ${width}x${height}`, graph);
// let tx = 0;
// let ty = 0;
// if (sWidth > width) {
// tx = (sWidth - width) / 2 + padding;
width = sWidth + padding * 2;
// } else {
// if (Math.abs(sWidth - width) >= 2 * padding + 1) {
// width = width - padding;
// }
// }
// if (sHeight > height) {
// ty = (sHeight - height) / 2 + padding;
height = sHeight + padding * 2;
// }
// width =
log.info(`Calculated bounds: ${width}x${height}`);
configureSvgSize(svgElem, height, width, useMaxWidth);
// Ensure the viewBox includes the whole svgBounds area with extra space for padding
const vBox = `0 0 ${width} ${height}`;
log.debug(
// const vBox = `0 0 ${width} ${height}`;
const vBox = `${svgBounds.x - padding} ${svgBounds.y - padding} ${
svgBounds.width + 2 * padding
} ${svgBounds.height + 2 * padding}`;
log.info(
'Graph.label',
graph._label,
'swidth',
@ -800,15 +810,12 @@ export const setupGraphViewbox = function (graph, svgElem, padding, useMaxWidth)
width,
'height',
height,
'tx',
tx,
'ty',
ty,
'vBox',
vBox
);
svgElem.attr('viewBox', vBox);
svgElem.select('g').attr('transform', `translate(${tx}, ${ty})`);
// svgElem.select('g').attr('transform', `translate(${tx}, ${ty})`);
};
export const initIdGenerator = class iterator {

View File

@ -294,13 +294,13 @@ describe('when formatting urls', function () {
describe('when calculating SVG size', function () {
it('should return width 100% when useMaxWidth is true', function () {
const attrs = utils.calculateSvgSizeAttrs(100, 200, true);
expect(attrs.get('height')).toEqual(100);
// expect(attrs.get('height')).toEqual(100);
expect(attrs.get('style')).toEqual('max-width: 200px;');
expect(attrs.get('width')).toEqual('100%');
});
it('should return absolute width when useMaxWidth is false', function () {
const attrs = utils.calculateSvgSizeAttrs(100, 200, false);
expect(attrs.get('height')).toEqual(100);
// expect(attrs.get('height')).toEqual(100);
expect(attrs.get('width')).toEqual(200);
});
});