diff --git a/cypress/helpers/util.js b/cypress/helpers/util.js
index aa04f7ae6..b075659f0 100644
--- a/cypress/helpers/util.js
+++ b/cypress/helpers/util.js
@@ -1,4 +1,5 @@
/* eslint-env jest */
+/* global cy */
import { Base64 } from 'js-base64';
export const mermaidUrl = (graphStr, options, api) => {
diff --git a/cypress/integration/rendering/classDiagram.spec.js b/cypress/integration/rendering/classDiagram.spec.js
index 84de183c8..3882b9e99 100644
--- a/cypress/integration/rendering/classDiagram.spec.js
+++ b/cypress/integration/rendering/classDiagram.spec.js
@@ -1,5 +1,5 @@
/* eslint-env jest */
-import { imgSnapshotTest } from '../../helpers/util';
+import { imgSnapshotTest, renderGraph } from '../../helpers/util';
describe('Class diagram', () => {
it('1: should render a simple class diagram', () => {
@@ -65,7 +65,7 @@ describe('Class diagram', () => {
cy.get('svg');
});
- it('should render a simple class diagram with different visibilities', () => {
+ it('3: should render a simple class diagram with different visibilities', () => {
imgSnapshotTest(
`
classDiagram
@@ -83,59 +83,6 @@ describe('Class diagram', () => {
cy.get('svg');
});
- it('should render multiple class diagrams', () => {
- imgSnapshotTest(
- [
- `
- classDiagram
- Class01 "1" <|--|> "*" AveryLongClass : Cool
- <<interface>> Class01
- Class03 "1" *-- "*" Class04
- Class05 "1" o-- "many" Class06
- Class07 "1" .. "*" Class08
- Class09 "1" --> "*" C2 : Where am i?
- Class09 "*" --* "*" C3
- Class09 "1" --|> "1" Class07
- Class07 : equals()
- Class07 : Object[] elementData
- Class01 : size()
- Class01 : int chimp
- Class01 : int gorilla
- Class08 "1" <--> "*" C2: Cool label
- class Class10 {
- <<service>>
- int id
- test()
- }
- `,
- `
- classDiagram
- Class01 "1" <|--|> "*" AveryLongClass : Cool
- <<interface>> Class01
- Class03 "1" *-- "*" Class04
- Class05 "1" o-- "many" Class06
- Class07 "1" .. "*" Class08
- Class09 "1" --> "*" C2 : Where am i?
- Class09 "*" --* "*" C3
- Class09 "1" --|> "1" Class07
- Class07 : equals()
- Class07 : Object[] elementData
- Class01 : size()
- Class01 : int chimp
- Class01 : int gorilla
- Class08 "1" <--> "*" C2: Cool label
- class Class10 {
- <<service>>
- int id
- test()
- }
- `,
- ],
- {}
- );
- cy.get('svg');
- });
-
it('4: should render a simple class diagram with comments', () => {
imgSnapshotTest(
`
@@ -353,4 +300,107 @@ describe('Class diagram', () => {
);
cy.get('svg');
});
+
+ it('16: should render multiple class diagrams', () => {
+ imgSnapshotTest(
+ [
+ `
+ classDiagram
+ Class01 "1" <|--|> "*" AveryLongClass : Cool
+ <<interface>> Class01
+ Class03 "1" *-- "*" Class04
+ Class05 "1" o-- "many" Class06
+ Class07 "1" .. "*" Class08
+ Class09 "1" --> "*" C2 : Where am i?
+ Class09 "*" --* "*" C3
+ Class09 "1" --|> "1" Class07
+ Class07 : equals()
+ Class07 : Object[] elementData
+ Class01 : size()
+ Class01 : int chimp
+ Class01 : int gorilla
+ Class08 "1" <--> "*" C2: Cool label
+ class Class10 {
+ <<service>>
+ int id
+ test()
+ }
+ `,
+ `
+ classDiagram
+ Class01 "1" <|--|> "*" AveryLongClass : Cool
+ <<interface>> Class01
+ Class03 "1" *-- "*" Class04
+ Class05 "1" o-- "many" Class06
+ Class07 "1" .. "*" Class08
+ Class09 "1" --> "*" C2 : Where am i?
+ Class09 "*" --* "*" C3
+ Class09 "1" --|> "1" Class07
+ Class07 : equals()
+ Class07 : Object[] elementData
+ Class01 : size()
+ Class01 : int chimp
+ Class01 : int gorilla
+ Class08 "1" <--> "*" C2: Cool label
+ class Class10 {
+ <<service>>
+ int id
+ test()
+ }
+ `,
+ ],
+ {}
+ );
+ cy.get('svg');
+ });
+
+ it('17: should render a class diagram when useMaxWidth is true (default)', () => {
+ renderGraph(
+ `
+ classDiagram
+ Class01 <|-- AveryLongClass : Cool
+ Class01 : size()
+ Class01 : int chimp
+ Class01 : int gorilla
+ Class01 : -int privateChimp
+ Class01 : +int publicGorilla
+ Class01 : #int protectedMarmoset
+ `,
+ { class: { useMaxWidth: true } }
+ );
+ cy.get('svg')
+ .should((svg) => {
+ expect(svg).to.have.attr('width', '100%');
+ expect(svg).to.have.attr('height', '218');
+ const style = svg.attr('style');
+ expect(style).to.match(/^max-width: [\d.]+px;$/);
+ const maxWidthValue = parseInt(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(160 * .95, 160 * 1.05);
+ });
+ });
+
+ it('18: should render a class diagram when useMaxWidth is false', () => {
+ renderGraph(
+ `
+ classDiagram
+ Class01 <|-- AveryLongClass : Cool
+ Class01 : size()
+ Class01 : int chimp
+ Class01 : int gorilla
+ Class01 : -int privateChimp
+ Class01 : +int publicGorilla
+ Class01 : #int protectedMarmoset
+ `,
+ { class: { useMaxWidth: false } }
+ );
+ cy.get('svg')
+ .should((svg) => {
+ 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(160 * .95, 160 * 1.05);
+ expect(svg).to.have.attr('height', '218');
+ expect(svg).to.not.have.attr('style');
+ });
+ });
});
diff --git a/cypress/integration/rendering/erDiagram.spec.js b/cypress/integration/rendering/erDiagram.spec.js
index e965ca57d..a387bf254 100644
--- a/cypress/integration/rendering/erDiagram.spec.js
+++ b/cypress/integration/rendering/erDiagram.spec.js
@@ -1,5 +1,5 @@
/* eslint-env jest */
-import { imgSnapshotTest } from '../../helpers/util';
+import { imgSnapshotTest, renderGraph } from '../../helpers/util';
describe('Entity Relationship Diagram', () => {
it('should render a simple ER diagram', () => {
@@ -101,4 +101,44 @@ describe('Entity Relationship Diagram', () => {
);
cy.get('svg');
});
+
+ it('should render an ER diagrams when useMaxWidth is true (default)', () => {
+ renderGraph(
+ `
+ erDiagram
+ CUSTOMER ||--o{ ORDER : places
+ ORDER ||--|{ LINE-ITEM : contains
+ `,
+ { er: { useMaxWidth: true } }
+ );
+ cy.get('svg')
+ .should((svg) => {
+ expect(svg).to.have.attr('width', '100%');
+ 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(''));
+ // use within because the absolute value can be slightly different depending on the environment ±5%
+ expect(maxWidthValue).to.be.within(140 * .95, 140 * 1.05);
+ });
+ });
+
+ it('should render an ER when useMaxWidth is false', () => {
+ renderGraph(
+ `
+ erDiagram
+ CUSTOMER ||--o{ ORDER : places
+ ORDER ||--|{ LINE-ITEM : contains
+ `,
+ { er: { useMaxWidth: false } }
+ );
+ cy.get('svg')
+ .should((svg) => {
+ 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 * .95, 140 * 1.05);
+ expect(svg).to.have.attr('height', '465');
+ expect(svg).to.not.have.attr('style');
+ });
+ });
});
diff --git a/cypress/integration/rendering/flowchart-v2.spec.js b/cypress/integration/rendering/flowchart-v2.spec.js
index 29f2ef5b0..7374dff53 100644
--- a/cypress/integration/rendering/flowchart-v2.spec.js
+++ b/cypress/integration/rendering/flowchart-v2.spec.js
@@ -1,5 +1,5 @@
/* eslint-env jest */
-import { imgSnapshotTest } from '../../helpers/util';
+import { imgSnapshotTest, renderGraph } from '../../helpers/util';
describe('Flowchart v2', () => {
it('1: should render a simple flowchart', () => {
@@ -47,7 +47,7 @@ describe('Flowchart v2', () => {
);
});
- it('Length of edges', () => {
+ it('4: Length of edges', () => {
imgSnapshotTest(
`flowchart TD
L1 --- L2
@@ -64,7 +64,7 @@ describe('Flowchart v2', () => {
{ flowchart: { diagramPadding: 0 } }
);
});
- it('36: should render escaped without html labels', () => {
+ it('5: should render escaped without html labels', () => {
imgSnapshotTest(
`flowchart TD
a["Haiya"]---->b
@@ -72,13 +72,57 @@ describe('Flowchart v2', () => {
{htmlLabels: false, flowchart: {htmlLabels: false}}
);
});
- it('37: should render non-escaped with html labels', () => {
+ it('6: should render non-escaped with html labels', () => {
imgSnapshotTest(
`flowchart TD
a["Haiya"]===>b
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
-
);
});
+ it('7: should render a flowchart when useMaxWidth is true (default)', () => {
+ renderGraph(
+ `flowchart TD
+ A[Christmas] -->|Get money| B(Go shopping)
+ B --> C{Let me think}
+ C -->|One| D[Laptop]
+ C -->|Two| E[iPhone]
+ C -->|Three| F[fa:fa-car Car]
+ `,
+ { flowchart: { useMaxWidth: true } }
+ );
+ cy.get('svg')
+ .should((svg) => {
+ expect(svg).to.have.attr('width', '100%');
+ 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 * .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(''));
+ expect(maxWidthValue).to.be.within(300 * .95, 300 * 1.05);
+ });
+ });
+ it('8: should render a flowchart when useMaxWidth is false', () => {
+ renderGraph(
+ `flowchart TD
+ A[Christmas] -->|Get money| B(Go shopping)
+ B --> C{Let me think}
+ C -->|One| D[Laptop]
+ C -->|Two| E[iPhone]
+ C -->|Three| F[fa:fa-car Car]
+ `,
+ { flowchart: { useMaxWidth: false } }
+ );
+ cy.get('svg')
+ .should((svg) => {
+ 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 * .95, 446 * 1.05);
+ expect(width).to.be.within(300 * .95, 300 * 1.05);
+ expect(svg).to.not.have.attr('style');
+ });
+ });
});
diff --git a/cypress/integration/rendering/flowchart.spec.js b/cypress/integration/rendering/flowchart.spec.js
index 804b49b7c..bf03696a2 100644
--- a/cypress/integration/rendering/flowchart.spec.js
+++ b/cypress/integration/rendering/flowchart.spec.js
@@ -1,5 +1,5 @@
/* eslint-env jest */
-import { imgSnapshotTest } from '../../helpers/util';
+import { imgSnapshotTest, renderGraph } from '../../helpers/util';
describe('Flowchart', () => {
it('1: should render a simple flowchart no htmlLabels', () => {
@@ -731,4 +731,49 @@ describe('Flowchart', () => {
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
);
});
+ it('38: should render a flowchart when useMaxWidth is true (default)', () => {
+ renderGraph(
+ `graph TD
+ A[Christmas] -->|Get money| B(Go shopping)
+ B --> C{Let me think}
+ C -->|One| D[Laptop]
+ C -->|Two| E[iPhone]
+ C -->|Three| F[fa:fa-car Car]
+ `,
+ { flowchart: { useMaxWidth: true } }
+ );
+ cy.get('svg')
+ .should((svg) => {
+ expect(svg).to.have.attr('width', '100%');
+ 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 * .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(''));
+ expect(maxWidthValue).to.be.within(300 * .95, 300 * 1.05);
+ });
+ });
+ it('39: should render a flowchart when useMaxWidth is false', () => {
+ renderGraph(
+ `graph TD
+ A[Christmas] -->|Get money| B(Go shopping)
+ B --> C{Let me think}
+ C -->|One| D[Laptop]
+ C -->|Two| E[iPhone]
+ C -->|Three| F[fa:fa-car Car]
+ `,
+ { flowchart: { useMaxWidth: false } }
+ );
+ cy.get('svg')
+ .should((svg) => {
+ 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 * .95, 446 * 1.05);
+ expect(width).to.be.within(300 * .95, 300 * 1.05);
+ expect(svg).to.not.have.attr('style');
+ });
+ });
});
diff --git a/cypress/integration/rendering/gantt.spec.js b/cypress/integration/rendering/gantt.spec.js
index e655681bb..422af1165 100644
--- a/cypress/integration/rendering/gantt.spec.js
+++ b/cypress/integration/rendering/gantt.spec.js
@@ -1,5 +1,5 @@
/* eslint-env jest */
-import { imgSnapshotTest } from '../../helpers/util.js';
+import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
describe('Gantt diagram', () => {
beforeEach(()=>{
@@ -163,4 +163,99 @@ describe('Gantt diagram', () => {
{}
);
});
+
+ it('should render a gantt diagram when useMaxWidth is true (default)', () => {
+ renderGraph(
+ `
+ gantt
+ dateFormat YYYY-MM-DD
+ axisFormat %d/%m
+ title Adding GANTT diagram to mermaid
+ excludes weekdays 2014-01-10
+
+ section A section
+ 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
+ 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
+ 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
+ Describe gantt syntax :after doc1, 3d
+ Add gantt diagram to demo page : 20h
+ Add another diagram to demo page : 48h
+ `,
+ { gantt: { useMaxWidth: true } }
+ );
+ cy.get('svg')
+ .should((svg) => {
+ expect(svg).to.have.attr('width', '100%');
+ 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 * .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(''));
+ expect(maxWidthValue).to.be.within(984 * .95, 984 * 1.05);
+ });
+ });
+
+ it('should render a gantt diagram when useMaxWidth is false', () => {
+ renderGraph(
+ `
+ gantt
+ dateFormat YYYY-MM-DD
+ axisFormat %d/%m
+ title Adding GANTT diagram to mermaid
+ excludes weekdays 2014-01-10
+
+ section A section
+ 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
+ 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
+ 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
+ Describe gantt syntax :after doc1, 3d
+ Add gantt diagram to demo page : 20h
+ Add another diagram to demo page : 48h
+ `,
+ { gantt: { useMaxWidth: false } }
+ );
+ cy.get('svg')
+ .should((svg) => {
+ 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 * .95, 484 * 1.05);
+ expect(width).to.be.within(984 * .95, 984 * 1.05);
+ expect(svg).to.not.have.attr('style');
+ });
+ });
});
diff --git a/cypress/integration/rendering/journey.spec.js b/cypress/integration/rendering/journey.spec.js
index 8bcf58412..6dd5f6c25 100644
--- a/cypress/integration/rendering/journey.spec.js
+++ b/cypress/integration/rendering/journey.spec.js
@@ -1,5 +1,5 @@
/* eslint-env jest */
-import { imgSnapshotTest } from '../../helpers/util.js';
+import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
describe('User journey diagram', () => {
it('Simple test', () => {
@@ -28,4 +28,43 @@ section Order from website
{}
);
});
+
+ it('should render a user journey diagram when useMaxWidth is true (default)', () => {
+ renderGraph(
+ `journey
+title Adding journey diagram functionality to mermaid
+section Order from website
+ `,
+ { journey: { useMaxWidth: true } }
+ );
+ 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(20);
+ const style = svg.attr('style');
+ expect(style).to.match(/^max-width: [\d.]+px;$/);
+ const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
+ expect(maxWidthValue).to.eq(400);
+ });
+ });
+
+ it('should render a user journey diagram when useMaxWidth is false', () => {
+ renderGraph(
+ `journey
+title Adding journey diagram functionality to mermaid
+section Order from website
+ `,
+ { journey: { useMaxWidth: false } }
+ );
+ cy.get('svg')
+ .should((svg) => {
+ const height = parseFloat(svg.attr('height'));
+ const width = parseFloat(svg.attr('width'));
+ expect(height).to.eq(20);
+ expect(width).to.eq(400);
+ expect(svg).to.not.have.attr('style');
+ });
+ });
});
diff --git a/cypress/integration/rendering/pie.spec.js b/cypress/integration/rendering/pie.spec.js
index b69aad631..bbedb9ebd 100644
--- a/cypress/integration/rendering/pie.spec.js
+++ b/cypress/integration/rendering/pie.spec.js
@@ -1,5 +1,5 @@
/* eslint-env jest */
-import { imgSnapshotTest } from '../../helpers/util.js';
+import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
describe('Pie Chart', () => {
it('should render a simple pie diagram', () => {
@@ -37,4 +37,45 @@ describe('Pie Chart', () => {
);
cy.get('svg');
});
+ it('should render a pie diagram when useMaxWidth is true (default)', () => {
+ renderGraph(
+ `
+ pie title Sports in Sweden
+ "Bandy" : 40
+ "Ice-Hockey" : 80
+ "Football" : 90
+ `,
+ { pie: { useMaxWidth: true } }
+ );
+ 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);
+ const style = svg.attr('style');
+ expect(style).to.match(/^max-width: [\d.]+px;$/);
+ const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
+ expect(maxWidthValue).to.eq(984);
+ });
+ });
+ it('should render a pie diagram when useMaxWidth is false', () => {
+ renderGraph(
+ `
+ pie title Sports in Sweden
+ "Bandy" : 40
+ "Ice-Hockey" : 80
+ "Football" : 90
+ `,
+ { pie: { useMaxWidth: false } }
+ );
+ cy.get('svg')
+ .should((svg) => {
+ const height = parseFloat(svg.attr('height'));
+ const width = parseFloat(svg.attr('width'));
+ expect(height).to.eq(450);
+ expect(width).to.eq(984);
+ expect(svg).to.not.have.attr('style');
+ });
+ });
});
diff --git a/cypress/integration/rendering/sequencediagram.spec.js b/cypress/integration/rendering/sequencediagram.spec.js
index e20c6104b..bb460418f 100644
--- a/cypress/integration/rendering/sequencediagram.spec.js
+++ b/cypress/integration/rendering/sequencediagram.spec.js
@@ -1,6 +1,6 @@
///
-import { imgSnapshotTest } from '../../helpers/util';
+import { imgSnapshotTest, renderGraph } from '../../helpers/util';
context('Sequence diagram', () => {
it('should render a simple sequence diagram', () => {
@@ -505,7 +505,7 @@ context('Sequence diagram', () => {
});
});
context('directives', () => {
- it('should overide config with directive settings', () => {
+ it('should override config with directive settings', () => {
imgSnapshotTest(
`
%%{init: { "config": { "mirrorActors": true }}}%%
@@ -517,7 +517,7 @@ context('Sequence diagram', () => {
{ logLevel:0, sequence: { mirrorActors: false, noteFontSize: 18, noteFontFamily: 'Arial' } }
);
});
- it('should overide config with directive settings', () => {
+ it('should override config with directive settings', () => {
imgSnapshotTest(
`
%%{init: { "config": { "mirrorActors": false, "wrap": true }}}%%
@@ -530,4 +530,85 @@ context('Sequence diagram', () => {
);
});
});
+ context('svg size', () => {
+ it('should render a sequence diagram when useMaxWidth is true (default)', () => {
+ renderGraph(
+ `
+ sequenceDiagram
+ participant Alice
+ participant Bob
+ participant John as John
Second Line
+ Alice ->> Bob: Hello Bob, how are you?
+ Bob-->>John: How about you John?
+ Bob--x Alice: I am good thanks!
+ Bob-x John: I am good thanks!
+ Note right of John: Bob thinks a long
long time, so long
that the text does
not fit on a row.
+ Bob-->Alice: Checking with John...
+ alt either this
+ Alice->>John: Yes
+ else or this
+ Alice->>John: No
+ else or this will happen
+ Alice->John: Maybe
+ end
+ par this happens in parallel
+ Alice -->> Bob: Parallel message 1
+ and
+ Alice -->> John: Parallel message 2
+ end
+ `,
+ { sequence: { useMaxWidth: true } }
+ );
+ 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(920);
+ 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(820 * .95, 820 * 1.05);
+ });
+ });
+ it('should render a sequence diagram when useMaxWidth is false', () => {
+ renderGraph(
+ `
+ sequenceDiagram
+ participant Alice
+ participant Bob
+ participant John as John
Second Line
+ Alice ->> Bob: Hello Bob, how are you?
+ Bob-->>John: How about you John?
+ Bob--x Alice: I am good thanks!
+ Bob-x John: I am good thanks!
+ Note right of John: Bob thinks a long
long time, so long
that the text does
not fit on a row.
+ Bob-->Alice: Checking with John...
+ alt either this
+ Alice->>John: Yes
+ else or this
+ Alice->>John: No
+ else or this will happen
+ Alice->John: Maybe
+ end
+ par this happens in parallel
+ Alice -->> Bob: Parallel message 1
+ and
+ Alice -->> John: Parallel message 2
+ end
+ `,
+ { sequence: { useMaxWidth: false } }
+ );
+ cy.get('svg')
+ .should((svg) => {
+ const height = parseFloat(svg.attr('height'));
+ const width = parseFloat(svg.attr('width'));
+ expect(height).to.eq(920);
+ // use within because the absolute value can be slightly different depending on the environment ±5%
+ expect(width).to.be.within(820 * .95, 820 * 1.05);
+ expect(svg).to.not.have.attr('style');
+ });
+ });
+ });
});
diff --git a/cypress/integration/rendering/stateDiagram-v2.spec.js b/cypress/integration/rendering/stateDiagram-v2.spec.js
index bc3cb8816..9013ec64f 100644
--- a/cypress/integration/rendering/stateDiagram-v2.spec.js
+++ b/cypress/integration/rendering/stateDiagram-v2.spec.js
@@ -1,5 +1,5 @@
/* eslint-env jest */
-import { imgSnapshotTest } from '../../helpers/util';
+import { imgSnapshotTest, renderGraph } from '../../helpers/util';
describe('State diagram', () => {
it('v2 should render a simple info', () => {
@@ -47,7 +47,7 @@ describe('State diagram', () => {
);
cy.get('svg');
});
- it('v2 should render a single state with short descr', () => {
+ it('v2 should render a single state with short descriptions', () => {
imgSnapshotTest(
`
stateDiagram-v2
@@ -58,7 +58,7 @@ describe('State diagram', () => {
);
cy.get('svg');
});
- it('v2 should render a transition descrions with new lines', () => {
+ it('v2 should render a transition descriptions with new lines', () => {
imgSnapshotTest(
`
stateDiagram-v2
@@ -201,7 +201,7 @@ describe('State diagram', () => {
);
cy.get('svg');
});
- it('v2 should render composit states', () => {
+ it('v2 should render composite states', () => {
imgSnapshotTest(
`
stateDiagram-v2
@@ -220,7 +220,7 @@ describe('State diagram', () => {
);
cy.get('svg');
});
- it('v2 should render multiple composit states', () => {
+ it('v2 should render multiple composite states', () => {
imgSnapshotTest(
`
stateDiagram-v2
@@ -249,7 +249,7 @@ describe('State diagram', () => {
{ logLevel: 0, fontFamily: 'courier' }
);
});
- it('v2 should render forks in composit states', () => {
+ it('v2 should render forks in composite states', () => {
imgSnapshotTest(
`
stateDiagram-v2
@@ -329,7 +329,7 @@ describe('State diagram', () => {
}
);
});
- it('v2 Simplest composit state', () => {
+ it('v2 Simplest composite state', () => {
imgSnapshotTest(
`
stateDiagram-v2
@@ -354,5 +354,47 @@ describe('State diagram', () => {
}
);
});
+ it('v2 should render a state diagram when useMaxWidth is true (default)', () => {
+ renderGraph(
+ `
+ stateDiagram-v2
+ [*] --> State1
+ State1 --> [*]
+ `,
+ { state: { useMaxWidth: true } }
+ );
+ 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(177);
+ 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 * .95, 135 * 1.05);
+ });
+ });
+ it('v2 should render a state diagram when useMaxWidth is false', () => {
+ renderGraph(
+ `
+ stateDiagram-v2
+
+ [*] --> State1
+ State1 --> [*]
+ `,
+ { state: { useMaxWidth: false } }
+ );
+ cy.get('svg')
+ .should((svg) => {
+ const height = parseFloat(svg.attr('height'));
+ const width = parseFloat(svg.attr('width'));
+ expect(height).to.eq(177);
+ // use within because the absolute value can be slightly different depending on the environment ±5%
+ expect(width).to.be.within(135 * .95, 135 * 1.05);
+ expect(svg).to.not.have.attr('style');
+ });
+ });
});
diff --git a/cypress/integration/rendering/stateDiagram.spec.js b/cypress/integration/rendering/stateDiagram.spec.js
index ac1000858..2d10a6a9e 100644
--- a/cypress/integration/rendering/stateDiagram.spec.js
+++ b/cypress/integration/rendering/stateDiagram.spec.js
@@ -1,5 +1,5 @@
/* eslint-env jest */
-import { imgSnapshotTest } from '../../helpers/util';
+import { imgSnapshotTest, renderGraph } from '../../helpers/util';
describe('State diagram', () => {
it('should render a simple state diagrams', () => {
@@ -37,7 +37,7 @@ describe('State diagram', () => {
);
cy.get('svg');
});
- it('should render a single state with short descr', () => {
+ it('should render a single state with short descriptions', () => {
imgSnapshotTest(
`
stateDiagram
@@ -48,7 +48,7 @@ describe('State diagram', () => {
);
cy.get('svg');
});
- it('should render a transition descrions with new lines', () => {
+ it('should render a transition descriptions with new lines', () => {
imgSnapshotTest(
`
stateDiagram
@@ -191,7 +191,7 @@ describe('State diagram', () => {
);
cy.get('svg');
});
- it('should render composit states', () => {
+ it('should render composite states', () => {
imgSnapshotTest(
`
stateDiagram
@@ -280,7 +280,7 @@ describe('State diagram', () => {
);
cy.get('svg');
});
- it('should render conurrency states', () => {
+ it('should render concurrency states', () => {
imgSnapshotTest(
`
stateDiagram
@@ -319,7 +319,7 @@ describe('State diagram', () => {
}
);
});
- it('Simplest composit state', () => {
+ it('Simplest composite state', () => {
imgSnapshotTest(
`
stateDiagram
@@ -344,5 +344,45 @@ describe('State diagram', () => {
}
);
});
-
+ it('should render a state diagram when useMaxWidth is true (default)', () => {
+ renderGraph(
+ `
+ stateDiagram
+ [*] --> State1
+ State1 --> [*]
+ `,
+ { state: { useMaxWidth: true } }
+ );
+ 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(139);
+ 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(112 * .95, 112 * 1.05);
+ });
+ });
+ it('should render a state diagram when useMaxWidth is false', () => {
+ renderGraph(
+ `
+ stateDiagram
+ [*] --> State1
+ State1 --> [*]
+ `,
+ { state: { useMaxWidth: false } }
+ );
+ cy.get('svg')
+ .should((svg) => {
+ const height = parseFloat(svg.attr('height'));
+ const width = parseFloat(svg.attr('width'));
+ expect(height).to.eq(139);
+ // use within because the absolute value can be slightly different depending on the environment ±5%
+ expect(width).to.be.within(112 * .95, 112 * 1.05);
+ expect(svg).to.not.have.attr('style');
+ });
+ });
});
diff --git a/src/defaultConfig.js b/src/defaultConfig.js
index 8d1348b5b..88b441272 100644
--- a/src/defaultConfig.js
+++ b/src/defaultConfig.js
@@ -173,8 +173,20 @@ const config = {
*/
curve: 'linear',
// Only used in new experimental rendering
- // repreesents the padding between the labels and the shape
- padding: 15
+ // represents the padding between the labels and the shape
+ padding: 15,
+
+ /**
+ *| Parameter | Description |Type | Required | Values|
+ *| --- | --- | --- | --- | --- |
+ *| useMaxWidth | See notes | Boolean | 4 | True, False |
+ *
+ ***Notes:**when this flag is set the height and width is set to 100% and is then scaling with the
+ *available space if not the absolute space required is used.
+ *
+ ***Default value true**.
+ */
+ useMaxWidth: true
},
/**
@@ -572,8 +584,23 @@ const config = {
* This might need adjustment to match your locale and preferences
***Default value '%Y-%m-%d'**.
*/
- axisFormat: '%Y-%m-%d'
+ axisFormat: '%Y-%m-%d',
+
+ /**
+ *| Parameter | Description |Type | Required | Values|
+ *| --- | --- | --- | --- | --- |
+ *| useMaxWidth | See notes | Boolean | 4 | True, False |
+ *
+ ***Notes:**when this flag is set the height and width is set to 100% and is then scaling with the
+ *available space if not the absolute space required is used.
+ *
+ ***Default value true**.
+ */
+ useMaxWidth: true,
+
+ useWidth: undefined
},
+
/**
* The object containing configurations specific for journey diagrams
*/
@@ -711,10 +738,35 @@ const config = {
rightAngles: false
},
class: {
- arrowMarkerAbsolute: false
+ arrowMarkerAbsolute: false,
+ /**
+ *| Parameter | Description |Type | Required | Values|
+ *| --- | --- | --- | --- | --- |
+ *| useMaxWidth | See notes | Boolean | 4 | True, False |
+ *
+ ***Notes:**when this flag is set the height and width is set to 100% and is then scaling with the
+ *available space if not the absolute space required is used.
+ *
+ ***Default value true**.
+ */
+ useMaxWidth: true
},
git: {
- arrowMarkerAbsolute: false
+ arrowMarkerAbsolute: false,
+
+ useWidth: undefined,
+
+ /**
+ *| Parameter | Description |Type | Required | Values|
+ *| --- | --- | --- | --- | --- |
+ *| useMaxWidth | See notes | Boolean | 4 | True, False |
+ *
+ ***Notes:**when this flag is set the height and width is set to 100% and is then scaling with the
+ *available space if not the absolute space required is used.
+ *
+ ***Default value true**.
+ */
+ useMaxWidth: true
},
state: {
dividerMargin: 10,
@@ -734,7 +786,18 @@ const config = {
labelHeight: 16,
edgeLengthFactor: '20',
compositTitleSize: 35,
- radius: 5
+ radius: 5,
+ /**
+ *| Parameter | Description |Type | Required | Values|
+ *| --- | --- | --- | --- | --- |
+ *| useMaxWidth | See notes | Boolean | 4 | True, False |
+ *
+ ***Notes:**when this flag is set the height and width is set to 100% and is then scaling with the
+ *available space if not the absolute space required is used.
+ *
+ ***Default value true**.
+ */
+ useMaxWidth: true
},
/**
@@ -821,6 +884,26 @@ const config = {
*/
fontSize: 12,
+ /**
+ *| Parameter | Description |Type | Required | Values|
+ *| --- | --- | --- | --- | --- |
+ *| useMaxWidth | See Notes | Boolean | Required | true, false |
+ *
+ ***Notes:**
+ *When this flag is set to true, the diagram width is locked to 100% and
+ *scaled based on available space. If set to false, the diagram reserves its
+ *absolute width.
+ ***Default value: true**.
+ */
+ useMaxWidth: true
+ },
+
+ /**
+ * The object containing configurations specific for pie diagrams
+ */
+ pie: {
+ useWidth: undefined,
+
/**
*| Parameter | Description |Type | Required | Values|
*| --- | --- | --- | --- | --- |
diff --git a/src/diagrams/class/classRenderer-v2.js b/src/diagrams/class/classRenderer-v2.js
index 07ed68d2a..3419b6b7d 100644
--- a/src/diagrams/class/classRenderer-v2.js
+++ b/src/diagrams/class/classRenderer-v2.js
@@ -9,7 +9,7 @@ import { getConfig } from '../../config';
import { render } from '../../dagre-wrapper/index.js';
// import addHtmlLabel from 'dagre-d3/lib/label/add-html-label.js';
import { curveLinear } from 'd3';
-import { interpolateToCurve, getStylesFromArray } from '../../utils';
+import { interpolateToCurve, getStylesFromArray, configureSvgSize } from '../../utils';
import common from '../common/common';
parser.yy = classDb;
@@ -325,13 +325,7 @@ export const drawOld = function(text, id) {
const width = svgBounds.width + padding * 2;
const height = svgBounds.height + padding * 2;
- if (conf.useMaxWidth) {
- diagram.attr('width', '100%');
- diagram.attr('style', `max-width: ${width}px;`);
- } else {
- diagram.attr('height', height);
- diagram.attr('width', width);
- }
+ configureSvgSize(diagram, 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}`;
@@ -427,13 +421,7 @@ export const draw = function(text, id) {
`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);
- }
+ configureSvgSize(svg, height, width, conf.useMaxWidth);
svg.attr('viewBox', `0 0 ${width} ${height}`);
svg
diff --git a/src/diagrams/class/classRenderer.js b/src/diagrams/class/classRenderer.js
index 93e0a8dfc..727ecca20 100644
--- a/src/diagrams/class/classRenderer.js
+++ b/src/diagrams/class/classRenderer.js
@@ -5,6 +5,7 @@ import { logger } from '../../logger';
import classDb, { lookUpDomId } from './classDb';
import { parser } from './parser/classDiagram';
import svgDraw from './svgDraw';
+import { configureSvgSize } from '../../utils';
parser.yy = classDb;
@@ -232,13 +233,7 @@ export const draw = function(text, id) {
const width = svgBounds.width + padding * 2;
const height = svgBounds.height + padding * 2;
- if (conf.useMaxWidth) {
- diagram.attr('width', '100%');
- diagram.attr('style', `max-width: ${width}px;`);
- } else {
- diagram.attr('height', height);
- diagram.attr('width', width);
- }
+ configureSvgSize(diagram, 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}`;
diff --git a/src/diagrams/er/erRenderer.js b/src/diagrams/er/erRenderer.js
index e73dcd667..ead9612db 100644
--- a/src/diagrams/er/erRenderer.js
+++ b/src/diagrams/er/erRenderer.js
@@ -6,6 +6,7 @@ import dagre from 'dagre';
import { getConfig } from '../../config';
import { logger } from '../../logger';
import erMarkers from './erMarkers';
+import { configureSvgSize } from '../../utils';
const conf = {};
@@ -344,13 +345,7 @@ export const draw = function(text, id) {
const width = svgBounds.width + padding * 2;
const height = svgBounds.height + 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);
- }
+ configureSvgSize(svg, height, width, conf.useMaxWidth);
svg.attr('viewBox', `${svgBounds.x - padding} ${svgBounds.y - padding} ${width} ${height}`);
}; // draw
diff --git a/src/diagrams/flowchart/flowRenderer-v2.js b/src/diagrams/flowchart/flowRenderer-v2.js
index 03c795e3f..d89ef118b 100644
--- a/src/diagrams/flowchart/flowRenderer-v2.js
+++ b/src/diagrams/flowchart/flowRenderer-v2.js
@@ -9,7 +9,7 @@ import { render } from '../../dagre-wrapper/index.js';
import addHtmlLabel from 'dagre-d3/lib/label/add-html-label.js';
import { logger } from '../../logger';
import common from '../common/common';
-import { interpolateToCurve, getStylesFromArray } from '../../utils';
+import { interpolateToCurve, getStylesFromArray, configureSvgSize } from '../../utils';
const conf = {};
export const setConf = function(cnf) {
@@ -418,13 +418,7 @@ export const draw = function(text, id) {
`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);
- }
+ configureSvgSize(svg, height, width, conf.useMaxWidth);
svg.attr('viewBox', `0 0 ${width} ${height}`);
svg
diff --git a/src/diagrams/flowchart/flowRenderer.js b/src/diagrams/flowchart/flowRenderer.js
index 5ab9ec293..be60bf4b3 100644
--- a/src/diagrams/flowchart/flowRenderer.js
+++ b/src/diagrams/flowchart/flowRenderer.js
@@ -9,7 +9,7 @@ import dagreD3 from 'dagre-d3';
import addHtmlLabel from 'dagre-d3/lib/label/add-html-label.js';
import { logger } from '../../logger';
import common from '../common/common';
-import { interpolateToCurve, getStylesFromArray } from '../../utils';
+import { interpolateToCurve, getStylesFromArray, configureSvgSize } from '../../utils';
import flowChartShapes from './flowChartShapes';
const conf = {};
@@ -401,13 +401,7 @@ export const draw = function(text, id) {
const width = svgBounds.width + padding * 2;
const height = svgBounds.height + 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);
- }
+ 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}`;
diff --git a/src/diagrams/gantt/ganttRenderer.js b/src/diagrams/gantt/ganttRenderer.js
index 98e6391a9..0d3220bc9 100644
--- a/src/diagrams/gantt/ganttRenderer.js
+++ b/src/diagrams/gantt/ganttRenderer.js
@@ -11,6 +11,7 @@ import {
import { parser } from './parser/gantt';
import common from '../common/common';
import ganttDb from './ganttDb';
+import { configureSvgSize } from '../../utils';
parser.yy = ganttDb;
@@ -53,7 +54,6 @@ export const draw = function(text, id) {
// Set height based on number of tasks
const h = taskArray.length * (conf.barHeight + conf.barGap) + 2 * conf.topPadding;
- elem.setAttribute('height', '100%');
// Set viewBox
elem.setAttribute('viewBox', '0 0 ' + w + ' ' + h);
const svg = select(`[id="${id}"]`);
@@ -97,9 +97,8 @@ export const draw = function(text, id) {
taskArray.sort(taskCompare);
makeGant(taskArray, w, h);
- if (typeof conf.useWidth !== 'undefined') {
- elem.setAttribute('width', w);
- }
+
+ configureSvgSize(svg, h, w, conf.useMaxWidth);
svg
.append('text')
diff --git a/src/diagrams/pie/pieRenderer.js b/src/diagrams/pie/pieRenderer.js
index ee725b9f5..9cc8ac638 100644
--- a/src/diagrams/pie/pieRenderer.js
+++ b/src/diagrams/pie/pieRenderer.js
@@ -5,6 +5,7 @@ import { select, scaleOrdinal, schemeSet2, pie as d3pie, entries, arc } from 'd3
import pieData from './pieDb';
import pieParser from './parser/pie';
import { logger } from '../../logger';
+import { configureSvgSize } from '../../utils';
const conf = {};
export const setConf = function(cnf) {
@@ -20,7 +21,8 @@ export const setConf = function(cnf) {
* @param text
* @param id
*/
-let w;
+let width;
+const height = 450;
export const draw = (txt, id) => {
try {
const parser = pieParser.parser;
@@ -31,34 +33,31 @@ export const draw = (txt, id) => {
parser.parse(txt);
logger.debug('Parsed info diagram');
const elem = document.getElementById(id);
- w = elem.parentElement.offsetWidth;
+ width = elem.parentElement.offsetWidth;
- if (typeof w === 'undefined') {
- w = 1200;
+ if (typeof width === 'undefined') {
+ width = 1200;
}
if (typeof conf.useWidth !== 'undefined') {
- w = conf.useWidth;
+ width = conf.useWidth;
}
- const h = 450;
- elem.setAttribute('height', '100%');
+
+ const diagram = select('#' + id);
+ console.log('conf', conf);
+ configureSvgSize(diagram, height, width, conf.useMaxWidth);
+
// Set viewBox
- elem.setAttribute('viewBox', '0 0 ' + w + ' ' + h);
+ elem.setAttribute('viewBox', '0 0 ' + width + ' ' + height);
// Fetch the default direction, use TD if none was found
-
- var width = w; // 450
- var height = 450;
var margin = 40;
var legendRectSize = 18;
var legendSpacing = 4;
var radius = Math.min(width, height) / 2 - margin;
- var svg = select('#' + id)
- .append('svg')
- .attr('width', width)
- .attr('height', height)
+ var svg = diagram
.append('g')
.attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')');
@@ -67,9 +66,8 @@ export const draw = (txt, id) => {
Object.keys(data).forEach(function(key) {
sum += data[key];
});
- logger.info(data);
- // set the color scale
+ // Set the color scale
var color = scaleOrdinal()
.domain(data)
.range(schemeSet2);
@@ -80,12 +78,12 @@ export const draw = (txt, id) => {
});
var dataReady = pie(entries(data));
- // shape helper to build arcs:
+ // Shape helper to build arcs:
var arcGenerator = arc()
.innerRadius(0)
.outerRadius(radius);
- // Build the pie chart: Basically, each part of the pie is a path that we build using the arc function.
+ // Build the pie chart: each part of the pie is a path that we build using the arc function.
svg
.selectAll('mySlices')
.data(dataReady)
@@ -99,7 +97,8 @@ export const draw = (txt, id) => {
.style('stroke-width', '2px')
.style('opacity', 0.7);
- // Now add the Percentage. Use the centroid method to get the best coordinates
+ // Now add the percentage.
+ // Use the centroid method to get the best coordinates.
svg
.selectAll('mySlices')
.data(dataReady)
@@ -119,10 +118,10 @@ export const draw = (txt, id) => {
.append('text')
.text(parser.yy.getTitle())
.attr('x', 0)
- .attr('y', -(h - 50) / 2)
+ .attr('y', -(height - 50) / 2)
.attr('class', 'pieTitleText');
- //Add the slegend/annotations for each section
+ // Add the legends/annotations for each section
var legend = svg
.selectAll('.legend')
.data(color.domain())
diff --git a/src/diagrams/sequence/sequenceRenderer.js b/src/diagrams/sequence/sequenceRenderer.js
index cc2e140f2..b4fda5400 100644
--- a/src/diagrams/sequence/sequenceRenderer.js
+++ b/src/diagrams/sequence/sequenceRenderer.js
@@ -5,7 +5,7 @@ import { parser } from './parser/sequenceDiagram';
import common from '../common/common';
import sequenceDb from './sequenceDb';
import * as configApi from '../../config';
-import utils, { assignWithDepth } from '../../utils';
+import utils, { assignWithDepth, configureSvgSize } from '../../utils';
parser.yy = sequenceDb;
@@ -706,15 +706,8 @@ export const draw = function(text, id) {
.attr('y', -25);
}
- if (conf.useMaxWidth) {
- diagram.attr('height', '100%');
- diagram.attr('width', '100%');
- diagram.attr('style', 'max-width:' + width + 'px;');
- // diagram.attr('style', 'max-width:100%;');
- } else {
- diagram.attr('height', height);
- diagram.attr('width', width);
- }
+ configureSvgSize(diagram, height, width, conf.useMaxWidth);
+
const extraVertForTitle = title ? 40 : 0;
diagram.attr(
'viewBox',
diff --git a/src/diagrams/state/stateRenderer-v2.js b/src/diagrams/state/stateRenderer-v2.js
index 90683d2d4..057307fbb 100644
--- a/src/diagrams/state/stateRenderer-v2.js
+++ b/src/diagrams/state/stateRenderer-v2.js
@@ -6,6 +6,7 @@ import { getConfig } from '../../config';
import { render } from '../../dagre-wrapper/index.js';
import { logger } from '../../logger';
+import { configureSvgSize } from '../../utils';
const conf = {};
export const setConf = function(cnf) {
@@ -211,11 +212,7 @@ export const draw = function(text, id) {
parser.yy = stateDb;
// Parse the graph definition
- // try {
parser.parse(text);
- // } catch (err) {
- // logger.error('Parsing failed', err);
- // }
// Fetch the default direction, use TD if none was found
let dir = stateDb.getDirection();
@@ -256,54 +253,18 @@ export const draw = function(text, id) {
render(element, g, ['barb'], 'statediagram', id);
const padding = 8;
- // 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})`);
const bounds = svg.node().getBBox();
const width = bounds.width + padding * 2;
const height = bounds.height + padding * 2;
- // diagram.attr('height', '100%');
- // diagram.attr('style', `width: ${bounds.width * 3 + conf.padding * 2};`);
- // diagram.attr('height', height);
-
// Zoom in a bit
- svg.attr('width', width * 1.75);
svg.attr('class', 'statediagram');
- // diagram.attr('height', bounds.height * 3 + conf.padding * 2);
- // svg.attr(
- // 'viewBox',
- // `${bounds.x - conf.padding} ${bounds.y - conf.padding} ` + width + ' ' + height
- // );
const svgBounds = svg.node().getBBox();
- if (conf.useMaxWidth) {
- svg.attr('width', '100%');
- svg.attr('style', `max-width: ${width}px;`);
- } else {
- svg.attr('height', height);
- svg.attr('width', width);
- }
+ configureSvgSize(svg, height, width * 1.75, 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}`;
diff --git a/src/diagrams/state/stateRenderer.js b/src/diagrams/state/stateRenderer.js
index f6489851a..e52969ee7 100644
--- a/src/diagrams/state/stateRenderer.js
+++ b/src/diagrams/state/stateRenderer.js
@@ -8,6 +8,7 @@ import { parser } from './parser/stateDiagram';
// import idCache from './id-cache';
import { drawState, addTitleAndBox, drawEdge } from './shapes';
import { getConfig } from '../../config';
+import { configureSvgSize } from '../../utils';
parser.yy = stateDb;
@@ -75,14 +76,10 @@ export const draw = function(text, id) {
const width = bounds.width + padding * 2;
const height = bounds.height + padding * 2;
- if (conf.useMaxWidth) {
- 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);
+ // zoom in a bit
+ const svgWidth = width * 1.75;
+ configureSvgSize(diagram, height, svgWidth, conf.useMaxWidth);
+
diagram.attr(
'viewBox',
`${bounds.x - conf.padding} ${bounds.y - conf.padding} ` + width + ' ' + height
diff --git a/src/diagrams/user-journey/journeyRenderer.js b/src/diagrams/user-journey/journeyRenderer.js
index e871a4693..854f2ce37 100644
--- a/src/diagrams/user-journey/journeyRenderer.js
+++ b/src/diagrams/user-journey/journeyRenderer.js
@@ -2,6 +2,7 @@ import { select } from 'd3';
import { parser } from './parser/journey';
import journeyDb from './journeyDb';
import svgDraw from './svgDraw';
+import { configureSvgSize } from '../../utils';
parser.yy = journeyDb;
@@ -118,14 +119,8 @@ export const draw = function(text, id) {
}
const height = box.stopy - box.starty + 2 * conf.diagramMarginY;
const width = LEFT_MARGIN + box.stopx + 2 * conf.diagramMarginX;
- if (conf.useMaxWidth) {
- diagram.attr('height', '100%');
- diagram.attr('width', '100%');
- diagram.attr('style', 'max-width:' + width + 'px;');
- } else {
- diagram.attr('height', height);
- diagram.attr('width', width);
- }
+
+ configureSvgSize(diagram, height, width, conf.useMaxWidth);
// Draw activity line
diagram
diff --git a/src/mermaidAPI.js b/src/mermaidAPI.js
index 096730791..3e9c76ec0 100644
--- a/src/mermaidAPI.js
+++ b/src/mermaidAPI.js
@@ -385,7 +385,7 @@ const render = function(id, _txt, cb, container) {
break;
case 'pie':
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
- pieRenderer.setConf(cnf.class);
+ pieRenderer.setConf(cnf.pie);
pieRenderer.draw(txt, id, pkg.version);
break;
case 'er':
diff --git a/src/utils.js b/src/utils.js
index 8fe374b00..5344afc04 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -695,12 +695,38 @@ export const calculateTextDimensions = memoize(
(text, config) => `${text}-${config.fontSize}-${config.fontWeight}-${config.fontFamily}`
);
+const d3Attrs = function(d3Elem, attrs) {
+ for (let attr of attrs) {
+ d3Elem.attr(attr[0], attr[1]);
+ }
+};
+
+export const calculateSvgSizeAttrs = function(height, width, useMaxWidth) {
+ let attrs = new Map();
+ attrs.set('height', height);
+ if (useMaxWidth) {
+ attrs.set('width', '100%');
+ attrs.set('style', `max-width: ${width}px;`);
+ } else {
+ attrs.set('width', width);
+ }
+ return attrs;
+};
+
+export const configureSvgSize = function(svgElem, height, width, useMaxWidth) {
+ const attrs = calculateSvgSizeAttrs(height, width, useMaxWidth);
+ console.log('svgElem', svgElem);
+ d3Attrs(svgElem, attrs);
+};
+
export default {
assignWithDepth,
wrapLabel,
calculateTextHeight,
calculateTextWidth,
calculateTextDimensions,
+ calculateSvgSizeAttrs,
+ configureSvgSize,
detectInit,
detectDirective,
detectType,
diff --git a/src/utils.spec.js b/src/utils.spec.js
index 08c4654e0..756ad3794 100644
--- a/src/utils.spec.js
+++ b/src/utils.spec.js
@@ -171,7 +171,6 @@ Alice->Bob: hi`;
expect(type).toBe('git');
});
});
-
describe('when finding substring in array ', function() {
it('should return the array index that contains the substring', function() {
const arr = ['stroke:val1', 'fill:val2'];
@@ -184,7 +183,6 @@ describe('when finding substring in array ', function() {
expect(result).toEqual(-1);
});
});
-
describe('when formatting urls', function() {
it('should handle links', function() {
const url = 'https://mermaid-js.github.io/mermaid/#/';
@@ -242,3 +240,16 @@ describe('when formatting urls', function() {
expect(result).toEqual('about:blank');
});
});
+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('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('width')).toEqual(200);
+ });
+});