This commit is contained in:
Knut Sveidqvist 2021-05-10 19:05:29 +02:00
commit a55777c62b
46 changed files with 3562 additions and 1087 deletions

View File

@ -23,6 +23,9 @@ A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Code Sample**
If applicable, add the code sample or a link to the [live editor](https://mermaid-js.github.io/mermaid-live-editor).
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]

View File

@ -462,4 +462,152 @@ flowchart TD
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
);
});
it('66: More nested subgraph cases (TB)', () => {
imgSnapshotTest(
`
flowchart TB
subgraph two
b1
end
subgraph three
c2
end
three --> two
two --> c2
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
);
});
it('67: More nested subgraph cases (RL)', () => {
imgSnapshotTest(
`
flowchart RL
subgraph two
b1
end
subgraph three
c2
end
three --> two
two --> c2
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
);
});
it('68: More nested subgraph cases (BT)', () => {
imgSnapshotTest(
`
flowchart BT
subgraph two
b1
end
subgraph three
c2
end
three --> two
two --> c2
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
);
});
it('69: More nested subgraph cases (LR)', () => {
imgSnapshotTest(
`
flowchart LR
subgraph two
b1
end
subgraph three
c2
end
three --> two
two --> c2
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
);
});
it('70: Handle nested subgraph cases (TB) link out and link between subgraphs', () => {
imgSnapshotTest(
`
flowchart TB
subgraph S1
sub1 -->sub2
end
subgraph S2
sub4
end
S1 --> S2
sub1 --> sub4
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
);
});
it('71: Handle nested subgraph cases (RL) link out and link between subgraphs', () => {
imgSnapshotTest(
`
flowchart RL
subgraph S1
sub1 -->sub2
end
subgraph S2
sub4
end
S1 --> S2
sub1 --> sub4
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
);
});
it('72: Handle nested subgraph cases (BT) link out and link between subgraphs', () => {
imgSnapshotTest(
`
flowchart BT
subgraph S1
sub1 -->sub2
end
subgraph S2
sub4
end
S1 --> S2
sub1 --> sub4
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
);
});
it('74: Handle nested subgraph cases (RL) link out and link between subgraphs', () => {
imgSnapshotTest(
`
flowchart RL
subgraph S1
sub1 -->sub2
end
subgraph S2
sub4
end
S1 --> S2
sub1 --> sub4
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
);
});
it('74: Handle labels for multiple edges from and to the same couple of nodes', () => {
imgSnapshotTest(
`
flowchart RL
subgraph one
a1 -- l1 --> a2
a1 -- l2 --> a2
end
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
);
});
});

View File

@ -329,6 +329,37 @@ describe('State diagram', () => {
}
);
});
it('v2 it should be possibel to use a choice', () => {
imgSnapshotTest(
`
stateDiagram-v2
[*] --> Off
Off --> On
state MyChoice [[choice]]
On --> MyChoice
MyChoice --> Washing
MyChoice --> Drying
Washing --> Finished
Finished --> [*]
`,
{
logLevel: 0,
}
);
});
it('v2 width of compond state should grow with title if title is wider', () => {
imgSnapshotTest(
`
stateDiagram-v2
state "Long state name" as NotShooting {
a-->b
}
`,
{
logLevel: 0,
}
);
});
it('v2 Simplest composite state', () => {
imgSnapshotTest(
`
@ -354,6 +385,58 @@ describe('State diagram', () => {
}
);
});
it('v2 should handle multiple notes added to one state', () => {
imgSnapshotTest(
`
stateDiagram-v2
MyState
note left of MyState : I am a leftie
note right of MyState : I am a rightie
`,
{
logLevel: 0, fontFamily: 'courier',
}
);
});
it('v2 should handle different rendering directions in composite states', () => {
imgSnapshotTest(
`
stateDiagram
direction LR
state A {
direction BT
a --> b
}
state C {
direction RL
c --> d
}
A --> C
`,
{
logLevel: 0, fontFamily: 'courier',
}
);
});
it('v2 handle transition from one state in a composite state to a composite state', () => {
imgSnapshotTest(
`
stateDiagram-v2
state S1 {
sub1 -->sub2
}
state S2 {
sub4
}
S1 --> S2
sub1 --> sub4
`,
{
logLevel: 0, fontFamily: 'courier',
}
);
});
it('v2 should render a state diagram when useMaxWidth is true (default)', () => {
renderGraph(
`

View File

@ -358,7 +358,7 @@ describe('State diagram', () => {
expect(svg).to.have.attr('width', '100%');
expect(svg).to.have.attr('height');
const height = parseFloat(svg.attr('height'));
expect(height).to.eq(139);
expect(height).to.be.within(139,141);
const style = svg.attr('style');
expect(style).to.match(/^max-width: [\d.]+px;$/);
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
@ -379,7 +379,7 @@ describe('State diagram', () => {
.should((svg) => {
const height = parseFloat(svg.attr('height'));
const width = parseFloat(svg.attr('width'));
expect(height).to.eq(139);
expect(height).to.be.within(139,141);
// use within because the absolute value can be slightly different depending on the environment ±5%
expect(width).to.be.within(112 * .95, 112 * 1.05);
expect(svg).to.not.have.attr('style');

View File

@ -12,132 +12,89 @@
/* background: rgb(221, 208, 208); */
/* background:#333; */
font-family: 'Arial';
/* font-size: 18px !important; */
}
h1 { color: grey;}
.mermaid2 {
display: none;
}
.mermaid svg {
font-size: 12px !important;
/* font-size: 18px !important; */
}
</style>
</head>
<body>
<h1>info below</h1>
<div>info below</div>
<div class="flex">
<div class="mermaid2" style="width: 100%; height: 400px;">
%%{init: { "logLevel": 1, "er": {"fontSize":18 }} }%%
erDiagram
CUSTOMER }|..|{ DELIVERY-ADDRESS : has
CUSTOMER ||--o{ ORDER : places
CUSTOMER ||--o{ INVOICE : "liable for"
DELIVERY-ADDRESS ||--o{ ORDER : receives
INVOICE ||--|{ ORDER : covers
ORDER ||--|{ ORDER-ITEM : includes
PRODUCT-CATEGORY ||--|{ PRODUCT : contains
PRODUCT ||--o{ ORDER-ITEM : "ordered in"
</div>
<div class="mermaid2" style="width: 50%; height: 400px;">
flowchart TD
A[Christmas] ==> D
A[Christmas] -->|Get money| B(Go shopping)
A[Christmas] ==> C
subgraph T ["Test"]
A
B
C
end
classDef Test fill:#F84E68,stroke:#333,color:white;
class A,T Test
classDef TestSub fill:green;
class T TestSub
linkStyle 0,1 color:orange, stroke: orange;
</div>
<div class="mermaid" style="width: 50%; height: 20%;">
%%{init:{"theme":"base", "themeVariables": {"primaryColor":"#411d4e", "titleColor":"white", "darkMode":true}}}%%
flowchart LR
subgraph A
<div class="mermaid" style="width: 100%; height: 20%;">
stateDiagram
direction LR
state A {
direction BT
a --> b
end
subgraph B
i -->f
end
A --> B </div>
<div class="mermaid2" style="width: 50%; height: 20%;">
flowchart TD
C -->|fa:fa-car Car| F[fa:fa-car Car]
</div>
<div class="mermaid" style="width: 50%; height: 20%;">
flowchart LR
classDef dark fill:#000,stroke:#000,stroke-width:4px,color:#fff
Lorem --> Ipsum --> Dolor
class Lorem,Dolor dark
</div>
<div class="mermaid2" style="width: 50%; height: 20%;">
%%{init: {'theme': 'base' }}%%
%%{init2: { 'logLevel': 0, 'theme': 'forest'} }%%
flowchart TD
L1 --- L2
L2 --- C
M1 ---> C
R1 .-> R2
R2 <.-> C
C -->|Label 1| E1
C <-- Label 2 ---> E2
C ----> E3
C <-...-> E4
C ======> E5
</div>
<div class="mermaid2" style="width: 50%; height: 21%;">
flowchart LR
A[red text] -->|default style| B(blue text)
C([red text]) -->|default style| D[[blue text]]
E[(red text)] -->|default style| F((blue text))
G>red text] -->|default style| H{blue text}
I{{red text}} -->|default style| J[/blue text/]
K[
ed text] -->|default style| L[/blue text]
M[
ed text/] -->|default style| N[blue text]
linkStyle default color:Sienna;
style A stroke:#ff0000,fill:#ffcccc,color:#ff0000
style B stroke:#0000ff,fill:#ccccff,color:#0000ff
style C stroke:#ff0000,fill:#ffcccc,color:#ff0000
style D stroke:#0000ff,fill:#ccccff,color:#0000ff
style E stroke:#ff0000,fill:#ffcccc,color:#ff0000
style F stroke:#0000ff,fill:#ccccff,color:#0000ff
style G stroke:#ff0000,fill:#ffcccc,color:#ff0000
style H stroke:#0000ff,fill:#ccccff,color:#0000ff
style I stroke:#ff0000,fill:#ffcccc,color:#ff0000
style J stroke:#0000ff,fill:#ccccff,color:#0000ff
style K stroke:#ff0000,fill:#ffcccc,color:#ff0000
style L stroke:#0000ff,fill:#ccccff,color:#0000ff
style M stroke:#ff0000,fill:#ffcccc,color:#ff0000
style N stroke:#0000ff,fill:#ccccff,color:#0000ff
</div>
}
state C {
direction RL
c --> d
}
A --> C
</div>
<div class="mermaid2" style="width: 100%; height: 20%;">
%%{int:{
"themeVariables": {
"transitionColor":"red",
"labelColor":"yellow",
"transitionLabelColor":"blue",
"stateBkg":"green",
"compositeBackground":"pink",
"altBackground":"purple",
"clusterTitleBackground":"blue",
"compositeBorder":"red"
}}}%%
stateDiagram
state CompositeState {
state AnotherCompositeState {
AnotherState --> YetANotherState:a label
}
}
</div>
<div class="mermaid2" style="width: 100%; height: 20%;">
sequenceDiagram
Alice->>+John: Hello John, how are you?
Alice->>+John: John, can you hear me?
John-->>-Alice: Hi Alice, I can hear you!
John-->>-Alice: I feel great!
note right of John: Hello note reader
</div>
<script src="./mermaid.js"></script>
<script>
mermaid.parseError = function (err, hash) {
// console.error('Mermaid error: ', err);
};
mermaid.initialize({
// theme: 'forest',
// themeVariables:{primaryColor: '#ff0000'},
// arrowMarkerAbsolute: true,
theme: 'default',
arrowMarkerAbsolute: true,
// themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
logLevel: 0,
logLevel: 5,
flowchart: { nodeSpacing: 10, curve: 'cardinal', htmlLabels: true },
htmlLabels: true,
// gantt: { axisFormat: '%m/%d/%Y' },
sequence: { actorFontFamily: 'courier',actorMargin: 50, showSequenceNumbers: false },
// sequenceDiagram: { actorMargin: 300 } // deprecated
fontFamily: '"arial", sans-serif',
fontFamily: 'courier',
// fontFamily: '"times", sans-serif',
// fontFamily: 'courier',
state:{
nodeSpacing: 50,
rankSpacing: 50,
defaultRenderer: 'dagre-wrapper',
},
fontSize: 18,
curve: 'cardinal',
securityLevel: 'loose',
// themeVariables: {relationLabelColor: 'red'}
});
function callback(){alert('It worked');}
</script>

204
cypress/platform/knsv2.html Normal file
View File

@ -0,0 +1,204 @@
<html>
<head>
<link
href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
rel="stylesheet"
/>
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
<style>
body {
/* background: rgb(221, 208, 208); */
/* background:#333; */
font-family: 'Arial';
/* font-size: 18px !important; */
}
h1 { color: grey;}
.mermaid2 {
display: none;
}
.mermaid svg {
/* font-size: 18px !important; */
}
</style>
</head>
<body>
<div>info below</div>
<div class="flex">
<div class="mermaid2" style="width: 100%; height: 400px;">
%%{init: { "logLevel": 1, "er": {"fontSize":18 }} }%%
erDiagram
CUSTOMER }|..|{ DELIVERY-ADDRESS : has
CUSTOMER ||--o{ ORDER : places
CUSTOMER ||--o{ INVOICE : "liable for"
DELIVERY-ADDRESS ||--o{ ORDER : receives
INVOICE ||--|{ ORDER : covers
ORDER ||--|{ ORDER-ITEM : includes
PRODUCT-CATEGORY ||--|{ PRODUCT : contains
PRODUCT ||--o{ ORDER-ITEM : "ordered in"
</div>
<div class="mermaid2" style="width: 50%; height: 400px;">
flowchart TD
A[Christmas] ==> D
A[Christmas] -->|Get money| B(Go shopping)
A[Christmas] ==> C
subgraph T ["Test"]
A
B
C
end
classDef Test fill:#F84E68,stroke:#333,color:white;
class A,T Test
classDef TestSub fill:green;
class T TestSub
linkStyle 0,1 color:orange, stroke: orange;
</div>
<div class="mermaid" style="width: 100%; height: 20%;">
graph TD
subgraph S1
sub1 -->sub2
end
subgraph S2
sub4
end
S1 --> S2
sub1 --> sub4
</div>
<div class="mermaid" style="width: 100%; height: 20%;">
graph TB
A --> B
</div>
<div class="mermaid2" style="width: 100%; height: 20%;">
stateDiagram-v2
state S1 {
sub1 -->sub2
}
state S2 {
sub4
}
S1 --> S2
sub1 --> sub4
</div>
<div class="mermaid2" style="width: 100%; height: 20%;">
requirementDiagram
requirement test_req {
id: 1
text: the test text.
risk: high
verifymethod: test
}
functionalRequirement test_req2 {
id: 1.1
text: the second test text.
risk: low
verifymethod: inspection
}
performanceRequirement test_req3 {
id: 1.2
text: the third test text.
risk: medium
verifymethod: demonstration
}
element test_entity {
type: simulation
}
element test_entity2 {
type: word doc
docRef: reqs/test_entity
}
test_entity - satisfies -> test_req2
test_req - traces -> test_req2
test_req - contains -> test_req3
test_req <- copies - test_entity2
</div>
<div class="mermaid2" style="width: 50%; height: 20%;">
flowchart LR
classDef dark fill:#000,stroke:#000,stroke-width:4px,color:#fff
Lorem --> Ipsum --> Dolor
class Lorem,Dolor dark
</div>
<div class="mermaid2" style="width: 50%; height: 20%;">
%%{init: {'theme': 'base' }}%%
%%{init2: { 'logLevel': 0, 'theme': 'forest'} }%%
flowchart TD
L1 --- L2
L2 --- C
M1 ---> C
R1 .-> R2
R2 <.-> C
C -->|Label 1| E1
C <-- Label 2 ---> E2
C ----> E3
C <-...-> E4
C ======> E5
</div>
<div class="mermaid2" style="width: 50%; height: 21%;">
flowchart LR
A[red text] -->|default style| B(blue text)
C([red text]) -->|default style| D[[blue text]]
E[(red text)] -->|default style| F((blue text))
G>red text] -->|default style| H{blue text}
I{{red text}} -->|default style| J[/blue text/]
K[
ed text] -->|default style| L[/blue text]
M[
ed text/] -->|default style| N[blue text]
linkStyle default color:Sienna;
style A stroke:#ff0000,fill:#ffcccc,color:#ff0000
style B stroke:#0000ff,fill:#ccccff,color:#0000ff
style C stroke:#ff0000,fill:#ffcccc,color:#ff0000
style D stroke:#0000ff,fill:#ccccff,color:#0000ff
style E stroke:#ff0000,fill:#ffcccc,color:#ff0000
style F stroke:#0000ff,fill:#ccccff,color:#0000ff
style G stroke:#ff0000,fill:#ffcccc,color:#ff0000
style H stroke:#0000ff,fill:#ccccff,color:#0000ff
style I stroke:#ff0000,fill:#ffcccc,color:#ff0000
style J stroke:#0000ff,fill:#ccccff,color:#0000ff
style K stroke:#ff0000,fill:#ffcccc,color:#ff0000
style L stroke:#0000ff,fill:#ccccff,color:#0000ff
style M stroke:#ff0000,fill:#ffcccc,color:#ff0000
style N stroke:#0000ff,fill:#ccccff,color:#0000ff
</div>
<script src="./mermaid.js"></script>
<script>
mermaid.parseError = function (err, hash) {
// console.error('Mermaid error: ', err);
};
mermaid.initialize({
theme: 'forest',
arrowMarkerAbsolute: true,
// themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
logLevel: 0,
state: {
defaultRenderer: 'dagre-wrapper',
},
flowchart: {
// defaultRenderer: 'dagre-wrapper',
nodeSpacing: 10, curve: 'cardinal', htmlLabels: true
},
htmlLabels: true,
// gantt: { axisFormat: '%m/%d/%Y' },
sequence: { actorFontFamily: 'courier',actorMargin: 50, showSequenceNumbers: false },
// sequenceDiagram: { actorMargin: 300 } // deprecated
// fontFamily: '"times", sans-serif',
// fontFamily: 'courier',
fontSize: 18,
curve: 'basis',
securityLevel: 'loose',
// themeVariables: {relationLabelColor: 'red'}
});
function callback(){alert('It worked');}
</script>
</body>
</html>

210
cypress/platform/knsv3.html Normal file
View File

@ -0,0 +1,210 @@
<html>
<head>
<link
href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
rel="stylesheet"
/>
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
<style>
body {
/* background: rgb(221, 208, 208); */
/* background:#333; */
font-family: 'Arial';
/* font-size: 18px !important; */
}
h1 { color: grey;}
.mermaid2 {
display: none;
}
.mermaid svg {
/* font-size: 18px !important; */
}
</style>
</head>
<body>
<div>info below</div>
<div class="flex">
<div class="mermaid2" style="width: 100%; height: 400px;">
%%{init: { "logLevel": 1, "er": {"fontSize":18 }} }%%
erDiagram
CUSTOMER }|..|{ DELIVERY-ADDRESS : has
CUSTOMER ||--o{ ORDER : places
CUSTOMER ||--o{ INVOICE : "liable for"
DELIVERY-ADDRESS ||--o{ ORDER : receives
INVOICE ||--|{ ORDER : covers
ORDER ||--|{ ORDER-ITEM : includes
PRODUCT-CATEGORY ||--|{ PRODUCT : contains
PRODUCT ||--o{ ORDER-ITEM : "ordered in"
</div>
<div class="mermaid2" style="width: 50%; height: 400px;">
flowchart TD
A[Christmas] ==> D
A[Christmas] -->|Get money| B(Go shopping)
A[Christmas] ==> C
subgraph T ["Test"]
A
B
C
end
classDef Test fill:#F84E68,stroke:#333,color:white;
class A,T Test
classDef TestSub fill:green;
class T TestSub
linkStyle 0,1 color:orange, stroke: orange;
</div>
<div class="mermaid" style="width: 100%; height: 20%;">
flowchart TB
subgraph S1
sub1 -->sub2
end
subgraph S2
sub4
end
S1 --> S2
sub1 --> sub4
</div>
<div class="mermaid2" style="width: 100%; height: 20%;">
flowchart TB
c1-->a2
subgraph one
a1-->a2
end
subgraph two
b1-->b2
end
subgraph three
c1-->c2
end
one --> two
three --> two
two --> c2
</div>
<div class="mermaid2" style="width: 100%; height: 20%;">
stateDiagram-v2
state S1 {
sub1 -->sub2
}
state S2 {
sub4
}
S1 --> S2
sub1 --> sub4
</div>
<div class="mermaid2" style="width: 100%; height: 20%;">
requirementDiagram
requirement test_req {
id: 1
text: the test text.
risk: high
verifymethod: test
}
functionalRequirement test_req2 {
id: 1.1
text: the second test text.
risk: low
verifymethod: inspection
}
performanceRequirement test_req3 {
id: 1.2
text: the third test text.
risk: medium
verifymethod: demonstration
}
element test_entity {
type: simulation
}
element test_entity2 {
type: word doc
docRef: reqs/test_entity
}
test_entity - satisfies -> test_req2
test_req - traces -> test_req2
test_req - contains -> test_req3
test_req <- copies - test_entity2
</div>
<div class="mermaid2" style="width: 50%; height: 20%;">
flowchart LR
classDef dark fill:#000,stroke:#000,stroke-width:4px,color:#fff
Lorem --> Ipsum --> Dolor
class Lorem,Dolor dark
</div>
<div class="mermaid2" style="width: 50%; height: 20%;">
%%{init: {'theme': 'base' }}%%
%%{init2: { 'logLevel': 0, 'theme': 'forest'} }%%
flowchart TD
L1 --- L2
L2 --- C
M1 ---> C
R1 .-> R2
R2 <.-> C
C -->|Label 1| E1
C <-- Label 2 ---> E2
C ----> E3
C <-...-> E4
C ======> E5
</div>
<div class="mermaid2" style="width: 50%; height: 21%;">
flowchart LR
A[red text] -->|default style| B(blue text)
C([red text]) -->|default style| D[[blue text]]
E[(red text)] -->|default style| F((blue text))
G>red text] -->|default style| H{blue text}
I{{red text}} -->|default style| J[/blue text/]
K[
ed text] -->|default style| L[/blue text]
M[
ed text/] -->|default style| N[blue text]
linkStyle default color:Sienna;
style A stroke:#ff0000,fill:#ffcccc,color:#ff0000
style B stroke:#0000ff,fill:#ccccff,color:#0000ff
style C stroke:#ff0000,fill:#ffcccc,color:#ff0000
style D stroke:#0000ff,fill:#ccccff,color:#0000ff
style E stroke:#ff0000,fill:#ffcccc,color:#ff0000
style F stroke:#0000ff,fill:#ccccff,color:#0000ff
style G stroke:#ff0000,fill:#ffcccc,color:#ff0000
style H stroke:#0000ff,fill:#ccccff,color:#0000ff
style I stroke:#ff0000,fill:#ffcccc,color:#ff0000
style J stroke:#0000ff,fill:#ccccff,color:#0000ff
style K stroke:#ff0000,fill:#ffcccc,color:#ff0000
style L stroke:#0000ff,fill:#ccccff,color:#0000ff
style M stroke:#ff0000,fill:#ffcccc,color:#ff0000
style N stroke:#0000ff,fill:#ccccff,color:#0000ff
</div>
<script src="./mermaid.js"></script>
<script>
mermaid.parseError = function (err, hash) {
// console.error('Mermaid error: ', err);
};
mermaid.initialize({
theme: 'neutral',
arrowMarkerAbsolute: true,
// themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
logLevel: 0,
flowchart: { nodeSpacing: 10, curve: 'cardinal', htmlLabels: true },
htmlLabels: true,
// gantt: { axisFormat: '%m/%d/%Y' },
sequence: { actorFontFamily: 'courier',actorMargin: 50, showSequenceNumbers: false },
// sequenceDiagram: { actorMargin: 300 } // deprecated
// fontFamily: '"times", sans-serif',
// fontFamily: 'courier',
fontSize: 18,
curve: 'cardinal',
securityLevel: 'loose',
// themeVariables: {relationLabelColor: 'red'}
});
function callback(){alert('It worked');}
</script>
</body>
</html>

1342
dist/mermaid.core.js vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

1342
dist/mermaid.js vendored

File diff suppressed because it is too large Load Diff

2
dist/mermaid.js.map vendored

File diff suppressed because one or more lines are too long

10
dist/mermaid.min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -219,6 +219,21 @@ available space if not the absolute space required is used.
Default value: true
### defaultRenderer
| Parameter | Description | Type | Required | Values |
| --------------- | ----------- | ------- | -------- | ----------------------- |
| defaultRenderer | See notes | boolean | 4 | dagre-d3, dagre-wrapper |
**Notes:**
Decides which rendering engine that is to be used for the rendering. Legal values are:
- dagre-d3
- dagre-wrapper - wrapper for dagre implemented in mermaid
Default value: 'dagre-d3'
## sequence
The object containing configurations specific for sequence diagrams
@ -764,6 +779,21 @@ available space if not the absolute space required is used.
Default value: true
## defaultRenderer
| Parameter | Description | Type | Required | Values |
| --------------- | ----------- | ------- | -------- | ----------------------- |
| defaultRenderer | See notes | boolean | 4 | dagre-d3, dagre-wrapper |
**Notes:**
Decides which rendering engine that is to be used for the rendering. Legal values are:
- dagre-d3
- dagre-wrapper - wrapper for dagre implemented in mermaid
Default value: 'dagre-d3'
## useMaxWidth
| Parameter | Description | Type | Required | Values |
@ -790,6 +820,21 @@ available space if not the absolute space required is used.
Default value: true
## defaultRenderer
| Parameter | Description | Type | Required | Values |
| --------------- | ----------- | ------- | -------- | ----------------------- |
| defaultRenderer | See notes | boolean | 4 | dagre-d3, dagre-wrapper |
**Notes:**
Decides which rendering engine that is to be used for the rendering. Legal values are:
- dagre-d3
- dagre-wrapper - wrapper for dagre implemented in mermaid
Default value: 'dagre-d3'
## er
The object containing configurations specific for entity relationship diagrams

View File

@ -514,7 +514,7 @@ text.actor {
Is it possible to adjust the margins for rendering the sequence diagram.
This is done by defining `mermaid.sequenceConfig` or by the CLI to use a json file with the configuration.
How to use the CLI is described in the [mermaidCLI](mermaidCLI.html) page.
How to use the CLI is described in the [mermaidCLI](mermaidCLI) page.
`mermaid.sequenceConfig` can be set to a JSON string with config parameters or the corresponding object.
```javascript

View File

@ -1,6 +1,6 @@
{
"name": "mermaid",
"version": "8.9.3",
"version": "8.10.1",
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
"main": "dist/mermaid.core.js",
"keywords": [

View File

@ -136,18 +136,20 @@ const roundedWithTitle = (parent, node) => {
const padding = 0 * node.padding;
const halfPadding = padding / 2;
const width = node.width > bbox.width ? node.width : bbox.width + node.padding;
// center the rect around its coordinate
rect
.attr('class', 'outer')
.attr('x', node.x - node.width / 2 - halfPadding)
.attr('x', node.x - width / 2 - halfPadding)
.attr('y', node.y - node.height / 2 - halfPadding)
.attr('width', node.width + padding)
.attr('width', width + padding)
.attr('height', node.height + padding);
innerRect
.attr('class', 'inner')
.attr('x', node.x - node.width / 2 - halfPadding)
.attr('x', node.x - width / 2 - halfPadding)
.attr('y', node.y - node.height / 2 - halfPadding + bbox.height - 1)
.attr('width', node.width + padding)
.attr('width', width + padding)
.attr('height', node.height + padding - bbox.height - 3);
// Center the label

View File

@ -85,6 +85,7 @@ function addHtmlLabel(node) {
const createLabel = (_vertexText, style, isTitle, isNode) => {
let vertexText = _vertexText || '';
if (typeof vertexText === 'object') vertexText = vertexText[0];
if (getConfig().flowchart.htmlLabels) {
// TODO: addHtmlLabel accepts a labelStyle. Do we possibly have that?
vertexText = vertexText.replace(/\\n|\n/g, '<br />');

View File

@ -1,5 +1,6 @@
import { log } from '../logger'; // eslint-disable-line
import createLabel from './createLabel';
// import { line, curveBasis, curveLinear, select } from 'd3';
import { line, curveBasis, select } from 'd3';
import { getConfig } from '../config';
import utils from '../utils';
@ -104,7 +105,7 @@ export const insertEdgeLabel = (elem, edge) => {
};
export const positionEdgeLabel = (edge, paths) => {
log.info('Moving label', edge.id, edge.label, edgeLabels[edge.id]);
log.info('Moving label abc78 ', edge.id, edge.label, edgeLabels[edge.id]);
let path = paths.updatedPath ? paths.updatedPath : paths.originalPath;
if (edge.label) {
const el = edgeLabels[edge.id];
@ -113,7 +114,7 @@ export const positionEdgeLabel = (edge, paths) => {
if (path) {
// // debugger;
const pos = utils.calcLabelPosition(path);
log.info('Moving label from (', x, ',', y, ') to (', pos.x, ',', pos.y, ')');
log.info('Moving label from (', x, ',', y, ') to (', pos.x, ',', pos.y, ') abc78');
// x = pos.x;
// y = pos.y;
}
@ -199,31 +200,35 @@ const outsideNode = (node, point) => {
};
export const intersection = (node, outsidePoint, insidePoint) => {
log.warn('intersection calc o:', outsidePoint, ' i:', insidePoint, node);
log.warn(`intersection calc abc89:
outsidePoint: ${JSON.stringify(outsidePoint)}
insidePoint : ${JSON.stringify(insidePoint)}
node : x:${node.x} y:${node.y} w:${node.width} h:${node.height}`);
const x = node.x;
const y = node.y;
const dx = Math.abs(x - insidePoint.x);
// const dy = Math.abs(y - insidePoint.y);
const w = node.width / 2;
let r = insidePoint.x < outsidePoint.x ? w - dx : w + dx;
const h = node.height / 2;
const edges = {
x1: x - w,
x2: x + w,
y1: y - h,
y2: y + h
};
// const edges = {
// x1: x - w,
// x2: x + w,
// y1: y - h,
// y2: y + h
// };
if (
outsidePoint.x === edges.x1 ||
outsidePoint.x === edges.x2 ||
outsidePoint.y === edges.y1 ||
outsidePoint.y === edges.y2
) {
log.warn('calc equals on edge');
return outsidePoint;
}
// if (
// outsidePoint.x === edges.x1 ||
// outsidePoint.x === edges.x2 ||
// outsidePoint.y === edges.y1 ||
// outsidePoint.y === edges.y2
// ) {
// log.warn('abc89 calc equals on edge', outsidePoint, edges);
// return outsidePoint;
// }
const Q = Math.abs(outsidePoint.y - insidePoint.y);
const R = Math.abs(outsidePoint.x - insidePoint.x);
@ -234,35 +239,101 @@ export const intersection = (node, outsidePoint, insidePoint) => {
let q = insidePoint.y < outsidePoint.y ? outsidePoint.y - h - y : y - h - outsidePoint.y;
r = (R * q) / Q;
const res = {
x: insidePoint.x < outsidePoint.x ? insidePoint.x + R - r : insidePoint.x - r,
y: insidePoint.y < outsidePoint.y ? insidePoint.y + Q - q : insidePoint.y - q
x: insidePoint.x < outsidePoint.x ? insidePoint.x + r : insidePoint.x - R + r,
y: insidePoint.y < outsidePoint.y ? insidePoint.y + Q - q : insidePoint.y - Q + q
};
log.warn(`topp/bott calc, Q ${Q}, q ${q}, R ${R}, r ${r}`, res);
if (r === 0) {
res.x = outsidePoint.x;
res.y = outsidePoint.y;
}
if (R === 0) {
res.x = outsidePoint.x;
}
if (Q === 0) {
res.y = outsidePoint.y;
}
log.warn(`abc89 topp/bott calc, Q ${Q}, q ${q}, R ${R}, r ${r}`, res);
return res;
} else {
// Intersection onn sides of rect
// q = (Q * r) / R;
// q = 2;
// r = (R * q) / Q;
if (insidePoint.x < outsidePoint.x) {
r = outsidePoint.x - w - x;
} else {
// r = outsidePoint.x - w - x;
r = x - w - outsidePoint.x;
}
let q = (q = (Q * r) / R);
log.warn(`sides calc, Q ${Q}, q ${q}, R ${R}, r ${r}`, {
x: insidePoint.x < outsidePoint.x ? insidePoint.x + R - r : insidePoint.x + dx - w,
y: insidePoint.y < outsidePoint.y ? insidePoint.y + q : insidePoint.y - q
});
let q = (Q * r) / R;
// OK let _x = insidePoint.x < outsidePoint.x ? insidePoint.x + R - r : insidePoint.x + dx - w;
// OK let _x = insidePoint.x < outsidePoint.x ? insidePoint.x + R - r : outsidePoint.x + r;
let _x = insidePoint.x < outsidePoint.x ? insidePoint.x + R - r : insidePoint.x - R + r;
// let _x = insidePoint.x < outsidePoint.x ? insidePoint.x + R - r : outsidePoint.x + r;
let _y = insidePoint.y < outsidePoint.y ? insidePoint.y + q : insidePoint.y - q;
log.warn(`sides calc abc89, Q ${Q}, q ${q}, R ${R}, r ${r}`, { _x, _y });
if (r === 0) {
_x = outsidePoint.x;
_y = outsidePoint.y;
}
if (R === 0) {
_x = outsidePoint.x;
}
if (Q === 0) {
_y = outsidePoint.y;
}
return {
x: insidePoint.x < outsidePoint.x ? insidePoint.x + R - r : insidePoint.x + dx - w,
y: insidePoint.y < outsidePoint.y ? insidePoint.y + q : insidePoint.y - q
};
return { x: _x, y: _y };
}
};
/**
* This function will page a path and node where the last point(s) in the path is inside the node
* and return an update path ending by the border of the node.
* @param {*} points
* @param {*} boundryNode
* @returns
*/
const cutPathAtIntersect = (_points, boundryNode) => {
log.warn('abc88 cutPathAtIntersect', _points, boundryNode);
let points = [];
let lastPointOutside = _points[0];
let isInside = false;
_points.forEach(point => {
// const node = clusterDb[edge.toCluster].node;
log.info('abc88 checking point', point, boundryNode);
// check if point is inside the boundry rect
if (!outsideNode(boundryNode, point) && !isInside) {
// First point inside the rect found
// Calc the intersection coord between the point anf the last opint ouside the rect
const inter = intersection(boundryNode, lastPointOutside, point);
log.warn('abc88 inside', point, lastPointOutside, inter);
log.warn('abc88 intersection', inter);
// // Check case where the intersection is the same as the last point
let pointPresent = false;
points.forEach(p => {
pointPresent = pointPresent || (p.x === inter.x && p.y === inter.y);
});
// // if (!pointPresent) {
if (!points.find(e => e.x === inter.x && e.y === inter.y)) {
points.push(inter);
} else {
log.warn('abc88 no intersect', inter, points);
}
// points.push(inter);
isInside = true;
} else {
// Outside
log.warn('abc88 outside', point, lastPointOutside);
lastPointOutside = point;
// points.push(point);
if (!isInside) points.push(point);
}
});
log.warn('abc88 returning points', points);
return points;
};
//(edgePaths, e, edge, clusterDb, diagramtype, graph)
export const insertEdge = function(elem, e, edge, clusterDb, diagramType, graph) {
@ -271,6 +342,7 @@ export const insertEdge = function(elem, e, edge, clusterDb, diagramType, graph)
const tail = graph.node(e.v);
var head = graph.node(e.w);
log.info('abc88 InsertEdge: ', edge);
if (head.intersect && tail.intersect) {
points = points.slice(1, edge.points.length - 1);
points.unshift(tail.intersect(points[0]));
@ -283,66 +355,84 @@ export const insertEdge = function(elem, e, edge, clusterDb, diagramType, graph)
points.push(head.intersect(points[points.length - 1]));
}
if (edge.toCluster) {
log.trace('edge', edge);
log.trace('to cluster', clusterDb[edge.toCluster]);
points = [];
let lastPointOutside;
let isInside = false;
edge.points.forEach(point => {
const node = clusterDb[edge.toCluster].node;
log.info('to cluster abc88', clusterDb[edge.toCluster]);
points = cutPathAtIntersect(edge.points, clusterDb[edge.toCluster].node);
// log.trace('edge', edge);
// points = [];
// let lastPointOutside; // = edge.points[0];
// let isInside = false;
// edge.points.forEach(point => {
// const node = clusterDb[edge.toCluster].node;
// log.warn('checking from', edge.fromCluster, point, node);
if (!outsideNode(node, point) && !isInside) {
log.trace('inside', edge.toCluster, point, lastPointOutside);
// if (!outsideNode(node, point) && !isInside) {
// log.trace('inside', edge.toCluster, point, lastPointOutside);
// First point inside the rect
const inter = intersection(node, lastPointOutside, point);
// // First point inside the rect
// const inter = intersection(node, lastPointOutside, point);
let pointPresent = false;
points.forEach(p => {
pointPresent = pointPresent || (p.x === inter.x && p.y === inter.y);
});
// if (!pointPresent) {
if (!points.find(e => e.x === inter.x && e.y === inter.y)) {
points.push(inter);
} else {
log.warn('no intersect', inter, points);
}
isInside = true;
} else {
if (!isInside) points.push(point);
}
lastPointOutside = point;
});
// let pointPresent = false;
// points.forEach(p => {
// pointPresent = pointPresent || (p.x === inter.x && p.y === inter.y);
// });
// // if (!pointPresent) {
// if (!points.find(e => e.x === inter.x && e.y === inter.y)) {
// points.push(inter);
// } else {
// log.warn('no intersect', inter, points);
// }
// isInside = true;
// } else {
// // outtside
// lastPointOutside = point;
// if (!isInside) points.push(point);
// }
// });
pointsHasChanged = true;
}
if (edge.fromCluster) {
log.trace('edge', edge);
log.warn('from cluster', clusterDb[edge.fromCluster]);
const updatedPoints = [];
let lastPointOutside;
let isInside = false;
for (let i = points.length - 1; i >= 0; i--) {
const point = points[i];
const node = clusterDb[edge.fromCluster].node;
log.info('from cluster abc88', clusterDb[edge.fromCluster]);
points = cutPathAtIntersect(points.reverse(), clusterDb[edge.fromCluster].node).reverse();
// log.warn('edge', edge);
// log.warn('from cluster', clusterDb[edge.fromCluster], points);
// const updatedPoints = [];
// let lastPointOutside = edge.points[edge.points.length - 1];
// let isInside = false;
// for (let i = points.length - 1; i >= 0; i--) {
// const point = points[i];
// const node = clusterDb[edge.fromCluster].node;
// log.warn('checking to', edge.fromCluster, point, node);
if (!outsideNode(node, point) && !isInside) {
log.warn('inside', edge.fromCluster, point, node);
// if (!outsideNode(node, point) && !isInside) {
// log.warn('inside', edge.fromCluster, point, node);
// First point inside the rect
const insterection = intersection(node, lastPointOutside, point);
// log.trace('intersect', intersection(node, lastPointOutside, point));
updatedPoints.unshift(insterection);
// points.push(insterection);
isInside = true;
} else {
// at the outside
log.trace('Outside point', point);
if (!isInside) updatedPoints.unshift(point);
}
lastPointOutside = point;
}
points = updatedPoints;
// // First point inside the rect
// const inter = intersection(node, lastPointOutside, point);
// log.warn('intersect', intersection(node, lastPointOutside, point));
// let pointPresent = false;
// points.forEach(p => {
// pointPresent = pointPresent || (p.x === inter.x && p.y === inter.y);
// });
// // if (!pointPresent) {
// if (!points.find(e => e.x === inter.x && e.y === inter.y)) {
// updatedPoints.unshift(inter);
// log.warn('Adding point -updated = ', updatedPoints);
// } else {
// log.warn('no intersect', inter, points);
// }
// // points.push(insterection);
// isInside = true;
// } else {
// // at the outside
// // if (!isInside) updatedPoints.unshift(point);
// updatedPoints.unshift(point);
// log.warn('Outside point', point, updatedPoints);
// }
// lastPointOutside = point;
// }
// points = updatedPoints;
// points = edge.points;
pointsHasChanged = true;
}
@ -359,6 +449,7 @@ export const insertEdge = function(elem, e, edge, clusterDb, diagramType, graph)
} else {
curve = curveBasis;
}
// curve = curveLinear;
const lineFunction = line()
.x(function(d) {
return d.x;

View File

@ -32,33 +32,33 @@ describe('Graphlib decorations', () => {
});
it('case 3 - intersection on otop of box outside point greater then inside point', function () {
const o = {x: 157.21875, y: 38.83361558001693};
const i = {x: 104.1328125, y: 105};
const o = {x: 157, y: 39};
const i = {x: 104, y: 105};
const node2 = {
width: 211.96875,
x: 113.984375,
y: 164.25,
height: 176.5
width: 212,
x: 114,
y: 164,
height: 176
}
const int = intersection(node2, o, i);
expect(int.x).toBeCloseTo(127.39979619565217)
// expect(int.y).toBeCloseTo(76)
expect(int.y).toBeCloseTo(67.833)
expect(int.x).toBeCloseTo(133.71)
expect(int.y).toBeCloseTo(76)
// expect(int.y).toBeCloseTo(67.833)
});
it('case 4 - intersection on top of box inside point greater then inside point', function () {
const o = {x: 144.65625, y: 38.83361558001693};
const i = {x: 197.7421875, y: 105};
const o = {x: 144, y: 38};
const i = {x: 198, y: 105};
const node2 = {
width: 211.96875,
x: 113.984375,
y: 164.25,
height: 176.5
width: 212,
x: 114,
y: 164,
height: 176
}
const int = intersection(node2, o, i);
expect(int.x).toBeCloseTo(167.9232336956522)
// expect(int.y).toBeCloseTo(76)
expect(int.y).toBeCloseTo(67.833)
expect(int.x).toBeCloseTo(174.626 )
expect(int.y).toBeCloseTo(76)
// expect(int.y).toBeCloseTo(67.833)
});
});

View File

@ -17,7 +17,7 @@ import { log } from '../logger';
const recursiveRender = (_elem, graph, diagramtype, parentCluster) => {
log.info('Graph in recursive render: XXX', graphlib.json.write(graph), parentCluster);
const dir = graph.graph().rankdir;
log.warn('Dir in recursive render - dir:', dir);
log.trace('Dir in recursive render - dir:', dir);
const elem = _elem.insert('g').attr('class', 'root'); // eslint-disable-line
if (!graph.nodes()) {
@ -26,7 +26,7 @@ const recursiveRender = (_elem, graph, diagramtype, parentCluster) => {
log.info('Recursive render XXX', graph.nodes());
}
if (graph.edges().length > 0) {
log.info('Recursive edges', graph.edge(graph.edges()[0]));
log.trace('Recursive edges', graph.edge(graph.edges()[0]));
}
const clusters = elem.insert('g').attr('class', 'clusters'); // eslint-disable-line
const edgePaths = elem.insert('g').attr('class', 'edgePaths');
@ -43,7 +43,7 @@ const recursiveRender = (_elem, graph, diagramtype, parentCluster) => {
log.info('Setting data for cluster XXX (', v, ') ', data, parentCluster);
graph.setNode(parentCluster.id, data);
if (!graph.parent(v)) {
log.warn('Setting parent', v, parentCluster.id);
log.trace('Setting parent', v, parentCluster.id);
graph.setParent(v, parentCluster.id, data);
}
}

View File

@ -17,7 +17,7 @@ export const clear = () => {
const isDecendant = (id, ancenstorId) => {
// if (id === ancenstorId) return true;
log.debug(
log.trace(
'In isDecendant',
ancenstorId,
' ',
@ -358,14 +358,20 @@ export const extractor = (graph, depth) => {
);
const graphSettings = graph.graph();
let dir = graphSettings.rankdir === 'TB' ? 'LR' : 'TB';
if (clusterDb[node]) {
if (clusterDb[node].clusterData && clusterDb[node].clusterData.dir) {
dir = clusterDb[node].clusterData.dir;
log.warn('Fixing dir', clusterDb[node].clusterData.dir, dir);
}
}
const clusterGraph = new graphlib.Graph({
multigraph: true,
compound: true
})
.setGraph({
rankdir: graphSettings.rankdir === 'TB' ? 'LR' : 'TB',
// Todo: set proper spacing
rankdir: dir, // Todo: set proper spacing
nodesep: 50,
ranksep: 50,
marginx: 8,

View File

@ -34,6 +34,44 @@ const question = (parent, node) => {
return shapeSvg;
};
const choice = (parent, node) => {
const shapeSvg = parent
.insert('g')
.attr('class', 'node default')
.attr('id', node.domId || node.id);
const s = 28;
const points = [
{ x: 0, y: s / 2 },
{ x: s / 2, y: 0 },
{ x: 0, y: -s / 2 },
{ x: -s / 2, y: 0 }
];
const choice = shapeSvg.insert('polygon', ':first-child').attr(
'points',
points
.map(function(d) {
return d.x + ',' + d.y;
})
.join(' ')
);
// center the circle around its coordinate
choice
.attr('class', 'state-start')
.attr('r', 7)
.attr('width', 28)
.attr('height', 28);
node.width = 28;
node.height = 28;
node.intersect = function(point) {
return intersect.circle(node, 14, point);
};
return shapeSvg;
};
const hexagon = (parent, node) => {
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
@ -319,10 +357,18 @@ const rectWithTitle = (parent, node) => {
const label = shapeSvg.insert('g').attr('class', 'label');
const text2 = node.labelText.flat();
log.info('Label text', text2[0]);
const text2 = node.labelText.flat ? node.labelText.flat() : node.labelText;
// const text2 = typeof text2prim === 'object' ? text2prim[0] : text2prim;
const text = label.node().appendChild(createLabel(text2[0], node.labelStyle, true, true));
let title = '';
if (typeof text2 === 'object') {
title = text2[0];
} else {
title = text2;
}
log.info('Label text abc79', title, text2, typeof text2 === 'object');
const text = label.node().appendChild(createLabel(title, node.labelStyle, true, true));
let bbox;
if (getConfig().flowchart.htmlLabels) {
const div = text.children[0];
@ -336,7 +382,9 @@ const rectWithTitle = (parent, node) => {
let titleBox = text.getBBox();
const descr = label
.node()
.appendChild(createLabel(textRows.join('<br/>'), node.labelStyle, true, true));
.appendChild(
createLabel(textRows.join ? textRows.join('<br/>') : textRows, node.labelStyle, true, true)
);
if (getConfig().flowchart.htmlLabels) {
const div = descr.children[0];
@ -826,6 +874,7 @@ const shapes = {
question,
rect,
rectWithTitle,
choice,
circle,
stadium,
hexagon,

View File

@ -226,7 +226,22 @@ const config = {
*
* Default value: true
*/
useMaxWidth: true
useMaxWidth: true,
/**
* | Parameter | Description | Type | Required | Values|
* | --- | --- | --- | --- | --- |
* | defaultRenderer | See notes | boolean | 4 | dagre-d3, dagre-wrapper |
*
* **Notes:**
*
* Decides which rendering engine that is to be used for the rendering. Legal values are:
* * dagre-d3
* * dagre-wrapper - wrapper for dagre implemented in mermaid
*
* Default value: 'dagre-d3'
*/
defaultRenderer: 'dagre-d3'
},
/**
@ -871,7 +886,21 @@ top of the chart
*
* Default value: true
*/
useMaxWidth: true
useMaxWidth: true,
/**
* | Parameter | Description | Type | Required | Values|
* | --- | --- | --- | --- | --- |
* | defaultRenderer | See notes | boolean | 4 | dagre-d3, dagre-wrapper |
*
* **Notes:**
*
* Decides which rendering engine that is to be used for the rendering. Legal values are:
* * dagre-d3
* * dagre-wrapper - wrapper for dagre implemented in mermaid
*
* Default value: 'dagre-d3'
*/
defaultRenderer: 'dagre-d3'
},
git: {
arrowMarkerAbsolute: false,
@ -923,7 +952,21 @@ top of the chart
*
* Default value: true
*/
useMaxWidth: true
useMaxWidth: true,
/**
* | Parameter | Description | Type | Required | Values|
* | --- | --- | --- | --- | --- |
* | defaultRenderer | See notes | boolean | 4 | dagre-d3, dagre-wrapper |
*
* **Notes:**
*
* Decides which rendering engine that is to be used for the rendering. Legal values are:
* * dagre-d3
* * dagre-wrapper - wrapper for dagre implemented in mermaid
*
* Default value: 'dagre-d3'
*/
defaultRenderer: 'dagre-d3'
},
/**

View File

@ -174,7 +174,9 @@ export const addVertices = function(vert, g, svgId) {
* @param {Object} g The graph object
*/
export const addEdges = function(edges, g) {
log.info('abc78 edges = ', edges);
let cnt = 0;
let linkIdCnt = {};
let defaultStyle;
let defaultLabelStyle;
@ -189,7 +191,17 @@ export const addEdges = function(edges, g) {
cnt++;
// Identify Link
var linkId = 'L-' + edge.start + '-' + edge.end;
var linkIdBase = 'L-' + edge.start + '-' + edge.end;
// count the links from+to the same node to give unique id
if (typeof 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]);
var linkNameStart = 'LS-' + edge.start;
var linkNameEnd = 'LE-' + edge.end;

View File

@ -30,6 +30,7 @@ title { this.begin("ti
<string>["] { this.popState(); }
<string>[^"]* { return "txt"; }
"pie" return 'PIE';
"showData" return 'showData';
":"[\s]*[\d]+(?:\.[\d]+)? return "value";
<<EOF>> return 'EOF';
@ -44,6 +45,7 @@ start
: eol start
| directive start
| PIE document
| PIE showData document {yy.setShowData(true);}
;
document

View File

@ -7,6 +7,7 @@ import * as configApi from '../../config';
let sections = {};
let title = '';
let showData = false;
export const parseDirective = function(statement, context, type) {
mermaidAPI.parseDirective(this, statement, context, type);
@ -24,6 +25,14 @@ const setTitle = function(txt) {
title = txt;
};
const setShowData = function(toggle) {
showData = toggle;
};
const getShowData = function() {
return showData;
};
const getTitle = function() {
return title;
};
@ -39,6 +48,7 @@ const cleanupValue = function(value) {
const clear = function() {
sections = {};
title = '';
showData = false;
};
// export const parseError = (err, hash) => {
// global.mermaidAPI.parseError(err, hash)
@ -52,6 +62,8 @@ export default {
cleanupValue,
clear,
setTitle,
getTitle
getTitle,
setShowData,
getShowData
// parseError
};

View File

@ -1,20 +1,14 @@
/**
* Created by AshishJ on 11-09-2019.
*/
import { select, scaleOrdinal, schemeSet2, pie as d3pie, entries, arc } from 'd3';
import { select, scaleOrdinal, pie as d3pie, entries, arc } from 'd3';
import pieData from './pieDb';
import pieParser from './parser/pie';
import { log } from '../../logger';
import { configureSvgSize } from '../../utils';
import * as configApi from '../../config';
const conf = {};
export const setConf = function(cnf) {
const keys = Object.keys(cnf);
keys.forEach(function(key) {
conf[key] = cnf[key];
});
};
let conf = configApi.getConfig();
/**
* Draws a Pie Chart with the data given in text.
@ -25,6 +19,7 @@ let width;
const height = 450;
export const draw = (txt, id) => {
try {
conf = configApi.getConfig();
const parser = pieParser.parser;
parser.yy = pieData;
log.debug('Rendering info diagram\n' + txt);
@ -42,9 +37,12 @@ export const draw = (txt, id) => {
if (typeof conf.useWidth !== 'undefined') {
width = conf.useWidth;
}
if (typeof conf.pie.useWidth !== 'undefined') {
width = conf.pie.useWidth;
}
const diagram = select('#' + id);
configureSvgSize(diagram, height, width, conf.useMaxWidth);
configureSvgSize(diagram, height, width, conf.pie.useMaxWidth);
// Set viewBox
elem.setAttribute('viewBox', '0 0 ' + width + ' ' + height);
@ -66,10 +64,26 @@ export const draw = (txt, id) => {
sum += data[key];
});
const themeVariables = conf.themeVariables;
var myGeneratedColors = [
themeVariables.pie1,
themeVariables.pie2,
themeVariables.pie3,
themeVariables.pie4,
themeVariables.pie5,
themeVariables.pie6,
themeVariables.pie7,
themeVariables.pie8,
themeVariables.pie9,
themeVariables.pie10,
themeVariables.pie11,
themeVariables.pie12
];
// Set the color scale
var color = scaleOrdinal()
.domain(data)
.range(schemeSet2);
.range(myGeneratedColors);
// Compute the position of each group on the pie:
var pie = d3pie().value(function(d) {
@ -92,9 +106,7 @@ export const draw = (txt, id) => {
.attr('fill', function(d) {
return color(d.data.key);
})
.attr('stroke', 'black')
.style('stroke-width', '2px')
.style('opacity', 0.7);
.attr('class', 'pieCircle');
// Now add the percentage.
// Use the centroid method to get the best coordinates.
@ -110,8 +122,7 @@ export const draw = (txt, id) => {
return 'translate(' + arcGenerator.centroid(d) + ')';
})
.style('text-anchor', 'middle')
.attr('class', 'slice')
.style('font-size', 17);
.attr('class', 'slice');
svg
.append('text')
@ -143,11 +154,16 @@ export const draw = (txt, id) => {
.style('stroke', color);
legend
.data(dataReady.filter(value => value.data.value !== 0))
.append('text')
.attr('x', legendRectSize + legendSpacing)
.attr('y', legendRectSize - legendSpacing)
.text(function(d) {
return d;
if (parser.yy.getShowData() || conf.showData || conf.pie.showData) {
return d.data.key + ' [' + d.data.value + ']';
} else {
return d.data.key;
}
});
} catch (e) {
log.error('Error while rendering info diagram');
@ -156,6 +172,5 @@ export const draw = (txt, id) => {
};
export default {
setConf,
draw
};

View File

@ -1,19 +1,26 @@
const getStyles = options =>
`.pieTitleText {
`
.pieCircle{
stroke: ${options.pieStrokeColor};
stroke-width : ${options.pieStrokeWidth};
opacity : ${options.pieOpacity};
}
.pieTitleText {
text-anchor: middle;
font-size: 25px;
fill: ${options.taskTextDarkColor};
font-size: ${options.pieTitleTextSize};
fill: ${options.pieTitleTextColor};
font-family: ${options.fontFamily};
}
.slice {
font-family: ${options.fontFamily};
fill: ${options.textColor};
fill: ${options.pieSectionTextColor};
font-size:${options.pieSectionTextSize};
// fill: white;
}
.legend text {
fill: ${options.taskTextDarkColor};
fill: ${options.pieLegendTextColor};
font-family: ${options.fontFamily};
font-size: 17px;
font-size: ${options.pieLegendTextSize};
}
`;

View File

@ -84,7 +84,8 @@
%% /* language grammar */
start
: directive start
: directive NEWLINE start
| directive start
| RD NEWLINE diagram EOF;
directive
@ -108,36 +109,37 @@ diagram
| requirementDef diagram
| elementDef diagram
| relationshipDef diagram
| directive diagram
| NEWLINE diagram;
requirementDef
: requirementType requirementName STRUCT_START NEWLINE requirementBody
: requirementType requirementName STRUCT_START NEWLINE requirementBody
{ yy.addRequirement($2, $1) };
requirementBody
: ID COLONSEP id NEWLINE requirementBody
: ID COLONSEP id NEWLINE requirementBody
{ yy.setNewReqId($3); }
| TEXT COLONSEP text NEWLINE requirementBody
| TEXT COLONSEP text NEWLINE requirementBody
{ yy.setNewReqText($3); }
| RISK COLONSEP riskLevel NEWLINE requirementBody
| RISK COLONSEP riskLevel NEWLINE requirementBody
{ yy.setNewReqRisk($3); }
| VERIFYMTHD COLONSEP verifyType NEWLINE requirementBody
| VERIFYMTHD COLONSEP verifyType NEWLINE requirementBody
{ yy.setNewReqVerifyMethod($3); }
| NEWLINE requirementBody
| STRUCT_STOP;
requirementType
: REQUIREMENT
: REQUIREMENT
{ $$=yy.RequirementType.REQUIREMENT;}
| FUNCTIONAL_REQUIREMENT
| FUNCTIONAL_REQUIREMENT
{ $$=yy.RequirementType.FUNCTIONAL_REQUIREMENT;}
| INTERFACE_REQUIREMENT
| INTERFACE_REQUIREMENT
{ $$=yy.RequirementType.INTERFACE_REQUIREMENT;}
| PERFORMANCE_REQUIREMENT
| PERFORMANCE_REQUIREMENT
{ $$=yy.RequirementType.PERFORMANCE_REQUIREMENT;}
| PHYSICAL_REQUIREMENT
| PHYSICAL_REQUIREMENT
{ $$=yy.RequirementType.PHYSICAL_REQUIREMENT;}
| DESIGN_CONSTRAINT
| DESIGN_CONSTRAINT
{ $$=yy.RequirementType.DESIGN_CONSTRAINT;};
riskLevel
@ -146,29 +148,29 @@ riskLevel
| HIGH_RISK { $$=yy.RiskLevel.HIGH_RISK;};
verifyType
: VERIFY_ANALYSIS
: VERIFY_ANALYSIS
{ $$=yy.VerifyType.VERIFY_ANALYSIS;}
| VERIFY_DEMONSTRATION
| VERIFY_DEMONSTRATION
{ $$=yy.VerifyType.VERIFY_DEMONSTRATION;}
| VERIFY_INSPECTION
| VERIFY_INSPECTION
{ $$=yy.VerifyType.VERIFY_INSPECTION;}
| VERIFY_TEST
| VERIFY_TEST
{ $$=yy.VerifyType.VERIFY_TEST;};
elementDef
: ELEMENT elementName STRUCT_START NEWLINE elementBody
: ELEMENT elementName STRUCT_START NEWLINE elementBody
{ yy.addElement($2) };
elementBody
: TYPE COLONSEP type NEWLINE elementBody
: TYPE COLONSEP type NEWLINE elementBody
{ yy.setNewElementType($3); }
| DOCREF COLONSEP ref NEWLINE elementBody
| DOCREF COLONSEP ref NEWLINE elementBody
{ yy.setNewElementDocRef($3); }
| NEWLINE elementBody
| STRUCT_STOP;
relationshipDef
: id END_ARROW_L relationship LINE id
: id END_ARROW_L relationship LINE id
{ yy.addRelationship($3, $5, $1) }
| id LINE relationship END_ARROW_R id
{ yy.addRelationship($3, $1, $5) };

View File

@ -20,8 +20,8 @@ const insertLineEndings = (parentNode, conf) => {
.attr('cx', conf.line_height / 2)
.attr('cy', conf.line_height / 2)
.attr('r', conf.line_height / 2)
.attr('stroke', conf.rect_border_color)
.attr('stroke-width', 1)
// .attr('stroke', conf.rect_border_color)
// .attr('stroke-width', 1)
.attr('fill', 'none');
containsNode
@ -30,7 +30,7 @@ const insertLineEndings = (parentNode, conf) => {
.attr('x2', conf.line_height)
.attr('y1', conf.line_height / 2)
.attr('y2', conf.line_height / 2)
.attr('stroke', conf.rect_border_color)
// .attr('stroke', conf.rect_border_color)
.attr('stroke-width', 1);
containsNode
@ -39,7 +39,7 @@ const insertLineEndings = (parentNode, conf) => {
.attr('y2', conf.line_height)
.attr('x1', conf.line_height / 2)
.attr('x2', conf.line_height / 2)
.attr('stroke', conf.rect_border_color)
// .attr('stroke', conf.rect_border_color)
.attr('stroke-width', 1);
parentNode
@ -54,13 +54,13 @@ const insertLineEndings = (parentNode, conf) => {
.append('path')
.attr(
'd',
`M0,0
L${conf.line_height},${conf.line_height / 2}
M${conf.line_height},${conf.line_height / 2}
`M0,0
L${conf.line_height},${conf.line_height / 2}
M${conf.line_height},${conf.line_height / 2}
L0,${conf.line_height}`
)
.attr('stroke-width', 1)
.attr('stroke', conf.rect_border_color);
.attr('stroke-width', 1);
// .attr('stroke', conf.rect_border_color);
};
export default {

View File

@ -1,7 +1,7 @@
import { line, select } from 'd3';
import dagre from 'dagre';
import graphlib from 'graphlib';
import * as configApi from '../../config';
// import * as configApi from '../../config';
import { log } from '../../logger';
import { configureSvgSize } from '../../utils';
import common from '../common/common';
@ -26,10 +26,6 @@ const newRectNode = (parentNode, id) => {
return parentNode
.insert('rect', '#' + id)
.attr('class', 'req reqBox')
.attr('fill', conf.rect_fill)
.attr('fill-opacity', '100%')
.attr('stroke', conf.rect_border_color)
.attr('stroke-size', conf.rect_border_size)
.attr('x', 0)
.attr('y', 0)
.attr('width', conf.rect_min_width + 'px')
@ -45,12 +41,11 @@ const newTitleNode = (parentNode, id, txts) => {
.attr('id', id)
.attr('x', x)
.attr('y', conf.rect_padding)
.attr('dominant-baseline', 'hanging')
.attr(
'style',
'font-family: ' + configApi.getConfig().fontFamily + '; font-size: ' + conf.fontSize + 'px'
);
.attr('dominant-baseline', 'hanging');
// .attr(
// 'style',
// 'font-family: ' + configApi.getConfig().fontFamily + '; font-size: ' + conf.fontSize + 'px'
// )
let i = 0;
txts.forEach(textStr => {
if (i == 0) {
@ -77,11 +72,11 @@ const newTitleNode = (parentNode, id, txts) => {
parentNode
.append('line')
.attr('class', 'req-title-line')
.attr('x1', '0')
.attr('x2', conf.rect_min_width)
.attr('y1', totalY)
.attr('y2', totalY)
.attr('style', `stroke: ${conf.rect_border_color}; stroke-width: 1`);
.attr('y2', totalY);
return {
titleNode: title,
@ -96,11 +91,11 @@ const newBodyNode = (parentNode, id, txts, yStart) => {
.attr('id', id)
.attr('x', conf.rect_padding)
.attr('y', yStart)
.attr('dominant-baseline', 'hanging')
.attr(
'style',
'font-family: ' + configApi.getConfig().fontFamily + '; font-size: ' + conf.fontSize + 'px'
);
.attr('dominant-baseline', 'hanging');
// .attr(
// 'style',
// 'font-family: ' + configApi.getConfig().fontFamily + '; font-size: ' + conf.fontSize + 'px'
// );
let currentRow = 0;
const charLimit = 30;
@ -145,13 +140,13 @@ const addEdgeLabel = (parentNode, svgPath, conf, txt) => {
const labelNode = parentNode
.append('text')
.attr('class', 'er relationshipLabel')
.attr('class', 'req relationshipLabel')
.attr('id', labelId)
.attr('x', labelPoint.x)
.attr('y', labelPoint.y)
.attr('text-anchor', 'middle')
.attr('dominant-baseline', 'middle')
.attr('style', 'font-family: ' + conf.fontFamily + '; font-size: ' + conf.fontSize + 'px')
// .attr('style', 'font-family: ' + conf.fontFamily + '; font-size: ' + conf.fontSize + 'px')
.text(txt);
// Figure out how big the opaque 'container' rectangle needs to be
@ -187,7 +182,6 @@ const drawRelationshipFromLayout = function(svg, rel, g, insert) {
.insert('path', '#' + insert)
.attr('class', 'er relationshipLine')
.attr('d', lineFunction(edge.points))
.attr('stroke', conf.rect_border_color)
.attr('fill', 'none');
if (rel.type == requirementDb.Relationships.CONTAINS) {
@ -217,7 +211,6 @@ export const drawReqs = (reqs, graph, svgNode) => {
Object.keys(reqs).forEach(reqName => {
let req = reqs[reqName];
reqName = elementString(reqName);
console.log('reqName: ', reqName);
log.info('Added new requirement: ', reqName);
const groupNode = svgNode.append('g').attr('id', reqName);
@ -277,7 +270,7 @@ export const drawElements = (els, graph, svgNode) => {
let bodyNode = newBodyNode(
groupNode,
textId + '_body',
[`Type: ${el.type || 'Not Specified'}`, `Doc Ref: ${el.docref || 'None'}`],
[`Type: ${el.type || 'Not Specified'}`, `Doc Ref: ${el.docRef || 'None'}`],
titleNodeInfo.y
);
@ -329,6 +322,7 @@ const elementString = str => {
export const draw = (text, id) => {
parser.yy = requirementDb;
parser.yy.clear();
parser.parse(text);
const svg = select(`[id='${id}']`);

View File

@ -1,3 +1,46 @@
const getStyles = () => ``;
const getStyles = options => `
marker {
fill: ${options.relationColor};
stroke: ${options.relationColor};
}
marker.cross {
stroke: ${options.lineColor};
}
svg {
font-family: ${options.fontFamily};
font-size: ${options.fontSize};
}
.reqBox {
fill: ${options.requirementBackground};
fill-opacity: 100%;
stroke: ${options.requirementBorderColor};
stroke-width: ${options.requirementBorderSize};
}
.reqTitle, .reqLabel{
fill: ${options.requirementTextColor};
}
.reqLabelBox {
fill: ${options.relationLabelBackground};
fill-opacity: 100%;
}
.req-title-line {
stroke: ${options.requirementBorderColor};
stroke-width: ${options.requirementBorderSize};
}
.relationshipLine {
stroke: ${options.relationColor};
stroke-width: 1;
}
.relationshipLabel {
fill: ${options.relationLabelColor};
}
`;
// fill', conf.rect_fill)
export default getStyles;

View File

@ -1,6 +1,6 @@
/** mermaid
* https://mermaidjs.github.io/
* (c) 2014-2015 Knut Sveidqvist
* (c) 2014-2021 Knut Sveidqvist
* MIT license.
*
* Based on js sequence diagrams jison grammr
@ -35,30 +35,42 @@
%x LINE
%%
.*direction\s+TB[^\n]* return 'direction_tb';
.*direction\s+BT[^\n]* return 'direction_bt';
.*direction\s+RL[^\n]* return 'direction_rl';
.*direction\s+LR[^\n]* return 'direction_lr';
\%\%\{ { this.begin('open_directive'); return 'open_directive'; }
<open_directive>((?:(?!\}\%\%)[^:.])*) { this.begin('type_directive'); return 'type_directive'; }
<type_directive>":" { this.popState(); this.begin('arg_directive'); return ':'; }
<type_directive,arg_directive>\}\%\% { this.popState(); this.popState(); return 'close_directive'; }
<arg_directive>((?:(?!\}\%\%).|\n)*) return 'arg_directive';
\%\%(?!\{)[^\n]* /* skip comments */
[^\}]\%\%[^\n]* /* skip comments */{ console.log('Crap after close'); }
[^\}]\%\%[^\n]* /* skip comments */{ /*console.log('Crap after close');*/ }
[\n]+ return 'NL';
[\s]+ /* skip all whitespace */
<ID,STATE,struct,LINE,open_directive,type_directive,arg_directive,close_directive>((?!\n)\s)+ /* skip same-line whitespace */
<INITIAL,ID,STATE,struct,LINE,open_directive,type_directive,arg_directive,close_directive>\#[^\n]* /* skip comments */
\%%[^\n]* /* skip comments */
"scale"\s+ { this.pushState('SCALE'); /* console.log('Got scale', yytext);*/ return 'scale'; }
<SCALE>\d+ return 'WIDTH';
<SCALE>\s+"width" {this.popState();}
<INITIAL,struct>"state"\s+ { this.pushState('STATE'); }
<INITIAL,struct>"state"\s+ { /*console.log('Starting STATE zxzx'+yy.getDirection());*/this.pushState('STATE'); }
<STATE>.*"<<fork>>" {this.popState();yytext=yytext.slice(0,-8).trim(); /*console.warn('Fork Fork: ',yytext);*/return 'FORK';}
<STATE>.*"<<join>>" {this.popState();yytext=yytext.slice(0,-8).trim();/*console.warn('Fork Join: ',yytext);*/return 'JOIN';}
<STATE>.*"<<choice>>" {this.popState();yytext=yytext.slice(0,-10).trim();/*console.warn('Fork Join: ',yytext);*/return 'CHOICE';}
<STATE>.*"[[fork]]" {this.popState();yytext=yytext.slice(0,-8).trim();/*console.warn('Fork Fork: ',yytext);*/return 'FORK';}
<STATE>.*"[[join]]" {this.popState();yytext=yytext.slice(0,-8).trim();/*console.warn('Fork Join: ',yytext);*/return 'JOIN';}
<STATE>["] this.begin("STATE_STRING");
<STATE>.*"[[choice]]" {this.popState();yytext=yytext.slice(0,-10).trim();/*console.warn('Fork Join: ',yytext);*/return 'CHOICE';}
<struct>.*direction\s+TB[^\n]* { return 'direction_tb';}
<struct>.*direction\s+BT[^\n]* { return 'direction_bt';}
<struct>.*direction\s+RL[^\n]* { return 'direction_rl';}
<struct>.*direction\s+LR[^\n]* { return 'direction_lr';}
<STATE>["] { /*console.log('Starting STATE_STRING zxzx');*/this.begin("STATE_STRING");}
<STATE>\s*"as"\s+ {this.popState();this.pushState('STATE_ID');return "AS";}
<STATE_ID>[^\n\{]* {this.popState();/* console.log('STATE_ID', yytext);*/return "ID";}
<STATE_STRING>["] this.popState();
@ -142,7 +154,6 @@ statement
| COMPOSIT_STATE
| COMPOSIT_STATE STRUCT_START document STRUCT_STOP
{
/* console.warn('Adding document for state without id ', $1);*/
$$={ stmt: 'state', id: $1, type: 'default', description: '', doc: $3 }
}
@ -159,7 +170,7 @@ statement
}
| STATE_DESCR AS ID STRUCT_START document STRUCT_STOP
{
//console.warn('Adding document for state with id ', $3, $4); yy.addDocument($3);
// console.warn('Adding document for state with id zxzx', $3, $4, yy.getDirection()); yy.addDocument($3);
$$={ stmt: 'state', id: $3, type: 'default', description: $1, doc: $5 }
}
| FORK {
@ -168,22 +179,36 @@ statement
| JOIN {
$$={ stmt: 'state', id: $1, type: 'join' }
}
| CHOICE {
$$={ stmt: 'state', id: $1, type: 'choice' }
}
| CONCURRENT {
$$={ stmt: 'state', id: yy.getDividerId(), type: 'divider' }
}
| note notePosition ID NOTE_TEXT
{
/*console.warn('got NOTE, position: ', $2.trim(), 'id = ', $3.trim(), 'note: ', $4);*/
/* console.warn('got NOTE, position: ', $2.trim(), 'id = ', $3.trim(), 'note: ', $4);*/
$$={ stmt: 'state', id: $3.trim(), note:{position: $2.trim(), text: $4.trim()}};
}
| note NOTE_TEXT AS ID
| directive
| direction
;
directive
: openDirective typeDirective closeDirective
| openDirective typeDirective ':' argDirective closeDirective
;
direction
: direction_tb
{ yy.setDirection('TB');$$={stmt:'dir', value:'TB'};}
| direction_bt
{ yy.setDirection('BT');$$={stmt:'dir', value:'BT'};}
| direction_rl
{ yy.setDirection('RL'); $$={stmt:'dir', value:'RL'};}
| direction_lr
{ yy.setDirection('LR');$$={stmt:'dir', value:'LR'};}
;
eol
: NL

View File

@ -67,6 +67,7 @@ const docTranslator = (parent, node, first) => {
const getRootDocV2 = () => {
docTranslator({ id: 'root' }, { id: 'root', doc: rootDoc }, true);
return { id: 'root', doc: rootDoc };
// Here
};
const extract = _doc => {
@ -194,7 +195,7 @@ export const addRelation = function(_id1, _id2, title) {
}
addState(id1, type1);
addState(id2, type2);
currentDocument.relations.push({ id1, id2, title });
currentDocument.relations.push({ id1, id2, title: title });
};
const addDescription = function(id, _descr) {
@ -230,7 +231,11 @@ let classes = [];
const getClasses = () => classes;
const getDirection = () => 'TB';
let direction = 'TB';
const getDirection = () => direction;
const setDirection = dir => {
direction = dir;
};
export const relationType = {
AGGREGATION: 0,
@ -253,6 +258,7 @@ export default {
getDirection,
addRelation,
getDividerId,
setDirection,
// addDescription,
cleanupLabel,
lineType,

View File

@ -84,8 +84,9 @@ const setupNode = (g, parent, node, altFlag) => {
// group
if (!nodeDb[node.id].type && node.doc) {
log.info('Setting cluser for ', node.id);
log.info('Setting cluster for ', node.id, getDir(node));
nodeDb[node.id].type = 'group';
nodeDb[node.id].dir = getDir(node);
nodeDb[node.id].shape = node.type === 'divider' ? 'divider' : 'roundedWithTitle';
nodeDb[node.id].classes =
nodeDb[node.id].classes +
@ -97,9 +98,13 @@ const setupNode = (g, parent, node, altFlag) => {
labelStyle: '',
shape: nodeDb[node.id].shape,
labelText: nodeDb[node.id].description,
// typeof nodeDb[node.id].description === 'object'
// ? nodeDb[node.id].description[0]
// : nodeDb[node.id].description,
classes: nodeDb[node.id].classes, //classStr,
style: '', //styles.style,
id: node.id,
dir: nodeDb[node.id].dir,
domId: 'state-' + node.id + '-' + cnt,
type: nodeDb[node.id].type,
padding: 15 //getConfig().flowchart.padding
@ -113,7 +118,7 @@ const setupNode = (g, parent, node, altFlag) => {
labelText: node.note.text,
classes: 'statediagram-note', //classStr,
style: '', //styles.style,
id: node.id + '----note',
id: node.id + '----note-' + cnt,
domId: 'state-' + node.id + '----note-' + cnt,
type: nodeDb[node.id].type,
padding: 15 //getConfig().flowchart.padding
@ -164,18 +169,18 @@ const setupNode = (g, parent, node, altFlag) => {
if (parent) {
if (parent.id !== 'root') {
log.info('Setting node ', node.id, ' to be child of its parent ', parent.id);
log.trace('Setting node ', node.id, ' to be child of its parent ', parent.id);
g.setParent(node.id, parent.id);
}
}
if (node.doc) {
log.info('Adding nodes children ');
log.trace('Adding nodes children ');
setupDoc(g, node, node.doc, !altFlag);
}
};
let cnt = 0;
const setupDoc = (g, parent, doc, altFlag) => {
cnt = 0;
// cnt = 0;
log.trace('items', doc);
doc.forEach(item => {
if (item.stmt === 'state' || item.stmt === 'default') {
@ -204,7 +209,18 @@ const setupDoc = (g, parent, doc, altFlag) => {
}
});
};
const getDir = (nodes, defaultDir) => {
let dir = defaultDir || 'TB';
if (nodes.doc) {
for (let i = 0; i < nodes.doc.length; i++) {
const node = nodes.doc[i];
if (node.stmt === 'dir') {
dir = node.value;
}
}
}
return dir;
};
/**
* Draws a flowchart in the tag with id: id based on the graph definition in text.
* @param text
@ -230,13 +246,17 @@ export const draw = function(text, id) {
const nodeSpacing = conf.nodeSpacing || 50;
const rankSpacing = conf.rankSpacing || 50;
log.info(stateDb.getRootDocV2());
stateDb.extract(stateDb.getRootDocV2());
log.info(stateDb.getRootDocV2());
// Create the input mermaid.graph
const g = new graphlib.Graph({
multigraph: true,
compound: true
})
.setGraph({
rankdir: 'TB',
rankdir: getDir(stateDb.getRootDocV2()),
nodesep: nodeSpacing,
ranksep: rankSpacing,
marginx: 8,
@ -246,9 +266,6 @@ export const draw = function(text, id) {
return {};
});
log.info(stateDb.getRootDocV2());
stateDb.extract(stateDb.getRootDocV2());
log.info(stateDb.getRootDocV2());
setupNode(g, undefined, stateDb.getRootDocV2(), true);
// Set up an SVG group so that we can translate the final graph.

View File

@ -1,5 +1,10 @@
const getStyles = options =>
`g.stateGroup text {
`
defs #statediagram-barbEnd {
fill: ${options.transitionColor};
stroke: ${options.transitionColor};
}
g.stateGroup text {
fill: ${options.nodeBorder};
stroke: none;
font-size: 10px;
@ -12,7 +17,7 @@ g.stateGroup text {
}
g.stateGroup .state-title {
font-weight: bolder;
fill: ${options.labelColor};
fill: ${options.stateLabelColor};
}
g.stateGroup rect {
@ -26,7 +31,7 @@ g.stateGroup line {
}
.transition {
stroke: ${options.lineColor};
stroke: ${options.transitionColor};
stroke-width: 1;
fill: none;
}
@ -46,7 +51,7 @@ g.stateGroup line {
fill: ${options.noteBkgColor};
text {
fill: black;
fill: ${options.noteTextColor};
stroke: none;
font-size: 10px;
}
@ -60,18 +65,18 @@ g.stateGroup line {
}
.edgeLabel .label rect {
fill: ${options.tertiaryColor};
fill: ${options.labelBackgroundColor};
opacity: 0.5;
}
.edgeLabel .label text {
fill: ${options.tertiaryTextColor};
fill: ${options.transitionLabelColor || options.tertiaryTextColor};
}
.label div .edgeLabel {
color: ${options.tertiaryTextColor};
color: ${options.transitionLabelColor || options.tertiaryTextColor};
}
.stateLabel text {
fill: ${options.labelColor};
fill: ${options.stateLabelColor};
font-size: 10px;
font-weight: bold;
}
@ -86,14 +91,19 @@ g.stateGroup line {
stroke-width: 1.5
}
.end-state-inner {
fill: ${options.background};
fill: ${options.compositeBackground || options.background};
// stroke: ${options.background};
stroke-width: 1.5
}
.node rect {
fill: ${options.stateBkg || options.mainBkg};
stroke: ${options.stateBorder || options.nodeBorder};
stroke-width: 1px;
}
.node polygon {
fill: ${options.mainBkg};
stroke: ${options.nodeBorder};
stroke: ${options.stateBorder || options.nodeBorder};;
stroke-width: 1px;
}
#statediagram-barbEnd {
@ -101,13 +111,13 @@ g.stateGroup line {
}
.statediagram-cluster rect {
fill: ${options.mainBkg};
stroke: ${options.nodeBorder};
fill: ${options.compositeTitleBackground};
stroke: ${options.stateBorder || options.nodeBorder};
stroke-width: 1px;
}
.cluster-label, .nodeLabel {
color: ${options.textColor};
color: ${options.stateLabelColor};
}
.statediagram-cluster rect.outer {
@ -115,7 +125,7 @@ g.stateGroup line {
ry: 5px;
}
.statediagram-state .divider {
stroke: ${options.nodeBorder};
stroke: ${options.stateBorder || options.nodeBorder};
}
.statediagram-state .title-state {
@ -123,10 +133,10 @@ g.stateGroup line {
ry: 5px;
}
.statediagram-cluster.statediagram-cluster .inner {
fill: ${options.background};
fill: ${options.compositeBackground || options.background};
}
.statediagram-cluster.statediagram-cluster-alt .inner {
fill: #e0e0e0;
fill: ${options.altBackground ? options.altBackground : '#efefef'};
}
.statediagram-cluster .inner {
@ -169,6 +179,9 @@ g.stateGroup line {
.statediagram-note .nodeLabel {
color: ${options.noteTextColor};
}
.statediagram .edgeLabel {
color: red; // ${options.noteTextColor};
}
#dependencyStart, #dependencyEnd {
fill: ${options.lineColor};

View File

@ -71,7 +71,6 @@ export const draw = function(text, id) {
drawActorLegend(diagram);
bounds.insert(0, 0, LEFT_MARGIN, Object.keys(actors).length * 50);
console.log(bounds);
drawTasks(diagram, tasks, 0);
const box = bounds.getBounds();

View File

@ -69,12 +69,13 @@ import theme from './themes';
import utils, { assignWithDepth } from './utils';
function parse(text) {
const graphInit = utils.detectInit(text);
const cnf = configApi.getConfig();
const graphInit = utils.detectInit(text, cnf);
if (graphInit) {
reinitialize(graphInit);
log.debug('reinit ', graphInit);
}
const graphType = utils.detectType(text);
const graphType = utils.detectType(text, cnf);
let parser;
log.debug('Type ' + graphType);
@ -139,7 +140,6 @@ function parse(text) {
break;
case 'requirement':
case 'requirementDiagram':
console.log('RequirementDiagram');
log.debug('RequirementDiagram');
parser = requirementParser;
parser.parser.yy = requirementDb;
@ -232,7 +232,7 @@ const render = function(id, _txt, cb, container) {
// }
// console.warn('Render fetching config');
const cnf = configApi.getConfig();
let cnf = configApi.getConfig();
// Check the maximum allowed text size
if (_txt.length > cnf.maxTextSize) {
txt = 'graph TB;a[Maximum text size in diagram exceeded];style a fill:#faa';
@ -274,7 +274,7 @@ const render = function(id, _txt, cb, container) {
txt = encodeEntities(txt);
const element = select('#d' + id).node();
const graphType = utils.detectType(txt);
const graphType = utils.detectType(txt, cnf);
// insert inline style into svg
const svg = element.firstChild;
@ -413,8 +413,8 @@ const render = function(id, _txt, cb, container) {
infoRenderer.draw(txt, id, pkg.version);
break;
case 'pie':
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
pieRenderer.setConf(cnf.pie);
//cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
//pieRenderer.setConf(cnf.pie);
pieRenderer.draw(txt, id, pkg.version);
break;
case 'er':
@ -560,6 +560,7 @@ const handleDirective = function(p, directive, type) {
};
function updateRendererConfigs(conf) {
// Todo remove, all diagrams should get config on demoand from the config object, no need for this
gitGraphRenderer.setConf(conf.git);
flowRenderer.setConf(conf.flowchart);
flowRendererV2.setConf(conf.flowchart);
@ -572,7 +573,7 @@ function updateRendererConfigs(conf) {
stateRenderer.setConf(conf.state);
stateRendererV2.setConf(conf.state);
infoRenderer.setConf(conf.class);
pieRenderer.setConf(conf.class);
// pieRenderer.setConf(conf.class);
erRenderer.setConf(conf.er);
journeyRenderer.setConf(conf.journey);
requirementRenderer.setConf(conf.requirement);

View File

@ -81,8 +81,6 @@ const getStyles = (type, userStyles, options) => {
${themes[type](options)}
${userStyles}
${type} { fill: apa;}
`;
};

View File

@ -49,6 +49,8 @@ class Theme {
this.tertiaryBorderColor =
this.tertiaryBorderColor || mkBorder(this.tertiaryColor, this.darkMode);
this.noteBorderColor = this.noteBorderColor || mkBorder(this.noteBkgColor, this.darkMode);
this.noteBkgColor = this.noteBkgColor || '#fff5ad';
this.noteTextColor = this.noteTextColor || '#333';
this.secondaryTextColor = this.secondaryTextColor || invert(this.secondaryColor);
this.tertiaryTextColor = this.tertiaryTextColor || invert(this.tertiaryColor);
@ -108,10 +110,21 @@ class Theme {
this.taskTextClickableColor = this.taskTextClickableColor || '#003163';
/* state colors */
this.labelColor = this.labelColor || this.primaryTextColor;
this.transitionColor = this.transitionColor || this.lineColor;
this.transitionLabelColor = this.transitionLabelColor || this.textColor;
/* The color of the text tables of the tstates*/
this.stateLabelColor = this.stateLabelColor || this.stateBkg || this.primaryTextColor;
this.stateBkg = this.stateBkg || this.mainBkg;
this.labelBackgroundColor = this.labelBackgroundColor || this.stateBkg;
this.compositeBackground = this.compositeBackground || this.background || this.tertiaryColor;
this.altBackground = this.altBackground || this.tertiaryColor;
this.compositeTitleBackground = this.compositeTitleBackground || this.mainBkg;
this.compositeBorder = this.compositeBorder || this.nodeBorder;
this.errorBkgColor = this.errorBkgColor || this.tertiaryColor;
this.errorTextColor = this.errorTextColor || this.tertiaryTextColor;
this.transitionColor = this.transitionColor || this.lineColor;
/* class */
this.classText = this.classText || this.textColor;
@ -125,6 +138,40 @@ class Theme {
this.fillType5 = this.fillType5 || adjust(this.secondaryColor, { h: -64 });
this.fillType6 = this.fillType6 || adjust(this.primaryColor, { h: 128 });
this.fillType7 = this.fillType7 || adjust(this.secondaryColor, { h: 128 });
/* pie */
this.pie1 = this.pie1 || this.primaryColor;
this.pie2 = this.pie2 || this.secondaryColor;
this.pie3 = this.pie3 || this.tertiaryColor;
this.pie4 = this.pie4 || adjust(this.primaryColor, { l: -10 });
this.pie5 = this.pie5 || adjust(this.secondaryColor, { l: -10 });
this.pie6 = this.pie6 || adjust(this.tertiaryColor, { l: -10 });
this.pie7 = this.pie7 || adjust(this.primaryColor, { h: +60, l: -10 });
this.pie8 = this.pie8 || adjust(this.primaryColor, { h: -60, l: -10 });
this.pie9 = this.pie9 || adjust(this.primaryColor, { h: 120, l: 0 });
this.pie10 = this.pie10 || adjust(this.primaryColor, { h: +60, l: -20 });
this.pie11 = this.pie11 || adjust(this.primaryColor, { h: -60, l: -20 });
this.pie12 = this.pie12 || adjust(this.primaryColor, { h: 120, l: -10 });
this.pieTitleTextSize = this.pieTitleTextSize || '25px';
this.pieTitleTextColor = this.pieTitleTextColor || this.taskTextDarkColor;
this.pieSectionTextSize = this.pieSectionTextSize || '17px';
this.pieSectionTextColor = this.pieSectionTextColor || this.textColor;
this.pieLegendTextSize = this.pieLegendTextSize || '17px';
this.pieLegendTextColor = this.pieLegendTextColor || this.taskTextDarkColor;
this.pieStrokeColor = this.pieStrokeColor || 'black';
this.pieStrokeWidth = this.pieStrokeWidth || '2px';
this.pieOpacity = this.pieOpacity || '0.7';
/* requirement-diagram */
this.requirementBackground = this.requirementBackground || this.primaryColor;
this.requirementBorderColor = this.requirementBorderColor || this.primaryBorderColor;
this.requirementBorderSize = this.requirementBorderSize || this.primaryBorderColor;
this.requirementTextColor = this.requirementTextColor || this.primaryTextColor;
this.relationColor = this.relationColor || this.lineColor;
this.relationLabelBackground =
this.relationLabelBackground ||
(this.darkMode ? darken(this.secondaryColor, 30) : this.secondaryColor);
this.relationLabelColor = this.relationLabelColor || this.actorTextColor;
}
calculate(overrides) {
if (typeof overrides !== 'object') {

View File

@ -127,8 +127,18 @@ class Theme {
this.taskTextDarkColor = this.darkTextColor;
/* state colors */
this.labelColor = this.textColor;
this.altBackground = lighten(this.background, 20);
this.transitionColor = this.transitionColor || this.lineColor;
this.transitionLabelColor = this.transitionLabelColor || this.textColor;
this.stateLabelColor = this.stateLabelColor || this.stateBkg || this.primaryTextColor;
this.stateBkg = this.stateBkg || this.mainBkg;
this.labelBackgroundColor = this.labelBackgroundColor || this.stateBkg;
this.compositeBackground = this.compositeBackground || this.background || this.tertiaryColor;
this.altBackground = this.altBackground || '#555';
this.compositeTitleBackground = this.compositeTitleBackground || this.mainBkg;
this.compositeBorder = this.compositeBorder || this.nodeBorder;
this.errorBkgColor = this.errorBkgColor || this.tertiaryColor;
this.errorTextColor = this.errorTextColor || this.tertiaryTextColor;
this.fillType0 = this.primaryColor;
this.fillType1 = this.secondaryColor;
@ -138,8 +148,43 @@ class Theme {
this.fillType5 = adjust(this.secondaryColor, { h: -64 });
this.fillType6 = adjust(this.primaryColor, { h: 128 });
this.fillType7 = adjust(this.secondaryColor, { h: 128 });
/* pie */
this.pie1 = this.pie1 || '#0b0000';
this.pie2 = this.pie2 || '#4d1037';
this.pie3 = this.pie3 || '#3f5258';
this.pie4 = this.pie4 || '#4f2f1b';
this.pie5 = this.pie5 || '#6e0a0a';
this.pie6 = this.pie6 || '#3b0048';
this.pie7 = this.pie7 || '#995a01';
this.pie8 = this.pie8 || '#154706';
this.pie9 = this.pie9 || '#161722';
this.pie10 = this.pie10 || '#00296f';
this.pie11 = this.pie11 || '#01629c';
this.pie12 = this.pie12 || '#010029';
this.pieTitleTextSize = this.pieTitleTextSize || '25px';
this.pieTitleTextColor = this.pieTitleTextColor || this.taskTextDarkColor;
this.pieSectionTextSize = this.pieSectionTextSize || '17px';
this.pieSectionTextColor = this.pieSectionTextColor || this.textColor;
this.pieLegendTextSize = this.pieLegendTextSize || '17px';
this.pieLegendTextColor = this.pieLegendTextColor || this.taskTextDarkColor;
this.pieStrokeColor = this.pieStrokeColor || 'black';
this.pieStrokeWidth = this.pieStrokeWidth || '2px';
this.pieOpacity = this.pieOpacity || '0.7';
/* class */
this.classText = this.primaryTextColor;
/* requirement-diagram */
this.requirementBackground = this.requirementBackground || this.primaryColor;
this.requirementBorderColor = this.requirementBorderColor || this.primaryBorderColor;
this.requirementBorderSize = this.requirementBorderSize || this.primaryBorderColor;
this.requirementTextColor = this.requirementTextColor || this.primaryTextColor;
this.relationColor = this.relationColor || this.lineColor;
this.relationLabelBackground =
this.relationLabelBackground ||
(this.darkMode ? darken(this.secondaryColor, 30) : this.secondaryColor);
this.relationLabelColor = this.relationLabelColor || this.actorTextColor;
}
calculate(overrides) {
if (typeof overrides !== 'object') {

View File

@ -139,6 +139,20 @@ class Theme {
this.taskTextOutsideColor = this.taskTextDarkColor;
/* state colors */
this.transitionColor = this.transitionColor || this.lineColor;
this.transitionLabelColor = this.transitionLabelColor || this.textColor;
this.stateLabelColor = this.stateLabelColor || this.stateBkg || this.primaryTextColor;
this.stateBkg = this.stateBkg || this.mainBkg;
this.labelBackgroundColor = this.labelBackgroundColor || this.stateBkg;
this.compositeBackground = this.compositeBackground || this.background || this.tertiaryColor;
this.altBackground = this.altBackground || '#f0f0f0';
this.compositeTitleBackground = this.compositeTitleBackground || this.mainBkg;
this.compositeBorder = this.compositeBorder || this.nodeBorder;
this.errorBkgColor = this.errorBkgColor || this.tertiaryColor;
this.errorTextColor = this.errorTextColor || this.tertiaryTextColor;
this.transitionColor = this.transitionColor || this.lineColor;
/* class */
this.classText = this.primaryTextColor;
/* journey */
@ -150,6 +164,38 @@ class Theme {
this.fillType5 = adjust(this.secondaryColor, { h: -64 });
this.fillType6 = adjust(this.primaryColor, { h: 128 });
this.fillType7 = adjust(this.secondaryColor, { h: 128 });
/* pie */
this.pie1 = this.pie1 || this.primaryColor;
this.pie2 = this.pie2 || this.secondaryColor;
this.pie3 = this.pie3 || adjust(this.tertiaryColor, { l: -40 });
this.pie4 = this.pie4 || adjust(this.primaryColor, { l: -10 });
this.pie5 = this.pie5 || adjust(this.secondaryColor, { l: -30 });
this.pie6 = this.pie6 || adjust(this.tertiaryColor, { l: -20 });
this.pie7 = this.pie7 || adjust(this.primaryColor, { h: +60, l: -20 });
this.pie8 = this.pie8 || adjust(this.primaryColor, { h: -60, l: -40 });
this.pie9 = this.pie9 || adjust(this.primaryColor, { h: 120, l: -40 });
this.pie10 = this.pie10 || adjust(this.primaryColor, { h: +60, l: -40 });
this.pie11 = this.pie11 || adjust(this.primaryColor, { h: -90, l: -40 });
this.pie12 = this.pie12 || adjust(this.primaryColor, { h: 120, l: -30 });
this.pieTitleTextSize = this.pieTitleTextSize || '25px';
this.pieTitleTextColor = this.pieTitleTextColor || this.taskTextDarkColor;
this.pieSectionTextSize = this.pieSectionTextSize || '17px';
this.pieSectionTextColor = this.pieSectionTextColor || this.textColor;
this.pieLegendTextSize = this.pieLegendTextSize || '17px';
this.pieLegendTextColor = this.pieLegendTextColor || this.taskTextDarkColor;
this.pieStrokeColor = this.pieStrokeColor || 'black';
this.pieStrokeWidth = this.pieStrokeWidth || '2px';
this.pieOpacity = this.pieOpacity || '0.7';
/* requirement-diagram */
this.requirementBackground = this.requirementBackground || this.primaryColor;
this.requirementBorderColor = this.requirementBorderColor || this.primaryBorderColor;
this.requirementBorderSize = this.requirementBorderSize || this.primaryBorderColor;
this.requirementTextColor = this.requirementTextColor || this.primaryTextColor;
this.relationColor = this.relationColor || this.lineColor;
this.relationLabelBackground = this.relationLabelBackground || this.labelBackground;
this.relationLabelColor = this.relationLabelColor || this.actorTextColor;
}
calculate(overrides) {
if (typeof overrides !== 'object') {

View File

@ -109,6 +109,20 @@ class Theme {
this.activeTaskBkgColor = this.mainBkg;
/* state colors */
this.transitionColor = this.transitionColor || this.lineColor;
this.transitionLabelColor = this.transitionLabelColor || this.textColor;
this.stateLabelColor = this.stateLabelColor || this.stateBkg || this.primaryTextColor;
this.stateBkg = this.stateBkg || this.mainBkg;
this.labelBackgroundColor = this.labelBackgroundColor || this.stateBkg;
this.compositeBackground = this.compositeBackground || this.background || this.tertiaryColor;
this.altBackground = this.altBackground || '#f0f0f0';
this.compositeTitleBackground = this.compositeTitleBackground || this.mainBkg;
this.compositeBorder = this.compositeBorder || this.nodeBorder;
this.errorBkgColor = this.errorBkgColor || this.tertiaryColor;
this.errorTextColor = this.errorTextColor || this.tertiaryTextColor;
this.transitionColor = this.transitionColor || this.lineColor;
/* class */
this.classText = this.primaryTextColor;
/* journey */
@ -120,6 +134,38 @@ class Theme {
this.fillType5 = adjust(this.secondaryColor, { h: -64 });
this.fillType6 = adjust(this.primaryColor, { h: 128 });
this.fillType7 = adjust(this.secondaryColor, { h: 128 });
/* pie */
this.pie1 = this.pie1 || this.primaryColor;
this.pie2 = this.pie2 || this.secondaryColor;
this.pie3 = this.pie3 || this.tertiaryColor;
this.pie4 = this.pie4 || adjust(this.primaryColor, { l: -30 });
this.pie5 = this.pie5 || adjust(this.secondaryColor, { l: -30 });
this.pie6 = this.pie6 || adjust(this.tertiaryColor, { h: +40, l: -40 });
this.pie7 = this.pie7 || adjust(this.primaryColor, { h: +60, l: -10 });
this.pie8 = this.pie8 || adjust(this.primaryColor, { h: -60, l: -10 });
this.pie9 = this.pie9 || adjust(this.primaryColor, { h: 120, l: 0 });
this.pie10 = this.pie10 || adjust(this.primaryColor, { h: +60, l: -50 });
this.pie11 = this.pie11 || adjust(this.primaryColor, { h: -60, l: -50 });
this.pie12 = this.pie12 || adjust(this.primaryColor, { h: 120, l: -50 });
this.pieTitleTextSize = this.pieTitleTextSize || '25px';
this.pieTitleTextColor = this.pieTitleTextColor || this.taskTextDarkColor;
this.pieSectionTextSize = this.pieSectionTextSize || '17px';
this.pieSectionTextColor = this.pieSectionTextColor || this.textColor;
this.pieLegendTextSize = this.pieLegendTextSize || '17px';
this.pieLegendTextColor = this.pieLegendTextColor || this.taskTextDarkColor;
this.pieStrokeColor = this.pieStrokeColor || 'black';
this.pieStrokeWidth = this.pieStrokeWidth || '2px';
this.pieOpacity = this.pieOpacity || '0.7';
/* requirement-diagram */
this.requirementBackground = this.requirementBackground || this.primaryColor;
this.requirementBorderColor = this.requirementBorderColor || this.primaryBorderColor;
this.requirementBorderSize = this.requirementBorderSize || this.primaryBorderColor;
this.requirementTextColor = this.requirementTextColor || this.primaryTextColor;
this.relationColor = this.relationColor || this.lineColor;
this.relationLabelBackground = this.relationLabelBackground || this.edgeLabelBackground;
this.relationLabelColor = this.relationLabelColor || this.actorTextColor;
}
calculate(overrides) {
if (typeof overrides !== 'object') {

View File

@ -24,7 +24,7 @@ class Theme {
this.lineColor = invert(this.background);
this.textColor = invert(this.background);
this.altBackground = lighten(this.contrast, 55);
// this.altBackground = lighten(this.contrast, 55);
this.mainBkg = '#eee';
this.secondBkg = 'calculated';
this.lineColor = '#666';
@ -119,9 +119,9 @@ class Theme {
this.labelBoxBorderColor = this.actorBorder;
this.labelTextColor = this.text;
this.loopTextColor = this.text;
this.noteBorderColor = darken(this.note, 60);
this.noteBkgColor = this.note;
this.noteTextColor = this.actorTextColor;
this.noteBorderColor = '#999';
this.noteBkgColor = '#666';
this.noteTextColor = '#fff';
/* Gantt chart variables */
@ -146,6 +146,20 @@ class Theme {
this.todayLineColor = this.critBkgColor;
/* state colors */
this.transitionColor = this.transitionColor || '#000';
this.transitionLabelColor = this.transitionLabelColor || this.textColor;
this.stateLabelColor = this.stateLabelColor || this.stateBkg || this.primaryTextColor;
this.stateBkg = this.stateBkg || this.mainBkg;
this.labelBackgroundColor = this.labelBackgroundColor || this.stateBkg;
this.compositeBackground = this.compositeBackground || this.background || this.tertiaryColor;
this.altBackground = this.altBackground || '#f4f4f4';
this.compositeTitleBackground = this.compositeTitleBackground || this.mainBkg;
this.stateBorder = this.stateBorder || '#000';
this.errorBkgColor = this.errorBkgColor || this.tertiaryColor;
this.errorTextColor = this.errorTextColor || this.tertiaryTextColor;
/* class */
this.classText = this.primaryTextColor;
/* journey */
@ -157,6 +171,51 @@ class Theme {
this.fillType5 = adjust(this.secondaryColor, { h: -64 });
this.fillType6 = adjust(this.primaryColor, { h: 128 });
this.fillType7 = adjust(this.secondaryColor, { h: 128 });
// /* pie */
this.pie1 = this.pie1 || '#F4F4F4';
this.pie2 = this.pie2 || '#555';
this.pie3 = this.pie3 || '#BBB';
this.pie4 = this.pie4 || '#777';
this.pie5 = this.pie5 || '#999';
this.pie6 = this.pie6 || '#DDD';
this.pie7 = this.pie7 || '#FFF';
this.pie8 = this.pie8 || '#DDD';
this.pie9 = this.pie9 || '#BBB';
this.pie10 = this.pie10 || '#999';
this.pie11 = this.pie11 || '#777';
this.pie12 = this.pie12 || '#555';
this.pieTitleTextSize = this.pieTitleTextSize || '25px';
this.pieTitleTextColor = this.pieTitleTextColor || this.taskTextDarkColor;
this.pieSectionTextSize = this.pieSectionTextSize || '17px';
this.pieSectionTextColor = this.pieSectionTextColor || this.textColor;
this.pieLegendTextSize = this.pieLegendTextSize || '17px';
this.pieLegendTextColor = this.pieLegendTextColor || this.taskTextDarkColor;
this.pieStrokeColor = this.pieStrokeColor || 'black';
this.pieStrokeWidth = this.pieStrokeWidth || '2px';
this.pieOpacity = this.pieOpacity || '0.7';
// this.pie1 = this.pie1 || '#212529';
// this.pie2 = this.pie2 || '#343A40';
// this.pie3 = this.pie3 || '#495057';
// this.pie4 = this.pie4 || '#6C757D';
// this.pie5 = this.pie5 || adjust(this.secondaryColor, { l: -10 });
// this.pie6 = this.pie6 || adjust(this.tertiaryColor, { l: -10 });
// this.pie7 = this.pie7 || adjust(this.primaryColor, { h: +60, l: -10 });
// this.pie8 = this.pie8 || adjust(this.primaryColor, { h: -60, l: -10 });
// this.pie9 = this.pie9 || adjust(this.primaryColor, { h: 120, l: 0 });
// this.pie10 = this.pie10 || adjust(this.primaryColor, { h: +60, l: -20 });
// this.pie11 = this.pie11 || adjust(this.primaryColor, { h: -60, l: -20 });
// this.pie12 = this.pie12 || adjust(this.primaryColor, { h: 120, l: -10 });
/* requirement-diagram */
this.requirementBackground = this.requirementBackground || this.primaryColor;
this.requirementBorderColor = this.requirementBorderColor || this.primaryBorderColor;
this.requirementBorderSize = this.requirementBorderSize || this.primaryBorderColor;
this.requirementTextColor = this.requirementTextColor || this.primaryTextColor;
this.relationColor = this.relationColor || this.lineColor;
this.relationLabelBackground = this.relationLabelBackground || this.edgeLabelBackground;
this.relationLabelColor = this.relationLabelColor || this.actorTextColor;
}
calculate(overrides) {
if (typeof overrides !== 'object') {

View File

@ -65,7 +65,7 @@ const anyComment = /\s*%%.*\n/gm;
* @param {string} text The text defining the graph
* @returns {object} the json object representing the init passed to mermaid.initialize()
*/
export const detectInit = function(text) {
export const detectInit = function(text, cnf) {
let inits = detectDirective(text, /(?:init\b)|(?:initialize\b)/);
let results = {};
if (Array.isArray(inits)) {
@ -75,7 +75,7 @@ export const detectInit = function(text) {
results = inits.args;
}
if (results) {
let type = detectType(text);
let type = detectType(text, cnf);
['config'].forEach(prop => {
if (typeof results[prop] !== 'undefined') {
if (type === 'flowchart-v2') {
@ -173,7 +173,7 @@ export const detectDirective = function(text, type = null) {
* @param {string} text The text defining the graph
* @returns {string} A graph definition key
*/
export const detectType = function(text) {
export const detectType = function(text, cnf) {
text = text.replace(directive, '').replace(anyComment, '\n');
log.debug('Detecting diagram type based on the text ' + text);
if (text.match(/^\s*sequenceDiagram/)) {
@ -187,6 +187,7 @@ export const detectType = function(text) {
return 'classDiagram';
}
if (text.match(/^\s*classDiagram/)) {
if (cnf && cnf.class && cnf.class.defaultRenderer === 'dagre-wrapper') return 'classDiagram';
return 'class';
}
@ -195,6 +196,7 @@ export const detectType = function(text) {
}
if (text.match(/^\s*stateDiagram/)) {
if (cnf && cnf.class && cnf.state.defaultRenderer === 'dagre-wrapper') return 'stateDiagram';
return 'state';
}
@ -223,6 +225,8 @@ export const detectType = function(text) {
if (text.match(/^\s*requirement/) || text.match(/^\s*requirementDiagram/)) {
return 'requirement';
}
if (cnf && cnf.flowchart && cnf.flowchart.defaultRenderer === 'dagre-wrapper')
return 'flowchart-v2';
return 'flowchart';
};