Merge branch 'develop' into sidv/5237_review

This commit is contained in:
Sidharth Vinod
2024-08-20 12:37:36 +05:30
committed by GitHub
54 changed files with 3520 additions and 4988 deletions

View File

@@ -9,7 +9,7 @@ elems
gantt
gitgraph
gzipped
handdrawn
handDrawn
knsv
Knut
marginx

View File

@@ -1,6 +1,6 @@
BRANDES
circo
handdrawn
handDrawn
KOEPF
neato
newbranch

View File

@@ -38,4 +38,4 @@ jobs:
working-directory: ./packages/mermaid
run: pnpm run docs:build
- uses: autofix-ci/action@dd55f44df8f7cdb7a6bf74c78677eb8acd40cd0a
- uses: autofix-ci/action@ff86a557419858bb967097bfc916833f5647fa8c

View File

@@ -1,14 +0,0 @@
import { urlSnapshotTest, openURLAndVerifyRendering } from '../../helpers/util.ts';
describe('Flowchart elk', () => {
it('should use dagre as fallback', () => {
urlSnapshotTest('http://localhost:9000/flow-elk.html', {
name: 'flow-elk fallback to dagre',
});
});
it('should allow overriding with external package', () => {
urlSnapshotTest('http://localhost:9000/flow-elk.html?elk=true', {
name: 'flow-elk overriding dagre with elk',
});
});
});

View File

@@ -837,6 +837,26 @@ subgraph "\`**Two**\`"
in the hat\`") -- "\`1o **ipa**\`" --> d("The dog in the hog")
end
`,
{ flowchart: { titleTopMargin: 0 } }
);
});
it('Sub graphs and markdown strings', () => {
imgSnapshotTest(
`---
config:
layout: elk
---
flowchart LR
subgraph subgraph_ko6czgs5u["Untitled subgraph"]
D["Option 1"]
end
C{"Evaluate"} -- One --> D
C -- Two --> E(("Option 2"))
D --> E
A["A"]
`,
{ flowchart: { titleTopMargin: 0 } }
);
@@ -875,11 +895,10 @@ describe('Title and arrow styling #4813', () => {
);
cy.get('svg').should((svg) => {
const edges = svg[0].querySelectorAll('.edges path');
// console.log(edges);
// expect(edges[0]).to.have.attr('pattern', 'solid');
// expect(edges[1]).to.have.attr('pattern', 'dotted');
// expect(edges[2]).to.have.css('stroke-width', '3.5px');
// expect(edges[3]).to.have.css('stroke-width', '1.5px');
expect(edges[0].getAttribute('class')).to.contain('edge-pattern-solid');
expect(edges[1].getAttribute('class')).to.contain('edge-pattern-dotted');
expect(edges[2].getAttribute('class')).to.contain('edge-thickness-thick');
expect(edges[3].getAttribute('class')).to.contain('edge-thickness-invisible');
});
});
});

File diff suppressed because it is too large Load Diff

View File

@@ -134,7 +134,7 @@ flowchart LR
</td>
<td>
<pre id="diagram2" class="mermaid">
%%{init: {"look": "handdrawn"} }%%
%%{init: {"look": "handDrawn"} }%%
flowchart LR
id1([This is the text in the box])
</pre
@@ -142,7 +142,7 @@ flowchart LR
</td>
<td>
<pre id="diagram3" class="mermaid">
%%{init: {"handdrawn": false, "layout": "elk"} }%%
%%{init: {"handDrawn": false, "layout": "elk"} }%%
flowchart LR
id1([This is the text in the box])
</pre
@@ -150,7 +150,7 @@ flowchart LR
</td>
<td>
<pre id="diagram4" class="mermaid">
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
%%{init: {"look": "handDrawn", "layout": "elk"} }%%
flowchart LR
id1([This is the text in the box])
</pre
@@ -185,7 +185,7 @@ flowchart LR
</td>
<td>
<pre id="diagram6" class="mermaid">
%%{init: {"look": "handdrawn"} }%%
%%{init: {"look": "handDrawn"} }%%
flowchart LR
id1[[This is the text in the box]]
</pre
@@ -193,7 +193,7 @@ flowchart LR
</td>
<td>
<pre id="diagram7" class="mermaid">
%%{init: {"handdrawn": false, "layout": "elk"} }%%
%%{init: {"handDrawn": false, "layout": "elk"} }%%
flowchart LR
id1[[This is the text in the box]]
</pre
@@ -201,7 +201,7 @@ flowchart LR
</td>
<td>
<pre id="diagram8" class="mermaid">
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
%%{init: {"look": "handDrawn", "layout": "elk"} }%%
flowchart LR
id1[[This is the text in the box]]
</pre
@@ -236,7 +236,7 @@ flowchart LR
</td>
<td>
<pre id="diagram10" class="mermaid">
%%{init: {"look": "handdrawn"} }%%
%%{init: {"look": "handDrawn"} }%%
flowchart LR
id1[(Database)]
</pre
@@ -244,7 +244,7 @@ flowchart LR
</td>
<td>
<pre id="diagram11" class="mermaid">
%%{init: {"handdrawn": false, "layout": "elk"} }%%
%%{init: {"handDrawn": false, "layout": "elk"} }%%
flowchart LR
id1[(Database)]
</pre
@@ -252,7 +252,7 @@ flowchart LR
</td>
<td>
<pre id="diagram12" class="mermaid">
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
%%{init: {"look": "handDrawn", "layout": "elk"} }%%
flowchart LR
id1[(Database)]
</pre
@@ -287,7 +287,7 @@ flowchart LR
</td>
<td>
<pre id="diagram14" class="mermaid">
%%{init: {"look": "handdrawn"} }%%
%%{init: {"look": "handDrawn"} }%%
flowchart LR
id1((This is the text in the circle))
</pre
@@ -295,7 +295,7 @@ flowchart LR
</td>
<td>
<pre id="diagram15" class="mermaid">
%%{init: {"handdrawn": false, "layout": "elk"} }%%
%%{init: {"handDrawn": false, "layout": "elk"} }%%
flowchart LR
id1((This is the text in the circle))
</pre
@@ -303,7 +303,7 @@ flowchart LR
</td>
<td>
<pre id="diagram16" class="mermaid">
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
%%{init: {"look": "handDrawn", "layout": "elk"} }%%
flowchart LR
id1((This is the text in the circle))
</pre
@@ -338,7 +338,7 @@ flowchart LR
</td>
<td>
<pre id="diagram18" class="mermaid">
%%{init: {"look": "handdrawn"} }%%
%%{init: {"look": "handDrawn"} }%%
flowchart TD
id1(((This is the text in the circle)))
</pre
@@ -346,7 +346,7 @@ flowchart LR
</td>
<td>
<pre id="diagram19" class="mermaid">
%%{init: {"handdrawn": false, "layout": "elk"} }%%
%%{init: {"handDrawn": false, "layout": "elk"} }%%
flowchart TD
id1(((This is the text in the circle)))
</pre
@@ -354,7 +354,7 @@ flowchart LR
</td>
<td>
<pre id="diagram20" class="mermaid">
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
%%{init: {"look": "handDrawn", "layout": "elk"} }%%
flowchart TD
id1(((This is the text in the circle)))
</pre
@@ -389,7 +389,7 @@ flowchart LR
</td>
<td>
<pre id="diagram22" class="mermaid">
%%{init: {"look": "handdrawn"} }%%
%%{init: {"look": "handDrawn"} }%%
flowchart LR
id1>This is the text in the box]
</pre
@@ -397,7 +397,7 @@ flowchart LR
</td>
<td>
<pre id="diagram23" class="mermaid">
%%{init: {"handdrawn": false, "layout": "elk"} }%%
%%{init: {"handDrawn": false, "layout": "elk"} }%%
flowchart LR
id1>This is the text in the box]
</pre
@@ -405,7 +405,7 @@ flowchart LR
</td>
<td>
<pre id="diagram24" class="mermaid">
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
%%{init: {"look": "handDrawn", "layout": "elk"} }%%
flowchart LR
id1>This is the text in the box]
</pre
@@ -440,7 +440,7 @@ flowchart LR
</td>
<td>
<pre id="diagram26" class="mermaid">
%%{init: {"look": "handdrawn"} }%%
%%{init: {"look": "handDrawn"} }%%
flowchart LR
id1{This is the text in the box}
</pre
@@ -448,7 +448,7 @@ flowchart LR
</td>
<td>
<pre id="diagram27" class="mermaid">
%%{init: {"handdrawn": false, "layout": "elk"} }%%
%%{init: {"handDrawn": false, "layout": "elk"} }%%
flowchart LR
id1{This is the text in the box}
</pre
@@ -456,7 +456,7 @@ flowchart LR
</td>
<td>
<pre id="diagram28" class="mermaid">
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
%%{init: {"look": "handDrawn", "layout": "elk"} }%%
flowchart LR
id1{This is the text in the box}
</pre
@@ -491,7 +491,7 @@ flowchart LR
</td>
<td>
<pre id="diagram31" class="mermaid">
%%{init: {"handdrawn": false, "layout": "elk"} }%%
%%{init: {"handDrawn": false, "layout": "elk"} }%%
flowchart LR
id1{{This is the text in the box}}
</pre
@@ -499,7 +499,7 @@ flowchart LR
</td>
<td>
<pre id="diagram32" class="mermaid">
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
%%{init: {"look": "handDrawn", "layout": "elk"} }%%
flowchart LR
id1{{This is the text in the box}}
</pre
@@ -534,7 +534,7 @@ flowchart LR
</td>
<td>
<pre id="diagram34" class="mermaid">
%%{init: {"look": "handdrawn"} }%%
%%{init: {"look": "handDrawn"} }%%
flowchart TD
id1[/This is the text in the box/]
</pre
@@ -542,7 +542,7 @@ flowchart LR
</td>
<td>
<pre id="diagram35" class="mermaid">
%%{init: {"handdrawn": false, "layout": "elk"} }%%
%%{init: {"handDrawn": false, "layout": "elk"} }%%
flowchart TD
id1[/This is the text in the box/]
</pre
@@ -550,7 +550,7 @@ flowchart LR
</td>
<td>
<pre id="diagram36" class="mermaid">
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
%%{init: {"look": "handDrawn", "layout": "elk"} }%%
flowchart TD
id1[/This is the text in the box/]
</pre
@@ -585,7 +585,7 @@ flowchart LR
</td>
<td>
<pre id="diagram38" class="mermaid">
%%{init: {"look": "handdrawn"} }%%
%%{init: {"look": "handDrawn"} }%%
flowchart TD
id1[\This is the text in the box\]
</pre
@@ -593,7 +593,7 @@ flowchart LR
</td>
<td>
<pre id="diagram39" class="mermaid">
%%{init: {"handdrawn": false, "layout": "elk"} }%%
%%{init: {"handDrawn": false, "layout": "elk"} }%%
flowchart TD
id1[\This is the text in the box\]
</pre
@@ -601,7 +601,7 @@ flowchart LR
</td>
<td>
<pre id="diagram40" class="mermaid">
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
%%{init: {"look": "handDrawn", "layout": "elk"} }%%
flowchart TD
id1[\This is the text in the box\]
@@ -637,7 +637,7 @@ flowchart LR
</td>
<td>
<pre id="diagram42" class="mermaid">
%%{init: {"look": "handdrawn"} }%%
%%{init: {"look": "handDrawn"} }%%
flowchart TD
A[/Christmas\]
</pre
@@ -645,7 +645,7 @@ flowchart LR
</td>
<td>
<pre id="diagram43" class="mermaid">
%%{init: {"handdrawn": false, "layout": "elk"} }%%
%%{init: {"handDrawn": false, "layout": "elk"} }%%
flowchart TD
A[/Christmas\]
</pre
@@ -653,7 +653,7 @@ flowchart LR
</td>
<td>
<pre id="diagram44" class="mermaid">
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
%%{init: {"look": "handDrawn", "layout": "elk"} }%%
flowchart TD
A[/Christmas\]
</pre
@@ -688,7 +688,7 @@ flowchart LR
</td>
<td>
<pre id="diagram46" class="mermaid">
%%{init: {"look": "handdrawn"} }%%
%%{init: {"look": "handDrawn"} }%%
flowchart TD
A[\Christmas/]
</pre
@@ -696,7 +696,7 @@ flowchart LR
</td>
<td>
<pre id="diagram47" class="mermaid">
%%{init: {"handdrawn": false, "layout": "elk"} }%%
%%{init: {"handDrawn": false, "layout": "elk"} }%%
flowchart TD
A[\Christmas/]
</pre
@@ -704,7 +704,7 @@ flowchart LR
</td>
<td>
<pre id="diagram48" class="mermaid">
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
%%{init: {"look": "handDrawn", "layout": "elk"} }%%
flowchart TD
A[\Christmas/]
</pre
@@ -739,7 +739,7 @@ flowchart LR
</td>
<td>
<pre id="diagram50" class="mermaid">
%%{init: {"look": "handdrawn"} }%%
%%{init: {"look": "handDrawn"} }%%
flowchart LR
id1(This is the text in the box)
</pre
@@ -747,7 +747,7 @@ flowchart LR
</td>
<td>
<pre id="diagram51" class="mermaid">
%%{init: {"handdrawn": false, "layout": "elk"} }%%
%%{init: {"handDrawn": false, "layout": "elk"} }%%
flowchart LR
id1(This is the text in the box)
</pre
@@ -755,7 +755,7 @@ flowchart LR
</td>
<td>
<pre id="diagram52" class="mermaid">
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
%%{init: {"look": "handDrawn", "layout": "elk"} }%%
flowchart LR
id1(This is the text in the box)
</pre
@@ -790,7 +790,7 @@ flowchart LR
</td>
<td>
<pre id="diagram54" class="mermaid">
%%{init: {"look": "handdrawn"} }%%
%%{init: {"look": "handDrawn"} }%%
flowchart LR
id1[This is the text in the box]
</pre
@@ -798,7 +798,7 @@ flowchart LR
</td>
<td>
<pre id="diagram55" class="mermaid">
%%{init: {"handdrawn": false, "layout": "elk"} }%%
%%{init: {"handDrawn": false, "layout": "elk"} }%%
flowchart LR
id1[This is the text in the box]
</pre
@@ -806,7 +806,7 @@ flowchart LR
</td>
<td>
<pre id="diagram56" class="mermaid">
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
%%{init: {"look": "handDrawn", "layout": "elk"} }%%
flowchart LR
id1[This is the text in the box]
</pre
@@ -827,7 +827,7 @@ flowchart LR
mermaid.parseError = function (err, hash) {};
mermaid.initialize({
handdrawn: false,
handDrawn: false,
mergeEdges: true,
layout: 'dagre',
flowchart: { titleTopMargin: 10 },

View File

@@ -125,7 +125,7 @@
</th>
<td>
<pre id="diagram1" class="mermaid">
%%{init: {"look": "handdrawn"} }%%
%%{init: {"look": "handDrawn"} }%%
stateDiagram-v2
stateA
@@ -134,7 +134,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram2" class="mermaid">
%%{init: {"look": "handdrawn"} }%%
%%{init: {"look": "handDrawn"} }%%
flowchart LR
id1[[This is the text in the box]]
@@ -152,7 +152,7 @@ flowchart LR
mermaid.parseError = function (err, hash) {};
mermaid.initialize({
handdrawn: false,
handDrawn: false,
mergeEdges: true,
layout: 'dagre',
flowchart: { titleTopMargin: 10 },

View File

@@ -36,12 +36,15 @@
font-family: 'Arial';
/* font-size: 18px !important; */
}
h1 {
color: grey;
}
.mermaid2 {
display: none;
}
.mermaid svg {
/* font-size: 18px !important; */
@@ -54,6 +57,7 @@
10px 10px;
background-repeat: repeat; */
}
.malware {
position: fixed;
bottom: 0;
@@ -69,32 +73,70 @@
font-family: monospace;
font-size: 72px;
}
/* tspan {
font-size: 6px !important;
} */
</style>
</head>
<body>
<pre id="diagram" class="mermaid">
<div class="flex">
<pre id="diagram" class="mermaid">
---
config:
look: handDrawn
flowchart:
htmlLabels: false
---
flowchart
a_a(Aftonbladet) --> b_b[gorilla]:::apa --> c_c{chimp}:::apa -->a_a
a_a --> c --> d_d --> c_c
classDef apa fill:#f9f,stroke:#333,stroke-width:4px;
class a_a apa;
click a_a "http://www.aftonbladet.se" "bookmark"
click c_c callback "new tooltip"
</pre
>
<pre id="diagram2" class="mermaid">
A[I am a long text, where do I go??? handdrawn - false]
</pre
>
<pre id="diagram" class="mermaid">
---
config:
look: handdrawn
flowchart:
htmlLabels: true
---
flowchart
A[I am a long text, where do I go??? handdrawn - true]
</pre
>
</div>
<div class="flex">
<pre id="diagram" class="mermaid">
---
config:
flowchart:
htmlLabels: false
---
flowchart
A[I am a long text, where do I go??? classic - false]
</pre
>
<pre id="diagram" class="mermaid">
---
config:
flowchart:
htmlLabels: true
---
flowchart
A[I am a long text, where do I go??? classic - true]
</pre
>
</div>
<pre id="diagram2" class="mermaid2">
flowchart LR
id1(Start)-->id2(Stop)
style id1 fill:#f9f,stroke:#333,stroke-width:4px
style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5
</pre>
<pre id="diagram3" class="mermaid">
<pre id="diagram3" class="mermaid2">
flowchart LR
A:::foo & B:::bar --> C:::foobar
classDef foo stroke:#f00
@@ -105,9 +147,9 @@ flowchart LR
</pre>
<pre id="diagram4" class="mermaid">
<pre id="diagram4" class="mermaid2">
stateDiagram
A:::foo
A:::foo
B:::bar --> C:::foobar
classDef foo stroke:#f00
classDef bar stroke:#0f0
@@ -127,8 +169,8 @@ flowchart LR
};
mermaid.initialize({
// theme: 'base',
// handdrawnSeed: 12,
// look: 'handdrawn',
// handDrawnSeed: 12,
// look: 'handDrawn',
// 'elk.nodePlacement.strategy': 'NETWORK_SIMPLEX',
// layout: 'dagre',
// layout: 'elk',

View File

@@ -115,7 +115,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram2" class="mermaid">
%%{init: {"look": "handdrawn"} }%%
%%{init: {"look": "handDrawn"} }%%
stateDiagram-v2
stateId
@@ -123,7 +123,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram3" class="mermaid">
%%{init: {"handdrawn": false, "layout": "elk"} }%%
%%{init: {"handDrawn": false, "layout": "elk"} }%%
stateDiagram-v2
stateId
@@ -131,7 +131,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram4" class="mermaid">
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
%%{init: {"look": "handDrawn", "layout": "elk"} }%%
stateDiagram-v2
stateId
@@ -162,21 +162,21 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram2" class="mermaid">
%%{init: {"look": "handdrawn"} }%%
%%{init: {"look": "handDrawn"} }%%
stateDiagram-v2
state "This is a state description" as s3
</pre>
</td>
<td>
<pre id="diagram3" class="mermaid">
%%{init: {"handdrawn": false, "layout": "elk"} }%%
%%{init: {"handDrawn": false, "layout": "elk"} }%%
stateDiagram-v2
state "This is a state description" as s4
</pre>
</td>
<td>
<pre id="diagram4" class="mermaid">
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
%%{init: {"look": "handDrawn", "layout": "elk"} }%%
stateDiagram-v2
state "This is a state description" as s5
</pre>
@@ -206,7 +206,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram2" class="mermaid">
%%{init: {"look": "handdrawn"} }%%
%%{init: {"look": "handDrawn"} }%%
stateDiagram-v2
s22 : This is a state description
@@ -214,7 +214,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram3" class="mermaid">
%%{init: {"handdrawn": false, "layout": "elk"} }%%
%%{init: {"handDrawn": false, "layout": "elk"} }%%
stateDiagram-v2
s23 : This is a state description
@@ -222,7 +222,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram4" class="mermaid">
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
%%{init: {"look": "handDrawn", "layout": "elk"} }%%
stateDiagram-v2
s24 : This is a state description
@@ -258,7 +258,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram2" class="mermaid">
%%{init: {"look": "handdrawn"} }%%
%%{init: {"look": "handDrawn"} }%%
stateDiagram-v2
s41 --> s42
@@ -268,7 +268,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram3" class="mermaid">
%%{init: {"handdrawn": false, "layout": "elk"} }%%
%%{init: {"handDrawn": false, "layout": "elk"} }%%
stateDiagram-v2
s51 --> s52
@@ -277,7 +277,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram4" class="mermaid">
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
%%{init: {"look": "handDrawn", "layout": "elk"} }%%
stateDiagram-v2
s61 --> s62
@@ -316,7 +316,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram2" class="mermaid">
%%{init: {"look": "handdrawn"} }%%
%%{init: {"look": "handDrawn"} }%%
stateDiagram-v2
a3 --> a4: A transition
@@ -326,7 +326,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram3" class="mermaid">
%%{init: {"handdrawn": false, "layout": "elk"} }%%
%%{init: {"handDrawn": false, "layout": "elk"} }%%
stateDiagram-v2
a5 --> a6: A transition
@@ -335,7 +335,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram4" class="mermaid">
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
%%{init: {"look": "handDrawn", "layout": "elk"} }%%
stateDiagram-v2
a7 --> a8: A transition
@@ -376,7 +376,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram2" class="mermaid">
%%{init: {"look": "handdrawn"} }%%
%%{init: {"look": "handDrawn"} }%%
stateDiagram-v2
[*] --> test
@@ -387,7 +387,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram3" class="mermaid">
%%{init: {"handdrawn": false, "layout": "elk"} }%%
%%{init: {"handDrawn": false, "layout": "elk"} }%%
stateDiagram-v2
[*] --> test
test --> [*]
@@ -397,7 +397,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram4" class="mermaid">
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
%%{init: {"look": "handDrawn", "layout": "elk"} }%%
stateDiagram-v2
[*] --> test
test --> [*]
@@ -445,7 +445,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram2" class="mermaid">
%%{init: {"look": "handdrawn"} }%%
%%{init: {"look": "handDrawn"} }%%
stateDiagram-v2
[*] --> First
@@ -459,7 +459,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram3" class="mermaid">
%%{init: {"handdrawn": false, "layout": "elk"} }%%
%%{init: {"handDrawn": false, "layout": "elk"} }%%
stateDiagram-v2
[*] --> First
state First {
@@ -472,7 +472,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram4" class="mermaid">
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
%%{init: {"look": "handDrawn", "layout": "elk"} }%%
stateDiagram-v2
[*] --> First
state First {
@@ -547,7 +547,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram2" class="mermaid">
%%{init: {"look": "handdrawn"} }%%
%%{init: {"look": "handDrawn"} }%%
stateDiagram-v2
[*] --> Level1
@@ -572,7 +572,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram3" class="mermaid">
%%{init: {"handdrawn": false, "layout": "elk"} }%%
%%{init: {"handDrawn": false, "layout": "elk"} }%%
stateDiagram-v2
[*] --> Level1
@@ -595,7 +595,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram4" class="mermaid">
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
%%{init: {"look": "handDrawn", "layout": "elk"} }%%
stateDiagram-v2
[*] --> Level1
@@ -676,7 +676,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram2" class="mermaid">
%%{init: {"look": "handdrawn"} }%%
%%{init: {"look": "handDrawn"} }%%
stateDiagram-v2
[*] --> B1
@@ -699,7 +699,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram3" class="mermaid">
%%{init: {"handdrawn": false, "layout": "elk"} }%%
%%{init: {"handDrawn": false, "layout": "elk"} }%%
stateDiagram-v2
[*] --> B1
B1 --> B2
@@ -722,7 +722,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram4" class="mermaid">
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
%%{init: {"look": "handDrawn", "layout": "elk"} }%%
stateDiagram-v2
[*] --> B1
B1 --> B2
@@ -784,7 +784,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram2" class="mermaid">
%%{init: {"look": "handdrawn"} }%%
%%{init: {"look": "handDrawn"} }%%
stateDiagram-v2
state if_state <<choice>>
@@ -796,7 +796,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram3" class="mermaid">
%%{init: {"handdrawn": false, "layout": "elk"} }%%
%%{init: {"handDrawn": false, "layout": "elk"} }%%
stateDiagram-v2
state if_state <<choice>>
[*] --> IsPositive
@@ -807,7 +807,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram4" class="mermaid">
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
%%{init: {"look": "handDrawn", "layout": "elk"} }%%
stateDiagram-v2
state if_state <<choice>>
[*] --> IsPositive
@@ -865,7 +865,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram2" class="mermaid">
%%{init: {"look": "handdrawn"} }%%
%%{init: {"look": "handDrawn"} }%%
stateDiagram-v2
state fork_state <<fork>>
[*] --> fork_state
@@ -882,7 +882,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram3" class="mermaid">
%%{init: {"handdrawn": false, "layout": "elk"} }%%
%%{init: {"handDrawn": false, "layout": "elk"} }%%
stateDiagram-v2
state fork_state <<fork>>
[*] --> fork_state
@@ -899,7 +899,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram4" class="mermaid">
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
%%{init: {"look": "handDrawn", "layout": "elk"} }%%
stateDiagram-v2
state fork_state <<fork>>
[*] --> fork_state
@@ -955,7 +955,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram2" class="mermaid">
%%{init: {"look": "handdrawn"} }%%
%%{init: {"look": "handDrawn"} }%%
stateDiagram-v2
TN3: The state with a note
note right of TN3
@@ -968,7 +968,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram3" class="mermaid">
%%{init: {"handdrawn": false, "layout": "elk"} }%%
%%{init: {"handDrawn": false, "layout": "elk"} }%%
stateDiagram-v2
TN5: The state with a note
note right of TN5
@@ -982,7 +982,7 @@ stateDiagram-v2
</td>
<td>
<pre id="diagram4" class="mermaid">
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
%%{init: {"look": "handDrawn", "layout": "elk"} }%%
stateDiagram-v2
TN7: The state with a note
note right of TN7
@@ -1052,7 +1052,7 @@ state Active {
</td>
<td>
<pre id="diagram2" class="mermaid">
%%{init: {"look": "handdrawn"} }%%
%%{init: {"look": "handDrawn"} }%%
stateDiagram-v2
[*] --> Active
@@ -1073,7 +1073,7 @@ state Active {
</td>
<td>
<pre id="diagram3" class="mermaid">
%%{init: {"handdrawn": false, "layout": "elk"} }%%
%%{init: {"handDrawn": false, "layout": "elk"} }%%
stateDiagram-v2
[*] --> Active
@@ -1095,7 +1095,7 @@ state Active {
</td>
<td>
<pre id="diagram4" class="mermaid">
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
%%{init: {"look": "handDrawn", "layout": "elk"} }%%
stateDiagram-v2
[*] --> Active
@@ -1159,7 +1159,7 @@ direction LR
</td>
<td>
<pre id="diagram2" class="mermaid">
%%{init: {"look": "handdrawn"} }%%
%%{init: {"look": "handDrawn"} }%%
stateDiagram-v2
direction LR
[*] --> D1
@@ -1174,7 +1174,7 @@ direction LR
</td>
<td>
<pre id="diagram3" class="mermaid">
%%{init: {"handdrawn": false, "layout": "elk"} }%%
%%{init: {"handDrawn": false, "layout": "elk"} }%%
stateDiagram-v2
direction LR
[*] --> D1
@@ -1189,7 +1189,7 @@ direction LR
</td>
<td>
<pre id="diagram4" class="mermaid">
%%{init: {"look": "handdrawn", "layout": "elk"} }%%
%%{init: {"look": "handDrawn", "layout": "elk"} }%%
stateDiagram-v2
direction LR
[*] --> D1
@@ -1229,7 +1229,7 @@ direction LR
};
mermaid.initialize({
handdrawn: false,
handDrawn: false,
mergeEdges: true,
layout: 'dagre',
flowchart: { titleTopMargin: 10 },
@@ -1254,7 +1254,7 @@ direction LR
let coll = document.getElementsByClassName("collapsible");
for (const element of coll) {
element.addEventListener("click", function () {
element.addEventListener("click", function () {
this.classList.toggle("active");
let content = this.nextElementSibling;
if (content.style.maxHeight) {

View File

@@ -9,7 +9,6 @@ function b64ToUtf8(str) {
// Adds a rendered flag to window when rendering is done, so cypress can wait for it.
function markRendered() {
console.log('Done rendering');
if (window.Cypress) {
window.rendered = true;
}

View File

@@ -210,11 +210,11 @@ If set to true, ignores legacyMathML.
---
### handdrawnSeed
### handDrawnSeed
`Optional` **handdrawnSeed**: `number`
`Optional` **handDrawnSeed**: `number`
Defines the seed to be used when using handdrawn look. This is important for the automated tests as they will always find differences without the seed. The default value is 0 which gives a random seed.
Defines the seed to be used when using handDrawn look. This is important for the automated tests as they will always find differences without the seed. The default value is 0 which gives a random seed.
#### Defined in
@@ -283,7 +283,7 @@ This option decides the amount of logging to be used by mermaid.
### look
`Optional` **look**: `"classic"` | `"handdrawn"`
`Optional` **look**: `"classic"` | `"handDrawn"`
Defines which main look to use for the diagram.

View File

@@ -98,7 +98,7 @@
"eslint-plugin-markdown": "^5.0.0",
"eslint-plugin-no-only-tests": "^3.1.0",
"eslint-plugin-tsdoc": "^0.3.0",
"eslint-plugin-unicorn": "^54.0.0",
"eslint-plugin-unicorn": "^55.0.0",
"express": "^4.19.1",
"globals": "^15.4.0",
"globby": "^14.0.1",

View File

@@ -503,7 +503,7 @@ export const render = async (data4Layout: LayoutData, svg, element, algorithm) =
// we will position the nodes when we get the layout from elkjs
elkGraph = await addVertices(nodeEl, data4Layout.nodes, elkGraph);
// Time for the edges, we start with adding an element in the node to hold the edges
const edgesEl = svg.insert('g').attr('class', 'edges edgePath');
const edgesEl = svg.insert('g').attr('class', 'edges edgePaths');
// Add the edges to the elk graph, this will entail creating the actual edges
elkGraph = await addEdges(data4Layout, elkGraph, svg);
@@ -620,7 +620,7 @@ export const render = async (data4Layout: LayoutData, svg, element, algorithm) =
}
if (endNode.isGroup) {
const bbox = endNode.domId.node().getBBox();
ew = Math.max(startNode.width, endNode.labels[0].width + endNode.padding);
ew = Math.max(endNode.width, endNode.labels[0].width + endNode.padding);
log.debug(
'UIO width',
@@ -639,12 +639,13 @@ export const render = async (data4Layout: LayoutData, svg, element, algorithm) =
y: startNode.y + startNode.height / 2 + offset.y,
});
}
if (startNode.shape === 'diamond') {
if (endNode.shape === 'diamond') {
edge.points.push({
x: endNode.x + endNode.width / 2 + offset.x,
y: endNode.y + endNode.height / 2 + offset.y,
});
}
edge.points = cutPathAtIntersect(
edge.points.reverse(),
{
@@ -660,8 +661,8 @@ export const render = async (data4Layout: LayoutData, svg, element, algorithm) =
edge.points = cutPathAtIntersect(
edge.points,
{
x: endNode.x + ew / 2 + offset.x,
y: endNode.y + endNode.height / 2 + offset.y,
x: endNode.x + ew / 2 + endNode.offset.x,
y: endNode.y + endNode.height / 2 + endNode.offset.y,
width: ew,
height: endNode.height,
padding: endNode.padding,

View File

@@ -68,12 +68,12 @@ export interface MermaidConfig {
* Defines which main look to use for the diagram.
*
*/
look?: 'classic' | 'handdrawn';
look?: 'classic' | 'handDrawn';
/**
* Defines the seed to be used when using handdrawn look. This is important for the automated tests as they will always find differences without the seed. The default value is 0 which gives a random seed.
* Defines the seed to be used when using handDrawn look. This is important for the automated tests as they will always find differences without the seed. The default value is 0 which gives a random seed.
*
*/
handdrawnSeed?: number;
handDrawnSeed?: number;
/**
* Defines which layout algorithm to use for rendering the diagram.
*

View File

@@ -8,13 +8,6 @@ import type { BlockDB } from './blockDB.js';
import { layout } from './layout.js';
import { calculateBlockSizes, insertBlocks, insertEdges } from './renderHelpers.js';
/**
* Returns the all the styles from classDef statements in the graph definition.
*
* @param text - The text with the classes
* @param diagObj - The diagram object
* @returns ClassDef - The styles
*/
export const getClasses = function (text: any, diagObj: any) {
return diagObj.db.getClasses();
};
@@ -45,8 +38,6 @@ export const draw = async function (
const markers = ['point', 'circle', 'cross'];
// Add the marker definitions to the svg as marker tags
// insertMarkers(svg, markers, diagObj.type, diagObj.arrowMarkerAbsolute);
// insertMarkers(svg, markers, diagObj.type, true);
insertMarkers(svg, markers, diagObj.type, id);
const bl = db.getBlocks();
@@ -59,11 +50,7 @@ export const draw = async function (
await insertBlocks(nodes, bl, db);
await insertEdges(nodes, edges, blArr, db, id);
// log.debug('Here', bl);
// Establish svg dimensions and get width and height
//
// const bounds2 = nodes.node().getBoundingClientRect();
// Why, oh why ????
if (bounds) {
const bounds2 = bounds;

View File

@@ -1,7 +1,7 @@
// @ts-ignore: JISON doesn't support types
import flowParser from './parser/flow.jison';
import flowDb from './flowDb.js';
import flowRendererV3 from './flowRenderer-v3-unified.js';
import renderer from './flowRenderer-v3-unified.js';
import flowStyles from './styles.js';
import type { MermaidConfig } from '../../config.type.js';
import { setConfig } from '../../diagram-api/diagramAPI.js';
@@ -9,7 +9,7 @@ import { setConfig } from '../../diagram-api/diagramAPI.js';
export const diagram = {
parser: flowParser,
db: flowDb,
renderer: flowRendererV3,
renderer,
styles: flowStyles,
init: (cnf: MermaidConfig) => {
if (!cnf.flowchart) {

View File

@@ -1,24 +1,23 @@
// @ts-ignore: JISON doesn't support types
import flowParser from './parser/flow.jison';
import flowDb from './flowDb.js';
import flowRenderer from './flowRenderer.js';
import flowRendererV2 from './flowRenderer-v2.js';
import renderer from './flowRenderer-v3-unified.js';
import flowStyles from './styles.js';
import type { MermaidConfig } from '../../config.type.js';
import { setConfig } from '../../diagram-api/diagramAPI.js';
export const diagram = {
parser: flowParser,
db: flowDb,
renderer: flowRendererV2,
renderer,
styles: flowStyles,
init: (cnf: MermaidConfig) => {
if (!cnf.flowchart) {
cnf.flowchart = {};
}
// TODO, broken as of 2022-09-14 (13809b50251845475e6dca65cc395761be38fbd2)
cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
flowRenderer.setConf(cnf.flowchart);
setConfig({ flowchart: { arrowMarkerAbsolute: cnf.arrowMarkerAbsolute } });
flowDb.clear();
flowDb.setGen('gen-1');
flowDb.setGen('gen-2');
},
};

View File

@@ -1,515 +0,0 @@
import * as graphlib from 'dagre-d3-es/src/graphlib/index.js';
import { select, curveLinear, selectAll } from 'd3';
import { getConfig } from '../../diagram-api/diagramAPI.js';
import utils, { getEdgeId } from '../../utils.js';
import { render } from '../../dagre-wrapper/index.js';
import { addHtmlLabel } from 'dagre-d3-es/src/dagre-js/label/add-html-label.js';
import { log } from '../../logger.js';
import common, { evaluate, renderKatex } from '../common/common.js';
import { interpolateToCurve, getStylesFromArray } from '../../utils.js';
import { setupGraphViewbox } from '../../setupGraphViewbox.js';
const conf = {};
export const setConf = function (cnf) {
const keys = Object.keys(cnf);
for (const key of keys) {
conf[key] = cnf[key];
}
};
/**
* Function that adds the vertices found during parsing to the graph to be rendered.
*
* @param vert Object containing the vertices.
* @param g The graph that is to be drawn.
* @param svgId
* @param root
* @param doc
* @param diagObj
*/
export const addVertices = async function (vert, g, svgId, root, doc, diagObj) {
const svg = root.select(`[id="${svgId}"]`);
const keys = vert.keys();
// Iterate through each item in the vertex object (containing all the vertices found) in the graph definition
for (const id of keys) {
const vertex = vert.get(id);
/**
* Variable for storing the classes for the vertex
*
* @type {string}
*/
let classStr = 'default';
if (vertex.classes.length > 0) {
classStr = vertex.classes.join(' ');
}
classStr = classStr + ' flowchart-label';
const styles = getStylesFromArray(vertex.styles);
// Use vertex id as text in the box if no text is provided by the graph definition
let vertexText = vertex.text !== undefined ? vertex.text : vertex.id;
// We create a SVG label, either by delegating to addHtmlLabel or manually
let vertexNode;
log.info('vertex', vertex, vertex.labelType);
if (vertex.labelType === 'markdown') {
log.info('vertex', vertex, vertex.labelType);
} else {
if (evaluate(getConfig().flowchart.htmlLabels)) {
// TODO: addHtmlLabel accepts a labelStyle. Do we possibly have that?
const node = {
label: vertexText,
};
vertexNode = addHtmlLabel(svg, node).node();
vertexNode.parentNode.removeChild(vertexNode);
} else {
const svgLabel = doc.createElementNS('http://www.w3.org/2000/svg', 'text');
svgLabel.setAttribute('style', styles.labelStyle.replace('color:', 'fill:'));
const rows = vertexText.split(common.lineBreakRegex);
for (const row of rows) {
const tspan = doc.createElementNS('http://www.w3.org/2000/svg', 'tspan');
tspan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
tspan.setAttribute('dy', '1em');
tspan.setAttribute('x', '1');
tspan.textContent = row;
svgLabel.appendChild(tspan);
}
vertexNode = svgLabel;
}
}
let radius = 0;
let _shape = '';
// Set the shape based parameters
switch (vertex.type) {
case 'round':
radius = 5;
_shape = 'rect';
break;
case 'square':
_shape = 'rect';
break;
case 'diamond':
_shape = 'question';
break;
case 'hexagon':
_shape = 'hexagon';
break;
case 'odd':
_shape = 'rect_left_inv_arrow';
break;
case 'lean_right':
_shape = 'lean_right';
break;
case 'lean_left':
_shape = 'lean_left';
break;
case 'trapezoid':
_shape = 'trapezoid';
break;
case 'inv_trapezoid':
_shape = 'inv_trapezoid';
break;
case 'odd_right':
_shape = 'rect_left_inv_arrow';
break;
case 'circle':
_shape = 'circle';
break;
case 'ellipse':
_shape = 'ellipse';
break;
case 'stadium':
_shape = 'stadium';
break;
case 'subroutine':
_shape = 'subroutine';
break;
case 'cylinder':
_shape = 'cylinder';
break;
case 'group':
_shape = 'rect';
break;
case 'doublecircle':
_shape = 'doublecircle';
break;
default:
_shape = 'rect';
}
const labelText = await renderKatex(vertexText, getConfig());
// Add the node
g.setNode(vertex.id, {
labelStyle: styles.labelStyle,
shape: _shape,
labelText,
labelType: vertex.labelType,
rx: radius,
ry: radius,
class: classStr,
style: styles.style,
id: vertex.id,
link: vertex.link,
linkTarget: vertex.linkTarget,
tooltip: diagObj.db.getTooltip(vertex.id) || '',
domId: diagObj.db.lookUpDomId(vertex.id),
haveCallback: vertex.haveCallback,
width: vertex.type === 'group' ? 500 : undefined,
dir: vertex.dir,
type: vertex.type,
props: vertex.props,
padding: getConfig().flowchart.padding,
});
log.info('setNode', {
labelStyle: styles.labelStyle,
labelType: vertex.labelType,
shape: _shape,
labelText,
rx: radius,
ry: radius,
class: classStr,
style: styles.style,
id: vertex.id,
domId: diagObj.db.lookUpDomId(vertex.id),
width: vertex.type === 'group' ? 500 : undefined,
type: vertex.type,
dir: vertex.dir,
props: vertex.props,
padding: getConfig().flowchart.padding,
});
}
};
/**
* Add edges to graph based on parsed graph definition
*
* @param {object} edges The edges to add to the graph
* @param {object} g The graph object
*/
export const addEdges = async function (edges, g) {
log.info('abc78 edges = ', edges);
let cnt = 0;
let linkIdCnt = {};
let defaultStyle;
let defaultLabelStyle;
if (edges.defaultStyle !== undefined) {
const defaultStyles = getStylesFromArray(edges.defaultStyle);
defaultStyle = defaultStyles.style;
defaultLabelStyle = defaultStyles.labelStyle;
}
for (const edge of edges) {
cnt++;
// Identify Link
const linkIdBase = getEdgeId(edge.start, edge.end, {
counter: cnt,
prefix: 'L',
});
// count the links from+to the same node to give unique id
if (linkIdCnt[linkIdBase] === undefined) {
linkIdCnt[linkIdBase] = 0;
log.info('abc78 new entry', linkIdBase, linkIdCnt[linkIdBase]);
} else {
linkIdCnt[linkIdBase]++;
log.info('abc78 new entry', linkIdBase, linkIdCnt[linkIdBase]);
}
let linkId = `${linkIdBase}_${linkIdCnt[linkIdBase]}`;
log.info('abc78 new link id to be used is', linkIdBase, linkId, linkIdCnt[linkIdBase]);
const linkNameStart = 'LS-' + edge.start;
const linkNameEnd = 'LE-' + edge.end;
const edgeData = { style: '', labelStyle: '' };
edgeData.minlen = edge.length || 1;
//edgeData.id = 'id' + cnt;
// Set link type for rendering
if (edge.type === 'arrow_open') {
edgeData.arrowhead = 'none';
} else {
edgeData.arrowhead = 'normal';
}
// Check of arrow types, placed here in order not to break old rendering
edgeData.arrowTypeStart = 'arrow_open';
edgeData.arrowTypeEnd = 'arrow_open';
/* eslint-disable no-fallthrough */
switch (edge.type) {
case 'double_arrow_cross':
edgeData.arrowTypeStart = 'arrow_cross';
case 'arrow_cross':
edgeData.arrowTypeEnd = 'arrow_cross';
break;
case 'double_arrow_point':
edgeData.arrowTypeStart = 'arrow_point';
case 'arrow_point':
edgeData.arrowTypeEnd = 'arrow_point';
break;
case 'double_arrow_circle':
edgeData.arrowTypeStart = 'arrow_circle';
case 'arrow_circle':
edgeData.arrowTypeEnd = 'arrow_circle';
break;
}
let style = '';
let labelStyle = '';
switch (edge.stroke) {
case 'normal':
style = 'fill:none;';
if (defaultStyle !== undefined) {
style = defaultStyle;
}
if (defaultLabelStyle !== undefined) {
labelStyle = defaultLabelStyle;
}
edgeData.thickness = 'normal';
edgeData.pattern = 'solid';
break;
case 'dotted':
edgeData.thickness = 'normal';
edgeData.pattern = 'dotted';
edgeData.style = 'fill:none;stroke-width:2px;stroke-dasharray:3;';
break;
case 'thick':
edgeData.thickness = 'thick';
edgeData.pattern = 'solid';
edgeData.style = 'stroke-width: 3.5px;fill:none;';
break;
case 'invisible':
edgeData.thickness = 'invisible';
edgeData.pattern = 'solid';
edgeData.style = 'stroke-width: 0;fill:none;';
break;
}
if (edge.style !== undefined) {
const styles = getStylesFromArray(edge.style);
style = styles.style;
labelStyle = styles.labelStyle;
}
edgeData.style = edgeData.style += style;
edgeData.labelStyle = edgeData.labelStyle += labelStyle;
if (edge.interpolate !== undefined) {
edgeData.curve = interpolateToCurve(edge.interpolate, curveLinear);
} else if (edges.defaultInterpolate !== undefined) {
edgeData.curve = interpolateToCurve(edges.defaultInterpolate, curveLinear);
} else {
edgeData.curve = interpolateToCurve(conf.curve, curveLinear);
}
if (edge.text === undefined) {
if (edge.style !== undefined) {
edgeData.arrowheadStyle = 'fill: #333';
}
} else {
edgeData.arrowheadStyle = 'fill: #333';
edgeData.labelpos = 'c';
}
edgeData.labelType = edge.labelType;
edgeData.label = await renderKatex(edge.text.replace(common.lineBreakRegex, '\n'), getConfig());
if (edge.style === undefined) {
edgeData.style = edgeData.style || 'stroke: #333; stroke-width: 1.5px;fill:none;';
}
edgeData.labelStyle = edgeData.labelStyle.replace('color:', 'fill:');
edgeData.id = linkId;
edgeData.classes = 'flowchart-link ' + linkNameStart + ' ' + linkNameEnd;
// Add the edge to the graph
g.setEdge(edge.start, edge.end, edgeData, cnt);
}
};
/**
* Returns the all the styles from classDef statements in the graph definition.
*
* @param text
* @param diagObj
* @returns {Map<string, import('../../diagram-api/types.js').DiagramStyleClassDef>} ClassDef styles
*/
export const getClasses = function (text, diagObj) {
return diagObj.db.getClasses();
};
/**
* Draws a flowchart in the tag with id: id based on the graph definition in text.
*
* @param text
* @param id
* @param _version
* @param diagObj
*/
export const draw = async function (text, id, _version, diagObj) {
log.info('Drawing flowchart');
// Fetch the default direction, use TD if none was found
let dir = diagObj.db.getDirection();
if (dir === undefined) {
dir = 'TD';
}
const { securityLevel, flowchart: conf } = getConfig();
const nodeSpacing = conf.nodeSpacing ?? 50;
const rankSpacing = conf.rankSpacing ?? 50;
// Handle root and document for when rendering in sandbox mode
let sandboxElement;
if (securityLevel === 'sandbox') {
sandboxElement = select('#i' + id);
}
const root =
securityLevel === 'sandbox'
? select(sandboxElement.nodes()[0].contentDocument.body)
: select('body');
const doc = securityLevel === 'sandbox' ? sandboxElement.nodes()[0].contentDocument : document;
// Create the input mermaid.graph
const g = new graphlib.Graph({
multigraph: true,
compound: true,
})
.setGraph({
rankdir: dir,
nodesep: nodeSpacing,
ranksep: rankSpacing,
marginx: 0,
marginy: 0,
})
.setDefaultEdgeLabel(function () {
return {};
});
let subG;
const subGraphs = diagObj.db.getSubGraphs();
log.info('Subgraphs - ', subGraphs);
for (let i = subGraphs.length - 1; i >= 0; i--) {
subG = subGraphs[i];
log.info('Subgraph - ', subG);
diagObj.db.addVertex(
subG.id,
{ text: subG.title, type: subG.labelType },
'group',
undefined,
subG.classes,
subG.dir
);
}
// Fetch the vertices/nodes and edges/links from the parsed graph definition
const vert = diagObj.db.getVertices();
const edges = diagObj.db.getEdges();
log.info('Edges', edges);
let i = 0;
for (i = subGraphs.length - 1; i >= 0; i--) {
subG = subGraphs[i];
selectAll('cluster').append('text');
for (const node of subG.nodes) {
log.info('Setting up subgraphs', node, subG.id);
g.setParent(node, subG.id);
}
}
await addVertices(vert, g, id, root, doc, diagObj);
await addEdges(edges, g, diagObj);
// Add custom shapes
// flowChartShapes.addToRenderV2(addShape);
// Set up an SVG group so that we can translate the final graph.
const svg = root.select(`[id="${id}"]`);
// Run the renderer. This is what draws the final graph.
const element = root.select('#' + id + ' g');
await render(element, g, ['point', 'circle', 'cross'], 'flowchart', id);
utils.insertTitle(svg, 'flowchartTitleText', conf.titleTopMargin, diagObj.db.getDiagramTitle());
setupGraphViewbox(g, svg, conf.diagramPadding, conf.useMaxWidth);
// Index nodes
diagObj.db.indexNodes('subGraph' + i);
// Add label rects for non html labels
if (!conf.htmlLabels) {
const labels = doc.querySelectorAll('[id="' + id + '"] .edgeLabel .label');
for (const label of labels) {
// Get dimensions of label
const dim = label.getBBox();
const rect = doc.createElementNS('http://www.w3.org/2000/svg', 'rect');
rect.setAttribute('rx', 0);
rect.setAttribute('ry', 0);
rect.setAttribute('width', dim.width);
rect.setAttribute('height', dim.height);
label.insertBefore(rect, label.firstChild);
}
}
// If node has a link, wrap it in an anchor SVG object.
const keys = [...vert.keys()];
keys.forEach((key) => {
const vertex = vert.get(key);
if (vertex.link) {
const node = select('#' + id + ' [id="' + key + '"]');
if (node) {
const link = doc.createElementNS('http://www.w3.org/2000/svg', 'a');
link.setAttributeNS('http://www.w3.org/2000/svg', 'class', vertex.classes.join(' '));
link.setAttributeNS('http://www.w3.org/2000/svg', 'href', vertex.link);
link.setAttributeNS('http://www.w3.org/2000/svg', 'rel', 'noopener');
if (securityLevel === 'sandbox') {
link.setAttributeNS('http://www.w3.org/2000/svg', 'target', '_top');
} else if (vertex.linkTarget) {
link.setAttributeNS('http://www.w3.org/2000/svg', 'target', vertex.linkTarget);
}
const linkNode = node.insert(function () {
return link;
}, ':first-child');
const shape = node.select('.label-container');
if (shape) {
linkNode.append(function () {
return shape.node();
});
}
const label = node.select('.label');
if (label) {
linkNode.append(function () {
return label.node();
});
}
}
}
});
};
export default {
setConf,
addVertices,
addEdges,
getClasses,
draw,
};

View File

@@ -1,150 +0,0 @@
import flowDb from './flowDb.js';
import { parser } from './parser/flow.jison';
import flowRenderer from './flowRenderer.js';
import { addDiagrams } from '../../diagram-api/diagram-orchestration.js';
const diag = {
db: flowDb,
};
addDiagrams();
describe('when using mermaid and ', function () {
describe('when calling addEdges ', function () {
beforeEach(function () {
parser.yy = flowDb;
flowDb.clear();
flowDb.setGen('gen-2');
});
it('should handle edges with text', async () => {
parser.parse('graph TD;A-->|text ex|B;');
flowDb.getVertices();
const edges = flowDb.getEdges();
const mockG = {
setEdge: function (start, end, options) {
expect(start).toContain('flowchart-A-');
expect(end).toContain('flowchart-B-');
expect(options.arrowhead).toBe('normal');
expect(options.label.match('text ex')).toBeTruthy();
},
};
await flowRenderer.addEdges(edges, mockG, diag);
});
it('should handle edges without text', async function () {
parser.parse('graph TD;A-->B;');
flowDb.getVertices();
const edges = flowDb.getEdges();
const mockG = {
setEdge: function (start, end, options) {
expect(start).toContain('flowchart-A-');
expect(end).toContain('flowchart-B-');
expect(options.arrowhead).toBe('normal');
},
};
await flowRenderer.addEdges(edges, mockG, diag);
});
it('should handle open-ended edges', async () => {
parser.parse('graph TD;A---B;');
flowDb.getVertices();
const edges = flowDb.getEdges();
const mockG = {
setEdge: function (start, end, options) {
expect(start).toContain('flowchart-A-');
expect(end).toContain('flowchart-B-');
expect(options.arrowhead).toBe('none');
},
};
await flowRenderer.addEdges(edges, mockG, diag);
});
it('should handle edges with styles defined', async () => {
parser.parse('graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2;');
flowDb.getVertices();
const edges = flowDb.getEdges();
const mockG = {
setEdge: function (start, end, options) {
expect(start).toContain('flowchart-A-');
expect(end).toContain('flowchart-B-');
expect(options.arrowhead).toBe('none');
expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:none;');
},
};
await flowRenderer.addEdges(edges, mockG, diag);
});
it('should handle edges with interpolation defined', async () => {
parser.parse('graph TD;A---B; linkStyle 0 interpolate basis');
flowDb.getVertices();
const edges = flowDb.getEdges();
const mockG = {
setEdge: function (start, end, options) {
expect(start).toContain('flowchart-A-');
expect(end).toContain('flowchart-B-');
expect(options.arrowhead).toBe('none');
expect(options.curve).toBe('basis'); // mocked as string
},
};
await flowRenderer.addEdges(edges, mockG, diag);
});
it('should handle edges with text and styles defined', async () => {
parser.parse('graph TD;A---|the text|B; linkStyle 0 stroke:val1,stroke-width:val2;');
flowDb.getVertices();
const edges = flowDb.getEdges();
const mockG = {
setEdge: function (start, end, options) {
expect(start).toContain('flowchart-A-');
expect(end).toContain('flowchart-B-');
expect(options.arrowhead).toBe('none');
expect(options.label.match('the text')).toBeTruthy();
expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:none;');
},
};
await flowRenderer.addEdges(edges, mockG, diag);
});
it('should set fill to "none" by default when handling edges', async () => {
parser.parse('graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2;');
flowDb.getVertices();
const edges = flowDb.getEdges();
const mockG = {
setEdge: function (start, end, options) {
expect(start).toContain('flowchart-A-');
expect(end).toContain('flowchart-B');
expect(options.arrowhead).toBe('none');
expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:none;');
},
};
await flowRenderer.addEdges(edges, mockG, diag);
});
it('should not set fill to none if fill is set in linkStyle', async () => {
parser.parse('graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2,fill:blue;');
flowDb.getVertices();
const edges = flowDb.getEdges();
const mockG = {
setEdge: function (start, end, options) {
expect(start).toContain('flowchart-A-');
expect(end).toContain('flowchart-B-');
expect(options.arrowhead).toBe('none');
expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:blue;');
},
};
await flowRenderer.addEdges(edges, mockG, diag);
});
});
});

View File

@@ -1,503 +0,0 @@
import * as graphlib from 'dagre-d3-es/src/graphlib/index.js';
import { select, curveLinear, selectAll } from 'd3';
import { getConfig } from '../../diagram-api/diagramAPI.js';
import { render as Render } from 'dagre-d3-es';
import { applyStyle } from 'dagre-d3-es/src/dagre-js/util.js';
import { addHtmlLabel } from 'dagre-d3-es/src/dagre-js/label/add-html-label.js';
import { log } from '../../logger.js';
import common, { evaluate, renderKatex } from '../common/common.js';
import { interpolateToCurve, getStylesFromArray, getEdgeId } from '../../utils.js';
import { setupGraphViewbox } from '../../setupGraphViewbox.js';
import flowChartShapes from './flowChartShapes.js';
import { replaceIconSubstring } from '../../rendering-util/createText.js';
const conf = {};
export const setConf = function (cnf) {
const keys = Object.keys(cnf);
for (const key of keys) {
conf[key] = cnf[key];
}
};
/**
* Function that adds the vertices found in the graph definition to the graph to be rendered.
*
* @param vert Object containing the vertices.
* @param g The graph that is to be drawn.
* @param svgId
* @param root
* @param _doc
* @param diagObj
*/
export const addVertices = async function (vert, g, svgId, root, _doc, diagObj) {
const svg = !root ? select(`[id="${svgId}"]`) : root.select(`[id="${svgId}"]`);
const doc = !_doc ? document : _doc;
const keys = Object.keys(vert);
// Iterate through each item in the vertex object (containing all the vertices found) in the graph definition
for (const id of keys) {
const vertex = vert[id];
/**
* Variable for storing the classes for the vertex
*
* @type {string}
*/
let classStr = 'default';
if (vertex.classes.length > 0) {
classStr = vertex.classes.join(' ');
}
const styles = getStylesFromArray(vertex.styles);
// Use vertex id as text in the box if no text is provided by the graph definition
let vertexText = vertex.text !== undefined ? vertex.text : vertex.id;
// We create a SVG label, either by delegating to addHtmlLabel or manually
let vertexNode;
if (evaluate(getConfig().flowchart.htmlLabels)) {
// TODO: addHtmlLabel accepts a labelStyle. Do we possibly have that?
const replacedVertexText = replaceIconSubstring(vertexText);
const node = {
label: await renderKatex(replacedVertexText, getConfig()),
};
vertexNode = addHtmlLabel(svg, node).node();
vertexNode.parentNode.removeChild(vertexNode);
} else {
const svgLabel = doc.createElementNS('http://www.w3.org/2000/svg', 'text');
svgLabel.setAttribute('style', styles.labelStyle.replace('color:', 'fill:'));
const rows = vertexText.split(common.lineBreakRegex);
for (const row of rows) {
const tspan = doc.createElementNS('http://www.w3.org/2000/svg', 'tspan');
tspan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
tspan.setAttribute('dy', '1em');
tspan.setAttribute('x', '1');
tspan.textContent = row;
svgLabel.appendChild(tspan);
}
vertexNode = svgLabel;
}
let radius = 0;
let _shape = '';
// Set the shape based parameters
switch (vertex.type) {
case 'round':
radius = 5;
_shape = 'rect';
break;
case 'square':
_shape = 'rect';
break;
case 'diamond':
_shape = 'question';
break;
case 'hexagon':
_shape = 'hexagon';
break;
case 'odd':
_shape = 'rect_left_inv_arrow';
break;
case 'lean_right':
_shape = 'lean_right';
break;
case 'lean_left':
_shape = 'lean_left';
break;
case 'trapezoid':
_shape = 'trapezoid';
break;
case 'inv_trapezoid':
_shape = 'inv_trapezoid';
break;
case 'odd_right':
_shape = 'rect_left_inv_arrow';
break;
case 'circle':
_shape = 'circle';
break;
case 'ellipse':
_shape = 'ellipse';
break;
case 'stadium':
_shape = 'stadium';
break;
case 'subroutine':
_shape = 'subroutine';
break;
case 'cylinder':
_shape = 'cylinder';
break;
case 'group':
_shape = 'rect';
break;
default:
_shape = 'rect';
}
// Add the node
log.warn('Adding node', vertex.id, vertex.domId);
g.setNode(diagObj.db.lookUpDomId(vertex.id), {
labelType: 'svg',
labelStyle: styles.labelStyle,
shape: _shape,
label: vertexNode,
rx: radius,
ry: radius,
class: classStr,
style: styles.style,
id: diagObj.db.lookUpDomId(vertex.id),
});
}
};
/**
* Add edges to graph based on parsed graph definition
*
* @param {object} edges The edges to add to the graph
* @param {object} g The graph object
* @param diagObj
*/
export const addEdges = async function (edges, g, diagObj) {
let cnt = 0;
let defaultStyle;
let defaultLabelStyle;
if (edges.defaultStyle !== undefined) {
const defaultStyles = getStylesFromArray(edges.defaultStyle);
defaultStyle = defaultStyles.style;
defaultLabelStyle = defaultStyles.labelStyle;
}
for (const edge of edges) {
cnt++;
// Identify Link
const linkId = getEdgeId(edge.start, edge.end, {
counter: cnt,
prefix: 'L',
});
const linkNameStart = 'LS-' + edge.start;
const linkNameEnd = 'LE-' + edge.end;
const edgeData = {};
// Set link type for rendering
if (edge.type === 'arrow_open') {
edgeData.arrowhead = 'none';
} else {
edgeData.arrowhead = 'normal';
}
let style = '';
let labelStyle = '';
if (edge.style !== undefined) {
const styles = getStylesFromArray(edge.style);
style = styles.style;
labelStyle = styles.labelStyle;
} else {
switch (edge.stroke) {
case 'normal':
style = 'fill:none';
if (defaultStyle !== undefined) {
style = defaultStyle;
}
if (defaultLabelStyle !== undefined) {
labelStyle = defaultLabelStyle;
}
break;
case 'dotted':
style = 'fill:none;stroke-width:2px;stroke-dasharray:3;';
break;
case 'thick':
style = ' stroke-width: 3.5px;fill:none';
break;
}
}
edgeData.style = style;
edgeData.labelStyle = labelStyle;
if (edge.interpolate !== undefined) {
edgeData.curve = interpolateToCurve(edge.interpolate, curveLinear);
} else if (edges.defaultInterpolate !== undefined) {
edgeData.curve = interpolateToCurve(edges.defaultInterpolate, curveLinear);
} else {
edgeData.curve = interpolateToCurve(conf.curve, curveLinear);
}
if (edge.text === undefined) {
if (edge.style !== undefined) {
edgeData.arrowheadStyle = 'fill: #333';
}
} else {
edgeData.arrowheadStyle = 'fill: #333';
edgeData.labelpos = 'c';
if (evaluate(getConfig().flowchart.htmlLabels)) {
edgeData.labelType = 'html';
edgeData.label = `<span id="L-${linkId}" class="edgeLabel L-${linkNameStart}' L-${linkNameEnd}" style="${
edgeData.labelStyle
}">${await renderKatex(replaceIconSubstring(edge.text), getConfig())}</span>`;
} else {
edgeData.labelType = 'text';
edgeData.label = edge.text.replace(common.lineBreakRegex, '\n');
if (edge.style === undefined) {
edgeData.style = edgeData.style || 'stroke: #333; stroke-width: 1.5px;fill:none';
}
edgeData.labelStyle = edgeData.labelStyle.replace('color:', 'fill:');
}
}
edgeData.id = linkId;
edgeData.class = linkNameStart + ' ' + linkNameEnd;
edgeData.minlen = edge.length || 1;
// Add the edge to the graph
g.setEdge(diagObj.db.lookUpDomId(edge.start), diagObj.db.lookUpDomId(edge.end), edgeData, cnt);
}
};
/**
* Returns the all the styles from classDef statements in the graph definition.
*
* @param text
* @param diagObj
* @returns {Map<string, import('../../diagram-api/types.js').DiagramStyleClassDef>} ClassDef styles
*/
export const getClasses = function (text, diagObj) {
log.info('Extracting classes');
return diagObj.db.getClasses();
};
/**
* Draws a flowchart in the tag with id: id based on the graph definition in text.
*
* @param text
* @param id
* @param _version
* @param diagObj
*/
export const draw = async function (text, id, _version, diagObj) {
log.info('Drawing flowchart');
const { securityLevel, flowchart: conf } = getConfig();
let sandboxElement;
if (securityLevel === 'sandbox') {
sandboxElement = select('#i' + id);
}
const root =
securityLevel === 'sandbox'
? select(sandboxElement.nodes()[0].contentDocument.body)
: select('body');
const doc = securityLevel === 'sandbox' ? sandboxElement.nodes()[0].contentDocument : document;
// Fetch the default direction, use TD if none was found
let dir = diagObj.db.getDirection();
if (dir === undefined) {
dir = 'TD';
}
const nodeSpacing = conf.nodeSpacing ?? 50;
const rankSpacing = conf.rankSpacing ?? 50;
// Create the input mermaid.graph
const g = new graphlib.Graph({
multigraph: true,
compound: true,
})
.setGraph({
rankdir: dir,
nodesep: nodeSpacing,
ranksep: rankSpacing,
marginx: 8,
marginy: 8,
})
.setDefaultEdgeLabel(function () {
return {};
});
let subG;
const subGraphs = diagObj.db.getSubGraphs();
for (let i = subGraphs.length - 1; i >= 0; i--) {
subG = subGraphs[i];
diagObj.db.addVertex(subG.id, subG.title, 'group', undefined, subG.classes);
}
// Fetch the vertices/nodes and edges/links from the parsed graph definition
const vert = diagObj.db.getVertices();
log.warn('Get vertices', vert);
const edges = diagObj.db.getEdges();
let i = 0;
for (i = subGraphs.length - 1; i >= 0; i--) {
subG = subGraphs[i];
selectAll('cluster').append('text');
for (const node of subG.nodes) {
log.warn(
'Setting subgraph',
node,
diagObj.db.lookUpDomId(node),
diagObj.db.lookUpDomId(subG.id)
);
g.setParent(diagObj.db.lookUpDomId(node), diagObj.db.lookUpDomId(subG.id));
}
}
await addVertices(vert, g, id, root, doc, diagObj);
await addEdges(edges, g, diagObj);
// Create the renderer
const render = new Render();
// Add custom shapes
flowChartShapes.addToRender(render);
// Add our custom arrow - an empty arrowhead
render.arrows().none = function normal(parent, id, edge, type) {
const marker = parent
.append('marker')
.attr('id', id)
.attr('viewBox', '0 0 10 10')
.attr('refX', 9)
.attr('refY', 5)
.attr('markerUnits', 'strokeWidth')
.attr('markerWidth', 8)
.attr('markerHeight', 6)
.attr('orient', 'auto');
const path = marker.append('path').attr('d', 'M 0 0 L 0 0 L 0 0 z');
applyStyle(path, edge[type + 'Style']);
};
// Override normal arrowhead defined in d3. Remove style & add class to allow css styling.
render.arrows().normal = function normal(parent, id) {
const marker = parent
.append('marker')
.attr('id', id)
.attr('viewBox', '0 0 10 10')
.attr('refX', 9)
.attr('refY', 5)
.attr('markerUnits', 'strokeWidth')
.attr('markerWidth', 8)
.attr('markerHeight', 6)
.attr('orient', 'auto');
marker
.append('path')
.attr('d', 'M 0 0 L 10 5 L 0 10 z')
.attr('class', 'arrowheadPath')
.style('stroke-width', 1)
.style('stroke-dasharray', '1,0');
};
// Set up an SVG group so that we can translate the final graph.
const svg = root.select(`[id="${id}"]`);
// Run the renderer. This is what draws the final graph.
const element = root.select('#' + id + ' g');
render(element, g);
element.selectAll('g.node').attr('title', function () {
return diagObj.db.getTooltip(this.id);
});
// Index nodes
diagObj.db.indexNodes('subGraph' + i);
// reposition labels
for (i = 0; i < subGraphs.length; i++) {
subG = subGraphs[i];
if (subG.title !== 'undefined') {
const clusterRects = doc.querySelectorAll(
'#' + id + ' [id="' + diagObj.db.lookUpDomId(subG.id) + '"] rect'
);
const clusterEl = doc.querySelectorAll(
'#' + id + ' [id="' + diagObj.db.lookUpDomId(subG.id) + '"]'
);
const xPos = clusterRects[0].x.baseVal.value;
const yPos = clusterRects[0].y.baseVal.value;
const _width = clusterRects[0].width.baseVal.value;
const cluster = select(clusterEl[0]);
const te = cluster.select('.label');
te.attr('transform', `translate(${xPos + _width / 2}, ${yPos + 14})`);
te.attr('id', id + 'Text');
for (const className of subG.classes) {
clusterEl[0].classList.add(className);
}
}
}
// Add label rects for non html labels
if (!conf.htmlLabels) {
const labels = doc.querySelectorAll('[id="' + id + '"] .edgeLabel .label');
for (const label of labels) {
// Get dimensions of label
const dim = label.getBBox();
const rect = doc.createElementNS('http://www.w3.org/2000/svg', 'rect');
rect.setAttribute('rx', 0);
rect.setAttribute('ry', 0);
rect.setAttribute('width', dim.width);
rect.setAttribute('height', dim.height);
// rect.setAttribute('style', 'fill:#e8e8e8;');
label.insertBefore(rect, label.firstChild);
}
}
setupGraphViewbox(g, svg, conf.diagramPadding, conf.useMaxWidth);
// If node has a link, wrap it in an anchor SVG object.
const keys = [...vert.keys()];
keys.forEach(function (key) {
const vertex = vert.get(key);
if (vertex.link) {
const node = root.select('#' + id + ' [id="' + diagObj.db.lookUpDomId(key) + '"]');
if (node) {
const link = doc.createElementNS('http://www.w3.org/2000/svg', 'a');
link.setAttributeNS('http://www.w3.org/2000/svg', 'class', vertex.classes.join(' '));
link.setAttributeNS('http://www.w3.org/2000/svg', 'href', vertex.link);
link.setAttributeNS('http://www.w3.org/2000/svg', 'rel', 'noopener');
if (securityLevel === 'sandbox') {
link.setAttributeNS('http://www.w3.org/2000/svg', 'target', '_top');
} else if (vertex.linkTarget) {
link.setAttributeNS('http://www.w3.org/2000/svg', 'target', vertex.linkTarget);
}
const linkNode = node.insert(function () {
return link;
}, ':first-child');
const shape = node.select('.label-container');
if (shape) {
linkNode.append(function () {
return shape.node();
});
}
const label = node.select('.label');
if (label) {
linkNode.append(function () {
return label.node();
});
}
}
}
});
};
export default {
setConf,
addVertices,
addEdges,
getClasses,
draw,
};

View File

@@ -1,277 +0,0 @@
/* eslint-disable @typescript-eslint/restrict-template-expressions */
import { addVertices, addEdges } from './flowRenderer.js';
import { setConfig } from '../../diagram-api/diagramAPI.js';
setConfig({
flowchart: {
htmlLabels: false,
},
});
describe('the flowchart renderer', function () {
describe('when adding vertices to a graph', function () {
[
['round', 'rect', 5],
['square', 'rect'],
['diamond', 'question'],
['hexagon', 'hexagon'],
['odd', 'rect_left_inv_arrow'],
['lean_right', 'lean_right'],
['lean_left', 'lean_left'],
['trapezoid', 'trapezoid'],
['inv_trapezoid', 'inv_trapezoid'],
['odd_right', 'rect_left_inv_arrow'],
['circle', 'circle'],
['ellipse', 'ellipse'],
['stadium', 'stadium'],
['subroutine', 'subroutine'],
['cylinder', 'cylinder'],
['group', 'rect'],
].forEach(function ([type, expectedShape, expectedRadios = 0]) {
it(`should add the correct shaped node to the graph for vertex type ${type}`, async function () {
const fakeDiag = {
db: {
lookUpDomId: () => {
return 'my-node-id';
},
},
};
const addedNodes = [];
const mockG = {
setNode: function (id, object) {
addedNodes.push([id, object]);
},
};
await addVertices(
{
v1: {
type,
id: 'my-node-id',
classes: [],
styles: [],
text: 'my vertex text',
},
},
mockG,
'svg-id',
undefined,
undefined,
fakeDiag
);
expect(addedNodes).toHaveLength(1);
expect(addedNodes[0][0]).toEqual('my-node-id');
expect(addedNodes[0][1]).toHaveProperty('id', 'my-node-id');
expect(addedNodes[0][1]).toHaveProperty('labelType', 'svg');
expect(addedNodes[0][1]).toHaveProperty('shape', expectedShape);
expect(addedNodes[0][1]).toHaveProperty('rx', expectedRadios);
expect(addedNodes[0][1]).toHaveProperty('ry', expectedRadios);
});
});
['Multi<br>Line', 'Multi<br/>Line', 'Multi<br />Line', 'Multi<br\t/>Line'].forEach(
function (labelText) {
it('should handle multiline texts with different line breaks', async function () {
const addedNodes = [];
const fakeDiag = {
db: {
lookUpDomId: () => {
return 'my-node-id';
},
},
};
const mockG = {
setNode: function (id, object) {
addedNodes.push([id, object]);
},
};
await addVertices(
{
v1: {
type: 'rect',
id: 'my-node-id',
classes: [],
styles: [],
text: 'Multi<br>Line',
},
},
mockG,
'svg-id',
false,
document,
fakeDiag
);
expect(addedNodes).toHaveLength(1);
expect(addedNodes[0][0]).toEqual('my-node-id');
expect(addedNodes[0][1]).toHaveProperty('id', 'my-node-id');
expect(addedNodes[0][1]).toHaveProperty('labelType', 'svg');
expect(addedNodes[0][1].label).toBeDefined();
expect(addedNodes[0][1].label).toBeDefined(); // <text> node
expect(addedNodes[0][1].label.firstChild.innerHTML).toEqual('Multi'); // <tspan> node, line 1
expect(addedNodes[0][1].label.lastChild.innerHTML).toEqual('Line'); // <tspan> node, line 2
});
}
);
[
[['fill:#fff'], 'fill:#fff;', ''],
[['color:#ccc'], '', 'color:#ccc;'],
[['fill:#fff', 'color:#ccc'], 'fill:#fff;', 'color:#ccc;'],
[
['fill:#fff', 'color:#ccc', 'text-align:center'],
'fill:#fff;',
'color:#ccc;text-align:center;',
],
].forEach(function ([style, expectedStyle, expectedLabelStyle]) {
it(`should add the styles to style and/or labelStyle for style ${style}`, async function () {
const addedNodes = [];
const fakeDiag = {
db: {
lookUpDomId: () => {
return 'my-node-id';
},
},
};
const mockG = {
setNode: function (id, object) {
addedNodes.push([id, object]);
},
};
await addVertices(
{
v1: {
type: 'rect',
id: 'my-node-id',
classes: [],
styles: style,
text: 'my vertex text',
},
},
mockG,
'svg-id',
undefined,
undefined,
fakeDiag
);
expect(addedNodes).toHaveLength(1);
expect(addedNodes[0][0]).toEqual('my-node-id');
expect(addedNodes[0][1]).toHaveProperty('id', 'my-node-id');
expect(addedNodes[0][1]).toHaveProperty('labelType', 'svg');
expect(addedNodes[0][1]).toHaveProperty('style', expectedStyle);
expect(addedNodes[0][1]).toHaveProperty('labelStyle', expectedLabelStyle);
});
});
it(`should add default class to all nodes which do not have another class assigned`, async function () {
const addedNodes = [];
const mockG = {
setNode: function (id, object) {
addedNodes.push([id, object]);
},
};
const fakeDiag = {
db: {
lookUpDomId: () => {
return 'my-node-id';
},
},
};
await addVertices(
{
v1: {
type: 'rect',
id: 'my-node-id',
classes: [],
styles: [],
text: 'my vertex text',
},
v2: {
type: 'rect',
id: 'myNode',
classes: ['myClass'],
styles: [],
text: 'my vertex text',
},
},
mockG,
'svg-id',
undefined,
undefined,
fakeDiag
);
expect(addedNodes).toHaveLength(2);
expect(addedNodes[0][0]).toEqual('my-node-id');
expect(addedNodes[0][1]).toHaveProperty('class', 'default');
expect(addedNodes[1][0]).toEqual('my-node-id');
expect(addedNodes[1][1]).toHaveProperty('class', 'myClass');
});
});
describe('when adding edges to a graph', function () {
it('should handle multiline texts and set centered label position', async function () {
const addedEdges = [];
const fakeDiag = {
db: {
lookUpDomId: () => {
return 'my-node-id';
},
},
};
const mockG = {
setEdge: function (s, e, data, c) {
addedEdges.push(data);
},
};
await addEdges(
[
{ text: 'Multi<br>Line' },
{ text: 'Multi<br/>Line' },
{ text: 'Multi<br />Line' },
{ text: 'Multi<br\t/>Line' },
{ style: ['stroke:DarkGray', 'stroke-width:2px'], text: 'Multi<br>Line' },
{ style: ['stroke:DarkGray', 'stroke-width:2px'], text: 'Multi<br/>Line' },
{ style: ['stroke:DarkGray', 'stroke-width:2px'], text: 'Multi<br />Line' },
{ style: ['stroke:DarkGray', 'stroke-width:2px'], text: 'Multi<br\t/>Line' },
],
mockG,
fakeDiag
);
addedEdges.forEach(function (edge) {
expect(edge).toHaveProperty('label', 'Multi\nLine');
expect(edge).toHaveProperty('labelpos', 'c');
});
});
[
[['stroke:DarkGray'], 'stroke:DarkGray;', ''],
[['color:red'], '', 'fill:red;'],
[['stroke:DarkGray', 'color:red'], 'stroke:DarkGray;', 'fill:red;'],
[
['stroke:DarkGray', 'color:red', 'stroke-width:2px'],
'stroke:DarkGray;stroke-width:2px;',
'fill:red;',
],
].forEach(function ([style, expectedStyle, expectedLabelStyle]) {
it(`should add the styles to style and/or labelStyle for style ${style}`, async function () {
const addedEdges = [];
const fakeDiag = {
db: {
lookUpDomId: () => {
return 'my-node-id';
},
},
};
const mockG = {
setEdge: function (s, e, data, c) {
addedEdges.push(data);
},
};
await addEdges([{ style: style, text: 'styling' }], mockG, fakeDiag);
expect(addedEdges).toHaveLength(1);
expect(addedEdges[0]).toHaveProperty('style', expectedStyle);
expect(addedEdges[0]).toHaveProperty('labelStyle', expectedLabelStyle);
});
});
});
});

View File

@@ -59,7 +59,7 @@ const getStyles = (options: FlowChartStyleOptions) =>
stroke: ${options.nodeBorder};
stroke-width: 1px;
}
.node .label text {
.rough-node .label text , .node .label text {
text-anchor: middle;
}
// .flowchart-label .text-outer-tspan {

View File

@@ -23,7 +23,7 @@ export interface FlowEdge {
end: string;
interpolate?: string;
type?: string;
stroke?: 'normal' | 'thick' | 'invisible';
stroke?: 'normal' | 'thick' | 'invisible' | 'dotted';
style?: string[];
length?: number;
text: string;

View File

@@ -1088,6 +1088,19 @@ export const draw = async function (_text: string, id: string, _version: string,
const { bounds: box } = bounds.getBounds();
if (box.startx === undefined) {
box.startx = 0;
}
if (box.starty === undefined) {
box.starty = 0;
}
if (box.stopx === undefined) {
box.stopx = 0;
}
if (box.stopy === undefined) {
box.stopy = 0;
}
// Make sure the height of the diagram supports long menus.
let boxHeight = box.stopy - box.starty;
if (boxHeight < requiredBoxSize.maxHeight) {

View File

@@ -131,12 +131,6 @@ const getDir = (parsedItem, defaultDir = DEFAULT_NESTED_DOC_DIR) => {
return dir;
};
/**
*
* @param nodes
* @param nodeData
* @param classes
*/
function insertOrUpdateNode(nodes, nodeData, classes) {
if (!nodeData.id || nodeData.id === '</join></fork>' || nodeData.id === '</choice>') {
return;

View File

@@ -11,12 +11,12 @@ import { createRoundedRectPathD } from './shapes/roundedRectPath.ts';
import {
styles2String,
userNodeOverrides,
} from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
} from '$root/rendering-util/rendering-elements/shapes/handDrawnShapeStyles.js';
const rect = async (parent, node) => {
log.info('Creating subgraph rect for ', node.id, node);
const siteConfig = getConfig();
const { themeVariables, handdrawnSeed } = siteConfig;
const { themeVariables, handDrawnSeed } = siteConfig;
const { clusterBkg, clusterBorder } = themeVariables;
const { labelStyles, nodeStyles } = styles2String(node);
@@ -33,9 +33,6 @@ const rect = async (parent, node) => {
// Create the label and insert it after the rect
const labelEl = shapeSvg.insert('g').attr('class', 'cluster-label ');
// const text = label
// .node()
// .appendChild(createLabel(node.label, node.labelStyle, undefined, true));
const text = await createText(labelEl, node.label, {
style: node.labelStyle,
useHtmlLabels,
@@ -53,10 +50,7 @@ const rect = async (parent, node) => {
dv.attr('height', bbox.height);
}
const padding = 0 * node.padding;
const width =
(node.width <= bbox.width + node.padding ? bbox.width + node.padding : node.width) + padding;
const width = node.width <= bbox.width + node.padding ? bbox.width + node.padding : node.width;
if (node.width <= bbox.width + node.padding) {
node.diff = (width - node.width) / 2 - node.padding;
} else {
@@ -66,11 +60,10 @@ const rect = async (parent, node) => {
const height = node.height;
const x = node.x - width / 2;
const y = node.y - height / 2;
// console.log('UIO diff 2', node.id, node.diff, 'totalWidth: ', width);
log.trace('Data ', node, JSON.stringify(node));
let rect;
if (node.look === 'handdrawn') {
if (node.look === 'handDrawn') {
// @ts-ignore TODO: Fix rough typings
const rc = rough.svg(shapeSvg);
const options = userNodeOverrides(node, {
@@ -79,10 +72,9 @@ const rect = async (parent, node) => {
// fill: 'red',
stroke: clusterBorder,
fillWeight: 3,
seed: handdrawnSeed,
seed: handDrawnSeed,
});
const roughNode = rc.path(createRoundedRectPathD(x, y, width, height, 0), options);
// console.log('Rough node insert CXC', roughNode);
rect = shapeSvg.insert(() => {
log.debug('Rough node insert CXC', roughNode);
return roughNode;
@@ -170,7 +162,7 @@ const noteGroup = (parent, node) => {
const roundedWithTitle = async (parent, node) => {
const siteConfig = getConfig();
const { themeVariables, handdrawnSeed } = siteConfig;
const { themeVariables, handDrawnSeed } = siteConfig;
const { altBackground, compositeBackground, compositeTitleBackground, nodeBorder } =
themeVariables;
@@ -226,7 +218,7 @@ const roundedWithTitle = async (parent, node) => {
// add the rect
let rect;
if (node.look === 'handdrawn') {
if (node.look === 'handDrawn') {
const isAlt = node.cssClasses.includes('statediagram-cluster-alt');
const rc = rough.svg(shapeSvg);
const roughOuterNode =
@@ -236,16 +228,16 @@ const roundedWithTitle = async (parent, node) => {
fill: compositeTitleBackground,
fillStyle: 'solid',
stroke: nodeBorder,
seed: handdrawnSeed,
seed: handDrawnSeed,
})
: rc.rectangle(x, y, width, height, { seed: handdrawnSeed });
: rc.rectangle(x, y, width, height, { seed: handDrawnSeed });
rect = shapeSvg.insert(() => roughOuterNode, ':first-child');
const roughInnerNode = rc.rectangle(x, innerY, width, innerHeight, {
fill: isAlt ? altBackground : compositeBackground,
fillStyle: isAlt ? 'hachure' : 'solid',
stroke: nodeBorder,
seed: handdrawnSeed,
seed: handDrawnSeed,
});
rect = shapeSvg.insert(() => roughOuterNode, ':first-child');
@@ -291,7 +283,7 @@ const roundedWithTitle = async (parent, node) => {
const divider = (parent, node) => {
const siteConfig = getConfig();
const { themeVariables, handdrawnSeed } = siteConfig;
const { themeVariables, handDrawnSeed } = siteConfig;
const { nodeBorder } = themeVariables;
// Add outer g element
@@ -318,14 +310,14 @@ const divider = (parent, node) => {
// add the rect
let rect;
if (node.look === 'handdrawn') {
if (node.look === 'handDrawn') {
const rc = rough.svg(shapeSvg);
const roughOuterNode = rc.rectangle(x, y, width, height, {
fill: 'lightgrey',
roughness: 0.5,
strokeLineDash: [5],
stroke: nodeBorder,
seed: handdrawnSeed,
seed: handDrawnSeed,
});
rect = shapeSvg.insert(() => roughOuterNode, ':first-child');
@@ -365,14 +357,15 @@ const shapes = {
divider,
};
let clusterElems = {};
let clusterElems = new Map();
export const insertCluster = (elem, node) => {
export const insertCluster = async (elem, node) => {
const shape = node.shape || 'rect';
const cluster = shapes[shape](elem, node);
clusterElems[node.id] = cluster;
const cluster = await shapes[shape](elem, node);
clusterElems.set(node.id, cluster);
return cluster;
};
export const getClusterTitleWidth = (elem, node) => {
const label = createLabel(node.label, node.labelStyle, undefined, true);
elem.node().appendChild(label);
@@ -382,7 +375,7 @@ export const getClusterTitleWidth = (elem, node) => {
};
export const clear = () => {
clusterElems = {};
clusterElems = new Map();
};
export const positionCluster = (node) => {
@@ -398,8 +391,8 @@ export const positionCluster = (node) => {
', ' +
node?.height +
')',
clusterElems[node.id]
clusterElems.get(node.id)
);
const el = clusterElems[node.id];
const el = clusterElems.get(node.id);
el.cluster.attr('transform', 'translate(' + node.x + ', ' + node.y + ')');
};

View File

@@ -31,7 +31,7 @@ async function addHtmlLabel(node) {
'<span class="' +
labelClass +
'" ' +
(node.labelStyle ? 'style="' + node.labelStyle + '"' : '') +
(node.labelStyle ? 'style="' + node.labelStyle + '"' : '') + // codeql [js/html-constructed-from-input] : false positive
'>' +
label +
'</span>'

View File

@@ -423,7 +423,7 @@ const fixCorners = function (lineData) {
};
export const insertEdge = function (elem, edge, clusterDb, diagramType, startNode, endNode, id) {
const { handdrawnSeed } = getConfig();
const { handDrawnSeed } = getConfig();
let points = edge.points;
let pointsHasChanged = false;
const tail = startNode;
@@ -510,13 +510,13 @@ export const insertEdge = function (elem, edge, clusterDb, diagramType, startNod
let svgPath;
let linePath = lineFunction(lineData);
const edgeStyles = Array.isArray(edge.style) ? edge.style : [edge.style];
if (edge.look === 'handdrawn') {
if (edge.look === 'handDrawn') {
const rc = rough.svg(elem);
Object.assign([], lineData);
const svgPathNode = rc.path(linePath, {
roughness: 0.3,
seed: handdrawnSeed,
seed: handDrawnSeed,
});
strokeClasses += ' transition';

View File

@@ -3,7 +3,7 @@ import type { Node } from '$root/rendering-util/types.d.ts';
import type { SVG } from '$root/diagram-api/types.js';
// @ts-ignore TODO: Fix rough typings
import rough from 'roughjs';
import { solidStateFill, styles2String } from './handdrawnStyles.js';
import { solidStateFill, styles2String } from './handDrawnShapeStyles.js';
import { getConfig } from '$root/diagram-api/diagramAPI.js';
export const choice = (parent: SVG, node: Node) => {
@@ -25,7 +25,7 @@ export const choice = (parent: SVG, node: Node) => {
];
let choice;
if (node.look === 'handdrawn') {
if (node.look === 'handDrawn') {
// @ts-ignore TODO: Fix rough typings
const rc = rough.svg(shapeSvg);
const pointArr = points.map(function (d) {

View File

@@ -5,7 +5,7 @@ import type { Node } from '$root/rendering-util/types.d.ts';
import {
styles2String,
userNodeOverrides,
} from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
} from '$root/rendering-util/rendering-elements/shapes/handDrawnShapeStyles.js';
import rough from 'roughjs';
export const circle = async (parent: SVGAElement, node: Node): Promise<SVGAElement> => {
@@ -17,7 +17,7 @@ export const circle = async (parent: SVGAElement, node: Node): Promise<SVGAEleme
let circleElem;
const { cssStyles } = node;
if (node.look === 'handdrawn') {
if (node.look === 'handDrawn') {
// @ts-ignore - rough is not typed
const rc = rough.svg(shapeSvg);
const options = userNodeOverrides(node, {});

View File

@@ -4,7 +4,7 @@ import type { Node } from '$root/rendering-util/types.d.ts';
import {
styles2String,
userNodeOverrides,
} from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
} from '$root/rendering-util/rendering-elements/shapes/handDrawnShapeStyles.js';
import rough from 'roughjs';
export const createCylinderPathD = (
@@ -63,7 +63,7 @@ export const cylinder = async (parent: SVGAElement, node: Node) => {
let cylinder: d3.Selection<SVGPathElement | SVGGElement, unknown, null, undefined>;
const { cssStyles } = node;
if (node.look === 'handdrawn') {
if (node.look === 'handDrawn') {
// @ts-ignore - rough is not typed
const rc = rough.svg(shapeSvg);
const outerPathData = createOuterCylinderPathD(0, 0, w, h, rx, ry);

View File

@@ -5,7 +5,7 @@ import type { Node } from '$root/rendering-util/types.d.ts';
import {
styles2String,
userNodeOverrides,
} from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
} from '$root/rendering-util/rendering-elements/shapes/handDrawnShapeStyles.js';
import rough from 'roughjs';
export const doublecircle = async (parent: SVGAElement, node: Node): Promise<SVGAElement> => {
@@ -19,7 +19,7 @@ export const doublecircle = async (parent: SVGAElement, node: Node): Promise<SVG
let circleGroup;
const { cssStyles } = node;
if (node.look === 'handdrawn') {
if (node.look === 'handDrawn') {
// @ts-ignore - rough is not typed
const rc = rough.svg(shapeSvg);
const outerOptions = userNodeOverrides(node, { roughness: 0.2, strokeWidth: 2.5 });

View File

@@ -5,7 +5,7 @@ import { createRoundedRectPathD } from './roundedRectPath.js';
import {
userNodeOverrides,
styles2String,
} from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
} from '$root/rendering-util/rendering-elements/shapes/handDrawnShapeStyles.js';
import rough from 'roughjs';
export const drawRect = async (parent: SVGAElement, node: Node, options: RectOptions) => {
@@ -31,7 +31,7 @@ export const drawRect = async (parent: SVGAElement, node: Node, options: RectOpt
ry = options.ry;
}
if (node.look === 'handdrawn') {
if (node.look === 'handDrawn') {
// @ts-ignore TODO: Fix rough typings
const rc = rough.svg(shapeSvg);
const options = userNodeOverrides(node, {});

View File

@@ -3,7 +3,7 @@ import intersect from '../intersect/index.js';
import type { Node } from '$root/rendering-util/types.d.ts';
import type { SVG } from '$root/diagram-api/types.js';
import rough from 'roughjs';
import { solidStateFill } from './handdrawnStyles.js';
import { solidStateFill } from './handDrawnShapeStyles.js';
import { getConfig } from '$root/diagram-api/diagramAPI.js';
export const forkJoin = (parent: SVG, node: Node, dir: string) => {
@@ -25,7 +25,7 @@ export const forkJoin = (parent: SVG, node: Node, dir: string) => {
const y = (-1 * height) / 2;
let shape;
if (node.look === 'handdrawn') {
if (node.look === 'handDrawn') {
// @ts-ignore TODO: Fix rough typings
const rc = rough.svg(shapeSvg);
const roughNode = rc.rectangle(x, y, width, height, solidStateFill(lineColor));

View File

@@ -3,7 +3,7 @@ import type { Node } from '$root/rendering-util/types.d.ts';
// Striped fill like start or fork nodes in state diagrams
export const solidStateFill = (color: string) => {
const { handdrawnSeed } = getConfig();
const { handDrawnSeed } = getConfig();
return {
fill: color,
hachureAngle: 120, // angle of hachure,
@@ -11,7 +11,7 @@ export const solidStateFill = (color: string) => {
fillWeight: 2,
roughness: 0.7,
stroke: color,
seed: handdrawnSeed,
seed: handDrawnSeed,
};
};
@@ -72,7 +72,7 @@ export const styles2String = (node: Node) => {
// Striped fill like start or fork nodes in state diagrams
// TODO remove any
export const userNodeOverrides = (node: Node, options: any) => {
const { themeVariables, handdrawnSeed } = getConfig();
const { themeVariables, handDrawnSeed } = getConfig();
const { nodeBorder, mainBkg } = themeVariables;
const { stylesMap } = compileStyles(node);
@@ -84,7 +84,7 @@ export const userNodeOverrides = (node: Node, options: any) => {
fillStyle: 'hachure', // solid fill
fillWeight: 4,
stroke: stylesMap.get('stroke') || nodeBorder,
seed: handdrawnSeed,
seed: handDrawnSeed,
strokeWidth: 1.3,
},
options

View File

@@ -4,7 +4,7 @@ import type { Node } from '$root/rendering-util/types.d.ts';
import {
styles2String,
userNodeOverrides,
} from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
} from '$root/rendering-util/rendering-elements/shapes/handDrawnShapeStyles.js';
import rough from 'roughjs';
import { insertPolygonShape } from './insertPolygonShape.js';
@@ -48,7 +48,7 @@ export const hexagon = async (parent: SVGAElement, node: Node): Promise<SVGAElem
let polygon: d3.Selection<SVGPolygonElement | SVGGElement, unknown, null, undefined>;
const { cssStyles } = node;
if (node.look === 'handdrawn') {
if (node.look === 'handDrawn') {
// @ts-ignore - rough is not typed
const rc = rough.svg(shapeSvg);
const options = userNodeOverrides(node, {});

View File

@@ -4,7 +4,7 @@ import type { Node } from '$root/rendering-util/types.d.ts';
import {
styles2String,
userNodeOverrides,
} from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
} from '$root/rendering-util/rendering-elements/shapes/handDrawnShapeStyles.js';
import rough from 'roughjs';
import { insertPolygonShape } from './insertPolygonShape.js';
@@ -40,7 +40,7 @@ export const inv_trapezoid = async (parent: SVGAElement, node: Node): Promise<SV
let polygon: d3.Selection<SVGPolygonElement | SVGGElement, unknown, null, undefined>;
const { cssStyles } = node;
if (node.look === 'handdrawn') {
if (node.look === 'handDrawn') {
// @ts-ignore - rough is not typed
const rc = rough.svg(shapeSvg);
const options = userNodeOverrides(node, {});

View File

@@ -4,7 +4,7 @@ import type { Node } from '$root/rendering-util/types.d.ts';
import {
styles2String,
userNodeOverrides,
} from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
} from '$root/rendering-util/rendering-elements/shapes/handDrawnShapeStyles.js';
import rough from 'roughjs';
import { insertPolygonShape } from './insertPolygonShape.js';
@@ -40,7 +40,7 @@ export const lean_left = async (parent: SVGAElement, node: Node): Promise<SVGAEl
let polygon: d3.Selection<SVGPolygonElement | SVGGElement, unknown, null, undefined>;
const { cssStyles } = node;
if (node.look === 'handdrawn') {
if (node.look === 'handDrawn') {
// @ts-ignore - rough is not typed
const rc = rough.svg(shapeSvg);
const options = userNodeOverrides(node, {});

View File

@@ -4,7 +4,7 @@ import type { Node } from '$root/rendering-util/types.d.ts';
import {
styles2String,
userNodeOverrides,
} from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
} from '$root/rendering-util/rendering-elements/shapes/handDrawnShapeStyles.js';
import rough from 'roughjs';
import { insertPolygonShape } from './insertPolygonShape.js';
@@ -40,7 +40,7 @@ export const lean_right = async (parent: SVGAElement, node: Node): Promise<SVGAE
let polygon: d3.Selection<SVGPolygonElement | SVGGElement, unknown, null, undefined>;
const { cssStyles } = node;
if (node.look === 'handdrawn') {
if (node.look === 'handDrawn') {
// @ts-ignore - rough is not typed
const rc = rough.svg(shapeSvg);
const options = userNodeOverrides(node, {});

View File

@@ -6,7 +6,7 @@ import type { Node } from '$root/rendering-util/types.d.ts';
import rough from 'roughjs';
export const note = async (parent: SVGAElement, node: Node) => {
const { themeVariables, handdrawnSeed } = getConfig();
const { themeVariables, handDrawnSeed } = getConfig();
const { noteBorderColor, noteBkgColor } = themeVariables;
const useHtmlLabels = node.useHtmlLabels;
@@ -23,7 +23,7 @@ export const note = async (parent: SVGAElement, node: Node) => {
const x = -totalWidth / 2;
const y = -totalHeight / 2;
if (node.look === 'handdrawn') {
if (node.look === 'handDrawn') {
// add the rect
// @ts-ignore TODO: Fix rough typings
const rc = rough.svg(shapeSvg);
@@ -31,7 +31,7 @@ export const note = async (parent: SVGAElement, node: Node) => {
roughness: 0.7,
fill: noteBkgColor,
fillWeight: 3,
seed: handdrawnSeed,
seed: handDrawnSeed,
// fillStyle: 'solid', // solid fill'
stroke: noteBorderColor,
});

View File

@@ -5,7 +5,7 @@ import type { Node } from '$root/rendering-util/types.d.ts';
import {
styles2String,
userNodeOverrides,
} from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
} from '$root/rendering-util/rendering-elements/shapes/handDrawnShapeStyles.js';
import rough from 'roughjs';
import { insertPolygonShape } from './insertPolygonShape.js';
@@ -38,7 +38,7 @@ export const question = async (parent: SVGAElement, node: Node): Promise<SVGAEle
let polygon: d3.Selection<SVGPolygonElement | SVGGElement, unknown, null, undefined>;
const { cssStyles } = node;
if (node.look === 'handdrawn') {
if (node.look === 'handDrawn') {
// @ts-ignore - rough is not typed
const rc = rough.svg(shapeSvg);
const options = userNodeOverrides(node, {});

View File

@@ -4,7 +4,7 @@ import type { Node } from '$root/rendering-util/types.d.ts';
import {
styles2String,
userNodeOverrides,
} from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
} from '$root/rendering-util/rendering-elements/shapes/handDrawnShapeStyles.js';
import rough from 'roughjs';
import { insertPolygonShape } from './insertPolygonShape.js';
@@ -40,7 +40,7 @@ export const rect_left_inv_arrow = async (
let polygon;
const { cssStyles } = node;
if (node.look === 'handdrawn') {
if (node.look === 'handDrawn') {
// @ts-ignore - rough is not typed
const rc = rough.svg(shapeSvg);
const options = userNodeOverrides(node, {});

View File

@@ -7,7 +7,7 @@ import intersect from '../intersect/index.js';
import {
styles2String,
userNodeOverrides,
} from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
} from '$root/rendering-util/rendering-elements/shapes/handDrawnShapeStyles.js';
import rough from 'roughjs';
import { getConfig } from '$root/diagram-api/diagramAPI.js';
import { createRoundedRectPathD } from './roundedRectPath.js';
@@ -104,7 +104,7 @@ export const rectWithTitle = async (parent: SVGElement, node: Node) => {
const y = -bbox.height / 2 - halfPadding;
let rect;
let innerLine;
if (node.look === 'handdrawn') {
if (node.look === 'handDrawn') {
// @ts-ignore No typings for rough
const rc = rough.svg(shapeSvg);
const options = userNodeOverrides(node, {});
@@ -134,6 +134,7 @@ export const rectWithTitle = async (parent: SVGElement, node: Node) => {
innerLine = g.insert('line');
rect
.attr('class', 'outer title-state')
.attr('style', nodeStyles)
.attr('x', -bbox.width / 2 - halfPadding)
.attr('y', -bbox.height / 2 - halfPadding)
.attr('width', bbox.width + (node.padding || 0))

View File

@@ -4,7 +4,7 @@ import type { Node } from '$root/rendering-util/types.d.ts';
import {
styles2String,
userNodeOverrides,
} from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
} from '$root/rendering-util/rendering-elements/shapes/handDrawnShapeStyles.js';
import rough from 'roughjs';
import { createRoundedRectPathD } from './roundedRectPath.js';
@@ -63,7 +63,7 @@ export const stadium = async (parent: SVGAElement, node: Node) => {
let rect;
const { cssStyles } = node;
if (node.look === 'handdrawn') {
if (node.look === 'handDrawn') {
// @ts-ignore - rough is not typed
const rc = rough.svg(shapeSvg);
const options = userNodeOverrides(node, {});

View File

@@ -3,7 +3,7 @@ import intersect from '../intersect/index.js';
import type { Node } from '$root/rendering-util/types.d.ts';
import type { SVG } from '$root/diagram-api/types.js';
import rough from 'roughjs';
import { solidStateFill } from './handdrawnStyles.js';
import { solidStateFill } from './handDrawnShapeStyles.js';
import { getConfig } from '$root/diagram-api/diagramAPI.js';
export const stateEnd = (parent: SVG, node: Node) => {
@@ -16,7 +16,7 @@ export const stateEnd = (parent: SVG, node: Node) => {
let circle;
let innerCircle;
if (node.look === 'handdrawn') {
if (node.look === 'handDrawn') {
// @ts-ignore TODO: Fix rough typings
const rc = rough.svg(shapeSvg);
const roughNode = rc.circle(0, 0, 14, { ...solidStateFill(lineColor), roughness: 0.5 });

View File

@@ -3,7 +3,7 @@ import intersect from '../intersect/index.js';
import type { Node } from '$root/rendering-util/types.d.ts';
import type { SVG } from '$root/diagram-api/types.js';
import rough from 'roughjs';
import { solidStateFill } from './handdrawnStyles.js';
import { solidStateFill } from './handDrawnShapeStyles.js';
import { getConfig } from '$root/diagram-api/diagramAPI.js';
export const stateStart = (parent: SVG, node: Node) => {
@@ -16,7 +16,7 @@ export const stateStart = (parent: SVG, node: Node) => {
.attr('id', node.domId || node.id);
let circle;
if (node.look === 'handdrawn') {
if (node.look === 'handDrawn') {
// @ts-ignore TODO: Fix rough typings
const rc = rough.svg(shapeSvg);
const roughNode = rc.circle(0, 0, 14, solidStateFill(lineColor));

View File

@@ -4,7 +4,7 @@ import type { Node } from '$root/rendering-util/types.d.ts';
import {
styles2String,
userNodeOverrides,
} from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
} from '$root/rendering-util/rendering-elements/shapes/handDrawnShapeStyles.js';
import rough from 'roughjs';
import { insertPolygonShape } from './insertPolygonShape.js';
@@ -43,8 +43,7 @@ export const subroutine = async (parent: SVGAElement, node: Node) => {
const h = bbox.height + node.padding;
const x = -bbox.width / 2 - halfPadding;
const y = -bbox.height / 2 - halfPadding;
let rect;
const { cssStyles } = node;
const points = [
{ x: 0, y: 0 },
{ x: w, y: 0 },
@@ -58,7 +57,7 @@ export const subroutine = async (parent: SVGAElement, node: Node) => {
{ x: -8, y: 0 },
];
if (node.look === 'handdrawn') {
if (node.look === 'handDrawn') {
// @ts-ignore - rough is not typed
const rc = rough.svg(shapeSvg);
const options = userNodeOverrides(node, {});
@@ -69,9 +68,10 @@ export const subroutine = async (parent: SVGAElement, node: Node) => {
shapeSvg.insert(() => l1, ':first-child');
shapeSvg.insert(() => l2, ':first-child');
rect = shapeSvg.insert(() => roughNode, ':first-child');
const rect = shapeSvg.insert(() => roughNode, ':first-child');
const { cssStyles } = node;
rect.attr('class', 'basic label-container').attr('style', cssStyles);
updateNodeBounds(node, rect);
} else {
const el = insertPolygonShape(shapeSvg, w, h, points);
if (nodeStyles) {

View File

@@ -4,7 +4,7 @@ import type { Node } from '$root/rendering-util/types.d.ts';
import {
styles2String,
userNodeOverrides,
} from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
} from '$root/rendering-util/rendering-elements/shapes/handDrawnShapeStyles.js';
import rough from 'roughjs';
import { insertPolygonShape } from './insertPolygonShape.js';
@@ -40,7 +40,7 @@ export const trapezoid = async (parent: SVGAElement, node: Node): Promise<SVGAEl
let polygon: d3.Selection<SVGPolygonElement | SVGGElement, unknown, null, undefined>;
const { cssStyles } = node;
if (node.look === 'handdrawn') {
if (node.look === 'handDrawn') {
// @ts-ignore - rough is not typed
const rc = rough.svg(shapeSvg);
const options = userNodeOverrides(node, {});

View File

@@ -133,4 +133,4 @@ export function insertPolygonShape(parent, w, h, points) {
}
export const getNodeClasses = (node, extra) =>
(node.look === 'handdrawn' ? 'rough-node' : 'node') + ' ' + node.cssClasses + ' ' + (extra || '');
(node.look === 'handDrawn' ? 'rough-node' : 'node') + ' ' + node.cssClasses + ' ' + (extra || '');

View File

@@ -94,7 +94,7 @@ interface Edge {
labelStyle?: string[];
minlen?: number;
pattern?: string;
thickness?: 'normal' | 'thick' | 'invisible';
thickness?: 'normal' | 'thick' | 'invisible' | 'dotted';
look?: string;
}

View File

@@ -79,11 +79,11 @@ properties:
type: string
enum:
- classic
- handdrawn
- handDrawn
default: 'classic'
handdrawnSeed:
handDrawnSeed:
description: |
Defines the seed to be used when using handdrawn look. This is important for the automated tests as they will always find differences without the seed. The default value is 0 which gives a random seed.
Defines the seed to be used when using handDrawn look. This is important for the automated tests as they will always find differences without the seed. The default value is 0 which gives a random seed.
type: number
default: 0
layout:

View File

@@ -1,6 +1,6 @@
{
"name": "@mermaid-js/parser",
"version": "0.1.0-rc.1",
"version": "0.1.0-rc.2",
"description": "MermaidJS parser",
"author": "Yokozuna59",
"contributors": [

5459
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff