mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-01-28 07:03:17 +08:00
Merge branch 'develop' into feature/Issue-1465_Class_migration
This commit is contained in:
commit
24e470a099
3
.gitignore
vendored
3
.gitignore
vendored
@ -16,4 +16,5 @@ dist/sequenceTest.html
|
||||
|
||||
.vscode/
|
||||
cypress/platform/current.html
|
||||
cypress/platform/experimental.html
|
||||
cypress/platform/experimental.html
|
||||
local/
|
@ -214,7 +214,7 @@ pie
|
||||
|
||||
## Related projects
|
||||
|
||||
- [Command Line Interface](https://github.com/mermaid-js/mermaid.cli)
|
||||
- [Command Line Interface](https://github.com/mermaid-js/mermaid-cli)
|
||||
- [Live Editor](https://github.com/mermaid-js/mermaid-live-editor)
|
||||
- [HTTP Server](https://github.com/TomWright/mermaid-server)
|
||||
|
||||
|
@ -6,6 +6,6 @@ describe('Sequencediagram', () => {
|
||||
cy.visit(url);
|
||||
cy.get('body')
|
||||
.find('svg')
|
||||
.should('have.length', 2);
|
||||
.should('have.length', 1);
|
||||
});
|
||||
});
|
||||
|
49
cypress/integration/rendering/flowchart-v2.spec.js
Normal file
49
cypress/integration/rendering/flowchart-v2.spec.js
Normal file
@ -0,0 +1,49 @@
|
||||
/* eslint-env jest */
|
||||
import { imgSnapshotTest } from '../../helpers/util';
|
||||
|
||||
describe('Flowchart v2', () => {
|
||||
it('1: should render a simple flowchart', () => {
|
||||
imgSnapshotTest(
|
||||
`flowchart TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me think}
|
||||
C -->|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('2: should render a simple flowchart with diagramPadding set to 0', () => {
|
||||
imgSnapshotTest(
|
||||
`flowchart TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me think}
|
||||
%% this is a comment
|
||||
C -->|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
`,
|
||||
{ flowchart: { diagramPadding: 0 } }
|
||||
);
|
||||
});
|
||||
|
||||
it('3: a link with correct arrowhead to a subgraph', () => {
|
||||
imgSnapshotTest(
|
||||
`flowchart TD
|
||||
P1
|
||||
P1 -->P1.5
|
||||
subgraph P1.5
|
||||
P2
|
||||
P2.5(( A ))
|
||||
P3
|
||||
end
|
||||
P2 --> P4
|
||||
P3 --> P6
|
||||
P1.5 --> P5
|
||||
`,
|
||||
{ flowchart: { diagramPadding: 0 } }
|
||||
);
|
||||
});
|
||||
});
|
@ -671,4 +671,18 @@ describe('Flowchart', () => {
|
||||
{ flowchart: { htmlLabels: false } }
|
||||
);
|
||||
});
|
||||
|
||||
it('33: should render a simple flowchart with diagramPadding set to 0', () => {
|
||||
imgSnapshotTest(
|
||||
`graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me think}
|
||||
%% this is a comment
|
||||
C -->|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
`,
|
||||
{ flowchart: { diagramPadding: 0 } }
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -2,6 +2,9 @@
|
||||
import { imgSnapshotTest } from '../../helpers/util.js';
|
||||
|
||||
describe('Gantt diagram', () => {
|
||||
beforeEach(()=>{
|
||||
cy.clock((new Date('1010-10-10')).getTime())
|
||||
})
|
||||
it('should render a gantt chart', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
|
@ -126,6 +126,29 @@ context('Sequence diagram', () => {
|
||||
participant A as Extremely utterly long line of longness which had preivously overflown the actor box as it is much longer than what it should be
|
||||
A->>Bob: Hola
|
||||
Bob-->A: Pasten !
|
||||
`,
|
||||
{logLevel: 0}
|
||||
);
|
||||
});
|
||||
it('should wrap (inline) long actor descriptions', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
participant A as wrap:Extremely utterly long line of longness which had preivously overflown the actor box as it is much longer than what it should be
|
||||
A->>Bob: Hola
|
||||
Bob-->A: Pasten !
|
||||
`,
|
||||
{logLevel: 0}
|
||||
);
|
||||
});
|
||||
it('should wrap (directive) long actor descriptions', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
%%{init: {'config': {'wrap': true }}}%%
|
||||
sequenceDiagram
|
||||
participant A as Extremely utterly long line of longness which had preivously overflown the actor box as it is much longer than what it should be
|
||||
A->>Bob: Hola
|
||||
Bob-->A: Pasten !
|
||||
`,
|
||||
{}
|
||||
);
|
||||
@ -141,6 +164,17 @@ context('Sequence diagram', () => {
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render long notes wrapped (inline) left of actor', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
Alice->>Bob: Hola
|
||||
Note left of Alice:wrap: Extremely utterly long line of longness which had preivously overflown the actor box as it is much longer than what it should be
|
||||
Bob->>Alice: I'm short though
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render long notes right of actor', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
@ -152,6 +186,17 @@ context('Sequence diagram', () => {
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render long notes wrapped (inline) right of actor', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
Alice->>Bob: Hola
|
||||
Note right of Alice:wrap: Extremely utterly long line of longness which had preivously overflown the actor box as it is much longer than what it should be
|
||||
Bob->>Alice: I'm short though
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render long notes over actor', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
@ -163,6 +208,17 @@ context('Sequence diagram', () => {
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render long notes wrapped (inline) over actor', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
Alice->>Bob: Hola
|
||||
Note over Alice:wrap: Extremely utterly long line of longness which had preivously overflown the actor box as it is much longer than what it should be
|
||||
Bob->>Alice: I'm short though
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render long messages from an actor to the left to one to the right', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
@ -173,6 +229,16 @@ context('Sequence diagram', () => {
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render long messages wrapped (inline) from an actor to the left to one to the right', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
Alice->>Bob:wrap:Extremely utterly long line of longness which had preivously overflown the actor box as it is much longer than what it should be
|
||||
Bob->>Alice: I'm short though
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render long messages from an actor to the right to one to the left', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
@ -183,6 +249,16 @@ context('Sequence diagram', () => {
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render long messages wrapped (inline) from an actor to the right to one to the left', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
Alice->>Bob: I'm short
|
||||
Bob->>Alice:wrap: Extremely utterly long line of longness which had preivously overflown the actor box as it is much longer than what it should be
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
});
|
||||
context('background rects', () => {
|
||||
it('should render a single and nested rects', () => {
|
||||
@ -216,6 +292,69 @@ context('Sequence diagram', () => {
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render a single and nested opt with long test overflowing', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
participant A
|
||||
participant B
|
||||
participant C
|
||||
participant D
|
||||
participant E
|
||||
participant G
|
||||
|
||||
A ->>+ B: Task 1
|
||||
opt this is an opt with a long title that will overflow
|
||||
B ->>+ C: Task 2
|
||||
C -->>- B: Return
|
||||
end
|
||||
|
||||
A ->> D: Task 3
|
||||
opt this is another opt with a long title that will overflow
|
||||
D ->>+ E: Task 4
|
||||
opt this is a nested opt with a long title that will overflow
|
||||
E ->>+ G: Task 5
|
||||
G -->>- E: Return
|
||||
end
|
||||
E ->> E: Task 6
|
||||
end
|
||||
D -->> A: Complete
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render a single and nested opt with long test wrapping', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
%%{init: { 'config': { 'wrap': true } } }%%
|
||||
sequenceDiagram
|
||||
participant A
|
||||
participant B
|
||||
participant C
|
||||
participant D
|
||||
participant E
|
||||
participant G
|
||||
|
||||
A ->>+ B: Task 1
|
||||
opt this is an opt with a long title that will overflow
|
||||
B ->>+ C: Task 2
|
||||
C -->>- B: Return
|
||||
end
|
||||
|
||||
A ->> D: Task 3
|
||||
opt this is another opt with a long title that will overflow
|
||||
D ->>+ E: Task 4
|
||||
opt this is a nested opt with a long title that will overflow
|
||||
E ->>+ G: Task 5
|
||||
G -->>- E: Return
|
||||
end
|
||||
E ->> E: Task 6
|
||||
end
|
||||
D -->> A: Complete
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render rect around and inside loops', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
@ -327,5 +466,68 @@ context('Sequence diagram', () => {
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render dark theme from init directive and configure font size 24 font', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
%%{init: {'theme': 'dark', 'config': {'fontSize': 24}}}%%
|
||||
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!
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render with wrapping enabled', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
%%{init: { 'config': { 'wrap': true }}}%%
|
||||
sequenceDiagram
|
||||
participant A as Alice, the talkative one
|
||||
A->>John: Hello John, how are you today? I'm feeling quite verbose today.
|
||||
A->>John: John, can you hear me? If you are not available, we can talk later.
|
||||
John-->>A: Hi Alice, I can hear you! I was finishing up an important meeting.
|
||||
John-->>A: I feel great! I was not ignoring you. I am sorry you had to wait for a response.
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render with an init directive', () => {
|
||||
imgSnapshotTest(
|
||||
`%%{init: { "theme": "dark", 'config': { "fontFamily": "Menlo", "fontSize": 18, "fontWeight": 400, "wrap": true }}}%%
|
||||
sequenceDiagram
|
||||
Alice->>Bob: Hello Bob, how are you? If you are not available right now, I can leave you a message. Please get back to me as soon as you can!
|
||||
Note left of Alice: Bob thinks
|
||||
Bob->>Alice: Fine!`,
|
||||
{}
|
||||
)
|
||||
});
|
||||
});
|
||||
context('directives', () => {
|
||||
it('should overide config with directive settings', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
%%{init: { "config": { "mirrorActors": true }}}%%
|
||||
sequenceDiagram
|
||||
Alice->>Bob: I'm short
|
||||
note left of Alice: config set to mirrorActors: false<br/>directive set to mirrorActors: true
|
||||
Bob->>Alice: Short as well
|
||||
`,
|
||||
{ logLevel:0, sequence: { mirrorActors: false, noteFontSize: 18, noteFontFamily: 'Arial' } }
|
||||
);
|
||||
});
|
||||
it('should overide config with directive settings', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
%%{init: { "config": { "mirrorActors": false, "wrap": true }}}%%
|
||||
sequenceDiagram
|
||||
Alice->>Bob: I'm short
|
||||
note left of Alice: config: mirrorActors=true<br/>directive: mirrorActors=false
|
||||
Bob->>Alice: Short as well
|
||||
`,
|
||||
{ logLevel:0, sequence: { mirrorActors: true, noteFontSize: 18, noteFontFamily: 'Arial' } }
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
278
cypress/integration/rendering/theme.spec.js
Normal file
278
cypress/integration/rendering/theme.spec.js
Normal file
@ -0,0 +1,278 @@
|
||||
/* eslint-env jest */
|
||||
import { imgSnapshotTest } from '../../helpers/util.js';
|
||||
|
||||
describe('Pie Chart', () => {
|
||||
// beforeEach(()=>{
|
||||
// cy.clock((new Date('2014-06-09')).getTime());
|
||||
// });
|
||||
|
||||
['default', 'forest', 'dark', 'neutral'].forEach(theme=>{
|
||||
describe(theme, () => {
|
||||
it('should render a pie diagram', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
pie title Sports in Sweden
|
||||
"Bandy" : 40
|
||||
"Ice-Hockey" : 80
|
||||
"Football" : 90
|
||||
`,
|
||||
{theme}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should render a flowchart diagram', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
%%{init: { 'logLevel': 0, 'theme': '${theme}'} }%%
|
||||
graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me think}
|
||||
B --> G[/Another/]
|
||||
C ==>|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
subgraph section
|
||||
C
|
||||
D
|
||||
E
|
||||
F
|
||||
G
|
||||
end
|
||||
`,
|
||||
{theme}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should render a new flowchart diagram', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
%%{init: { 'logLevel': 0, 'theme': '${theme}'} }%%
|
||||
flowchart TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me think}
|
||||
B --> G[Another]
|
||||
C ==>|One| D[Laptop]
|
||||
C x--x|Two| E[iPhone]
|
||||
C o--o|Three| F[fa:fa-car Car]
|
||||
subgraph section
|
||||
C
|
||||
D
|
||||
E
|
||||
F
|
||||
G
|
||||
end
|
||||
`,
|
||||
{theme}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should render a sequence diagram', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
%%{init: { 'logLevel': 0, 'theme': '${theme}'} }%%
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
par Action 1
|
||||
Alice->>John: Hello John, how are you?
|
||||
and Action 2
|
||||
Alice->>Bob: Hello Bob, how are you?
|
||||
end
|
||||
Alice->>+John: Hello John, how are you?
|
||||
Alice->>+John: John, can you hear me?
|
||||
John-->>-Alice: Hi Alice, I can hear you!
|
||||
Note right of John: John is perceptive
|
||||
John-->>-Alice: I feel great!
|
||||
loop Every minute
|
||||
John-->Alice: Great!
|
||||
end
|
||||
|
||||
|
||||
`,
|
||||
{theme}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
|
||||
it('should render a class diagram', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
%%{init: { 'logLevel': 0, 'theme': '${theme}'} }%%
|
||||
classDiagram
|
||||
Animal "*" <|-- "1" Duck
|
||||
Animal "1" <|-- "10" Fish
|
||||
Animal <|-- Zebra
|
||||
Animal : +int age
|
||||
Animal : +String gender
|
||||
Animal: +isMammal()
|
||||
Animal: +mate()
|
||||
class Duck{
|
||||
+String beakColor
|
||||
+swim()
|
||||
+quack()
|
||||
}
|
||||
class Fish{
|
||||
-int sizeInFeet
|
||||
-canEat()
|
||||
}
|
||||
class Zebra{
|
||||
+bool is_wild
|
||||
+run()
|
||||
}
|
||||
classA <|-- classB
|
||||
classC *-- classD
|
||||
classE o-- classF
|
||||
classG <-- classH
|
||||
classI -- classJ
|
||||
classK <.. classL
|
||||
classM <|.. classN
|
||||
classO .. classP
|
||||
classA --|> classB : Inheritance
|
||||
classC --* classD : Composition
|
||||
classE --o classF : Aggregation
|
||||
classG --> classH : Association
|
||||
classI -- classJ : Link(Solid)
|
||||
classK ..> classL : Dependency
|
||||
classM ..|> classN : Realization
|
||||
classO .. classP : Link(Dashed)
|
||||
`,
|
||||
{theme}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should render a state diagram', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
%%{init: { 'logLevel': 0, 'theme': '${theme}'} }%%
|
||||
stateDiagram
|
||||
[*] --> Active
|
||||
|
||||
state Active {
|
||||
[*] --> NumLockOff
|
||||
NumLockOff --> NumLockOn : EvNumLockPressed
|
||||
NumLockOn --> NumLockOff : EvNumLockPressed
|
||||
--
|
||||
[*] --> CapsLockOff
|
||||
CapsLockOff --> CapsLockOn : EvCapsLockPressed
|
||||
CapsLockOn --> CapsLockOff : EvCapsLockPressed
|
||||
--
|
||||
[*] --> ScrollLockOff
|
||||
ScrollLockOff --> ScrollLockOn : EvCapsLockPressed
|
||||
ScrollLockOn --> ScrollLockOff : EvCapsLockPressed
|
||||
}
|
||||
state SomethingElse {
|
||||
A --> B
|
||||
B --> A
|
||||
}
|
||||
|
||||
Active --> SomethingElse
|
||||
note right of SomethingElse : This is the note to the right.
|
||||
`,
|
||||
{theme}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should render a state diagram (v2)', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
%%{init: { 'logLevel': 0, 'theme': '${theme}'} }%%
|
||||
stateDiagram-v2
|
||||
[*] --> Active
|
||||
|
||||
state Active {
|
||||
[*] --> NumLockOff
|
||||
NumLockOff --> NumLockOn : EvNumLockPressed
|
||||
NumLockOn --> NumLockOff : EvNumLockPressed
|
||||
--
|
||||
[*] --> CapsLockOff
|
||||
CapsLockOff --> CapsLockOn : EvCapsLockPressed
|
||||
CapsLockOn --> CapsLockOff : EvCapsLockPressed
|
||||
--
|
||||
[*] --> ScrollLockOff
|
||||
ScrollLockOff --> ScrollLockOn : EvCapsLockPressed
|
||||
ScrollLockOn --> ScrollLockOff : EvCapsLockPressed
|
||||
}
|
||||
state SomethingElse {
|
||||
A --> B
|
||||
B --> A
|
||||
}
|
||||
|
||||
Active --> SomethingElse2
|
||||
note right of SomethingElse2 : This is the note to the right.
|
||||
`,
|
||||
{theme}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should render a er diagram', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
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"
|
||||
|
||||
`,
|
||||
{theme}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should render a user journey diagram', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
journey
|
||||
title My working day
|
||||
section Go to work
|
||||
Make tea: 5: Me
|
||||
Go upstairs: 3: Me
|
||||
Do work: 1: Me, Cat
|
||||
section Go home
|
||||
Go downstairs: 5: Me
|
||||
Sit down: 5: Me `,
|
||||
{theme}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should render a gantt diagram', () => {
|
||||
cy.clock((new Date('2014-01-06')).getTime());
|
||||
imgSnapshotTest(
|
||||
`
|
||||
gantt
|
||||
dateFormat :YYYY-MM-DD
|
||||
title :Adding GANTT diagram functionality to mermaid
|
||||
excludes :excludes the named dates/days from being included in a charted task..
|
||||
section A section
|
||||
Completed task :done, des1, 2014-01-06,2014-01-08
|
||||
Active task :active, des2, 2014-01-09, 3d
|
||||
Future task : des3, after des2, 5d
|
||||
Future task2 : des4, after des3, 5d
|
||||
|
||||
section Critical tasks
|
||||
Completed task in the critical line :crit, done, 2014-01-06,24h
|
||||
Implement parser and jison :crit, done, after des1, 2d
|
||||
Create tests for parser :crit, active, 3d
|
||||
Future task in critical line :crit, 5d
|
||||
Create tests for renderer :2d
|
||||
Add to mermaid :1d
|
||||
|
||||
section Documentation
|
||||
Describe gantt syntax :active, a1, after des1, 3d
|
||||
Add gantt diagram to demo page :after a1 , 20h
|
||||
Add another diagram to demo page :doc1, after a1 , 48h
|
||||
|
||||
section Last section
|
||||
Describe gantt syntax :after doc1, 3d
|
||||
Add gantt diagram to demo page :20h
|
||||
Add another diagram to demo page :48h
|
||||
`,
|
||||
{theme}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@ -1,10 +1,52 @@
|
||||
import mermaid from '../../dist/mermaid.core'
|
||||
import mermaid from '../../dist/mermaid.core';
|
||||
|
||||
let code = `flowchart LR
|
||||
Power_Supply --> Transmitter_A
|
||||
Power_Supply --> Transmitter_B
|
||||
Transmitter_A --> D
|
||||
Transmitter_B --> D`;
|
||||
|
||||
let code2 = `gantt
|
||||
dateFormat YYYY-MM-DD
|
||||
title Adding GANTT diagram functionality to mermaid
|
||||
section A section
|
||||
Completed task :done, des1, 2014-01-06,2014-01-08
|
||||
Active task :active, des2, 2014-01-09, 3d
|
||||
Future task : des3, after des2, 5d
|
||||
Future task2 : des4, after des3, 5d
|
||||
section Critical tasks
|
||||
Completed task in the critical line :crit, done, 2014-01-06,24h
|
||||
Implement parser and jison :crit, done, after des1, 2d
|
||||
Create tests for parser :crit, active, 3d
|
||||
Future task in critical line :crit, 5d
|
||||
Create tests for renderer :2d
|
||||
Add to mermaid :1d`;
|
||||
|
||||
mermaid.initialize({
|
||||
theme: 'forest',
|
||||
gantt: { axisFormatter: [
|
||||
['%Y-%m-%d', (d) => {
|
||||
return d.getDay() === 1
|
||||
}]
|
||||
] }
|
||||
})
|
||||
theme: 'default',
|
||||
fontFamily: '"Lucida Console", Monaco, monospace',
|
||||
startOnLoad: false,
|
||||
flowchart: {
|
||||
htmlLabels: true
|
||||
},
|
||||
gantt: {
|
||||
axisFormatter: [
|
||||
[
|
||||
'%Y-%m-%d',
|
||||
d => {
|
||||
return d.getDay() === 1;
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
});
|
||||
mermaid.render(
|
||||
'the-id-of-the-svg',
|
||||
code,
|
||||
svg => {
|
||||
console.log(svg);
|
||||
const elem = document.querySelector('#graph-to-be');
|
||||
elem.innerHTML = svg;
|
||||
}
|
||||
// ,document.querySelector('#tmp')
|
||||
);
|
||||
|
@ -17,63 +17,110 @@
|
||||
.mermaid2 {
|
||||
display: none;
|
||||
}
|
||||
.someClass > * {
|
||||
/* fill: red !important; */
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>info below</h1>
|
||||
<div class="flex">
|
||||
<div class="flex flex-wrap">
|
||||
<div class="mermaid2" style="width: 50%; height: 20%;">
|
||||
flowchart BT
|
||||
subgraph two
|
||||
b1
|
||||
end
|
||||
subgraph three
|
||||
c1-->c2
|
||||
end
|
||||
c1 --apa apa apa--> b1
|
||||
two --> c2
|
||||
</div>
|
||||
<div class="mermaid" style="width: 50%; height: 20%;">
|
||||
sequenceDiagram
|
||||
Alice->>Bob:Extremely utterly long line of longness which had preivously overflown the actor box as it is much longer than what it should be
|
||||
Bob->>Alice: I'm short though
|
||||
</div>
|
||||
<div class="mermaid2" style="width: 50%; height: 20%;">
|
||||
flowchart TB
|
||||
subgraph two
|
||||
b1
|
||||
end
|
||||
subgraph three
|
||||
c1-->c2
|
||||
end
|
||||
c1 --apa apa apa--> b1
|
||||
b1 --> c2
|
||||
%%{init: { 'logLevel': 0, 'theme': 'forest'} }%%
|
||||
pie title Sports in Sweden
|
||||
"Bandy" : 40
|
||||
"Ice-Hockey" : 80
|
||||
"Football" : 90
|
||||
</div>
|
||||
<div class="mermaid2" style="width: 50%; height: 20%;">
|
||||
%%{init: { 'logLevel': 0, 'theme': 'default'} }%%
|
||||
graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me think}
|
||||
B --> G[/Another/]
|
||||
C ==>|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
subgraph section
|
||||
C
|
||||
D
|
||||
E
|
||||
F
|
||||
G
|
||||
end
|
||||
</div>
|
||||
<div class="mermaid2" style="width: 50%; height: 20%;">
|
||||
%%{init: { 'logLevel': 1, 'theme': 'forest'} }%%
|
||||
graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me think}
|
||||
B --> G[/Another/]
|
||||
C ==>|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
subgraph section
|
||||
C
|
||||
D
|
||||
E
|
||||
F
|
||||
G
|
||||
end
|
||||
</div>
|
||||
<div class="mermaid" style="width: 50%; height: 20%;">
|
||||
%%{init: { 'logLevel': 1, 'theme': 'neutral'} }%%
|
||||
|
||||
flowchart BT
|
||||
subgraph a
|
||||
b1 -- ok --> b2
|
||||
end
|
||||
a -- sert --> c
|
||||
c --> d
|
||||
b1 --> d
|
||||
a --asd123 --> d
|
||||
graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me think}
|
||||
B --> G[/Another/]
|
||||
C ==>|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
subgraph section
|
||||
C
|
||||
D
|
||||
E
|
||||
F
|
||||
G
|
||||
end
|
||||
</div>
|
||||
<div class="mermaid2" style="width: 50%; height: 20%;">
|
||||
stateDiagram-v2
|
||||
state A {
|
||||
B1 --> B2: ok
|
||||
}
|
||||
A --> C: sert
|
||||
C --> D
|
||||
B1 --> D
|
||||
A --> D: asd123
|
||||
</div>
|
||||
</div>
|
||||
<div class="mermaid2" style="width: 50%; height: 20%;">
|
||||
<div class="mermaid2" style="background: #3f3f3f; width: 50%; height: 20%;">
|
||||
%%{init: { 'logLevel': 1, 'theme': 'dark'} }%%
|
||||
|
||||
graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me think}
|
||||
B --> G[/Another/]
|
||||
C ==>|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
subgraph section
|
||||
C
|
||||
D
|
||||
E
|
||||
F
|
||||
G
|
||||
end
|
||||
</div>
|
||||
<div class="mermaid2" style="background: #3f3f3f; width: 50%; height: 20%;">
|
||||
%%{init: { 'logLevel': 1} }%%
|
||||
|
||||
graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me think}
|
||||
B --> G[/Another/]
|
||||
C ==>|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
subgraph section
|
||||
C
|
||||
D
|
||||
E
|
||||
F
|
||||
G
|
||||
end
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
@ -81,17 +128,20 @@ stateDiagram-v2
|
||||
// console.error('Mermaid error: ', err);
|
||||
};
|
||||
mermaid.initialize({
|
||||
theme: 'forest',
|
||||
// theme: 'dark',
|
||||
// theme: 'dark',
|
||||
// arrowMarkerAbsolute: true,
|
||||
// themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
|
||||
logLevel: 0,
|
||||
flowchart: { curve: 'linear', "htmlLabels": false },
|
||||
flowchart: { useMaxWidth: true },
|
||||
graph: { curve: 'cardinal', "htmlLabels": false },
|
||||
// gantt: { axisFormat: '%m/%d/%Y' },
|
||||
sequence: { actorMargin: 50, showSequenceNumbers: true },
|
||||
// sequenceDiagram: { actorMargin: 300 } // deprecated
|
||||
fontFamily: '"arial", sans-serif',
|
||||
curve: 'linear',
|
||||
securityLevel: 'loose'
|
||||
curve: 'cardinal',
|
||||
securityLevel: 'strict',
|
||||
});
|
||||
function callback(){alert('It worked');}
|
||||
</script>
|
||||
|
@ -1,12 +1,16 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<!-- <meta charset="iso-8859-15"/> -->
|
||||
<script src="/e2e.js"></script>
|
||||
<link href="https://fonts.googleapis.com/css?family=Mansalva&display=swap" rel="stylesheet" />
|
||||
<link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
|
||||
<!-- <link href="https://fonts.googleapis.com/css?family=Mansalva&display=swap" rel="stylesheet" /> -->
|
||||
<!-- <link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet"> -->
|
||||
<style>
|
||||
body {
|
||||
/* font-family: 'Mansalva', cursive;*/
|
||||
font-family: 'Mansalva', cursive;
|
||||
/* font-family: 'Mansalva', cursive; */
|
||||
/* font-family: '"Noto Sans SC", sans-serif'; */
|
||||
/* font-family: "trebuchet ms", verdana, arial; */
|
||||
}
|
||||
/* .mermaid-main-font {
|
||||
font-family: "trebuchet ms", verdana, arial;
|
||||
@ -34,6 +38,7 @@
|
||||
// fontFamily: '\"trebuchet ms\", verdana, arial;'
|
||||
// fontFamily: '"Comic Sans MS", "Comic Sans", cursive'
|
||||
// fontFamily: '"Mansalva", cursive',
|
||||
// fontFamily: '"Noto Sans SC", sans-serif'
|
||||
fontFamily: '"Noto Sans SC", sans-serif'
|
||||
});
|
||||
</script>
|
||||
|
141
cypress/platform/theme-directives.html
Normal file
141
cypress/platform/theme-directives.html
Normal file
@ -0,0 +1,141 @@
|
||||
<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';
|
||||
}
|
||||
h1 { color: grey;}
|
||||
.mermaid2 {
|
||||
display: none;
|
||||
}
|
||||
.someClass > * {
|
||||
/* fill: red !important; */
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>info below</h1>
|
||||
<div class="flex flex-wrap">
|
||||
<div class="mermaid" style="width: 50%; height: 20%;">
|
||||
%%{init: { 'logLevel': 0, 'theme': 'default'} }%%
|
||||
graph TD
|
||||
A[Default] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me think}
|
||||
B --> G[/Another/]
|
||||
C ==>|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
subgraph section
|
||||
C
|
||||
D
|
||||
E
|
||||
F
|
||||
G
|
||||
end
|
||||
</div>
|
||||
<div class="mermaid" style="width: 50%; height: 20%;">
|
||||
%%{init: { 'logLevel': 1, 'theme': 'forest'} }%%
|
||||
graph TD
|
||||
A[Forest] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me think}
|
||||
B --> G[/Another/]
|
||||
C ==>|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
subgraph section
|
||||
C
|
||||
D
|
||||
E
|
||||
F
|
||||
G
|
||||
end
|
||||
</div>
|
||||
<div class="mermaid" style="width: 50%; height: 20%;">
|
||||
%%{init: { 'logLevel': 1, 'theme': 'neutral'} }%%
|
||||
|
||||
graph TD
|
||||
A[Neutral] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me think}
|
||||
B --> G[/Another/]
|
||||
C ==>|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
subgraph section
|
||||
C
|
||||
D
|
||||
E
|
||||
F
|
||||
G
|
||||
end
|
||||
</div>
|
||||
<div class="mermaid" style="background: #3f3f3f; width: 50%; height: 20%;">
|
||||
%%{init: { 'logLevel': 1, 'theme': 'dark'} }%%
|
||||
|
||||
graph TD
|
||||
A[Dark] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me think}
|
||||
B --> G[/Another/]
|
||||
C ==>|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
subgraph section
|
||||
C
|
||||
D
|
||||
E
|
||||
F
|
||||
G
|
||||
end
|
||||
</div>
|
||||
<div class="mermaid" style="background: #3f3f3f; width: 50%; height: 20%;">
|
||||
%%{init: { 'logLevel': 1} }%%
|
||||
|
||||
graph TD
|
||||
A[None set] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me think}
|
||||
B --> G[/Another/]
|
||||
C ==>|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
subgraph section
|
||||
C
|
||||
D
|
||||
E
|
||||
F
|
||||
G
|
||||
end
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
mermaid.parseError = function (err, hash) {
|
||||
// console.error('Mermaid error: ', err);
|
||||
};
|
||||
mermaid.initialize({
|
||||
// theme: 'dark',
|
||||
// theme: 'dark',
|
||||
// arrowMarkerAbsolute: true,
|
||||
// themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
|
||||
logLevel: 0,
|
||||
flowchart: { useMaxWidth: true },
|
||||
graph: { curve: 'cardinal', "htmlLabels": false },
|
||||
// gantt: { axisFormat: '%m/%d/%Y' },
|
||||
sequence: { actorMargin: 50, showSequenceNumbers: true },
|
||||
// sequenceDiagram: { actorMargin: 300 } // deprecated
|
||||
fontFamily: '"arial", sans-serif',
|
||||
curve: 'cardinal',
|
||||
securityLevel: 'strict',
|
||||
});
|
||||
function callback(){alert('It worked');}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -12,7 +12,9 @@ const contentLoaded = function() {
|
||||
pos = pos + 7;
|
||||
const graphBase64 = document.location.href.substr(pos);
|
||||
const graphObj = JSON.parse(Base64.decode(graphBase64));
|
||||
// const graph = 'hello'
|
||||
if (graphObj.mermaid && graphObj.mermaid.theme === 'dark') {
|
||||
document.body.style.background = '#3f3f3f';
|
||||
}
|
||||
console.log(graphObj);
|
||||
if (Array.isArray(graphObj.code)) {
|
||||
const numCodes = graphObj.code.length;
|
||||
@ -30,6 +32,7 @@ const contentLoaded = function() {
|
||||
div.innerHTML = graphObj.code;
|
||||
document.getElementsByTagName('body')[0].appendChild(div);
|
||||
}
|
||||
|
||||
global.mermaid.initialize(graphObj.mermaid);
|
||||
global.mermaid.init();
|
||||
}
|
||||
|
@ -1,22 +1,17 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<style>
|
||||
/* .mermaid {
|
||||
font-family: "trebuchet ms", verdana, arial;;
|
||||
} */
|
||||
/* .mermaid {
|
||||
font-family: 'arial';
|
||||
} */
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="mermaid">
|
||||
graph LR
|
||||
A-->B
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
gantt
|
||||
title A Gantt Diagram
|
||||
dateFormat YYYY-MM-DD
|
||||
section Section
|
||||
A task :a1, 2014-01-01, 30d
|
||||
Another task :after a1 , 20d
|
||||
section Another
|
||||
Task in sec :2014-01-12 , 12d
|
||||
another task : 24d
|
||||
</div>
|
||||
<div id="graph-to-be"></div>
|
||||
<script src="./bundle-test.js" charset="utf-8"></script>
|
||||
</body>
|
||||
|
||||
|
5172
dist/mermaid.core.js
vendored
5172
dist/mermaid.core.js
vendored
File diff suppressed because one or more lines are too long
2
dist/mermaid.core.js.map
vendored
2
dist/mermaid.core.js.map
vendored
File diff suppressed because one or more lines are too long
9095
dist/mermaid.js
vendored
9095
dist/mermaid.js
vendored
File diff suppressed because one or more lines are too long
2
dist/mermaid.js.map
vendored
2
dist/mermaid.js.map
vendored
File diff suppressed because one or more lines are too long
20
dist/mermaid.min.js
vendored
20
dist/mermaid.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/mermaid.min.js.map
vendored
2
dist/mermaid.min.js.map
vendored
File diff suppressed because one or more lines are too long
196
docs/8.6.0_docs.md
Normal file
196
docs/8.6.0_docs.md
Normal file
@ -0,0 +1,196 @@
|
||||
# Version 8.6.0 Changes
|
||||
|
||||
**Edit this Page** [![N|Solid](./img/GitHub-Mark-32px.png)](https://github.com/mermaid-js/mermaid/blob/develop/docs/8.6.0_docs.md)
|
||||
|
||||
## [New Mermaid Live-Editor Beta](https://mermaid-js.github.io/docs/mermaid-live-editor-beta/#/edit/eyJjb2RlIjoiJSV7aW5pdDoge1widGhlbWVcIjogXCJmb3Jlc3RcIiwgXCJsb2dMZXZlbFwiOiAxIH19JSVcbmdyYXBoIFREXG4gIEFbQ2hyaXN0bWFzXSAtLT58R2V0IG1vbmV5fCBCKEdvIHNob3BwaW5nKVxuICBCIC0tPiBDe0xldCBtZSB0aGlua31cbiAgQyAtLT58T25lfCBEW0xhcHRvcF1cbiAgQyAtLT58VHdvfCBFW2lQaG9uZV1cbiAgQyAtLT58VGhyZWV8IEZbZmE6ZmEtY2FyIENhcl1cblx0XHQiLCJtZXJtYWlkIjp7InRoZW1lIjoiZGFyayJ9fQ)
|
||||
|
||||
## [CDN](https://unpkg.com/mermaid/)
|
||||
|
||||
With version 8.6.0 comes the release of directives for mermaid and a new system for configurations, with the aim of establishing centralized, sane defaults and simple implementation.
|
||||
|
||||
the init directive is the main method of configuration for Site and Current Levels.
|
||||
|
||||
The three levels of are Configuration, Global, Site and Current.
|
||||
|
||||
| Level of Configuration | Description |
|
||||
| --- | --- |
|
||||
| Global Configuration| Default Mermaid Configurations|
|
||||
| Site Configuration| Configurations made by site owner|
|
||||
| Current Configuration| Configurations made by Implementors|
|
||||
|
||||
|
||||
# Limits to Modifying Configurations
|
||||
secure Array
|
||||
|
||||
| Parameter | Description |Type | Required | Values|
|
||||
| --- | --- | --- | --- | --- |
|
||||
| secure | Array of parameters excluded from init directive| Array | Required | Any parameters|
|
||||
|
||||
The modifiable parts of the Configuration are limited by the secure array, which is an array of immutable parameters, this array can be expanded by site owners.
|
||||
|
||||
**Notes**: secure arrays work like nesting dolls, with the Global Configurations’ secure array being the default and immutable list of immutable parameters, or the smallest doll, to which site owners may add to, but implementors may not modify it.
|
||||
|
||||
# Secure Arrays
|
||||
|
||||
Site owners can add to the **secure** array using this command:
|
||||
mermaidAPI.initialize( { startOnLoad: true, secure: ['parameter1', 'parameter2'] } );
|
||||
|
||||
default values for the **secure array** consists of: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize']. These default values are immutable.
|
||||
|
||||
Implementors can only modify configurations using directives, but cannot change the **secure** array.
|
||||
|
||||
# Modifying Configurations and directives:
|
||||
The Two types of directives: are “init” or “initialize” and “wrap”.
|
||||
|
||||
**Notes**: All directives are enclosed in %%{ }%%.
|
||||
|
||||
Older versions of mermaid will not parse directives because %% will comment out the directive.
|
||||
|
||||
# Init
|
||||
init, or initialize: the init or initialize directive gives the user the ability to overwrite and change the values for configuration parameters, with respect to the secure array that is in effect.
|
||||
|
||||
| Parameter | Description |Type | Required | Values|
|
||||
| --- | --- | --- | --- | --- |
|
||||
| init | modifies configurations| Directive| Optional | Any parameters not included in the secure array|
|
||||
|
||||
**Notes:**
|
||||
|
||||
init would be an argument-directive: %%{init: { **insert argument here**}}%%
|
||||
|
||||
The json object that is passed as {**argument** } must be valid, quoted json or it will be ignored.
|
||||
**for example**:
|
||||
|
||||
%%{init: {"theme": default, "logLevel": 1 }}%%
|
||||
|
||||
Configurations that are passed through init cannot change the parameters in secure arrays of higher levels. In the event of a conflict, mermaid will give priority to secure arrays and parse the request, without changing the values of the parameters in conflict.
|
||||
|
||||
When deployed within code, init is called before the graph/diagram description.
|
||||
**for example**:
|
||||
%%{init: {"theme": "default", "logLevel": 1 }}%%
|
||||
graph LR
|
||||
a-->b
|
||||
b-->c
|
||||
c-->d
|
||||
d-->e
|
||||
e-->f
|
||||
f-->g
|
||||
g-->
|
||||
|
||||
# Wrap
|
||||
| Parameter | Description |Type | Required | Values|
|
||||
| --- | --- | --- | --- | --- |
|
||||
| wrap | a callable text-wrap function| Directive| Optional | %%{wrap}%%|
|
||||
|
||||
**Notes:**
|
||||
|
||||
Wrap is a function that is currently only deployable for sequence diagrams.
|
||||
|
||||
wrap respects manually added <br\> so if the user wants to break up their text, they have full control over those breaks by adding their own <br\> tags.
|
||||
|
||||
It is a non-argument directive and can be executed thusly:
|
||||
|
||||
%%{wrap}%%.
|
||||
|
||||
**an example of text wrapping in a sequence diagram**:
|
||||
|
||||
![Image showing wrapped text](./img/wrapped%20text.png)
|
||||
|
||||
|
||||
# Resetting Configurations:
|
||||
There are two more functions in the mermaidAPI that can be called by site owners: **reset** and **globalReset**.
|
||||
|
||||
**reset**: resets the configuration to whatever the last configuration was. This can be done to undo more recent changes to the last mermaidAPI.initialize({...}) configuration.
|
||||
|
||||
**globalReset** will reset both the current configuration AND the site configuration back to the global defaults.
|
||||
|
||||
**Notes**: both reset and globalReset are only available to site owners, as such implementors would have to edit their configs with init.
|
||||
|
||||
# Additional Utils to mermaid
|
||||
• **memoize**: simple caching for computationally expensive functions. It reduces the rendering time for computationally intensive diagrams by about 90%.
|
||||
|
||||
• **assignWithDepth** - this is an improvement on previous functions with config.js and Object.assign. The purpose of this function is to provide a sane mechanism for merging objects, similar to object.assign, but with depth.
|
||||
|
||||
Example of **assignWithDepth**:
|
||||
|
||||
![Image showing assignWithDepth](./img/assignWithDepth.png)
|
||||
|
||||
|
||||
Example of **object.Assign**:
|
||||
|
||||
![Image showing object.assign without depth](./img/object.assign%20without%20depth.png)
|
||||
|
||||
• **calculateTextDimensions, calculateTextWidth,** and **calculateTextHeight** - for measuring text dimensions, width and height.
|
||||
|
||||
**Notes**:For more information on usage, parameters, and return info for these new functions take a look at the jsdocs for them in the utils package.
|
||||
|
||||
|
||||
# New API Requests Introduced in Version 8.6.0
|
||||
|
||||
## setSiteConfig
|
||||
|
||||
| Function | Description | Type | Values |Parameters|Returns|
|
||||
| --------- | ------------------- | ------- | ------------------ | ------------------ | ------------------ |
|
||||
| setSiteConfig|Sets the siteConfig to desired values | Put Request | Any Values, except ones in secure array|conf|siteConfig|
|
||||
|
||||
**Notes:
|
||||
Sets the siteConfig. The siteConfig is a protected configuration for repeat use. Calls to reset() will reset
|
||||
the currentConfig to siteConfig. Calls to reset(configApi.defaultConfig) will reset siteConfig and currentConfig
|
||||
to the defaultConfig
|
||||
Note: currentConfig is set in this function
|
||||
Default value: At default, will mirror Global Config**
|
||||
|
||||
|
||||
## getSiteConfig
|
||||
| Function | Description | Type | Values |
|
||||
| --------- | ------------------- | ------- | ------------------ |
|
||||
| setSiteConfig|Returns the current siteConfig base configuration | Get Request | Returns Any Values in siteConfig|
|
||||
|
||||
**Notes :
|
||||
Returns any values in siteConfig.**
|
||||
|
||||
|
||||
## setConfig
|
||||
| Function | Description | Type | Values |Parameters|Returns|
|
||||
| --------- | ------------------- | ------- | ------------------ |----------|-------|
|
||||
| setSiteConfig|Sets the siteConfig to desired values | Put Request| Any Values, those in secure array|conf|currentConfig merged with the sanitized conf|
|
||||
|
||||
|
||||
**Notes :
|
||||
Sets the currentConfig. The parameter conf is sanitized based on the siteConfig.secure keys. Any
|
||||
values found in conf with key found in siteConfig.secure will be replaced with the corresponding
|
||||
siteConfig value.**
|
||||
|
||||
|
||||
|
||||
## getConfig
|
||||
| Function | Description | Type | Return Values |
|
||||
| --------- | ------------------- | ------- | ------------------ |
|
||||
| getConfig |Obtains the currentConfig | Get Request | Any Values from currentConfig|
|
||||
|
||||
**Notes :
|
||||
Returns any values in currentConfig.**
|
||||
|
||||
|
||||
## sanitize
|
||||
| Function | Description | Type | Values |
|
||||
| --------- | ------------------- | ------- | ------------------ |
|
||||
| sanitize |Sets the siteConfig to desired values. | Put Request(?) |None|
|
||||
|
||||
**Note: modifies options in-place
|
||||
Ensures options parameter does not attempt to override siteConfig secure keys.**
|
||||
|
||||
## reset
|
||||
|
||||
| Function | Description | Type | Required | Values |Parameter|
|
||||
| --------- | -------------------| ------- | -------- | ------------------ |---------|
|
||||
| reset|Resets currentConfig to conf| Put Request | Required | None| conf|
|
||||
|
||||
## conf
|
||||
| Parameter | Description |Type | Required | Values|
|
||||
| --- | --- | --- | --- | --- |
|
||||
| conf| base set of values, which currentConfig coul be reset to.| Dictionary | Required | Any Values, with respect to the secure Array|
|
||||
|
||||
**Notes :
|
||||
default: current siteConfig (optional, default `getSiteConfig()`)**
|
||||
|
||||
## For more information, read [Setup](https://mermaid-js.github.io/mermaid/#/Setup).
|
@ -1,5 +1,7 @@
|
||||
# Change Log
|
||||
|
||||
**Edit this Page** [![N|Solid](./img/GitHub-Mark-32px.png)](https://github.com/mermaid-js/mermaid/blob/develop/docs/CHANGELOG.md)
|
||||
|
||||
## [Unreleased](https://github.com/knsv/mermaid/tree/HEAD)
|
||||
|
||||
[Full Changelog](https://github.com/knsv/mermaid/compare/8.1.0...HEAD)
|
||||
@ -856,4 +858,4 @@
|
||||
## [0.1.0](https://github.com/knsv/mermaid/tree/0.1.0) (2014-11-16)
|
||||
|
||||
|
||||
\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
|
||||
\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
|
||||
|
116
docs/README.md
116
docs/README.md
@ -5,17 +5,41 @@
|
||||
[![Join the chat at https://gitter.im/knsv/mermaid](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/knsv/mermaid?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
![banner](./img/header.png)
|
||||
**Edit this Page** [![N|Solid](./img/GitHub-Mark-32px.png)](https://github.com/mermaid-js/mermaid/blob/develop/docs/README.md)
|
||||
|
||||
Generation of diagrams and flowcharts from text in a similar manner as markdown.
|
||||
|
||||
Ever wanted to simplify documentation and avoid heavy tools like Visio when explaining your code?
|
||||
|
||||
This is why mermaid was born, a simple markdown-like script language for generating charts from text via javascript.
|
||||
|
||||
Check out the list of [Integrations and Usages of Mermaid](./integrations.md)
|
||||
|
||||
**Mermaid was nominated and won the JS Open Source Awards (2019) in the category "The most exciting use of technology"!!! Thanks to all involved, people committing pull requests, people answering questions and special thanks to Tyler Long who is helping me maintain the project.**
|
||||
|
||||
|
||||
|
||||
Mermaid is a tool that generates diagrams and charts, from markdown-inspired text definitions
|
||||
|
||||
This allows for simplified generation and updating of even the most complex diagrams and charts, while avoiding time-damanding and heavy tools like visio.
|
||||
|
||||
mermaid, is a simple markdown-inspired script language for generating charts from text-definitions, via javascript. As such, using it cuts the times it takes to create, modify and render diagrams.
|
||||
|
||||
Even non-programmers can create diagrams through the [mermaid live editor](https://github.com/mermaidjs/mermaid-live-editor).
|
||||
|
||||
For a more detailed introduction to mermaid, look to the [Beginner's Guide](https://mermaid-js.github.io/mermaid/#/n00b-overview) section.
|
||||
|
||||
You should also Check out the list of [Integrations and Usages of Mermaid](./integrations.md)
|
||||
|
||||
You can also watch some popular mermaid tutorials on the [mermaid Overview](./n00b-overview.md)
|
||||
|
||||
## [CDN](https://unpkg.com/mermaid/)
|
||||
|
||||
## [Documentation](https://mermaidjs.github.io)
|
||||
|
||||
## [Contribution](https://github.com/mermaid-js/mermaid/blob/develop/CONTRIBUTING.md)
|
||||
|
||||
|
||||
# New in Version 8.6.0
|
||||
|
||||
## [New Mermaid Live-Editor Beta](https://mermaid-js.github.io/docs/mermaid-live-editor-beta/#/edit/eyJjb2RlIjoiJSV7aW5pdDoge1widGhlbWVcIjogXCJmb3Jlc3RcIiwgXCJsb2dMZXZlbFwiOiAxIH19JSVcbmdyYXBoIFREXG4gIEFbQ2hyaXN0bWFzXSAtLT58R2V0IG1vbmV5fCBCKEdvIHNob3BwaW5nKVxuICBCIC0tPiBDe0xldCBtZSB0aGlua31cbiAgQyAtLT58T25lfCBEW0xhcHRvcF1cbiAgQyAtLT58VHdvfCBFW2lQaG9uZV1cbiAgQyAtLT58VGhyZWV8IEZbZmE6ZmEtY2FyIENhcl1cblx0XHQiLCJtZXJtYWlkIjp7InRoZW1lIjoiZGFyayJ9fQ)
|
||||
|
||||
## [New Configuration Protocols in version 8.6.0](https://github.com/NeilCuzon/mermaid/edit/develop/docs/8.6.0_docs.md)
|
||||
|
||||
|
||||
## New diagrams in 8.5
|
||||
|
||||
With version 8.5 there are some bug fixes and enhancements, plus a new diagram type, entity relationship diagrams.
|
||||
@ -24,10 +48,19 @@ With version 8.5 there are some bug fixes and enhancements, plus a new diagram t
|
||||
|
||||
## Special note regarding version 8.2
|
||||
|
||||
In version 8.2 a security improvement was introduced. A securityLevel configuration was introduced which sets the level of trust to be used on the parsed diagrams.
|
||||
In version 8.2 a security improvement was introduced. A **securityLevel** configuration was introduced which sets the level of trust to be used on the parsed diagrams.
|
||||
|
||||
## securityLevel
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ------------- | --------------------------------- | ------ | -------- | ------------- |
|
||||
| securitylevel | Level of trust for parsed diagram | String | Required | Strict, Loose |
|
||||
|
||||
\*\*Notes:
|
||||
|
||||
- **strict**: (**default**) tags in text are encoded, click functionality is disabeled
|
||||
- **loose**: tags in text are allowed, click functionality is enabled
|
||||
|
||||
- **true**: (default) tags in text are encoded, click functionality is disabled
|
||||
- false: tags in text are allowed, click functionality is enabled
|
||||
|
||||
Closed issues:
|
||||
|
||||
@ -43,9 +76,9 @@ mermaidAPI.initialize({
|
||||
|
||||
**🖖 Keep a steady pulse: mermaid needs more Collaborators [#866](https://github.com/knsv/mermaid/issues/866)**
|
||||
|
||||
## Diagrams
|
||||
# Diagrams that mermaid can render:
|
||||
|
||||
### Flowchart
|
||||
### [Flowchart](https://mermaid-js.github.io/mermaid/#/flowchart)
|
||||
|
||||
```
|
||||
graph TD;
|
||||
@ -57,7 +90,7 @@ graph TD;
|
||||
|
||||
![Flowchart](./img/flow.png)
|
||||
|
||||
### Sequence diagram
|
||||
### [Sequence diagram](https://mermaid-js.github.io/mermaid/#/sequenceDiagram)
|
||||
|
||||
```
|
||||
sequenceDiagram
|
||||
@ -75,7 +108,7 @@ sequenceDiagram
|
||||
|
||||
![Sequence diagram](./img/sequence.png)
|
||||
|
||||
### Gantt diagram
|
||||
### [Gantt diagram](https://mermaid-js.github.io/mermaid/#/gantt)
|
||||
|
||||
```
|
||||
gantt
|
||||
@ -92,7 +125,7 @@ Future task2 : des4, after des3, 5d
|
||||
|
||||
![Gantt diagram](./img/gantt.png)
|
||||
|
||||
### Class diagram - :exclamation: experimental
|
||||
### [Class diagram - :exclamation: experimental](https://mermaid-js.github.io/mermaid/#/classDiagram)
|
||||
|
||||
```
|
||||
classDiagram
|
||||
@ -134,10 +167,9 @@ commit
|
||||
merge newbranch
|
||||
|
||||
```
|
||||
|
||||
![Git graph](./img/git.png)
|
||||
|
||||
### Entity Relationship Diagram - :exclamation: experimental
|
||||
### [Entity Relationship Diagram - :exclamation: experimental](https://mermaid-js.github.io/mermaid/#/entityRelationshipDiagram)
|
||||
|
||||
```
|
||||
erDiagram
|
||||
@ -149,6 +181,21 @@ erDiagram
|
||||
|
||||
![ER diagram](./img/simple-er.png)
|
||||
|
||||
### [User Journey Diagram](https://mermaid-js.github.io/mermaid/#/user-journey)
|
||||
|
||||
```markdown
|
||||
journey
|
||||
title My working day
|
||||
section Go to work
|
||||
Make tea: 5: Me
|
||||
Go upstairs: 3: Me
|
||||
Do work: 1: Me, Cat
|
||||
section Go home
|
||||
Go downstairs: 5: Me
|
||||
Sit down: 5: Me
|
||||
```
|
||||
![Journey diagram](./img/user-journey.png)
|
||||
|
||||
## Installation
|
||||
|
||||
### CDN
|
||||
@ -157,24 +204,43 @@ erDiagram
|
||||
https://unpkg.com/mermaid@<version>/dist/
|
||||
```
|
||||
|
||||
Replace `<version>` with expected version number.
|
||||
To select a version:
|
||||
|
||||
Example: https://unpkg.com/mermaid@7.1.0/dist/
|
||||
Replace `<version>` with the desired version number.
|
||||
|
||||
### Node.js
|
||||
Alternatively, you can also adjust the version number in the page itself.
|
||||
|
||||
Latest Version: https://unpkg.com/browse/mermaid@8.6.0/
|
||||
|
||||
## Incorporating mermaid to a website
|
||||
to support mermaid on your website, all you have to do is add Mermaid’s JavaScript package
|
||||
|
||||
```
|
||||
yarn add mermaid
|
||||
1.You will need to isntall node v10 or 12, which would have npm
|
||||
|
||||
2. download yarn using npm.
|
||||
|
||||
2. enter the following command:
|
||||
yarn add mermaid
|
||||
|
||||
3. You can then add mermaid as a dev dependency using this command:
|
||||
yarn add --dev mermaid
|
||||
|
||||
```
|
||||
|
||||
## Documentation
|
||||
## To install mermaid without a bundler, one can use the script tag like so:
|
||||
|
||||
https://mermaidjs.github.io
|
||||
<script src="https://unpkg.com/mermaid/"></script>
|
||||
<script>mermaid.initialize({startOnLoad:true});</script>
|
||||
|
||||
## it can then be followed by the diagram definitions as could be found in the [examples in the documentation](https://mermaid-js.github.io/mermaid/#/n00b-gettingStarted).
|
||||
|
||||
|
||||
## On your page mermaid will look for tags with class="mermaid". From these tags mermaid will try to read the chart definiton and replace it with an svg chart.
|
||||
|
||||
## Sibling projects
|
||||
|
||||
- [mermaid CLI](https://github.com/mermaidjs/mermaid.cli)
|
||||
- [mermaid live editor](https://github.com/mermaidjs/mermaid-live-editor)
|
||||
- [mermaid CLI](https://github.com/mermaidjs/mermaid.cli)
|
||||
- [mermaid webpack demo](https://github.com/mermaidjs/mermaid-webpack-demo)
|
||||
- [mermaid Parcel demo](https://github.com/mermaidjs/mermaid-parcel-demo)
|
||||
|
||||
|
934
docs/Setup.md
Normal file
934
docs/Setup.md
Normal file
@ -0,0 +1,934 @@
|
||||
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
|
||||
|
||||
## mermaidAPI
|
||||
|
||||
This is the api to be used when optionally handling the integration with the web page, instead of using the default integration provided by mermaid.js.
|
||||
|
||||
The core of this api is the [**render**][1] function which, given a graph
|
||||
definition as text, renders the graph/diagram and returns an svg element for the graph.
|
||||
|
||||
It is is then up to the user of the API to make use of the svg, either insert it somewhere in the page or do something completely different.
|
||||
|
||||
In addition to the render function, a number of behavioral configuration options are available.
|
||||
|
||||
## Configuration
|
||||
|
||||
**Configuration methods in Mermaid version 8.6.0 have been updated, to learn more\[[click here][2]].**
|
||||
|
||||
## **What follows are config instructions for older versions**
|
||||
|
||||
These are the default options which can be overridden with the initialization call like so:
|
||||
**Example 1:**
|
||||
|
||||
<pre>
|
||||
mermaid.initialize({
|
||||
flowchart:{
|
||||
htmlLabels: false
|
||||
}
|
||||
});
|
||||
</pre>
|
||||
|
||||
**Example 2:**
|
||||
|
||||
<pre>
|
||||
<script>
|
||||
var config = {
|
||||
startOnLoad:true,
|
||||
flowchart:{
|
||||
useMaxWidth:true,
|
||||
htmlLabels:true,
|
||||
curve:'cardinal',
|
||||
},
|
||||
|
||||
securityLevel:'loose',
|
||||
};
|
||||
mermaid.initialize(config);
|
||||
</script>
|
||||
</pre>
|
||||
|
||||
A summary of all options and their defaults is found [here][3]. A description of each option follows below.
|
||||
|
||||
## theme
|
||||
|
||||
theme , the CSS style sheet
|
||||
|
||||
theme , the CSS style sheet
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| --------- | --------------- | ------ | -------- | ---------------------------------------------------- |
|
||||
| Theme | Built in Themes | String | Optional | Values include, default, forest, dark, neutral, null |
|
||||
|
||||
**Notes:**To disable any pre-defined mermaid theme, use "null".
|
||||
|
||||
<pre>
|
||||
"theme": "forest",
|
||||
"themeCSS": ".node rect { fill: red; }"
|
||||
</pre>
|
||||
|
||||
## fontFamily
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ---------- | ------------------------------------------------------ | ------ | -------- | ----------------------------- |
|
||||
| fontFamily | specifies the font to be used in the rendered diagrams | String | Required | Verdana, Arial, Trebuchet MS, |
|
||||
|
||||
\*\*notes: Default value is \\"trebuchet ms\\".
|
||||
|
||||
## logLevel
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| --------- | ----------------------------------------------------- | ------ | -------- | ------------- |
|
||||
| logLevel | This option decides the amount of logging to be used. | String | Required | 1, 2, 3, 4, 5 |
|
||||
|
||||
**Notes:**
|
||||
|
||||
- debug: 1.
|
||||
- info: 2.
|
||||
- warn: 3.
|
||||
- error: 4.
|
||||
- fatal: 5(default).
|
||||
|
||||
## securityLevel
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ------------- | --------------------------------- | ------ | -------- | ------------------------- |
|
||||
| securitylevel | Level of trust for parsed diagram | String | Required | Strict, Loose, antiscript |
|
||||
|
||||
\*\*Notes:
|
||||
|
||||
- **strict**: (**default**) tags in text are encoded, click functionality is disabeled
|
||||
- **loose**: tags in text are allowed, click functionality is enabled
|
||||
- **antiscript**: html tags in text are allowed, (only script element is removed), click functionality is enabled
|
||||
|
||||
## startOnLoad
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ----------- | --------------------------------------------- | ------- | -------- | ----------- |
|
||||
| startOnLoad | Dictates whether mermaind starts on Page load | Boolean | Required | True, False |
|
||||
|
||||
**Notes:**
|
||||
**Default value: true**
|
||||
|
||||
## arrowMarkerAbsolute
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ------------------- | ---------------------------------------------------------------------------- | ------- | -------- | ----------- |
|
||||
| arrowMarkerAbsolute | Controls whether or arrow markers in html code are absolute paths or anchors | Boolean | Required | True, False |
|
||||
|
||||
## Notes\*\*: This matters if you are using base tag settings.
|
||||
|
||||
**Default value: false**.
|
||||
|
||||
## secure
|
||||
|
||||
This option controls which currentConfig keys are considered _secure_ and can only be changed via
|
||||
call to mermaidAPI.initialize. Calls to mermaidAPI.reinitialize cannot make changes to
|
||||
the `secure` keys in the current currentConfig. This prevents malicious graph directives from
|
||||
overriding a site's default security.
|
||||
|
||||
## flowchart
|
||||
|
||||
The object containing configurations specific for flowcharts
|
||||
|
||||
### diagramPadding
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| -------------- | ----------------------------------------------- | ------- | -------- | ------------------ |
|
||||
| diagramPadding | amount of padding around the diagram as a whole | Integer | Required | Any Positive Value |
|
||||
|
||||
**Notes:**The amount of padding around the diagram as a whole so that embedded diagrams have margins, expressed in pixels
|
||||
**Default value: 8**.
|
||||
|
||||
### htmlLabels
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ---------- | -------------------------------------------------------------------------------------------- | ------- | -------- | ----------- |
|
||||
| htmlLabels | Flag for setting whether or not a html tag should be used for rendering labels on the edges. | Boolean | Required | True, False |
|
||||
|
||||
**Notes: Default value: true**.
|
||||
|
||||
### nodeSpacing
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ----------- | --------------------------------------------------- | ------- | -------- | -------------------- |
|
||||
| nodeSpacing | Defines the spacing between nodes on the same level | Integer | Required | Any positive Numbers |
|
||||
|
||||
**Notes:
|
||||
Pertains to horizontal spacing for TB (top to bottom) or BT (bottom to top) graphs, and the vertical spacing for LR as well as RL graphs.**
|
||||
**Default value 50**.
|
||||
|
||||
### rankSpacing
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ----------- | ----------------------------------------------------- | ------- | -------- | -------------------- |
|
||||
| rankSpacing | Defines the spacing between nodes on different levels | Integer | Required | Any Positive Numbers |
|
||||
|
||||
**Notes: pertains to vertical spacing for TB (top to bottom) or BT (bottom to top), and the horizontal spacing for LR as well as RL graphs.
|
||||
**Default value 50\*\*.
|
||||
|
||||
### curve
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| --------- | -------------------------------------------------- | ------ | -------- | ----------------------- |
|
||||
| curve | Defines how mermaid renders curves for flowcharts. | String | Required | Basis, Linear, Cardinal |
|
||||
|
||||
**Notes:
|
||||
Default Vaue: Linear**
|
||||
|
||||
## sequence
|
||||
|
||||
The object containing configurations specific for sequence diagrams
|
||||
|
||||
### activationWidth
|
||||
|
||||
widt of the activation rect
|
||||
**Default value 10**.
|
||||
|
||||
### diagramMarginX
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| -------------- | ---------------------------------------------------- | ------- | -------- | ------------------- |
|
||||
| diagramMarginX | margin to the right and left of the sequence diagram | Integer | Required | Any Positive Values |
|
||||
|
||||
**Notes:**
|
||||
**Default value 50**.
|
||||
|
||||
### diagramMarginY
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| -------------- | ------------------------------------------------- | ------- | -------- | ------------------- |
|
||||
| diagramMarginY | Margin to the over and under the sequence diagram | Integer | Required | Any Positive Values |
|
||||
|
||||
**Notes:**
|
||||
**Default value 10**.
|
||||
|
||||
### actorMargin
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ----------- | ---------------------- | ------- | -------- | ------------------ |
|
||||
| actorMargin | Margin between actors. | Integer | Required | Any Positive Value |
|
||||
|
||||
**Notes:**
|
||||
**Default value 50**.
|
||||
|
||||
### width
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| --------- | -------------------- | ------- | -------- | ------------------ |
|
||||
| width | Width of actor boxes | Integer | Required | Any Positive Value |
|
||||
|
||||
**Notes:**
|
||||
**Default value 150**.
|
||||
|
||||
### height
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| --------- | --------------------- | ------- | -------- | ------------------ |
|
||||
| height | Height of actor boxes | Integer | Required | Any Positive Value |
|
||||
|
||||
**Notes:**
|
||||
**Default value 65**..
|
||||
|
||||
### boxMargin
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| --------- | ------------------------ | ------- | -------- | ------------------ |
|
||||
| boxMargin | Margin around loop boxes | Integer | Required | Any Positive Value |
|
||||
|
||||
**Notes:**
|
||||
|
||||
**Default value 10**.
|
||||
|
||||
### boxTextMargin
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ------------- | -------------------------------------------- | ------- | -------- | ------------------ |
|
||||
| boxTextMargin | margin around the text in loop/alt/opt boxes | Integer | Required | Any Positive Value |
|
||||
|
||||
**Notes:**
|
||||
|
||||
**Default value 5**.
|
||||
|
||||
### noteMargin
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ---------- | -------------------- | ------- | -------- | ------------------ |
|
||||
| noteMargin | margin around notes. | Integer | Required | Any Positive Value |
|
||||
|
||||
**Notes:**
|
||||
|
||||
**Default value 10**.
|
||||
|
||||
### messageMargin
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ------------- | ----------------------- | ------- | -------- | ------------------ |
|
||||
| messageMargin | Space between messages. | Integer | Required | Any Positive Value |
|
||||
|
||||
**Notes:**
|
||||
|
||||
Space between messages.
|
||||
**Default value 35**.
|
||||
|
||||
### messageAlign
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ------------ | --------------------------- | ------- | -------- | ------------------- |
|
||||
| messageAlign | Multiline message alignment | Integer | Required | left, center, right |
|
||||
|
||||
**Notes:**center **default**
|
||||
|
||||
### mirrorActors
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ------------ | ---------------------------- | ------- | -------- | ----------- |
|
||||
| mirrorActors | mirror actors under diagram. | Boolean | Required | True, False |
|
||||
|
||||
**Notes:**
|
||||
|
||||
**Default value true**.
|
||||
|
||||
### bottomMarginAdj
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| --------------- | ------------------------------------------- | ------- | -------- | ------------------ |
|
||||
| bottomMarginAdj | Prolongs the edge of the diagram downwards. | Integer | Required | Any Positive Value |
|
||||
|
||||
**Notes:**Depending on css styling this might need adjustment.
|
||||
**Default value 1**.
|
||||
|
||||
### useMaxWidth
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ----------- | ----------- | ------- | -------- | ----------- |
|
||||
| useMaxWidth | See Notes | Boolean | Required | True, False |
|
||||
|
||||
**Notes:**
|
||||
when this flag is set to true, the height and width is set to 100% and is then scaling with the
|
||||
available space. If set to false, the absolute space required is used.
|
||||
**Default value: True**.
|
||||
|
||||
### rightAngles
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ----------- | ------------------------------------ | ------- | -------- | ----------- |
|
||||
| rightAngles | display curve arrows as right angles | Boolean | Required | True, False |
|
||||
|
||||
**Notes:**
|
||||
|
||||
This will display arrows that start and begin at the same node as right angles, rather than a curve
|
||||
**Default value false**.
|
||||
|
||||
### showSequenceNumbers
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ------------------- | ------------------------------- | ------- | -------- | ----------- |
|
||||
| showSequenceNumbers | This will show the node numbers | Boolean | Required | True, False |
|
||||
|
||||
**Notes:**
|
||||
**Default value false**.
|
||||
|
||||
### actorFontSize
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ------------- | -------------------------------------------------- | ------- | -------- | ------------------ |
|
||||
| actorFontSize | This sets the font size of the actor's description | Integer | Require | Any Positive Value |
|
||||
|
||||
**Notes:**
|
||||
**Default value 14**..
|
||||
|
||||
### actorFontFamily
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| --------------- | ---------------------------------------------------- | ---- | -------- | --------------------- |
|
||||
| actorFontFamily | This sets the font family of the actor's description | 3 | 4 | Open-Sans, Sans-Serif |
|
||||
|
||||
**Notes:**
|
||||
**Default value "Open-Sans", "sans-serif"**.
|
||||
|
||||
### actorFontWeight
|
||||
|
||||
This sets the font weight of the actor's description
|
||||
\*\*Default value 400.
|
||||
|
||||
### noteFontSize
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ------------ | ------------------------------------------------ | ------- | -------- | ------------------ |
|
||||
| noteFontSize | This sets the font size of actor-attached notes. | Integer | Required | Any Positive Value |
|
||||
|
||||
**Notes:**
|
||||
**Default value 14**..
|
||||
|
||||
### noteFontFamily
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| -------------- | -------------------------------------------------- | ------ | -------- | ---------------------------- |
|
||||
| noteFontFamily | This sets the font family of actor-attached notes. | String | Required | trebuchet ms, verdana, arial |
|
||||
|
||||
**Notes:**
|
||||
**Default value: trebuchet ms **.
|
||||
|
||||
### noteFontWeight
|
||||
|
||||
This sets the font weight of the note's description
|
||||
\*\*Default value 400.
|
||||
|
||||
### noteAlign
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| --------- | ----------------------------------------------------- | ------ | -------- | ------------------- |
|
||||
| noteAlign | This sets the text alignment of actor-attached notes. | string | required | left, center, right |
|
||||
|
||||
**Notes:**
|
||||
**Default value center**.
|
||||
|
||||
### messageFontSize
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| --------------- | ------------------------------------------ | ------- | -------- | ------------------- |
|
||||
| messageFontSize | This sets the font size of actor messages. | Integer | Required | Any Positive Number |
|
||||
|
||||
**Notes:**
|
||||
**Default value 16**.
|
||||
|
||||
### messageFontFamily
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ----------------- | -------------------------------------------- | ------ | -------- | ---------------------------- |
|
||||
| messageFontFamily | This sets the font family of actor messages. | String | Required | trebuchet ms", verdana, aria |
|
||||
|
||||
**Notes:**
|
||||
**Default value:"trebuchet ms**.
|
||||
|
||||
### messageFontWeight
|
||||
|
||||
This sets the font weight of the message's description
|
||||
\*\*Default value 400.
|
||||
|
||||
### wrap
|
||||
|
||||
This sets the auto-wrap state for the diagram
|
||||
\*\*Default value false.
|
||||
|
||||
### wrapPadding
|
||||
|
||||
This sets the auto-wrap padding for the diagram (sides only)
|
||||
\*\*Default value 10.
|
||||
|
||||
### labelBoxWidth
|
||||
|
||||
This sets the width of the loop-box (loop, alt, opt, par)
|
||||
\*\*Default value 50.
|
||||
|
||||
### labelBoxHeight
|
||||
|
||||
This sets the height of the loop-box (loop, alt, opt, par)
|
||||
\*\*Default value 20.
|
||||
|
||||
## gantt
|
||||
|
||||
The object containing configurations specific for gantt diagrams\*
|
||||
|
||||
### titleTopMargin
|
||||
|
||||
### titleTopMargin
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| -------------- | ---------------------------------------------- | ------- | -------- | ------------------ |
|
||||
| titleTopMargin | Margin top for the text over the gantt diagram | Integer | Required | Any Positive Value |
|
||||
|
||||
**Notes:**
|
||||
**Default value 25**.
|
||||
|
||||
### barHeight
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| --------- | ----------------------------------- | ------- | -------- | ------------------ |
|
||||
| barHeight | The height of the bars in the graph | Integer | Required | Any Positive Value |
|
||||
|
||||
**Notes:**
|
||||
**Default value 20**.
|
||||
|
||||
### barGap
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| --------- | ----------------------------------------------------------------- | ------- | -------- | ------------------ |
|
||||
| barGap | The margin between the different activities in the gantt diagram. | Integer | Optional | Any Positive Value |
|
||||
|
||||
**Notes:**
|
||||
**Default value 4**.
|
||||
|
||||
### topPadding
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ---------- | -------------------------------------------------------------------------- | ------- | -------- | ------------------ |
|
||||
| topPadding | Margin between title and gantt diagram and between axis and gantt diagram. | Integer | Required | Any Positive Value |
|
||||
|
||||
**Notes:**
|
||||
**Default value 50**.
|
||||
|
||||
### leftPadding
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ----------- | ----------------------------------------------------------------------- | ------- | -------- | ------------------ |
|
||||
| leftPadding | The space allocated for the section name to the left of the activities. | Integer | Required | Any Positive Value |
|
||||
|
||||
**Notes:**
|
||||
**Default value 75**.
|
||||
|
||||
### gridLineStartPadding
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| -------------------- | --------------------------------------------- | ------- | -------- | ------------------ |
|
||||
| gridLineStartPadding | Vertical starting position of the grid lines. | Integer | Required | Any Positive Value |
|
||||
|
||||
**Notes:**
|
||||
**Default value 35**.
|
||||
|
||||
### fontSize
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| --------- | ----------- | ------- | -------- | ------------------ |
|
||||
| fontSize | Font size | Integer | Required | Any Positive Value |
|
||||
|
||||
**Notes:**
|
||||
**Default value 11**.
|
||||
|
||||
### fontFamily
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ---------- | ----------- | ------ | -------- | ------------------------- |
|
||||
| fontFamily | font Family | string | required | "Open-Sans", "sans-serif" |
|
||||
|
||||
**Notes:**
|
||||
|
||||
**Default value '"Open-Sans", "sans-serif"'**.
|
||||
|
||||
### numberSectionStyles
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ------------------- | ---------------------------------------- | ------- | -------- | ------------------ |
|
||||
| numberSectionStyles | The number of alternating section styles | Integer | 4 | Any Positive Value |
|
||||
|
||||
**Notes:**
|
||||
**Default value 4**.
|
||||
|
||||
### axisFormat
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ---------- | ---------------------------- | ---- | -------- | ---------------- |
|
||||
| axisFormat | Datetime format of the axis. | 3 | Required | Date in yy-mm-dd |
|
||||
|
||||
**Notes:**
|
||||
|
||||
This might need adjustment to match your locale and preferences
|
||||
**Default value '%Y-%m-%d'**.
|
||||
|
||||
## journey
|
||||
|
||||
The object containing configurations specific for sequence diagrams
|
||||
|
||||
### diagramMarginX
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| -------------- | ---------------------------------------------------- | ------- | -------- | ------------------ |
|
||||
| diagramMarginX | margin to the right and left of the sequence diagram | Integer | Required | Any Positive Value |
|
||||
|
||||
**Notes:**
|
||||
**Default value 50**.
|
||||
|
||||
### diagramMarginY
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| -------------- | -------------------------------------------------- | ------- | -------- | ------------------ |
|
||||
| diagramMarginY | margin to the over and under the sequence diagram. | Integer | Required | Any Positive Value |
|
||||
|
||||
**Notes:**
|
||||
**Default value 10**..
|
||||
|
||||
### actorMargin
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ----------- | ---------------------- | ------- | -------- | ------------------ |
|
||||
| actorMargin | Margin between actors. | Integer | Required | Any Positive Value |
|
||||
|
||||
**Notes:**
|
||||
**Default value 50**.
|
||||
|
||||
### width
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| --------- | -------------------- | ------- | -------- | ------------------ |
|
||||
| width | Width of actor boxes | Integer | Required | Any Positive Value |
|
||||
|
||||
**Notes:**
|
||||
**Default value 150**.
|
||||
|
||||
### height
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| --------- | --------------------- | ------- | -------- | ------------------ |
|
||||
| height | Height of actor boxes | Integer | Required | Any Positive Value |
|
||||
|
||||
**Notes:**
|
||||
**Default value 65**.
|
||||
|
||||
### boxMargin
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| --------- | ------------------------ | ------- | -------- | ------------------ |
|
||||
| boxMargin | Margin around loop boxes | Integer | Required | Any Positive Value |
|
||||
|
||||
**Notes:**
|
||||
**Default value 10**.
|
||||
|
||||
### boxTextMargin
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ------------- | -------------------------------------------- | ------- | -------- | ------------------ |
|
||||
| boxTextMargin | margin around the text in loop/alt/opt boxes | Integer | Required | Any Positive Value |
|
||||
|
||||
**Notes:**
|
||||
|
||||
### noteMargin
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ---------- | -------------------- | ------- | -------- | ------------------ |
|
||||
| noteMargin | margin around notes. | Integer | Required | Any Positive Value |
|
||||
|
||||
**Notes:**
|
||||
**Default value 10**.
|
||||
|
||||
### messageMargin
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ------------- | ----------------------- | ------- | -------- | ------------------ |
|
||||
| messageMargin | Space between messages. | Integer | Required | Any Positive Value |
|
||||
|
||||
**Notes:**
|
||||
|
||||
Space between messages.
|
||||
**Default value 35**.
|
||||
|
||||
### messageAlign
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ------------ | --------------------------- | ---- | -------- | ------------------- |
|
||||
| messageAlign | Multiline message alignment | 3 | 4 | left, center, right |
|
||||
|
||||
**Notes:**default:center\*\*
|
||||
|
||||
### bottomMarginAdj
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| --------------- | ------------------------------------------- | ------- | -------- | ------------------ |
|
||||
| bottomMarginAdj | Prolongs the edge of the diagram downwards. | Integer | 4 | Any Positive Value |
|
||||
|
||||
**Notes:**Depending on css styling this might need adjustment.
|
||||
**Default value 1**.
|
||||
|
||||
### useMaxWidth
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ----------- | ----------- | ------- | -------- | ----------- |
|
||||
| useMaxWidth | See notes | Boolean | 4 | True, False |
|
||||
|
||||
**Notes:**when this flag is set the height and width is set to 100% and is then scaling with the
|
||||
available space if not the absolute space required is used.
|
||||
|
||||
**Default value true**.
|
||||
|
||||
### rightAngles
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ----------- | ---------------------------------- | ---- | -------- | ----------- |
|
||||
| rightAngles | Curved Arrows become Right Angles, | 3 | 4 | True, False |
|
||||
|
||||
**Notes:**This will display arrows that start and begin at the same node as right angles, rather than a curves
|
||||
**Default value false**.
|
||||
|
||||
## er
|
||||
|
||||
The object containing configurations specific for entity relationship diagrams
|
||||
|
||||
### diagramPadding
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| -------------- | ----------------------------------------------- | ------- | -------- | ------------------ |
|
||||
| diagramPadding | amount of padding around the diagram as a whole | Integer | Required | Any Positive Value |
|
||||
|
||||
**Notes:**The amount of padding around the diagram as a whole so that embedded diagrams have margins, expressed in pixels
|
||||
**Default value: 20**.
|
||||
|
||||
### layoutDirection
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| --------------- | ---------------------------------------- | ------ | -------- | -------------------- |
|
||||
| layoutDirection | Directional bias for layout of entities. | String | Required | "TB", "BT","LR","RL" |
|
||||
|
||||
**Notes:**
|
||||
'TB' for Top-Bottom, 'BT'for Bottom-Top, 'LR' for Left-Right, or 'RL' for Right to Left.
|
||||
T = top, B = bottom, L = left, and R = right.
|
||||
**Default value: TB **.
|
||||
|
||||
### minEntityWidth
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| -------------- | ----------------------------------- | ------- | -------- | ------------------ |
|
||||
| minEntityWidth | The mimimum width of an entity box, | Integer | Required | Any Positive Value |
|
||||
|
||||
**Notes:**expressed in pixels
|
||||
**Default value: 100**.
|
||||
|
||||
### minEntityHeight
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| --------------- | ------------------------------------ | ------- | -------- | ------------------ |
|
||||
| minEntityHeight | The minimum height of an entity box, | Integer | 4 | Any Positive Value |
|
||||
|
||||
**Notes:**expressed in pixels
|
||||
**Default value: 75 **
|
||||
|
||||
### entityPadding
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ------------- | ------------------------------------------------------------ | ------- | -------- | ------------------ |
|
||||
| entityPadding | minimum internal padding betweentext in box and box borders | Integer | 4 | Any Positive Value |
|
||||
|
||||
**Notes:**The minimum internal padding betweentext in an entity box and the enclosing box borders, expressed in pixels.
|
||||
**Default value: 15 **
|
||||
|
||||
### stroke
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| --------- | ----------------------------------- | ------ | -------- | -------------------- |
|
||||
| stroke | Stroke color of box edges and lines | String | 4 | Any recognized color |
|
||||
|
||||
**Default value: gray **
|
||||
|
||||
### fill
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| --------- | -------------------------- | ------ | -------- | -------------------- |
|
||||
| fill | Fill color of entity boxes | String | 4 | Any recognized color |
|
||||
|
||||
**Notes:**
|
||||
**Default value:'honeydew'**
|
||||
|
||||
### fontSize
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| --------- | ------------------- | ------- | -------- | ------------------ |
|
||||
| fontSize | Font Size in pixels | Integer | | Any Positive Value |
|
||||
|
||||
**Notes:**Font size (expressed as an integer representing a number of pixels)
|
||||
**Default value: 12 **
|
||||
|
||||
### useMaxWidth
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| ----------- | ----------- | ------- | -------- | ----------- |
|
||||
| useMaxWidth | See Notes | Boolean | Required | true, false |
|
||||
|
||||
**Notes:**
|
||||
When this flag is set to true, the diagram width is locked to 100% and
|
||||
scaled based on available space. If set to false, the diagram reserves its
|
||||
absolute width.
|
||||
**Default value: true**.
|
||||
|
||||
## render
|
||||
|
||||
Function that renders an svg with a graph from a chart definition. Usage example below.
|
||||
|
||||
```js
|
||||
mermaidAPI.initialize({
|
||||
startOnLoad:true
|
||||
});
|
||||
$(function(){
|
||||
const graphDefinition = 'graph TB\na-->b';
|
||||
const cb = function(svgGraph){
|
||||
console.log(svgGraph);
|
||||
};
|
||||
mermaidAPI.render('id1',graphDefinition,cb);
|
||||
});
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
- `id` the id of the element to be rendered
|
||||
- `_txt` the graph definition
|
||||
- `cb` callback which is called after rendering is finished with the svg code as inparam.
|
||||
- `container` selector to element in which a div with the graph temporarily will be inserted. In one is
|
||||
provided a hidden div will be inserted in the body of the page instead. The element will be removed when rendering is
|
||||
completed.
|
||||
|
||||
##
|
||||
|
||||
## mermaidAPI configuration defaults
|
||||
|
||||
<pre>
|
||||
|
||||
<script>
|
||||
var config = {
|
||||
theme:'default',
|
||||
logLevel:'fatal',
|
||||
securityLevel:'strict',
|
||||
startOnLoad:true,
|
||||
arrowMarkerAbsolute:false,
|
||||
|
||||
er:{
|
||||
diagramPadding:20,
|
||||
layoutDirection:'TB',
|
||||
minEntityWidth:100,
|
||||
minEntityHeight:75,
|
||||
entityPadding:15,
|
||||
stroke:'gray',
|
||||
fill:'honeydew',
|
||||
fontSize:12,
|
||||
useMaxWidth:true,
|
||||
},
|
||||
flowchart:{
|
||||
diagramPadding:8,
|
||||
htmlLabels:true,
|
||||
curve:'linear',
|
||||
},
|
||||
sequence:{
|
||||
diagramMarginX:50,
|
||||
diagramMarginY:10,
|
||||
actorMargin:50,
|
||||
width:150,
|
||||
height:65,
|
||||
boxMargin:10,
|
||||
boxTextMargin:5,
|
||||
noteMargin:10,
|
||||
messageMargin:35,
|
||||
messageAlign:'center',
|
||||
mirrorActors:true,
|
||||
bottomMarginAdj:1,
|
||||
useMaxWidth:true,
|
||||
rightAngles:false,
|
||||
showSequenceNumbers:false,
|
||||
},
|
||||
gantt:{
|
||||
titleTopMargin:25,
|
||||
barHeight:20,
|
||||
barGap:4,
|
||||
topPadding:50,
|
||||
leftPadding:75,
|
||||
gridLineStartPadding:35,
|
||||
fontSize:11,
|
||||
fontFamily:'"Open-Sans", "sans-serif"',
|
||||
numberSectionStyles:4,
|
||||
axisFormat:'%Y-%m-%d',
|
||||
}
|
||||
};
|
||||
mermaid.initialize(config);
|
||||
</script>
|
||||
</pre>
|
||||
|
||||
## setSiteConfig
|
||||
|
||||
## setSiteConfig
|
||||
|
||||
| Function | Description | Type | Values |
|
||||
| ------------- | ------------------------------------- | ----------- | --------------------------------------- |
|
||||
| setSiteConfig | Sets the siteConfig to desired values | Put Request | Any Values, except ones in secure array |
|
||||
|
||||
**Notes:**
|
||||
Sets the siteConfig. The siteConfig is a protected configuration for repeat use. Calls to reset() will reset
|
||||
the currentConfig to siteConfig. Calls to reset(configApi.defaultConfig) will reset siteConfig and currentConfig
|
||||
to the defaultConfig
|
||||
Note: currentConfig is set in this function
|
||||
|
||||
\*Default value: At default, will mirror Global Config\*\*
|
||||
|
||||
### Parameters
|
||||
|
||||
- `conf` the base currentConfig to use as siteConfig
|
||||
|
||||
Returns **any** the siteConfig
|
||||
|
||||
## getSiteConfig
|
||||
|
||||
## getSiteConfig
|
||||
|
||||
| Function | Description | Type | Values |
|
||||
| ------------- | ------------------------------------------------- | ----------- | --------------------------------- |
|
||||
| setSiteConfig | Returns the current siteConfig base configuration | Get Request | Returns Any Values in siteConfig |
|
||||
|
||||
**Notes**:
|
||||
Returns **any** values in siteConfig.
|
||||
|
||||
Returns **any**
|
||||
|
||||
## setConfig
|
||||
|
||||
## setConfig
|
||||
|
||||
| Function | Description | Type | Values |
|
||||
| ------------- | ------------------------------------- | ----------- | --------------------------------------- |
|
||||
| setSiteConfig | Sets the siteConfig to desired values | Put Request | Any Values, except ones in secure array |
|
||||
|
||||
**Notes**:
|
||||
Sets the currentConfig. The parameter conf is sanitized based on the siteConfig.secure keys. Any
|
||||
values found in conf with key found in siteConfig.secure will be replaced with the corresponding
|
||||
siteConfig value.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `conf` the potential currentConfig
|
||||
|
||||
Returns **any** the currentConfig merged with the sanitized conf
|
||||
|
||||
## getConfig
|
||||
|
||||
## getConfig
|
||||
|
||||
| Function | Description | Type | Return Values |
|
||||
| --------- | ------------------------- | ----------- | ----------------------------- |
|
||||
| getConfig | Obtains the currentConfig | Get Request | Any Values from currentConfig |
|
||||
|
||||
**Notes**:
|
||||
Returns **any** the currentConfig
|
||||
|
||||
Returns **any** the currentConfig
|
||||
|
||||
## sanitize
|
||||
|
||||
## sanitize
|
||||
|
||||
| Function | Description | Type | Values |
|
||||
| -------- | -------------------------------------- | ----------- | ------ |
|
||||
| sanitize | Sets the siteConfig to desired values. | Put Request | None |
|
||||
|
||||
Ensures options parameter does not attempt to override siteConfig secure keys
|
||||
Note: modifies options in-place
|
||||
|
||||
### Parameters
|
||||
|
||||
- `options` the potential setConfig parameter
|
||||
|
||||
## reset
|
||||
|
||||
## reset
|
||||
|
||||
| Function | Description | Type | Required | Values |
|
||||
| -------- | ---------------------------- | ----------- | -------- | ------ |
|
||||
| reset | Resets currentConfig to conf | Put Request | Required | None |
|
||||
|
||||
| Parameter | Description | Type | Required | Values |
|
||||
| --------- | ------------------------------------------------------------- | ---------- | -------- | -------------------------------------------- |
|
||||
| conf | base set of values, which currentConfig coul be **reset** to. | Dictionary | Required | Any Values, with respect to the secure Array |
|
||||
|
||||
\*Notes :
|
||||
(default: current siteConfig ) (optional, default `getSiteConfig()`)
|
||||
|
||||
### Parameters
|
||||
|
||||
- `conf` the base currentConfig to reset to (default: current siteConfig ) (optional, default `getSiteConfig()`)
|
||||
|
||||
[1]: Setup.md?id=render
|
||||
|
||||
[2]: 8.6.0_docs.md
|
||||
|
||||
[3]: #mermaidapi-configuration-defaults
|
@ -21,10 +21,10 @@
|
||||
- Guide
|
||||
|
||||
- [Development](development.md)
|
||||
- [mermaidAPI](mermaidAPI.md)
|
||||
- [Configurations](Setup.md)
|
||||
- [Changelog](CHANGELOG.md)
|
||||
|
||||
- I'm a n00b
|
||||
- Beginner's Guide
|
||||
- [overview](n00b-overview.md)
|
||||
- [Getting started - easier](n00b-gettingStarted.md)
|
||||
- [Diagram syntax intro](n00b-syntaxReference.md)
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Breaking changes
|
||||
|
||||
**Edit this Page** [![N|Solid](./img/GitHub-Mark-32px.png)](https://github.com/mermaid-js/mermaid/blob/develop/docs/breakingChanges.md)
|
||||
### Breaking changes from history version to latest version:
|
||||
|
||||
## #1
|
||||
|
@ -1,4 +1,5 @@
|
||||
# Class diagrams
|
||||
**Edit this Page** [![N|Solid](./img/GitHub-Mark-32px.png)](https://github.com/mermaid-js/mermaid/blob/develop/docs/classDiagram.md)
|
||||
|
||||
> "In software engineering, a class diagram in the Unified Modeling Language (UML) is a type of static structure diagram that describes the structure of a system by showing the system's classes, their attributes, operations (or methods), and the relationships among objects."
|
||||
Wikipedia
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Development
|
||||
|
||||
|
||||
**Edit this Page** [![N|Solid](./img/GitHub-Mark-32px.png)](https://github.com/mermaid-js/mermaid/blob/develop/docs/development.md)
|
||||
## Updating the documentation
|
||||
|
||||
Please continue writing documentation at [mermaid-js/mermaid/docs](https://github.com/mermaid-js/mermaid/tree/develop/docs).
|
||||
|
@ -1,9 +1,26 @@
|
||||
### Directives
|
||||
## Directives
|
||||
**Edit this Page** [![N|Solid](./img/GitHub-Mark-32px.png)](./directives.md)
|
||||
|
||||
#### Init directives
|
||||
|
||||
With this version, directives are supported. Technically there are two flavors of directive: init/initialize and everything else. The init/initialize directive is parsed early in the flow enough to be able to re-initialize mermaid with a new configuration object. Example:
|
||||
## Directives were added in [Version 8.6.0](/8.6.0_docs.md). Please Read it for more information.
|
||||
|
||||
## Directives
|
||||
With this version, directives are supported. Directives are divided in two sets, by priority. the first set, containing 'init' or 'initialize' directives take priority. While the other set, containing all other kinds of directives are considered only after 'init' and the graph-type declared.
|
||||
|
||||
#### Init
|
||||
|
||||
|
||||
| Parameter | Description |Type | Required | Values|
|
||||
| --- | --- | --- | --- | --- |
|
||||
| init | modifies configurations| Directive| Optional | Any parameters not included in the secure array|
|
||||
|
||||
**Notes:**
|
||||
|
||||
init would be an argument-directive: %%{init: { **insert argument here**}}%%
|
||||
|
||||
The json object that is passed as {**argument** } must be valid, quoted json or it will be ignored.
|
||||
|
||||
The init/initialize directive is parsed early in the flow, enough to be able to re-initialize mermaid with a new configuration object. Example:
|
||||
```
|
||||
%%{init: { 'logLevel': 'debug', 'theme': 'dark' } }%%
|
||||
graph >
|
||||
@ -12,7 +29,7 @@ A-->B
|
||||
|
||||
will set the `logLevel` to `debug` and the `theme` to `dark` for a flowchart diagram.
|
||||
|
||||
Note: init or initialize are both acceptable as init directives. Also note that init directives are coalesced. This means:
|
||||
Note: 'init' or 'initialize' are both acceptable as init directives. Also note that init directives are coalesced. This means:
|
||||
|
||||
```
|
||||
%%{init: { 'logLevel': 'debug', 'theme': 'forest' } }%%
|
||||
@ -31,10 +48,11 @@ will result an init object looking like this:
|
||||
```
|
||||
|
||||
to be sent to `mermaid.initialize(...)`
|
||||
|
||||
|
||||
#### Other directives
|
||||
|
||||
The other flavor of directive is everything else. In this category are any directives that follow the graph type declaration. Essentially, these directives will not be processed early in the flow like the init directive. Each individual graph type will handle these directives. As an example:
|
||||
In this category are any directives that follow the graph type declaration. Essentially, these directives will not be processed early in the flow like the init directive. Each individual graph type will handle these directives. As an example:
|
||||
|
||||
```
|
||||
%%{init: { 'logLevel': 'debug', 'theme': 'dark' } }%%
|
||||
@ -43,15 +61,20 @@ sequenceDiagram
|
||||
Alice->>Bob: Hi Bob
|
||||
Bob->>Alice: Hi Alice
|
||||
```
|
||||
|
||||
## Chronology
|
||||
This will set the `logLevel` to `debug` and `theme` to `dark` for a sequence diagram. Then, during processing, the config for the sequence diagram is set by the `config` directive. This directive is handled in the `sequenceDb.js`. In this example, the fontFamily, fontSize, and fontWeight are all set for this sequence diagram.
|
||||
|
||||
#### Backwards Compatibility
|
||||
|
||||
Init directives and any other non-multiline directives should be backwards compatible because they will be treated as comments in prior versions of mermaid-js.
|
||||
Init directives and any other non-multiline directives should be backwards compatible, because they will be treated as comments in prior versions of mermaid-js.
|
||||
|
||||
Multiline directives, however, will pose an issue and will render an error. This is unavoidable.
|
||||
|
||||
### Wrapping
|
||||
|
||||
The `%%{wrap}%%` directive and the inline `wrap:` text hint have also been added for sequence diagrams. This has been explained in my previous comments and has not materially changed.
|
||||
The `%%{wrap}%%` directive and the inline `wrap:` text hint have also been added for sequence diagrams. This has been explained in my previous comments and has not materially changed.
|
||||
|
||||
# Wrap
|
||||
| Parameter | Description |Type | Required | Values|
|
||||
| --- | --- | --- | --- | --- |
|
||||
| wrap | a callable text-wrap function| Directive| Optional | %%{wrap}%%|
|
||||
|
@ -5,17 +5,19 @@
|
||||
Note that practitioners of ER modelling almost always refer to *entity types* simply as *entities*. For example the CUSTOMER entity type would be referred to simply as the CUSTOMER entity. This is so common it would be inadvisable to do anything else, but technically an entity is an abstract *instance* of an entity type, and this is what an ER diagram shows - abstract instances, and the relationships between them. This is why entities are always named using singular nouns.
|
||||
|
||||
Mermaid can render ER diagrams
|
||||
```
|
||||
erDiagram
|
||||
CUSTOMER ||--o{ ORDER : places
|
||||
ORDER ||--|{ LINE-ITEM : contains
|
||||
CUSTOMER }|..|{ DELIVERY-ADDRESS : uses
|
||||
```
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
CUSTOMER ||--o{ ORDER : places
|
||||
ORDER ||--|{ LINE-ITEM : contains
|
||||
CUSTOMER }|..|{ DELIVERY-ADDRESS : uses
|
||||
CUSTOMER }|..|{ DELIVERY-ADDRESS : uses
|
||||
```
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
CUSTOMER ||--o{ ORDER : places
|
||||
ORDER ||--|{ LINE-ITEM : contains
|
||||
CUSTOMER }|..|{ DELIVERY-ADDRESS : uses
|
||||
```
|
||||
|
||||
Entity names are often capitalised, although there is no accepted standard on this, and it is not required in Mermaid.
|
||||
@ -31,9 +33,11 @@ ER diagrams are a new feature in Mermaid and are **experimental**. There are li
|
||||
### Entities and Relationships
|
||||
|
||||
Mermaid syntax for ER diagrams is compatible with PlantUML, with an extension to label the relationship. Each statement consists of the following parts, all of which are mandatory:
|
||||
```
|
||||
|
||||
```mermaid
|
||||
<first-entity> <relationship> <second-entity> : <relationship-label>
|
||||
```
|
||||
|
||||
Where:
|
||||
|
||||
- `first-entity` is the name of an entity. Names must begin with an alphabetic character and may also contain digits and hyphens
|
||||
@ -43,7 +47,7 @@ Where:
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
```mermaid
|
||||
PROPERTY ||--|{ ROOM : contains
|
||||
```
|
||||
|
||||
@ -51,9 +55,9 @@ This statement can be read as *a property contains one or more rooms, and a room
|
||||
|
||||
### Relationship Syntax
|
||||
|
||||
The `relationship` part of each statement can be broken down into three sub-components:
|
||||
The `relationship` part of each statement can be broken down into three sub-components:
|
||||
|
||||
- the cardinality of the first entity with respect to the second,
|
||||
- the cardinality of the first entity with respect to the second,
|
||||
- whether the relationship confers identity on a 'child' entity
|
||||
- the cardinality of the second entity with respect to the first
|
||||
|
||||
@ -68,13 +72,37 @@ Cardinality is a property that describes how many elements of another entity can
|
||||
|
||||
### Identification
|
||||
|
||||
Relationships may be classified as either *identifying* or *non-identifying* and these are rendered with either solid or dashed lines respectively. This is relevant when one of the entities in question can not have independent existence without the other. For example a firm that insures people to drive cars might need to store data on `NAMED-DRIVER`s. In modelling this we might start out by observing that a `CAR` can be driven by many `PERSON` instances, and a `PERSON` can drive many `CAR`s - both entities can exist without the other, so this is a non-identifying relationship that we might specify in Mermaid as: `PERSON }|..|{ CAR : "driver"`. Note the two dots in the middle of the relationship that will result in a dashed line being drawn between the two entities. But when this many-to-many relationship is resolved into two one-to-many relationships, we observe that a `NAMED-DRIVER` cannot exist without both a `PERSON` and a `CAR` - the relationships become identifying and would be specified using hyphens, which translate to a solid line:
|
||||
Relationships may be classified as either *identifying* or *non-identifying* and these are rendered with either solid or dashed lines respectively. This is relevant when one of the entities in question can not have independent existence without the other. For example a firm that insures people to drive cars might need to store data on `NAMED-DRIVER`s. In modelling this we might start out by observing that a `CAR` can be driven by many `PERSON` instances, and a `PERSON` can drive many `CAR`s - both entities can exist without the other, so this is a non-identifying relationship that we might specify in Mermaid as: `PERSON }|..|{ CAR : "driver"`. Note the two dots in the middle of the relationship that will result in a dashed line being drawn between the two entities. But when this many-to-many relationship is resolved into two one-to-many relationships, we observe that a `NAMED-DRIVER` cannot exist without both a `PERSON` and a `CAR` - the relationships become identifying and would be specified using hyphens, which translate to a solid line:
|
||||
|
||||
```
|
||||
```mermaid
|
||||
CAR ||--o{ NAMED-DRIVER : allows
|
||||
PERSON ||--o{ NAMED-DRIVER : is
|
||||
```
|
||||
|
||||
### Other Things
|
||||
|
||||
- If you want the relationship label to be more than one word, you must use double quotes around the phrase
|
||||
- If you don't want a label at all on a relationship, you must use an empty double-quoted string
|
||||
|
||||
## Styling
|
||||
|
||||
### Config options
|
||||
|
||||
For simple color customization:
|
||||
|
||||
| Name | Used as |
|
||||
| :------- | :------------------------------------------------------ |
|
||||
| `fill` | Background color of an entity |
|
||||
| `stroke` | Border color of an entity, line color of a relationship |
|
||||
|
||||
### Classes used
|
||||
|
||||
The following CSS class selectors are available for richer styling:
|
||||
|
||||
| Selector | Description |
|
||||
| :------------------------- | :---------------------------------------------------- |
|
||||
| `.er.entityBox` | The box representing an entity |
|
||||
| `.er.entityLabel` | The label for an entity |
|
||||
| `.er.relationshipLabel` | The label for a relationship |
|
||||
| `.er.relationshipLabelBox` | The box surrounding a relationship label |
|
||||
| `.er.relationshipLine` | The line representing a relationship between entities |
|
||||
|
@ -1,3 +1,7 @@
|
||||
Frequently Asked Questions:
|
||||
|
||||
**Edit this Page** [![N|Solid](./img/GitHub-Mark-32px.png)](https://github.com/mermaid-js/mermaid/blob/develop/docs/faq.md)
|
||||
|
||||
1. [How to add title to flowchart?](https://github.com/knsv/mermaid/issues/556#issuecomment-363182217)
|
||||
1. [How to specify custom CSS file?](https://github.com/mermaidjs/mermaid.cli/pull/24#issuecomment-373402785)
|
||||
1. [How to fix tooltip misplacement issue?](https://github.com/knsv/mermaid/issues/542#issuecomment-3343564621)
|
||||
|
@ -1,5 +1,6 @@
|
||||
# Flowcharts - Basic Syntax
|
||||
|
||||
**Edit this Page** [![N|Solid](./img/GitHub-Mark-32px.png)](./flowchart.md)
|
||||
## Graph
|
||||
|
||||
This statement declares the direction of the Flowchart.
|
||||
|
@ -1,5 +1,7 @@
|
||||
# Gantt diagrams
|
||||
|
||||
**Edit this Page** [![N|Solid](./img/GitHub-Mark-32px.png)](./gantt.md)
|
||||
|
||||
> A Gantt chart is a type of bar chart, first developed by Karol Adamiecki in 1896, and independently by Henry Gantt in the 1910s, that illustrates a project schedule and the amount of time it would take for any one project to finish. Gantt charts illustrate number of days between the start and finish dates of the terminal elements and summary elements of a project.
|
||||
|
||||
## A note to users
|
||||
|
BIN
docs/img/GitHub-Mark-32px.png
Normal file
BIN
docs/img/GitHub-Mark-32px.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
BIN
docs/img/assignWithDepth.png
Normal file
BIN
docs/img/assignWithDepth.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
BIN
docs/img/object.assign without depth.png
Normal file
BIN
docs/img/object.assign without depth.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
BIN
docs/img/user-journey.png
Normal file
BIN
docs/img/user-journey.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 36 KiB |
BIN
docs/img/without wrap.png
Normal file
BIN
docs/img/without wrap.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 182 KiB |
BIN
docs/img/wrapped text.png
Normal file
BIN
docs/img/wrapped text.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 109 KiB |
@ -6,7 +6,8 @@
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<meta name="description" content="Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.">
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/vue.css">
|
||||
<!-- <link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/vue.css"> -->
|
||||
<link rel="stylesheet" href="theme.css">
|
||||
<script src="//cdn.jsdelivr.net/npm/mermaid@8.5.2/dist/mermaid.min.js"></script>
|
||||
<!-- <script src="http://localhost:9000/mermaid.js"></script> -->
|
||||
<script>
|
||||
@ -54,7 +55,11 @@
|
||||
}
|
||||
|
||||
var num = 0;
|
||||
mermaid.initialize({ logLevel:0, startOnLoad: false, themeCSS:'.label { font-family: Source Sans Pro,Helvetica Neue,Arial,sans-serif; }' });
|
||||
const isDarkMode = window.matchMedia("(prefers-color-scheme: dark)").matches
|
||||
|
||||
const conf = { logLevel:4, startOnLoad: false, themeCSS:'.label { font-family: Source Sans Pro,Helvetica Neue,Arial,sans-serif; }' };
|
||||
if(isDarkMode) conf.theme = 'dark';
|
||||
mermaid.initialize(conf);
|
||||
|
||||
</script>
|
||||
<script>
|
||||
|
@ -1,518 +0,0 @@
|
||||
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
|
||||
|
||||
## mermaidAPI
|
||||
|
||||
This is the api to be used when optionally handling the integration with the web page, instead of using the default integration provided by mermaid.js.
|
||||
|
||||
The core of this api is the [**render**][1] function which, given a graph
|
||||
definition as text, renders the graph/diagram and returns an svg element for the graph.
|
||||
|
||||
It is is then up to the user of the API to make use of the svg, either insert it somewhere in the page or do something completely different.
|
||||
|
||||
In addition to the render function, a number of behavioral configuration options are available.
|
||||
|
||||
## Configuration
|
||||
|
||||
These are the default options which can be overridden with the initialization call like so:
|
||||
**Example 1:**
|
||||
|
||||
<pre>
|
||||
mermaid.initialize({
|
||||
flowchart:{
|
||||
htmlLabels: false
|
||||
}
|
||||
});
|
||||
</pre>
|
||||
|
||||
**Example 2:**
|
||||
|
||||
<pre>
|
||||
<script>
|
||||
var config = {
|
||||
startOnLoad:true,
|
||||
flowchart:{
|
||||
useMaxWidth:true,
|
||||
htmlLabels:true,
|
||||
curve:'cardinal',
|
||||
},
|
||||
|
||||
securityLevel:'loose',
|
||||
};
|
||||
mermaid.initialize(config);
|
||||
</script>
|
||||
</pre>
|
||||
|
||||
A summary of all options and their defaults is found [here][2]. A description of each option follows below.
|
||||
|
||||
## theme
|
||||
|
||||
theme , the CSS style sheet
|
||||
|
||||
**theme** - Choose one of the built-in themes:
|
||||
|
||||
- default
|
||||
- forest
|
||||
- dark
|
||||
- neutral.
|
||||
To disable any pre-defined mermaid theme, use "null".
|
||||
|
||||
**themeCSS** - Use your own CSS. This overrides **theme**.
|
||||
|
||||
<pre>
|
||||
"theme": "forest",
|
||||
"themeCSS": ".node rect { fill: red; }"
|
||||
</pre>
|
||||
|
||||
## fontFamily
|
||||
|
||||
**fontFamily** The font to be used for the rendered diagrams. Default value is \\"trebuchet ms\\", verdana, arial;
|
||||
|
||||
## logLevel
|
||||
|
||||
This option decides the amount of logging to be used.
|
||||
|
||||
- debug: 1
|
||||
- info: 2
|
||||
- warn: 3
|
||||
- error: 4
|
||||
- fatal: (**default**) 5
|
||||
|
||||
## securityLevel
|
||||
|
||||
Sets the level of trust to be used on the parsed diagrams.
|
||||
|
||||
- **strict**: (**default**) tags in text are encoded, click functionality is disabeled
|
||||
- **loose**: tags in text are allowed, click functionality is enabled
|
||||
|
||||
## startOnLoad
|
||||
|
||||
This options controls whether or mermaid starts when the page loads
|
||||
**Default value true**.
|
||||
|
||||
## arrowMarkerAbsolute
|
||||
|
||||
This options controls whether or arrow markers in html code will be absolute paths or
|
||||
an anchor, #. This matters if you are using base tag settings.
|
||||
**Default value false**.
|
||||
|
||||
## flowchart
|
||||
|
||||
The object containing configurations specific for flowcharts
|
||||
|
||||
### htmlLabels
|
||||
|
||||
Flag for setting whether or not a html tag should be used for rendering labels
|
||||
on the edges.
|
||||
**Default value true**.
|
||||
|
||||
### nodeSpacing
|
||||
|
||||
Defines the spacing between nodes on the same level (meaning horizontal spacing for
|
||||
TB or BT graphs, and the vertical spacing for LR as well as RL graphs).
|
||||
**Default value 50**.
|
||||
|
||||
### rankSpacing
|
||||
|
||||
Defines the spacing between nodes on different levels (meaning vertical spacing for
|
||||
TB or BT graphs, and the horizontal spacing for LR as well as RL graphs).
|
||||
**Default value 50**.
|
||||
|
||||
### curve
|
||||
|
||||
How mermaid renders curves for flowcharts. Possible values are
|
||||
|
||||
- basis
|
||||
- linear **default**
|
||||
- cardinal
|
||||
|
||||
## sequence
|
||||
|
||||
The object containing configurations specific for sequence diagrams
|
||||
|
||||
### diagramMarginX
|
||||
|
||||
margin to the right and left of the sequence diagram.
|
||||
**Default value 50**.
|
||||
|
||||
### diagramMarginY
|
||||
|
||||
margin to the over and under the sequence diagram.
|
||||
**Default value 10**.
|
||||
|
||||
### actorMargin
|
||||
|
||||
Margin between actors.
|
||||
**Default value 50**.
|
||||
|
||||
### width
|
||||
|
||||
Width of actor boxes
|
||||
**Default value 150**.
|
||||
|
||||
### height
|
||||
|
||||
Height of actor boxes
|
||||
**Default value 65**.
|
||||
|
||||
### boxMargin
|
||||
|
||||
Margin around loop boxes
|
||||
**Default value 10**.
|
||||
|
||||
### boxTextMargin
|
||||
|
||||
margin around the text in loop/alt/opt boxes
|
||||
**Default value 5**.
|
||||
|
||||
### noteMargin
|
||||
|
||||
margin around notes.
|
||||
**Default value 10**.
|
||||
|
||||
### messageMargin
|
||||
|
||||
Space between messages.
|
||||
**Default value 35**.
|
||||
|
||||
### messageAlign
|
||||
|
||||
Multiline message alignment. Possible values are:
|
||||
|
||||
- left
|
||||
- center **default**
|
||||
- right
|
||||
|
||||
### mirrorActors
|
||||
|
||||
mirror actors under diagram.
|
||||
**Default value true**.
|
||||
|
||||
### bottomMarginAdj
|
||||
|
||||
Depending on css styling this might need adjustment.
|
||||
Prolongs the edge of the diagram downwards.
|
||||
**Default value 1**.
|
||||
|
||||
### useMaxWidth
|
||||
|
||||
when this flag is set the height and width is set to 100% and is then scaling with the
|
||||
available space if not the absolute space required is used.
|
||||
**Default value true**.
|
||||
|
||||
### rightAngles
|
||||
|
||||
This will display arrows that start and begin at the same node as right angles, rather than a curve
|
||||
**Default value false**.
|
||||
|
||||
### showSequenceNumbers
|
||||
|
||||
This will show the node numbers
|
||||
**Default value false**.
|
||||
|
||||
### actorFontSize
|
||||
|
||||
This sets the font size of the actor's description
|
||||
**Default value 14**.
|
||||
|
||||
### actorFontFamily
|
||||
|
||||
This sets the font family of the actor's description
|
||||
**Default value "Open-Sans", "sans-serif"**.
|
||||
|
||||
### actorFontWeight
|
||||
|
||||
This sets the font weight of the actor's description
|
||||
\*\*Default value 400.
|
||||
|
||||
### noteFontSize
|
||||
|
||||
This sets the font size of actor-attached notes.
|
||||
**Default value 14**.
|
||||
|
||||
### noteFontFamily
|
||||
|
||||
This sets the font family of actor-attached notes.
|
||||
**Default value "trebuchet ms", verdana, arial**.
|
||||
|
||||
### noteFontWeight
|
||||
|
||||
This sets the font weight of the note's description
|
||||
\*\*Default value 400.
|
||||
|
||||
### noteAlign
|
||||
|
||||
This sets the text alignment of actor-attached notes.
|
||||
**Default value center**.
|
||||
|
||||
### messageFontSize
|
||||
|
||||
This sets the font size of actor messages.
|
||||
**Default value 16**.
|
||||
|
||||
### messageFontFamily
|
||||
|
||||
This sets the font family of actor messages.
|
||||
**Default value "trebuchet ms", verdana, arial**.
|
||||
|
||||
### messageFontWeight
|
||||
|
||||
This sets the font weight of the message's description
|
||||
\*\*Default value 400.
|
||||
|
||||
### wrapEnabled
|
||||
|
||||
This sets the auto-wrap state for the diagram
|
||||
\*\*Default value false.
|
||||
|
||||
### wrapPadding
|
||||
|
||||
This sets the auto-wrap padding for the diagram (sides only)
|
||||
\*\*Default value 15.
|
||||
|
||||
## gantt
|
||||
|
||||
The object containing configurations specific for gantt diagrams\*
|
||||
|
||||
### titleTopMargin
|
||||
|
||||
Margin top for the text over the gantt diagram
|
||||
**Default value 25**.
|
||||
|
||||
### barHeight
|
||||
|
||||
The height of the bars in the graph
|
||||
**Default value 20**.
|
||||
|
||||
### barGap
|
||||
|
||||
The margin between the different activities in the gantt diagram.
|
||||
**Default value 4**.
|
||||
|
||||
### topPadding
|
||||
|
||||
Margin between title and gantt diagram and between axis and gantt diagram.
|
||||
**Default value 50**.
|
||||
|
||||
### leftPadding
|
||||
|
||||
The space allocated for the section name to the left of the activities.
|
||||
**Default value 75**.
|
||||
|
||||
### gridLineStartPadding
|
||||
|
||||
Vertical starting position of the grid lines.
|
||||
**Default value 35**.
|
||||
|
||||
### fontSize
|
||||
|
||||
Font size ...
|
||||
**Default value 11**.
|
||||
|
||||
### fontFamily
|
||||
|
||||
font family ...
|
||||
**Default value '"Open-Sans", "sans-serif"'**.
|
||||
|
||||
### numberSectionStyles
|
||||
|
||||
The number of alternating section styles.
|
||||
**Default value 4**.
|
||||
|
||||
### axisFormat
|
||||
|
||||
Datetime format of the axis. This might need adjustment to match your locale and preferences
|
||||
**Default value '%Y-%m-%d'**.
|
||||
|
||||
## journey
|
||||
|
||||
The object containing configurations specific for sequence diagrams
|
||||
|
||||
### diagramMarginX
|
||||
|
||||
margin to the right and left of the sequence diagram.
|
||||
**Default value 50**.
|
||||
|
||||
### diagramMarginY
|
||||
|
||||
margin to the over and under the sequence diagram.
|
||||
**Default value 10**.
|
||||
|
||||
### actorMargin
|
||||
|
||||
Margin between actors.
|
||||
**Default value 50**.
|
||||
|
||||
### width
|
||||
|
||||
Width of actor boxes
|
||||
**Default value 150**.
|
||||
|
||||
### height
|
||||
|
||||
Height of actor boxes
|
||||
**Default value 65**.
|
||||
|
||||
### boxMargin
|
||||
|
||||
Margin around loop boxes
|
||||
**Default value 10**.
|
||||
|
||||
### boxTextMargin
|
||||
|
||||
margin around the text in loop/alt/opt boxes
|
||||
**Default value 5**.
|
||||
|
||||
### noteMargin
|
||||
|
||||
margin around notes.
|
||||
**Default value 10**.
|
||||
|
||||
### messageMargin
|
||||
|
||||
Space between messages.
|
||||
**Default value 35**.
|
||||
|
||||
### messageAlign
|
||||
|
||||
Multiline message alignment. Possible values are:
|
||||
|
||||
- left
|
||||
- center **default**
|
||||
- right
|
||||
|
||||
### bottomMarginAdj
|
||||
|
||||
Depending on css styling this might need adjustment.
|
||||
Prolongs the edge of the diagram downwards.
|
||||
**Default value 1**.
|
||||
|
||||
### useMaxWidth
|
||||
|
||||
when this flag is set the height and width is set to 100% and is then scaling with the
|
||||
available space if not the absolute space required is used.
|
||||
**Default value true**.
|
||||
|
||||
### rightAngles
|
||||
|
||||
This will display arrows that start and begin at the same node as right angles, rather than a curve
|
||||
**Default value false**.
|
||||
|
||||
## er
|
||||
|
||||
The object containing configurations specific for entity relationship diagrams
|
||||
|
||||
### diagramPadding
|
||||
|
||||
The amount of padding around the diagram as a whole so that embedded diagrams have margins, expressed in pixels
|
||||
|
||||
### layoutDirection
|
||||
|
||||
Directional bias for layout of entities. Can be either 'TB', 'BT', 'LR', or 'RL',
|
||||
where T = top, B = bottom, L = left, and R = right.
|
||||
|
||||
### minEntityWidth
|
||||
|
||||
The mimimum width of an entity box, expressed in pixels
|
||||
|
||||
### minEntityHeight
|
||||
|
||||
The minimum height of an entity box, expressed in pixels
|
||||
|
||||
### entityPadding
|
||||
|
||||
The minimum internal padding between the text in an entity box and the enclosing box borders, expressed in pixels
|
||||
|
||||
### stroke
|
||||
|
||||
Stroke color of box edges and lines
|
||||
|
||||
### fill
|
||||
|
||||
Fill color of entity boxes
|
||||
|
||||
### fontSize
|
||||
|
||||
Font size (expressed as an integer representing a number of pixels)
|
||||
|
||||
## render
|
||||
|
||||
Function that renders an svg with a graph from a chart definition. Usage example below.
|
||||
|
||||
```js
|
||||
mermaidAPI.initialize({
|
||||
startOnLoad:true
|
||||
});
|
||||
$(function(){
|
||||
const graphDefinition = 'graph TB\na-->b';
|
||||
const cb = function(svgGraph){
|
||||
console.log(svgGraph);
|
||||
};
|
||||
mermaidAPI.render('id1',graphDefinition,cb);
|
||||
});
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
- `id` the id of the element to be rendered
|
||||
- `_txt`
|
||||
- `cb` callback which is called after rendering is finished with the svg code as inparam.
|
||||
- `container` selector to element in which a div with the graph temporarily will be inserted. In one is
|
||||
provided a hidden div will be inserted in the body of the page instead. The element will be removed when rendering is
|
||||
completed.
|
||||
- `txt` the graph definition
|
||||
|
||||
##
|
||||
|
||||
## mermaidAPI configuration defaults
|
||||
|
||||
<pre>
|
||||
|
||||
<script>
|
||||
var config = {
|
||||
theme:'default',
|
||||
logLevel:'fatal',
|
||||
securityLevel:'strict',
|
||||
startOnLoad:true,
|
||||
arrowMarkerAbsolute:false,
|
||||
|
||||
flowchart:{
|
||||
htmlLabels:true,
|
||||
curve:'linear',
|
||||
},
|
||||
sequence:{
|
||||
diagramMarginX:50,
|
||||
diagramMarginY:10,
|
||||
actorMargin:50,
|
||||
width:150,
|
||||
height:65,
|
||||
boxMargin:10,
|
||||
boxTextMargin:5,
|
||||
noteMargin:10,
|
||||
messageMargin:35,
|
||||
messageAlign:'center',
|
||||
mirrorActors:true,
|
||||
bottomMarginAdj:1,
|
||||
useMaxWidth:true,
|
||||
rightAngles:false,
|
||||
showSequenceNumbers:false,
|
||||
},
|
||||
gantt:{
|
||||
titleTopMargin:25,
|
||||
barHeight:20,
|
||||
barGap:4,
|
||||
topPadding:50,
|
||||
leftPadding:75,
|
||||
gridLineStartPadding:35,
|
||||
fontSize:11,
|
||||
fontFamily:'"Open-Sans", "sans-serif"',
|
||||
numberSectionStyles:4,
|
||||
axisFormat:'%Y-%m-%d',
|
||||
}
|
||||
};
|
||||
mermaid.initialize(config);
|
||||
</script>
|
||||
</pre>
|
||||
|
||||
[1]: https://github.com/knsv/mermaid/blob/master/docs/mermaidAPI.md#render
|
||||
|
||||
[2]: https://github.com/knsv/mermaid/blob/master/docs/mermaidAPI.md#mermaidapi-configuration-defaults
|
@ -1,16 +1,16 @@
|
||||
# A basic mermaid User-Guide for Beginners
|
||||
|
||||
Creating diagrams and charts, using mermaid code is simple.
|
||||
Creating diagrams and charts using mermaid code is simple.
|
||||
|
||||
But how is the code turned into a diagram in a web page? This is done with the use of a mermaid renderer.
|
||||
|
||||
Thankfully the mermaid renderer is very accessible, in essence it is a piece of javascript that can be called.
|
||||
The mermaid renderer is very accessible, in essence it is a piece of javascript that can be called.
|
||||
|
||||
Most widely used web browsers, such as Firefox, Chrome and Safari, can render mermaid, Internet Explorer however cannot. The web browser also needs access to the online mermaid renderer which it downloads from https://cdn.jsdelivr.net/npm/mermaid
|
||||
Most web browsers, such as Firefox, Chrome and Safari, can render mermaid, Internet Explorer however cannot. The web browser also needs access to the online mermaid renderer which it downloads from https://cdn.jsdelivr.net/npm/mermaid
|
||||
|
||||
# For beginners, there are three relatively easy ways you can use mermaid:
|
||||
## For beginners, there are three relatively easy ways you can use mermaid:
|
||||
1. Using the mermaid [live editor](https://mermaid-js.github.io/mermaid-live-editor/)
|
||||
2. Using a mermaid plugin, such as that for Confluence or [Atom](https://atom.io/packages/atom-mermaid).
|
||||
2. Using one of the many mermaid plugins
|
||||
3. Calling mermaid renderer with HTML, deployed in a friendly browser.
|
||||
|
||||
# Following either of these examples, you can get started with creating your own diagrams using mermaid code.
|
||||
@ -30,12 +30,12 @@ It is also an easier way to develop diagrams. You can also click "Copy Markdown"
|
||||
|
||||
![Flowchart](./img/liveEditorOptions.png)
|
||||
|
||||
The `Mermaid configuration` is for controlling mermaid behaviour. An easy introduction to mermaid configuration is found in the [Advanced usage](n00b-advanced.md) section. A complete configuration reference cataloguing default values is found on the [mermaidAPI](mermaidAPI.md) page.
|
||||
The `Mermaid configuration` is for controlling mermaid behaviour. An easy introduction to mermaid configuration is found in the [Advanced usage](n00b-advanced.md) section. A complete configuration reference cataloguing default values is found on the [mermaidAPI](https://mermaid-js.github.io/mermaid/#/Setup) page.
|
||||
|
||||
|
||||
## 2. Using mermaid plugins:
|
||||
|
||||
Thanks to the growing popularity of mermaid, many plugins already exist which incorporate a mermaid renderer. An extensive list can be found [here](integrations.md).
|
||||
Thanks to the growing popularity of mermaid, many plugins already exist which incorporate a mermaid renderer. An extensive list can be found [here](./integrations.md).
|
||||
|
||||
One example in the list is the [Atlassian Confluence mermaid plugin](https://marketplace.atlassian.com/apps/1214124/mermaid-plugin-for-confluence?hosting=server&tab=overview)
|
||||
|
||||
@ -126,10 +126,11 @@ This is what needs to go into the html file:
|
||||
|
||||
# *Finally*
|
||||
# If the three steps mentioned are followed you will end up with something like this:
|
||||
|
||||
```
|
||||
<html>
|
||||
<body>
|
||||
<script src="https://cdn.jsdelivr.net/npm/mermaid@8.4.0/dist/mermaid.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/mermaid@8.6.0/dist/mermaid.min.js"></script>
|
||||
<script>mermaid.initialize({startOnLoad:true});</script>
|
||||
|
||||
Here is one mermaid diagram:
|
||||
@ -150,7 +151,7 @@ This is what needs to go into the html file:
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
# Save this to a html file and fetch it with a browser from the web server (or just drag it into your web browser window) and voila!
|
||||
# Save this to an html file and open it with a browser from the web server (or just drag it into your web browser window) and voila!
|
||||
|
||||
---
|
||||
|
||||
|
@ -1,8 +1,27 @@
|
||||
# Overview for n00bs
|
||||
# Overview for Beginners
|
||||
**Edit this Page** [![N|Solid](./img/GitHub-Mark-32px.png)](https://github.com/mermaid-js/mermaid/blob/develop/docs/n00b-overview.md)
|
||||
|
||||
mermaid is a tool that aims to make diagrams and flowcharts for documentation, easier.
|
||||
## There is no explanation like a Good Diagram
|
||||
|
||||
with mermaid, diagrams can be created through comments like this in a script:
|
||||
A picture is worth a thousand words, a good diagram would be worth more. There is no disputing that they are indeed very useful. Yet very few people use them, even fewer still do so, for documentation.
|
||||
|
||||
mermaid aims to change that.
|
||||
|
||||
## Creating and Maintaining Diagrams should not be an expensive and frustrating process.
|
||||
|
||||
Anyone who has used Visio, or (God Forbid) Excel to make a Gantt Chart, knows how hard it is to make, edit and maintain good visualizations.
|
||||
|
||||
In an environment of constantly changing information , diagrams/charts become obsolete/inaccurate very fast. This hobbles the information transfer and productivity in teams.
|
||||
|
||||
# Doc Rot kills Diagrams
|
||||
|
||||
The fast setting Doc-Rot in diagrams makes it quite hard to rationalize taking hours in a desktop application, to produce a diagram that you would need to recreate again the following week in order to account for updates and changes in the app you are documenting. Yet that is often the reality for diagrams and charts and the people who make them.
|
||||
|
||||
mermaid seeks to change that. mermaid is a javascript based tool that utilizes a markdown inspired syntax to generate documentation, which is actually quicker, less complicated and more convenient than most traditional diagramming software. This is a relatively straightforward solution to a major hurdle in software teams.
|
||||
|
||||
# The primary objective of mermaid is to help in addressing the problem of Doc Rot.
|
||||
|
||||
With mermaid, diagrams can be created through comments like this in a script:
|
||||
|
||||
```
|
||||
graph TD
|
||||
@ -15,15 +34,41 @@ And they are rendered into this and made part of the documentation:
|
||||
|
||||
![Flowchart](./img/n00b-firstFlow.png)
|
||||
|
||||
Most of the similar visuals that you might need to create can be scripted in a similar way, with a varitety of different symbols and chart types available.
|
||||
Since the diagram source is text based, it can be part of production scripts (and other pieces of code). So less time needs be spent on documenting as a separate task.
|
||||
## Advantages of Using Mermaid
|
||||
|
||||
Comparing with Visio and similar applications, mermaid is a really fast way to create good visualizations. This is especially apparent when editing a complex visualisations, a process that usually takes hours in a desktop application, but only takes minutes (or even less if generation has been scripted) with mermaid.
|
||||
- The Advantages of mermaid include its ease of generation, modification and rendering.
|
||||
- The number of integrations that it has.
|
||||
- It is a package that can be deployed to create
|
||||
|
||||
mermaid can potentially cut down the amount of time and effort spent on the process of creating diagrams, to a fraction of what you usually put in.
|
||||
|
||||
However, a lot of the mermaid documentation is geared to professional frontend developers, presuming a skill set which I simply do not have.
|
||||
## Diagramming and charting is a gigantic waste of developer time, but not having diagrams ruins productivity.
|
||||
|
||||
If you need some basic instructions and introductions, here are a few good places to start:
|
||||
mermaid can cut down the amount of time, effort and the learning curve that is associated with creating diagrams and charts, by a wide margin.
|
||||
|
||||
For information on how to use mermaid, click [here](https://mermaid-js.github.io/mermaid/#/n00b-gettingStarted), or you can try out the mermaid [live editor](https://mermaid-js.github.io/mermaid-live-editor/), alternatively, you could also view the [integrations and uses](https://github.com/mermaid-js/mermaid/blob/develop/docs/integrations.md) for mermaid.
|
||||
Because, the text base for diagrams allows for it to be updated easily, it can also be made part of production scripts (and other pieces of code). So less time needs be spent on documenting, as a separate task.
|
||||
|
||||
|
||||
## mermaid helps Documentation catch up with Development, in quickly changing projects.
|
||||
|
||||
Being based on markdown, mermaid can be used, not only by accomplished front-end developers, but by most computer savvy people to render simple diagrams, at much faster speeds.
|
||||
In fact one can pick up the syntax for it quite easily from the examples given and there are many tutorials in the internet.
|
||||
|
||||
## mermaid is for everyone.
|
||||
|
||||
For information on how to use mermaid, click [here](https://mermaid-js.github.io/mermaid/#/n00b-gettingStarted).
|
||||
You can try out the mermaid [live editor](https://mermaid-js.github.io/mermaid-live-editor/).
|
||||
Alternatively, you could also view the [integrations and uses](https://mermaid-js.github.io/mermaid/#/./integrations).
|
||||
|
||||
# For anyone who may need video tutorials, here is a list of beginner friendly introductions:
|
||||
|
||||
https://www.youtube.com/watch?v=SQ9QmuTHuSI&t=438s
|
||||
|
||||
https://www.youtube.com/watch?v=5RQqht3NNSE
|
||||
|
||||
https://www.youtube.com/watch?v=7_2IroEs6Is&t=207s
|
||||
|
||||
https://www.youtube.com/watch?v=9HZzKkAqrX8
|
||||
|
||||
https://www.youtube.com/watch?v=7_2IroEs6Is&t=207s
|
||||
|
||||
https://www.youtube.com/watch?v=9HZzKkAqrX8
|
||||
|
@ -1,6 +1,30 @@
|
||||
## Diagram syntax reference
|
||||
## Diagram syntax
|
||||
**Edit this Page** [![N|Solid](./img/GitHub-Mark-32px.png)](https://github.com/mermaid-js/mermaid/blob/develop/docs/n00b-syntaxReference.md)
|
||||
|
||||
If you are new to mermaid, read the [Getting Started](n00b-gettingStarted.md) and [Overview](n00b-overview.md) sections, to learn the basics of mermaid.
|
||||
Video Tutorials can be found at the bottom of the Overview Section.
|
||||
|
||||
This section is a list of diagram types supported by mermaid. Below is a list of links to aricles that explain the syntax of the diagrams or charts that 0can be called.
|
||||
|
||||
They also detail how diagrams can be defined, or described in the manner with which the diagram is to be rendered by the renderer.
|
||||
|
||||
### The benefits of text based diagramming are its speed and modifiability. mermaid allows for easy maintenance and modification of diagrams. This means your diagrams will always be up to date and closely follow your code and improve your documentation.
|
||||
|
||||
## mermaid tag:
|
||||
These Diagram Definitions can be entered within a \<div class=mermaid> tag.
|
||||
like so :
|
||||
```
|
||||
<div class="mermaid">
|
||||
graph LR
|
||||
A --- B
|
||||
B-->C[fa:fa-ban forbidden]
|
||||
B-->D(fa:fa-spinner);
|
||||
</div>
|
||||
```
|
||||
## mermaid Live Editor
|
||||
These definitions can also be entered into the [mermaid live editor](https://mermaid-js.github.io/mermaid-live-editor), to render them immediately.
|
||||
This would then offer
|
||||
|
||||
Having already [gotten started](n00b-gettingStarted.md), existing diagram syntax documentation was easy enough to follow even for a n00b like me..
|
||||
|
||||
- [Flowchart](flowchart.md)
|
||||
- [Sequence diagram](sequenceDiagram.md)
|
||||
@ -8,4 +32,6 @@ Having already [gotten started](n00b-gettingStarted.md), existing diagram syntax
|
||||
- [State Diagram](stateDiagram.md)
|
||||
- [Gantt](gantt.md)
|
||||
- [Pie Chart](pie.md)
|
||||
|
||||
- [Entity Relationship Diagram](entityRelationshipDiagram.md)
|
||||
- [User Journey Diagram](user-journey.md)
|
||||
- [Directives](directives.md)
|
||||
|
@ -1,5 +1,7 @@
|
||||
# Pie chart diagrams
|
||||
|
||||
**Edit this Page** [![N|Solid](./img/GitHub-Mark-32px.png)](./pie.md)
|
||||
|
||||
> A pie chart (or a circle chart) is a circular statistical graphic, which is divided into slices to illustrate numerical proportion. In a pie chart, the arc length of each slice (and consequently its central angle and area), is proportional to the quantity it represents. While it is named for its resemblance to a pie which has been sliced, there are variations on the way it can be presented. The earliest known pie chart is generally credited to William Playfair's Statistical Breviary of 1801
|
||||
-Wikipedia
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
# Sequence diagrams
|
||||
|
||||
**Edit this Page** [![N|Solid](./img/GitHub-Mark-32px.png)](./sequenceDiagram.md)
|
||||
|
||||
> A Sequence diagram is an interaction diagram that shows how processes operate with one another and in what order.
|
||||
|
||||
Mermaid can render sequence diagrams.
|
||||
@ -16,6 +18,10 @@ sequenceDiagram
|
||||
John-->>Alice: Great!
|
||||
```
|
||||
|
||||
## A note on nodes, the word "end" could potentially break the diagram, due to the way that the mermaid language is scripted.
|
||||
## If unavoidable, one must use parentheses(), quotation marks "", or brackets {},[], to enclose the word "end". i.e : (end), [end], {end}.
|
||||
|
||||
|
||||
## Syntax
|
||||
|
||||
### Participants
|
||||
|
@ -1,5 +1,7 @@
|
||||
# State diagrams
|
||||
|
||||
**Edit this Page** [![N|Solid](./img/GitHub-Mark-32px.png)](./stateDiagram.md)
|
||||
|
||||
> "A state diagram is a type of diagram used in computer science and related fields to describe the behavior of systems. State diagrams require that the system described is composed of a finite number of states; sometimes, this is indeed the case, while at other times this is a reasonable abstraction." Wikipedia
|
||||
|
||||
Mermaid can render state diagrams. The syntax tries to be compliant with the syntax used in plantUml as this will make it easier for users to share diagrams between mermaid and plantUml.
|
||||
|
9
docs/theme.css
Normal file
9
docs/theme.css
Normal file
File diff suppressed because one or more lines are too long
@ -1,11 +1,20 @@
|
||||
# Usage
|
||||
**Edit this Page** [![N|Solid](./img/GitHub-Mark-32px.png)](https://github.com/mermaid-js/mermaid/blob/develop/docs/usage.md)
|
||||
|
||||
## Installation
|
||||
|
||||
### npm package
|
||||
### npm package
|
||||
|
||||
```
|
||||
yarn add mermaid
|
||||
1.You will need to isntall node v10 or 12, which would have npm.
|
||||
|
||||
2. download yarn using npm.
|
||||
|
||||
2. enter the following command:
|
||||
yarn add mermaid
|
||||
|
||||
3. You can then add mermaid as a dev dependency using this command:
|
||||
yarn add --dev mermaid
|
||||
```
|
||||
|
||||
### CDN
|
||||
@ -27,19 +36,22 @@ locate the graphs on the page and transform them to svg files.
|
||||
### Include mermaid on your web page:
|
||||
|
||||
```html
|
||||
<script src="mermaid.min.js"></script>
|
||||
<script>mermaid.initialize({startOnLoad:true});</script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/mermaid@8.6.0/dist/mermaid.min.js"></script>
|
||||
<script>mermaid.initialize({startOnLoad:true});</script>
|
||||
```
|
||||
|
||||
Further down on your page mermaid will look for tags with `class="mermaid"`. From these tags mermaid will try to
|
||||
read the chart definiton and replace it with the svg chart.
|
||||
|
||||
|
||||
### Define a chart like this:
|
||||
### Define a chart like thi:
|
||||
|
||||
```html
|
||||
<div class="mermaid">
|
||||
CHART DEFINITION GOES HERE
|
||||
graph LR
|
||||
A --- B
|
||||
B-->C[fa:fa-ban forbidden]
|
||||
B-->D(fa:fa-spinner);
|
||||
</div>
|
||||
```
|
||||
|
||||
@ -53,9 +65,51 @@ Would end up like this:
|
||||
</div>
|
||||
```
|
||||
|
||||
## Simple full example:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<div class="mermaid">
|
||||
graph LR
|
||||
A --- B
|
||||
B-->C[fa:fa-ban forbidden]
|
||||
B-->D(fa:fa-spinner);
|
||||
</div>
|
||||
<script src="https://cdn.jsdelivr.net/npm/mermaid@8.6.0/dist/mermaid.min.js"></script>
|
||||
<script>mermaid.initialize({startOnLoad:true});</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
## Try it out, save this code as HTML and load it.
|
||||
|
||||
### To enable click event and tags in nodes
|
||||
|
||||
In version 8.2 a security improvement was introduced. A `securityLevel` configuration was introduced which sets the level of trust to be used on the parsed diagrams.
|
||||
|
||||
* **true**: (default) tags in text are encoded, click functionality is disabled
|
||||
* false: tags in text are allowed, click functionality is enabled
|
||||
|
||||
⚠️ **Note** : This changes the default behaviour of mermaid so that after upgrade to 8.2, if the `securityLevel` is not configured, tags in flowcharts are encoded as tags and clicking is prohibited.
|
||||
|
||||
If your application is taking resposibility for the diagram source security you can set the `securityLevel` accordingly. By doing this clicks and tags are again allowed.
|
||||
|
||||
```javascript
|
||||
mermaidAPI.initialize({
|
||||
securityLevel: 'loose'
|
||||
});
|
||||
```
|
||||
|
||||
## Notes:
|
||||
An id attribute is also added to mermaid tags without one.
|
||||
|
||||
### To enable click event and tags in nodes
|
||||
Mermaid can load multiple diagrams, in the same page.
|
||||
|
||||
## To enable click event and tags in nodes:
|
||||
|
||||
In version 8.2 a security improvement was introduced. A `securityLevel` configuration was introduced which sets the level of trust to be used on the parsed diagrams.
|
||||
|
||||
@ -72,26 +126,6 @@ If your application is taking resposibility for the diagram source security you
|
||||
});
|
||||
```
|
||||
|
||||
### Simple full example:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<div class="mermaid">
|
||||
graph LR
|
||||
A --- B
|
||||
B-->C[fa:fa-ban forbidden]
|
||||
B-->D(fa:fa-spinner);
|
||||
</div>
|
||||
<script src="mermaid.min.js"></script>
|
||||
<script>mermaid.initialize({startOnLoad:true});</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
### Labels out of bounds
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
# User Journey Diagram
|
||||
|
||||
**Edit this Page** [![N|Solid](./img/GitHub-Mark-32px.png)](https://github.com/mermaid-js/mermaid/blob/develop/docs/user-journey.md)
|
||||
> User journeys describe at a high level of detail exactly what steps different users take to complete a specific task within a system, application or website. This technique shows the current (as-is) user workflow, and reveals areas of improvement for the to-be workflow. (Wikipedia)
|
||||
|
||||
Mermaid can render user journey diagrams:
|
||||
|
16
package.json
16
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mermaid",
|
||||
"version": "8.5.2",
|
||||
"version": "8.6.0",
|
||||
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
|
||||
"main": "dist/mermaid.core.js",
|
||||
"keywords": [
|
||||
@ -16,7 +16,7 @@
|
||||
"build:development": "webpack --progress --colors",
|
||||
"build:production": "yarn build:development -p --config webpack.config.prod.babel.js",
|
||||
"build": "yarn build:development && yarn build:production",
|
||||
"postbuild": "documentation build src/mermaidAPI.js --shallow -f md --markdown-toc false -o docs/mermaidAPI.md",
|
||||
"postbuild": "documentation build src/mermaidAPI.js src/config.js --shallow -f md --markdown-toc false -o docs/Setup.md",
|
||||
"build:watch": "yarn build --watch",
|
||||
"minify": "minify ./dist/mermaid.js > ./dist/mermaid.min.js",
|
||||
"release": "yarn build",
|
||||
@ -29,7 +29,6 @@
|
||||
"test": "yarn lint && jest src/.*",
|
||||
"test:watch": "jest --watch src",
|
||||
"prepublishOnly": "yarn build && yarn test && yarn e2e",
|
||||
"prepush": "yarn test",
|
||||
"prepare": "yarn build"
|
||||
},
|
||||
"repository": {
|
||||
@ -50,16 +49,16 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@braintree/sanitize-url": "^3.1.0",
|
||||
"crypto-random-string": "^3.0.1",
|
||||
"d3": "^5.7.0",
|
||||
"dagre": "^0.8.4",
|
||||
"dagre-d3": "^0.6.4",
|
||||
"entity-decode": "^2.0.2",
|
||||
"graphlib": "^2.1.7",
|
||||
"he": "^1.2.0",
|
||||
"khroma": "^1.1.0",
|
||||
"minify": "^4.1.1",
|
||||
"moment-mini": "^2.22.1",
|
||||
"scope-css": "^1.2.1"
|
||||
"stylis": "^3.5.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.2.2",
|
||||
@ -106,5 +105,10 @@
|
||||
"sideEffects": [
|
||||
"**/*.css",
|
||||
"**/*.scss"
|
||||
]
|
||||
],
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-push": "yarn test"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
990
src/config.js
990
src/config.js
@ -1,36 +1,972 @@
|
||||
let config = {};
|
||||
import { assignWithDepth } from './utils';
|
||||
import { logger } from './logger';
|
||||
// import themeVariables from './theme-default';
|
||||
// import themeForestVariables from './theme-forest';
|
||||
// import themeNeutralVariables from './theme-neutral';
|
||||
|
||||
const setConf = function(cnf) {
|
||||
// Top level initially mermaid, gflow, sequenceDiagram and gantt
|
||||
const lvl1Keys = Object.keys(cnf);
|
||||
for (let i = 0; i < lvl1Keys.length; i++) {
|
||||
if (typeof cnf[lvl1Keys[i]] === 'object' && cnf[lvl1Keys[i]] != null) {
|
||||
const lvl2Keys = Object.keys(cnf[lvl1Keys[i]]);
|
||||
const themes = {};
|
||||
|
||||
for (let j = 0; j < lvl2Keys.length; j++) {
|
||||
// logger.debug('Setting conf ', lvl1Keys[i], '-', lvl2Keys[j])
|
||||
if (typeof config[lvl1Keys[i]] === 'undefined') {
|
||||
config[lvl1Keys[i]] = {};
|
||||
}
|
||||
// logger.debug('Setting config: ' + lvl1Keys[i] + ' ' + lvl2Keys[j] + ' to ' + cnf[lvl1Keys[i]][lvl2Keys[j]])
|
||||
config[lvl1Keys[i]][lvl2Keys[j]] = cnf[lvl1Keys[i]][lvl2Keys[j]];
|
||||
}
|
||||
} else {
|
||||
config[lvl1Keys[i]] = cnf[lvl1Keys[i]];
|
||||
for (const themeName of ['default', 'forest', 'dark', 'neutral', 'base']) {
|
||||
themes[themeName] = require(`./themes/theme-${themeName}.js`);
|
||||
}
|
||||
/**
|
||||
* **Configuration methods in Mermaid version 8.6.0 have been updated, to learn more[[click here](8.6.0_docs.md)].**
|
||||
*
|
||||
* ## **What follows are config instructions for older versions**
|
||||
* These are the default options which can be overridden with the initialization call like so:
|
||||
* **Example 1:**
|
||||
* <pre>
|
||||
* mermaid.initialize({
|
||||
* flowchart:{
|
||||
* htmlLabels: false
|
||||
* }
|
||||
* });
|
||||
* </pre>
|
||||
*
|
||||
* **Example 2:**
|
||||
* <pre>
|
||||
* <script>
|
||||
* var config = {
|
||||
* startOnLoad:true,
|
||||
* flowchart:{
|
||||
* useMaxWidth:true,
|
||||
* htmlLabels:true,
|
||||
* curve:'cardinal',
|
||||
* },
|
||||
*
|
||||
* securityLevel:'loose',
|
||||
* };
|
||||
* mermaid.initialize(config);
|
||||
* </script>
|
||||
* </pre>
|
||||
* A summary of all options and their defaults is found [here](#mermaidapi-configuration-defaults). A description of each option follows below.
|
||||
*
|
||||
* @name Configuration
|
||||
*/
|
||||
const config = {
|
||||
/** theme , the CSS style sheet
|
||||
*
|
||||
* theme , the CSS style sheet
|
||||
*
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| Theme |Built in Themes| String | Optional | Values include, default, forest, dark, neutral, null|
|
||||
*
|
||||
***Notes:**To disable any pre-defined mermaid theme, use "null".
|
||||
* <pre>
|
||||
* "theme": "forest",
|
||||
* "themeCSS": ".node rect { fill: red; }"
|
||||
* </pre>
|
||||
*/
|
||||
theme: 'default',
|
||||
themeVariables: themes['default'].getThemeVariables(),
|
||||
themeCSS: undefined,
|
||||
/* **maxTextSize** - The maximum allowed size of the users text diamgram */
|
||||
maxTextSize: 50000,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*|fontFamily | specifies the font to be used in the rendered diagrams| String | Required | Verdana, Arial, Trebuchet MS,|
|
||||
*
|
||||
***notes: Default value is \\"trebuchet ms\\".
|
||||
*/
|
||||
fontFamily: '"trebuchet ms", verdana, arial;',
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| logLevel |This option decides the amount of logging to be used.| String | Required | 1, 2, 3, 4, 5 |
|
||||
*
|
||||
*
|
||||
***Notes:**
|
||||
*- debug: 1.
|
||||
*- info: 2.
|
||||
*- warn: 3.
|
||||
*- error: 4.
|
||||
*- fatal: 5(default).
|
||||
*/
|
||||
logLevel: 5,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| securitylevel | Level of trust for parsed diagram|String | Required | Strict, Loose, antiscript |
|
||||
*
|
||||
***Notes:
|
||||
*- **strict**: (**default**) tags in text are encoded, click functionality is disabeled
|
||||
*- **loose**: tags in text are allowed, click functionality is enabled
|
||||
*- **antiscript**: html tags in text are allowed, (only script element is removed), click functionality is enabled
|
||||
*/
|
||||
securityLevel: 'strict',
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| startOnLoad| Dictates whether mermaind starts on Page load | Boolean | Required | True, False |
|
||||
*
|
||||
***Notes:**
|
||||
***Default value: true**
|
||||
*/
|
||||
startOnLoad: true,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required |Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| arrowMarkerAbsolute | Controls whether or arrow markers in html code are absolute paths or anchors | Boolean | Required | True, False |
|
||||
*
|
||||
*
|
||||
*## Notes**: This matters if you are using base tag settings.
|
||||
***Default value: false**.
|
||||
*/
|
||||
arrowMarkerAbsolute: false,
|
||||
|
||||
/**
|
||||
* This option controls which currentConfig keys are considered _secure_ and can only be changed via
|
||||
* call to mermaidAPI.initialize. Calls to mermaidAPI.reinitialize cannot make changes to
|
||||
* the `secure` keys in the current currentConfig. This prevents malicious graph directives from
|
||||
* overriding a site's default security.
|
||||
*/
|
||||
secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'],
|
||||
|
||||
/**
|
||||
* The object containing configurations specific for flowcharts
|
||||
*/
|
||||
flowchart: {
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| diagramPadding | amount of padding around the diagram as a whole | Integer | Required | Any Positive Value |
|
||||
*
|
||||
***Notes:**The amount of padding around the diagram as a whole so that embedded diagrams have margins, expressed in pixels
|
||||
***Default value: 8**.
|
||||
*/
|
||||
diagramPadding: 8,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| htmlLabels | Flag for setting whether or not a html tag should be used for rendering labels on the edges. | Boolean| Required | True, False|
|
||||
*
|
||||
***Notes: Default value: true**.
|
||||
*/
|
||||
htmlLabels: true,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| nodeSpacing | Defines the spacing between nodes on the same level | Integer| Required | Any positive Numbers |
|
||||
*
|
||||
***Notes:
|
||||
*Pertains to horizontal spacing for TB (top to bottom) or BT (bottom to top) graphs, and the vertical spacing for LR as well as RL graphs.**
|
||||
***Default value 50**.
|
||||
*/
|
||||
nodeSpacing: 50,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| rankSpacing | Defines the spacing between nodes on different levels | Integer | Required| Any Positive Numbers |
|
||||
*
|
||||
***Notes: pertains to vertical spacing for TB (top to bottom) or BT (bottom to top), and the horizontal spacing for LR as well as RL graphs.
|
||||
***Default value 50**.
|
||||
*/
|
||||
rankSpacing: 50,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| curve | Defines how mermaid renders curves for flowcharts. | String | Required | Basis, Linear, Cardinal|
|
||||
*
|
||||
***Notes:
|
||||
*Default Vaue: Linear**
|
||||
*/
|
||||
curve: 'linear',
|
||||
// Only used in new experimental rendering
|
||||
// repreesents the padding between the labels and the shape
|
||||
padding: 15
|
||||
},
|
||||
|
||||
/**
|
||||
* The object containing configurations specific for sequence diagrams
|
||||
*/
|
||||
sequence: {
|
||||
/**
|
||||
* widt of the activation rect
|
||||
* **Default value 10**.
|
||||
*/
|
||||
activationWidth: 10,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| diagramMarginX | margin to the right and left of the sequence diagram | Integer | Required | Any Positive Values |
|
||||
*
|
||||
***Notes:**
|
||||
***Default value 50**.
|
||||
*/
|
||||
diagramMarginX: 50,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| diagramMarginY | Margin to the over and under the sequence diagram | Integer | Required | Any Positive Values|
|
||||
*
|
||||
***Notes:**
|
||||
***Default value 10**.
|
||||
*/
|
||||
diagramMarginY: 10,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| actorMargin | Margin between actors. | Integer | Required | Any Positive Value |
|
||||
*
|
||||
***Notes:**
|
||||
***Default value 50**.
|
||||
*/
|
||||
actorMargin: 50,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| width | Width of actor boxes | Integer | Required | Any Positive Value |
|
||||
*
|
||||
***Notes:**
|
||||
***Default value 150**.
|
||||
*/
|
||||
width: 150,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| height | Height of actor boxes | Integer | Required | Any Positive Value|
|
||||
*
|
||||
***Notes:**
|
||||
***Default value 65**..
|
||||
*/
|
||||
height: 65,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| boxMargin | Margin around loop boxes | Integer | Required | Any Positive Value |
|
||||
*
|
||||
***Notes:**
|
||||
*
|
||||
***Default value 10**.
|
||||
*/
|
||||
boxMargin: 10,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| boxTextMargin| margin around the text in loop/alt/opt boxes | Integer | Required| Any Positive Value|
|
||||
*
|
||||
***Notes:**
|
||||
*
|
||||
***Default value 5**.
|
||||
*/
|
||||
boxTextMargin: 5,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| noteMargin | margin around notes. | Integer | Required | Any Positive Value |
|
||||
*
|
||||
***Notes:**
|
||||
*
|
||||
***Default value 10**.
|
||||
*/
|
||||
noteMargin: 10,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| messageMargin | Space between messages. | Integer | Required | Any Positive Value |
|
||||
*
|
||||
***Notes:**
|
||||
*
|
||||
*Space between messages.
|
||||
***Default value 35**.
|
||||
*/
|
||||
messageMargin: 35,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| messageAlign | Multiline message alignment | Integer | Required | left, center, right |
|
||||
*
|
||||
***Notes:**center **default**
|
||||
*/
|
||||
messageAlign: 'center',
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| mirrorActors | mirror actors under diagram. | Boolean| Required | True, False |
|
||||
*
|
||||
***Notes:**
|
||||
*
|
||||
***Default value true**.
|
||||
*/
|
||||
mirrorActors: true,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| bottomMarginAdj | Prolongs the edge of the diagram downwards. | Integer | Required | Any Positive Value |
|
||||
*
|
||||
***Notes:**Depending on css styling this might need adjustment.
|
||||
***Default value 1**.
|
||||
*/
|
||||
bottomMarginAdj: 1,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| useMaxWidth | See Notes | Boolean | Required | True, False |
|
||||
*
|
||||
***Notes:**
|
||||
*when this flag is set to true, the height and width is set to 100% and is then scaling with the
|
||||
*available space. If set to false, the absolute space required is used.
|
||||
***Default value: True**.
|
||||
*/
|
||||
useMaxWidth: true,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| rightAngles | display curve arrows as right angles| Boolean | Required | True, False |
|
||||
*
|
||||
***Notes:**
|
||||
*
|
||||
*This will display arrows that start and begin at the same node as right angles, rather than a curve
|
||||
***Default value false**.
|
||||
*/
|
||||
rightAngles: false,
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| showSequenceNumbers | This will show the node numbers | Boolean | Required | True, False |
|
||||
*
|
||||
***Notes:**
|
||||
***Default value false**.
|
||||
*/
|
||||
showSequenceNumbers: false,
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| actorFontSize| This sets the font size of the actor's description | Integer | Require | Any Positive Value |
|
||||
*
|
||||
***Notes:**
|
||||
***Default value 14**..
|
||||
*/
|
||||
actorFontSize: 14,
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| actorFontFamily |This sets the font family of the actor's description | 3 | 4 | Open-Sans, Sans-Serif |
|
||||
*
|
||||
***Notes:**
|
||||
***Default value "Open-Sans", "sans-serif"**.
|
||||
*/
|
||||
actorFontFamily: '"Open-Sans", "sans-serif"',
|
||||
/**
|
||||
* This sets the font weight of the actor's description
|
||||
* **Default value 400.
|
||||
*/
|
||||
actorFontWeight: 400,
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| noteFontSize |This sets the font size of actor-attached notes. | Integer | Required | Any Positive Value |
|
||||
*
|
||||
***Notes:**
|
||||
***Default value 14**..
|
||||
*/
|
||||
noteFontSize: 14,
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| noteFontFamily| This sets the font family of actor-attached notes. | String | Required | trebuchet ms, verdana, arial |
|
||||
*
|
||||
***Notes:**
|
||||
***Default value: trebuchet ms **.
|
||||
*/
|
||||
noteFontFamily: '"trebuchet ms", verdana, arial',
|
||||
/**
|
||||
* This sets the font weight of the note's description
|
||||
* **Default value 400.
|
||||
*/
|
||||
noteFontWeight: 400,
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| noteAlign | This sets the text alignment of actor-attached notes. | string | required | left, center, right|
|
||||
*
|
||||
***Notes:**
|
||||
***Default value center**.
|
||||
*/
|
||||
noteAlign: 'center',
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| messageFontSize | This sets the font size of actor messages. | Integer | Required | Any Positive Number |
|
||||
*
|
||||
***Notes:**
|
||||
***Default value 16**.
|
||||
*/
|
||||
messageFontSize: 16,
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| messageFontFamily | This sets the font family of actor messages. | String| Required | trebuchet ms", verdana, aria |
|
||||
*
|
||||
***Notes:**
|
||||
***Default value:"trebuchet ms**.
|
||||
*/
|
||||
messageFontFamily: '"trebuchet ms", verdana, arial',
|
||||
/**
|
||||
* This sets the font weight of the message's description
|
||||
* **Default value 400.
|
||||
*/
|
||||
messageFontWeight: 400,
|
||||
/**
|
||||
* This sets the auto-wrap state for the diagram
|
||||
* **Default value false.
|
||||
*/
|
||||
wrap: false,
|
||||
/**
|
||||
* This sets the auto-wrap padding for the diagram (sides only)
|
||||
* **Default value 10.
|
||||
*/
|
||||
wrapPadding: 10,
|
||||
/**
|
||||
* This sets the width of the loop-box (loop, alt, opt, par)
|
||||
* **Default value 50.
|
||||
*/
|
||||
labelBoxWidth: 50,
|
||||
/**
|
||||
* This sets the height of the loop-box (loop, alt, opt, par)
|
||||
* **Default value 20.
|
||||
*/
|
||||
labelBoxHeight: 20,
|
||||
messageFont: function() {
|
||||
return {
|
||||
fontFamily: this.messageFontFamily,
|
||||
fontSize: this.messageFontSize,
|
||||
fontWeight: this.messageFontWeight
|
||||
};
|
||||
},
|
||||
noteFont: function() {
|
||||
return {
|
||||
fontFamily: this.noteFontFamily,
|
||||
fontSize: this.noteFontSize,
|
||||
fontWeight: this.noteFontWeight
|
||||
};
|
||||
},
|
||||
actorFont: function() {
|
||||
return {
|
||||
fontFamily: this.actorFontFamily,
|
||||
fontSize: this.actorFontSize,
|
||||
fontWeight: this.actorFontWeight
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* The object containing configurations specific for gantt diagrams*
|
||||
*/
|
||||
gantt: {
|
||||
/**
|
||||
*### titleTopMargin
|
||||
*
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| titleTopMargin | Margin top for the text over the gantt diagram | Integer | Required | Any Positive Value |
|
||||
*
|
||||
***Notes:**
|
||||
***Default value 25**.
|
||||
*/
|
||||
titleTopMargin: 25,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| barHeight | The height of the bars in the graph | Integer | Required | Any Positive Value |
|
||||
*
|
||||
***Notes:**
|
||||
***Default value 20**.
|
||||
*/
|
||||
barHeight: 20,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| barGap | The margin between the different activities in the gantt diagram. | Integer | Optional |Any Positive Value |
|
||||
*
|
||||
***Notes:**
|
||||
***Default value 4**.
|
||||
*/
|
||||
barGap: 4,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| topPadding | Margin between title and gantt diagram and between axis and gantt diagram. | Integer | Required | Any Positive Value |
|
||||
*
|
||||
***Notes:**
|
||||
***Default value 50**.
|
||||
*/
|
||||
topPadding: 50,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| leftPadding | The space allocated for the section name to the left of the activities. | Integer| Required | Any Positive Value |
|
||||
*
|
||||
***Notes:**
|
||||
***Default value 75**.
|
||||
*/
|
||||
leftPadding: 75,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| gridLineStartPadding | Vertical starting position of the grid lines. | Integer | Required | Any Positive Value |
|
||||
*
|
||||
***Notes:**
|
||||
***Default value 35**.
|
||||
*/
|
||||
gridLineStartPadding: 35,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| fontSize | Font size| Integer | Required | Any Positive Value |
|
||||
*
|
||||
***Notes:**
|
||||
***Default value 11**.
|
||||
*/
|
||||
fontSize: 11,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| fontFamily | font Family | string | required |"Open-Sans", "sans-serif" |
|
||||
*
|
||||
***Notes:**
|
||||
*
|
||||
***Default value '"Open-Sans", "sans-serif"'**.
|
||||
*/
|
||||
fontFamily: '"Open-Sans", "sans-serif"',
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| numberSectionStyles | The number of alternating section styles | Integer | 4 | Any Positive Value |
|
||||
*
|
||||
***Notes:**
|
||||
***Default value 4**.
|
||||
*/
|
||||
numberSectionStyles: 4,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| axisFormat | Datetime format of the axis. | 3 | Required | Date in yy-mm-dd |
|
||||
*
|
||||
***Notes:**
|
||||
*
|
||||
* This might need adjustment to match your locale and preferences
|
||||
***Default value '%Y-%m-%d'**.
|
||||
*/
|
||||
axisFormat: '%Y-%m-%d'
|
||||
},
|
||||
/**
|
||||
* The object containing configurations specific for sequence diagrams
|
||||
*/
|
||||
journey: {
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| diagramMarginX | margin to the right and left of the sequence diagram | Integer | Required | Any Positive Value |
|
||||
*
|
||||
***Notes:**
|
||||
***Default value 50**.
|
||||
*/
|
||||
diagramMarginX: 50,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| diagramMarginY | margin to the over and under the sequence diagram. | Integer | Required | Any Positive Value|
|
||||
*
|
||||
***Notes:**
|
||||
***Default value 10**..
|
||||
*/
|
||||
diagramMarginY: 10,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| actorMargin | Margin between actors. | Integer | Required | Any Positive Value|
|
||||
*
|
||||
***Notes:**
|
||||
***Default value 50**.
|
||||
*/
|
||||
actorMargin: 50,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| width | Width of actor boxes | Integer | Required | Any Positive Value |
|
||||
*
|
||||
***Notes:**
|
||||
***Default value 150**.
|
||||
*/
|
||||
width: 150,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| height | Height of actor boxes | Integer | Required | Any Positive Value |
|
||||
*
|
||||
***Notes:**
|
||||
***Default value 65**.
|
||||
*/
|
||||
height: 65,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| boxMargin | Margin around loop boxes | Integer | Required | Any Positive Value |
|
||||
*
|
||||
***Notes:**
|
||||
***Default value 10**.
|
||||
*/
|
||||
boxMargin: 10,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| boxTextMargin | margin around the text in loop/alt/opt boxes | Integer | Required | Any Positive Value |
|
||||
*
|
||||
***Notes:**
|
||||
*/
|
||||
boxTextMargin: 5,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| noteMargin | margin around notes. | Integer | Required | Any Positive Value |
|
||||
*
|
||||
***Notes:**
|
||||
***Default value 10**.
|
||||
*/
|
||||
noteMargin: 10,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| messageMargin |Space between messages. | Integer | Required | Any Positive Value |
|
||||
*
|
||||
***Notes:**
|
||||
*
|
||||
*Space between messages.
|
||||
***Default value 35**.
|
||||
*/
|
||||
messageMargin: 35,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| messageAlign |Multiline message alignment | 3 | 4 | left, center, right |
|
||||
*
|
||||
***Notes:**default:center**
|
||||
*/
|
||||
messageAlign: 'center',
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| bottomMarginAdj | Prolongs the edge of the diagram downwards. | Integer | 4 | Any Positive Value |
|
||||
*
|
||||
***Notes:**Depending on css styling this might need adjustment.
|
||||
***Default value 1**.
|
||||
*/
|
||||
bottomMarginAdj: 1,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| useMaxWidth | See notes | Boolean | 4 | True, False |
|
||||
*
|
||||
***Notes:**when this flag is set the height and width is set to 100% and is then scaling with the
|
||||
*available space if not the absolute space required is used.
|
||||
*
|
||||
***Default value true**.
|
||||
*/
|
||||
useMaxWidth: true,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| rightAngles | Curved Arrows become Right Angles, | 3 | 4 | True, False |
|
||||
*
|
||||
***Notes:**This will display arrows that start and begin at the same node as right angles, rather than a curves
|
||||
***Default value false**.
|
||||
*/
|
||||
rightAngles: false
|
||||
},
|
||||
class: {
|
||||
arrowMarkerAbsolute: false
|
||||
},
|
||||
git: {
|
||||
arrowMarkerAbsolute: false
|
||||
},
|
||||
state: {
|
||||
dividerMargin: 10,
|
||||
sizeUnit: 5,
|
||||
padding: 8,
|
||||
textHeight: 10,
|
||||
titleShift: -15,
|
||||
noteMargin: 10,
|
||||
forkWidth: 70,
|
||||
forkHeight: 7,
|
||||
// Used
|
||||
miniPadding: 2,
|
||||
// Font size factor, this is used to guess the width of the edges labels before rendering by dagre
|
||||
// layout. This might need updating if/when switching font
|
||||
fontSizeFactor: 5.02,
|
||||
fontSize: 24,
|
||||
labelHeight: 16,
|
||||
edgeLengthFactor: '20',
|
||||
compositTitleSize: 35,
|
||||
radius: 5
|
||||
},
|
||||
|
||||
/**
|
||||
* The object containing configurations specific for entity relationship diagrams
|
||||
*/
|
||||
er: {
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| diagramPadding | amount of padding around the diagram as a whole | Integer | Required | Any Positive Value |
|
||||
*
|
||||
***Notes:**The amount of padding around the diagram as a whole so that embedded diagrams have margins, expressed in pixels
|
||||
***Default value: 20**.
|
||||
*/
|
||||
diagramPadding: 20,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| layoutDirection | Directional bias for layout of entities. | String | Required | "TB", "BT","LR","RL" |
|
||||
*
|
||||
***Notes:**
|
||||
*'TB' for Top-Bottom, 'BT'for Bottom-Top, 'LR' for Left-Right, or 'RL' for Right to Left.
|
||||
* T = top, B = bottom, L = left, and R = right.
|
||||
***Default value: TB **.
|
||||
*/
|
||||
layoutDirection: 'TB',
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| minEntityWidth | The mimimum width of an entity box, | Integer | Required| Any Positive Value |
|
||||
*
|
||||
***Notes:**expressed in pixels
|
||||
***Default value: 100**.
|
||||
*/
|
||||
minEntityWidth: 100,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| minEntityHeight| The minimum height of an entity box, | Integer | 4 | Any Positive Value |
|
||||
*
|
||||
***Notes:**expressed in pixels
|
||||
***Default value: 75 **
|
||||
*/
|
||||
minEntityHeight: 75,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| entityPadding|minimum internal padding betweentext in box and box borders| Integer | 4 | Any Positive Value |
|
||||
*
|
||||
***Notes:**The minimum internal padding betweentext in an entity box and the enclosing box borders, expressed in pixels.
|
||||
***Default value: 15 **
|
||||
*/
|
||||
entityPadding: 15,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| stroke | Stroke color of box edges and lines | String | 4 | Any recognized color |
|
||||
***Default value: gray **
|
||||
*/
|
||||
stroke: 'gray',
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| fill | Fill color of entity boxes | String | 4 | Any recognized color |
|
||||
*
|
||||
***Notes:**
|
||||
***Default value:'honeydew'**
|
||||
*/
|
||||
fill: 'honeydew',
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| fontSize| Font Size in pixels| Integer | | Any Positive Value |
|
||||
*
|
||||
***Notes:**Font size (expressed as an integer representing a number of pixels)
|
||||
***Default value: 12 **
|
||||
*/
|
||||
fontSize: 12,
|
||||
|
||||
/**
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| useMaxWidth | See Notes | Boolean | Required | true, false |
|
||||
*
|
||||
***Notes:**
|
||||
*When this flag is set to true, the diagram width is locked to 100% and
|
||||
*scaled based on available space. If set to false, the diagram reserves its
|
||||
*absolute width.
|
||||
***Default value: true**.
|
||||
*/
|
||||
useMaxWidth: true
|
||||
}
|
||||
};
|
||||
|
||||
export const setConfig = conf => {
|
||||
setConf(conf);
|
||||
};
|
||||
export const getConfig = () => config;
|
||||
// debugger;
|
||||
config.class.arrowMarkerAbsolute = config.arrowMarkerAbsolute;
|
||||
config.git.arrowMarkerAbsolute = config.arrowMarkerAbsolute;
|
||||
export const defaultConfig = Object.freeze(config);
|
||||
|
||||
const configApi = {
|
||||
setConfig,
|
||||
getConfig
|
||||
// get conf() {
|
||||
// return config;
|
||||
// }
|
||||
const siteConfig = assignWithDepth({}, defaultConfig);
|
||||
const currentConfig = assignWithDepth({}, defaultConfig);
|
||||
|
||||
/**
|
||||
*## setSiteConfig
|
||||
*| Function | Description | Type | Values |
|
||||
*| --------- | ------------------- | ------- | ------------------ |
|
||||
*| setSiteConfig|Sets the siteConfig to desired values | Put Request | Any Values, except ones in secure array|
|
||||
***Notes:**
|
||||
*Sets the siteConfig. The siteConfig is a protected configuration for repeat use. Calls to reset() will reset
|
||||
*the currentConfig to siteConfig. Calls to reset(configApi.defaultConfig) will reset siteConfig and currentConfig
|
||||
*to the defaultConfig
|
||||
*Note: currentConfig is set in this function
|
||||
**Default value: At default, will mirror Global Config**
|
||||
* @param conf - the base currentConfig to use as siteConfig
|
||||
* @returns {*} - the siteConfig
|
||||
*/
|
||||
export const setSiteConfig = conf => {
|
||||
assignWithDepth(currentConfig, conf, { clobber: true });
|
||||
// Set theme variables if user has set the theme option
|
||||
assignWithDepth(siteConfig, conf);
|
||||
|
||||
return getSiteConfig();
|
||||
};
|
||||
/**
|
||||
*## getSiteConfig
|
||||
*| Function | Description | Type | Values |
|
||||
*| --------- | ------------------- | ------- | ------------------ |
|
||||
*| setSiteConfig|Returns the current siteConfig base configuration | Get Request | Returns Any Values in siteConfig|
|
||||
***Notes**:
|
||||
*Returns **any** values in siteConfig.
|
||||
* @returns {*}
|
||||
*/
|
||||
export const getSiteConfig = () => {
|
||||
return assignWithDepth({}, siteConfig);
|
||||
};
|
||||
/**
|
||||
*## setConfig
|
||||
*| Function | Description | Type | Values |
|
||||
*| --------- | ------------------- | ------- | ------------------ |
|
||||
*| setSiteConfig|Sets the siteConfig to desired values | Put Request| Any Values, except ones in secure array|
|
||||
***Notes**:
|
||||
*Sets the currentConfig. The parameter conf is sanitized based on the siteConfig.secure keys. Any
|
||||
*values found in conf with key found in siteConfig.secure will be replaced with the corresponding
|
||||
*siteConfig value.
|
||||
* @param conf - the potential currentConfig
|
||||
* @returns {*} - the currentConfig merged with the sanitized conf
|
||||
*/
|
||||
export const setConfig = conf => {
|
||||
sanitize(conf);
|
||||
|
||||
assignWithDepth(currentConfig, conf);
|
||||
return getConfig();
|
||||
};
|
||||
/**
|
||||
* ## getConfig
|
||||
*| Function | Description | Type | Return Values |
|
||||
*| --------- | ------------------- | ------- | ------------------ |
|
||||
*| getConfig |Obtains the currentConfig | Get Request | Any Values from currentConfig|
|
||||
***Notes**:
|
||||
*Returns **any** the currentConfig
|
||||
* @returns {*} - the currentConfig
|
||||
*/
|
||||
export const getConfig = () => {
|
||||
return assignWithDepth({}, currentConfig);
|
||||
};
|
||||
/**
|
||||
*## sanitize
|
||||
*| Function | Description | Type | Values |
|
||||
*| --------- | ------------------- | ------- | ------------------ |
|
||||
*| sanitize |Sets the siteConfig to desired values. | Put Request |None|
|
||||
*Ensures options parameter does not attempt to override siteConfig secure keys
|
||||
*Note: modifies options in-place
|
||||
* @param options - the potential setConfig parameter
|
||||
*/
|
||||
export const sanitize = options => {
|
||||
Object.keys(siteConfig.secure).forEach(key => {
|
||||
if (typeof options[siteConfig.secure[key]] !== 'undefined') {
|
||||
// DO NOT attempt to print options[siteConfig.secure[key]] within `${}` as a malicious script
|
||||
// can exploit the logger's attempt to stringify the value and execute arbitrary code
|
||||
logger.warn(
|
||||
`Denied attempt to modify a secure key ${siteConfig.secure[key]}`,
|
||||
options[siteConfig.secure[key]]
|
||||
);
|
||||
delete options[siteConfig.secure[key]];
|
||||
}
|
||||
});
|
||||
};
|
||||
/**
|
||||
*## reset
|
||||
*| Function | Description | Type | Required | Values |
|
||||
*| --------- | ------------------- | ------- | -------- | ------------------ |
|
||||
*| reset|Resets currentConfig to conf| Put Request | Required | None|
|
||||
*
|
||||
*| Parameter | Description |Type | Required | Values|
|
||||
*| --- | --- | --- | --- | --- |
|
||||
*| conf| base set of values, which currentConfig coul be **reset** to.| Dictionary | Required | Any Values, with respect to the secure Array|
|
||||
*
|
||||
**Notes :
|
||||
(default: current siteConfig ) (optional, default `getSiteConfig()`)
|
||||
* @param conf - the base currentConfig to reset to (default: current siteConfig )
|
||||
*/
|
||||
export const reset = (conf = getSiteConfig()) => {
|
||||
Object.keys(siteConfig).forEach(key => delete siteConfig[key]);
|
||||
Object.keys(currentConfig).forEach(key => delete currentConfig[key]);
|
||||
assignWithDepth(siteConfig, conf, { clobber: true });
|
||||
assignWithDepth(currentConfig, conf, { clobber: true });
|
||||
};
|
||||
|
||||
const configApi = Object.freeze({
|
||||
sanitize,
|
||||
setSiteConfig,
|
||||
getSiteConfig,
|
||||
setConfig,
|
||||
getConfig,
|
||||
reset,
|
||||
defaultConfig
|
||||
});
|
||||
export default configApi;
|
||||
|
52
src/config.spec.js
Normal file
52
src/config.spec.js
Normal file
@ -0,0 +1,52 @@
|
||||
/* eslint-env jasmine */
|
||||
import configApi from './config';
|
||||
|
||||
describe('when working with site config', function() {
|
||||
beforeEach(() => {
|
||||
configApi.reset(configApi.defaultConfig);
|
||||
});
|
||||
it('should set site config and config properly', function() {
|
||||
let config_0 = { foo: 'bar', bar: 0 };
|
||||
configApi.setSiteConfig(config_0);
|
||||
let config_1 = configApi.getSiteConfig();
|
||||
let config_2 = configApi.getConfig();
|
||||
expect(config_1.foo).toEqual(config_0.foo);
|
||||
expect(config_1.bar).toEqual(config_0.bar);
|
||||
expect(config_1).toEqual(config_2);
|
||||
});
|
||||
it('should set config and respect secure keys', function() {
|
||||
let config_0 = { foo: 'bar', bar: 0, secure: [...configApi.defaultConfig.secure, 'bar'] };
|
||||
configApi.setSiteConfig(config_0);
|
||||
let config_1 = { foo: 'baf', bar: 'foo'};
|
||||
configApi.setConfig(config_1);
|
||||
let config_2 = configApi.getConfig();
|
||||
expect(config_2.foo).toEqual(config_1.foo);
|
||||
expect(config_2.bar).toEqual(0); // Should be siteConfig.bar
|
||||
});
|
||||
it('should set reset config properly', function() {
|
||||
let config_0 = { foo: 'bar', bar: 0};
|
||||
configApi.setSiteConfig(config_0);
|
||||
let config_1 = { foo: 'baf'};
|
||||
configApi.setConfig(config_1);
|
||||
let config_2 = configApi.getConfig();
|
||||
expect(config_2.foo).toEqual(config_1.foo);
|
||||
configApi.reset();
|
||||
let config_3 = configApi.getConfig();
|
||||
expect(config_3.foo).toEqual(config_0.foo);
|
||||
let config_4 = configApi.getSiteConfig();
|
||||
expect(config_4.foo).toEqual(config_0.foo);
|
||||
});
|
||||
it('should set global reset config properly', function() {
|
||||
let config_0 = { foo: 'bar', bar: 0};
|
||||
configApi.setSiteConfig(config_0);
|
||||
let config_1 = configApi.getSiteConfig();
|
||||
expect(config_1.foo).toEqual(config_0.foo);
|
||||
let config_2 = configApi.getConfig();
|
||||
expect(config_2.foo).toEqual(config_0.foo);
|
||||
configApi.reset(configApi.defaultConfig);
|
||||
let config_3 = configApi.getSiteConfig();
|
||||
expect(config_3.foo).toBeUndefined();
|
||||
let config_4 = configApi.getConfig();
|
||||
expect(config_4.foo).toBeUndefined();
|
||||
});
|
||||
});
|
@ -107,7 +107,7 @@ export const intersection = (node, outsidePoint, insidePoint) => {
|
||||
outsidePoint.y === edges.y1 ||
|
||||
outsidePoint.y === edges.y2
|
||||
) {
|
||||
// logger.warn('calc equals on edge');
|
||||
logger.warn('calc equals on edge');
|
||||
return outsidePoint;
|
||||
}
|
||||
|
||||
@ -181,9 +181,18 @@ export const insertEdge = function(elem, e, edge, clusterDb, diagramType, graph)
|
||||
logger.trace('inside', edge.toCluster, point, lastPointOutside);
|
||||
|
||||
// First point inside the rect
|
||||
const insterection = intersection(node, lastPointOutside, point);
|
||||
logger.trace('intersect', insterection);
|
||||
points.push(insterection);
|
||||
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 {
|
||||
logger.warn('no intersect', inter, points);
|
||||
}
|
||||
isInside = true;
|
||||
} else {
|
||||
if (!isInside) points.push(point);
|
||||
|
@ -16,10 +16,15 @@ function intersectPolygon(node, polyPoints, point) {
|
||||
|
||||
var minX = Number.POSITIVE_INFINITY;
|
||||
var minY = Number.POSITIVE_INFINITY;
|
||||
polyPoints.forEach(function(entry) {
|
||||
minX = Math.min(minX, entry.x);
|
||||
minY = Math.min(minY, entry.y);
|
||||
});
|
||||
if (typeof polyPoints.forEach === 'function') {
|
||||
polyPoints.forEach(function(entry) {
|
||||
minX = Math.min(minX, entry.x);
|
||||
minY = Math.min(minY, entry.y);
|
||||
});
|
||||
} else {
|
||||
minX = Math.min(minX, polyPoints.x);
|
||||
minY = Math.min(minY, polyPoints.y);
|
||||
}
|
||||
|
||||
var left = x1 - node.width / 2 - minX;
|
||||
var top = y1 - node.height / 2 - minY;
|
||||
|
63
src/diagrams/class/styles.js
Normal file
63
src/diagrams/class/styles.js
Normal file
@ -0,0 +1,63 @@
|
||||
const getStyles = options =>
|
||||
`g.classGroup text {
|
||||
fill: ${options.nodeBorder};
|
||||
fill: ${options.classText};
|
||||
stroke: none;
|
||||
font-family: ${options.fontFamily};
|
||||
font-size: 10px;
|
||||
|
||||
.title {
|
||||
font-weight: bolder;
|
||||
}
|
||||
}
|
||||
|
||||
g.clickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
g.classGroup rect {
|
||||
fill: ${options.nodeBkg};
|
||||
stroke: ${options.nodeBorder};
|
||||
}
|
||||
|
||||
g.classGroup line {
|
||||
stroke: ${options.nodeBorder};
|
||||
stroke-width: 1;
|
||||
}
|
||||
|
||||
.classLabel .box {
|
||||
stroke: none;
|
||||
stroke-width: 0;
|
||||
fill: ${options.nodeBkg};
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.classLabel .label {
|
||||
fill: ${options.nodeBorder};
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.relation {
|
||||
stroke: ${options.lineColor};
|
||||
stroke-width: 1;
|
||||
fill: none;
|
||||
}
|
||||
|
||||
.dashed-line{
|
||||
stroke-dasharray: 3;
|
||||
}
|
||||
|
||||
#compositionStart, #compositionEnd, #dependencyStart, #dependencyEnd, #extensionStart, #extensionEnd {
|
||||
fill: ${options.lineColor};
|
||||
stroke: ${options.lineColor};
|
||||
stroke-width: 1;
|
||||
}
|
||||
|
||||
#aggregationStart, #aggregationEnd {
|
||||
fill: ${options.nodeBkg};
|
||||
stroke: ${options.lineColor};
|
||||
stroke-width: 1;
|
||||
}
|
||||
`;
|
||||
|
||||
export default getStyles;
|
@ -5,6 +5,30 @@ export const getRows = s => {
|
||||
return str.split('#br#');
|
||||
};
|
||||
|
||||
export const removeScript = txt => {
|
||||
var rs = '';
|
||||
var idx = 0;
|
||||
|
||||
while (idx >= 0) {
|
||||
idx = txt.indexOf('<script');
|
||||
if (idx >= 0) {
|
||||
rs += txt.substr(0, idx);
|
||||
txt = txt.substr(idx + 1);
|
||||
|
||||
idx = txt.indexOf('</script>');
|
||||
if (idx >= 0) {
|
||||
idx += 9;
|
||||
txt = txt.substr(idx);
|
||||
}
|
||||
} else {
|
||||
rs += txt;
|
||||
idx = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rs;
|
||||
};
|
||||
|
||||
export const sanitizeText = (text, config) => {
|
||||
let txt = text;
|
||||
let htmlLabels = true;
|
||||
@ -14,12 +38,18 @@ export const sanitizeText = (text, config) => {
|
||||
)
|
||||
htmlLabels = false;
|
||||
|
||||
if (config.securityLevel !== 'loose' && htmlLabels) {
|
||||
// eslint-disable-line
|
||||
txt = breakToPlaceholder(txt);
|
||||
txt = txt.replace(/</g, '<').replace(/>/g, '>');
|
||||
txt = txt.replace(/=/g, '=');
|
||||
txt = placeholderToBreak(txt);
|
||||
if (htmlLabels) {
|
||||
var level = config.securityLevel;
|
||||
|
||||
if (level == 'antiscript') {
|
||||
txt = removeScript(txt);
|
||||
} else if (level !== 'loose') {
|
||||
// eslint-disable-line
|
||||
txt = breakToPlaceholder(txt);
|
||||
txt = txt.replace(/</g, '<').replace(/>/g, '>');
|
||||
txt = txt.replace(/=/g, '=');
|
||||
txt = placeholderToBreak(txt);
|
||||
}
|
||||
}
|
||||
|
||||
return txt;
|
||||
@ -27,6 +57,14 @@ export const sanitizeText = (text, config) => {
|
||||
|
||||
export const lineBreakRegex = /<br\s*\/?>/gi;
|
||||
|
||||
export const hasBreaks = text => {
|
||||
return /<br\s*[/]?>/gi.test(text);
|
||||
};
|
||||
|
||||
export const splitBreaks = text => {
|
||||
return text.split(/<br\s*[/]?>/gi);
|
||||
};
|
||||
|
||||
const breakToPlaceholder = s => {
|
||||
return s.replace(lineBreakRegex, '#br#');
|
||||
};
|
||||
@ -38,5 +76,8 @@ const placeholderToBreak = s => {
|
||||
export default {
|
||||
getRows,
|
||||
sanitizeText,
|
||||
lineBreakRegex
|
||||
hasBreaks,
|
||||
splitBreaks,
|
||||
lineBreakRegex,
|
||||
removeScript
|
||||
};
|
||||
|
26
src/diagrams/common/common.spec.js
Normal file
26
src/diagrams/common/common.spec.js
Normal file
@ -0,0 +1,26 @@
|
||||
import { removeScript } from './common';
|
||||
|
||||
describe('when securityLevel is antiscript, all script must be removed', function() {
|
||||
it('should remove all script block, script inline.', function() {
|
||||
const labelString = `1
|
||||
Act1: Hello 1<script src="http://abc.com/script1.js"></script>1
|
||||
<b>Act2</b>:
|
||||
1<script>
|
||||
alert('script run......');
|
||||
</script>1
|
||||
1`;
|
||||
|
||||
const result = removeScript(labelString);
|
||||
const hasScript = (result.indexOf("script") >= 0);
|
||||
expect(hasScript).toEqual(false);
|
||||
|
||||
const exactlyString = `1
|
||||
Act1: Hello 11
|
||||
<b>Act2</b>:
|
||||
11
|
||||
1`;
|
||||
|
||||
const isEqual = (result == exactlyString);
|
||||
expect(isEqual).toEqual(true);
|
||||
});
|
||||
});
|
@ -43,6 +43,7 @@ const drawEntities = function(svgNode, entities, graph) {
|
||||
const textId = 'entity-' + id;
|
||||
const textNode = groupNode
|
||||
.append('text')
|
||||
.attr('class', 'er entityLabel')
|
||||
.attr('id', textId)
|
||||
.attr('x', 0)
|
||||
.attr('y', 0)
|
||||
@ -65,6 +66,7 @@ const drawEntities = function(svgNode, entities, graph) {
|
||||
// Draw the rectangle - insert it before the text so that the text is not obscured
|
||||
const rectNode = groupNode
|
||||
.insert('rect', '#' + textId)
|
||||
.attr('class', 'er entityBox')
|
||||
.attr('fill', conf.fill)
|
||||
.attr('fill-opacity', '100%')
|
||||
.attr('stroke', conf.stroke)
|
||||
@ -148,6 +150,7 @@ const drawRelationshipFromLayout = function(svg, rel, g, insert) {
|
||||
// Insert the line at the right place
|
||||
const svgPath = svg
|
||||
.insert('path', '#' + insert)
|
||||
.attr('class', 'er relationshipLine')
|
||||
.attr('d', lineFunction(edge.points))
|
||||
.attr('stroke', conf.stroke)
|
||||
.attr('fill', 'none');
|
||||
@ -224,6 +227,7 @@ const drawRelationshipFromLayout = function(svg, rel, g, insert) {
|
||||
|
||||
const labelNode = svg
|
||||
.append('text')
|
||||
.attr('class', 'er relationshipLabel')
|
||||
.attr('id', labelId)
|
||||
.attr('x', labelPoint.x)
|
||||
.attr('y', labelPoint.y)
|
||||
@ -241,6 +245,7 @@ const drawRelationshipFromLayout = function(svg, rel, g, insert) {
|
||||
// Insert the opaque rectangle before the text label
|
||||
svg
|
||||
.insert('rect', '#' + labelId)
|
||||
.attr('class', 'er relationshipLabelBox')
|
||||
.attr('x', labelPoint.x - labelBBox.width / 2)
|
||||
.attr('y', labelPoint.y - labelBBox.height / 2)
|
||||
.attr('width', labelBBox.width)
|
||||
@ -339,9 +344,14 @@ export const draw = function(text, id) {
|
||||
const width = svgBounds.width + padding * 2;
|
||||
const height = svgBounds.height + padding * 2;
|
||||
|
||||
svg.attr('height', height);
|
||||
svg.attr('width', '100%');
|
||||
svg.attr('style', `max-width: ${width}px;`);
|
||||
if (conf.useMaxWidth) {
|
||||
svg.attr('width', '100%');
|
||||
svg.attr('style', `max-width: ${width}px;`);
|
||||
} else {
|
||||
svg.attr('height', height);
|
||||
svg.attr('width', width);
|
||||
}
|
||||
|
||||
svg.attr('viewBox', `${svgBounds.x - padding} ${svgBounds.y - padding} ${width} ${height}`);
|
||||
}; // draw
|
||||
|
||||
|
22
src/diagrams/er/styles.js
Normal file
22
src/diagrams/er/styles.js
Normal file
@ -0,0 +1,22 @@
|
||||
const getStyles = options =>
|
||||
`
|
||||
.entityBox {
|
||||
fill: ${options.mainBkg};
|
||||
stroke: ${options.nodeBorder};
|
||||
}
|
||||
|
||||
.relationshipLabelBox {
|
||||
fill: ${options.edgeLabelBackground};
|
||||
fillopactity: 0;
|
||||
background-color: ${options.edgeLabelBackground};
|
||||
rect {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
.relationshipLine {
|
||||
stroke: ${options.lineColor};
|
||||
}
|
||||
`;
|
||||
|
||||
export default getStyles;
|
@ -219,7 +219,7 @@ const setTooltip = function(ids, tooltip) {
|
||||
const setClickFun = function(_id, functionName) {
|
||||
let id = _id;
|
||||
if (_id[0].match(/\d/)) id = MERMAID_DOM_ID_PREFIX + id;
|
||||
if (config.securityLevel !== 'loose') {
|
||||
if (getConfig().securityLevel !== 'loose') {
|
||||
return;
|
||||
}
|
||||
if (typeof functionName === 'undefined') {
|
||||
|
@ -407,7 +407,7 @@ export const draw = function(text, id) {
|
||||
return flowDb.getTooltip(this.id);
|
||||
});
|
||||
|
||||
const padding = 8;
|
||||
const padding = conf.diagramPadding;
|
||||
const svgBounds = svg.node().getBBox();
|
||||
const width = svgBounds.width + padding * 2;
|
||||
const height = svgBounds.height + padding * 2;
|
||||
|
@ -394,7 +394,7 @@ export const draw = function(text, id) {
|
||||
return flowDb.getTooltip(this.id);
|
||||
});
|
||||
|
||||
const padding = 8;
|
||||
const padding = conf.diagramPadding;
|
||||
const svgBounds = svg.node().getBBox();
|
||||
const width = svgBounds.width + padding * 2;
|
||||
const height = svgBounds.height + padding * 2;
|
||||
|
75
src/diagrams/flowchart/styles.js
Normal file
75
src/diagrams/flowchart/styles.js
Normal file
@ -0,0 +1,75 @@
|
||||
const getStyles = options =>
|
||||
`.label {
|
||||
font-family: ${options.fontFamily};
|
||||
color: ${options.textColor};
|
||||
}
|
||||
|
||||
.label text {
|
||||
fill: ${options.textColor};
|
||||
}
|
||||
|
||||
.node rect,
|
||||
.node circle,
|
||||
.node ellipse,
|
||||
.node polygon,
|
||||
.node path {
|
||||
fill: ${options.mainBkg};
|
||||
stroke: ${options.nodeBorder};
|
||||
stroke-width: 1px;
|
||||
}
|
||||
|
||||
.node .label {
|
||||
text-align: center;
|
||||
}
|
||||
.node.clickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.arrowheadPath {
|
||||
fill: ${options.arrowheadColor};
|
||||
}
|
||||
|
||||
.edgePath .path {
|
||||
stroke: ${options.lineColor};
|
||||
stroke-width: 1.5px;
|
||||
}
|
||||
|
||||
.flowchart-link {
|
||||
stroke: ${options.lineColor};
|
||||
fill: none;
|
||||
}
|
||||
|
||||
.edgeLabel {
|
||||
background-color: ${options.edgeLabelBackground};
|
||||
rect {
|
||||
opacity: 0.5;
|
||||
}
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.cluster rect {
|
||||
fill: ${options.secondBkg};
|
||||
stroke: ${options.clusterBorder};
|
||||
stroke-width: 1px;
|
||||
}
|
||||
|
||||
.cluster text {
|
||||
fill: ${options.titleColor};
|
||||
}
|
||||
|
||||
div.mermaidTooltip {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
max-width: 200px;
|
||||
padding: 2px;
|
||||
font-family: ${options.fontFamily};
|
||||
font-size: 12px;
|
||||
background: ${options.secondBkg};
|
||||
border: 1px solid ${options.border2};
|
||||
border-radius: 2px;
|
||||
pointer-events: none;
|
||||
z-index: 100;
|
||||
}
|
||||
`;
|
||||
|
||||
export default getStyles;
|
@ -4,7 +4,6 @@ import { logger } from '../../logger';
|
||||
import { getConfig } from '../../config';
|
||||
import utils from '../../utils';
|
||||
|
||||
const config = getConfig();
|
||||
let dateFormat = '';
|
||||
let axisFormat = '';
|
||||
let todayMarker = '';
|
||||
@ -17,6 +16,9 @@ const tags = ['active', 'done', 'crit', 'milestone'];
|
||||
let funs = [];
|
||||
let inclusiveEndDates = false;
|
||||
|
||||
// The serial order of the task in the script
|
||||
let lastOrder = 0;
|
||||
|
||||
export const clear = function() {
|
||||
sections = [];
|
||||
tasks = [];
|
||||
@ -32,6 +34,7 @@ export const clear = function() {
|
||||
todayMarker = '';
|
||||
excludes = [];
|
||||
inclusiveEndDates = false;
|
||||
lastOrder = 0;
|
||||
};
|
||||
|
||||
export const setAxisFormat = function(txt) {
|
||||
@ -374,6 +377,9 @@ export const addTask = function(descr, data) {
|
||||
rawTask.done = taskInfo.done;
|
||||
rawTask.crit = taskInfo.crit;
|
||||
rawTask.milestone = taskInfo.milestone;
|
||||
rawTask.order = lastOrder;
|
||||
|
||||
lastOrder++;
|
||||
|
||||
const pos = rawTasks.push(rawTask);
|
||||
|
||||
@ -462,7 +468,7 @@ const compileTasks = function() {
|
||||
*/
|
||||
export const setLink = function(ids, _linkStr) {
|
||||
let linkStr = _linkStr;
|
||||
if (config.securityLevel !== 'loose') {
|
||||
if (getConfig().securityLevel !== 'loose') {
|
||||
linkStr = sanitizeUrl(_linkStr);
|
||||
}
|
||||
ids.split(',').forEach(function(id) {
|
||||
@ -491,7 +497,7 @@ export const setClass = function(ids, className) {
|
||||
};
|
||||
|
||||
const setClickFun = function(id, functionName, functionArgs) {
|
||||
if (config.securityLevel !== 'loose') {
|
||||
if (getConfig().securityLevel !== 'loose') {
|
||||
return;
|
||||
}
|
||||
if (typeof functionName === 'undefined') {
|
||||
|
@ -176,6 +176,137 @@ describe('when using the ganttDb', function() {
|
||||
expect(tasks[6].task).toEqual('test7');
|
||||
});
|
||||
|
||||
it('should maintain the order in which tasks are created', function() {
|
||||
ganttDb.setTitle('Project Execution');
|
||||
ganttDb.setDateFormat('YYYY-MM-DD');
|
||||
ganttDb.addSection('section A section');
|
||||
ganttDb.addTask('Completed task', 'done, des1, 2014-01-06,2014-01-08');
|
||||
ganttDb.addTask('Active task', 'active, des2, 2014-01-09, 3d');
|
||||
ganttDb.addTask('Future task', 'des3, after des2, 5d');
|
||||
ganttDb.addTask('Future task2', 'des4, after des3, 5d');
|
||||
|
||||
ganttDb.addSection('section Critical tasks');
|
||||
ganttDb.addTask('Completed task in the critical line', 'crit, done, 2014-01-06,24h');
|
||||
ganttDb.addTask('Implement parser and jison', 'crit, done, after des1, 2d');
|
||||
ganttDb.addTask('Create tests for parser', 'crit, active, 3d');
|
||||
ganttDb.addTask('Future task in critical line', 'crit, 5d');
|
||||
ganttDb.addTask('Create tests for renderer', '2d');
|
||||
ganttDb.addTask('Add to mermaid', '1d');
|
||||
|
||||
ganttDb.addSection('section Documentation');
|
||||
ganttDb.addTask('Describe gantt syntax', 'active, a1, after des1, 3d');
|
||||
ganttDb.addTask('Add gantt diagram to demo page', 'after a1 , 20h');
|
||||
ganttDb.addTask('Add another diagram to demo page', 'doc1, after a1 , 48h');
|
||||
|
||||
ganttDb.addSection('section Last section');
|
||||
ganttDb.addTask('Describe gantt syntax', 'after doc1, 3d');
|
||||
ganttDb.addTask('Add gantt diagram to demo page', '20h');
|
||||
ganttDb.addTask('Add another diagram to demo page', '48h');
|
||||
|
||||
const tasks = ganttDb.getTasks();
|
||||
|
||||
// Section - A section
|
||||
expect(tasks[0].startTime).toEqual(moment('2014-01-06', 'YYYY-MM-DD').toDate());
|
||||
expect(tasks[0].endTime).toEqual(moment('2014-01-08', 'YYYY-MM-DD').toDate());
|
||||
expect(tasks[0].order).toEqual(0);
|
||||
expect(tasks[0].id).toEqual('des1');
|
||||
expect(tasks[0].task).toEqual('Completed task');
|
||||
|
||||
expect(tasks[1].startTime).toEqual(moment('2014-01-09', 'YYYY-MM-DD').toDate());
|
||||
expect(tasks[1].endTime).toEqual(moment('2014-01-12', 'YYYY-MM-DD').toDate());
|
||||
expect(tasks[1].order).toEqual(1);
|
||||
expect(tasks[1].id).toEqual('des2');
|
||||
expect(tasks[1].task).toEqual('Active task');
|
||||
|
||||
expect(tasks[2].startTime).toEqual(moment('2014-01-12', 'YYYY-MM-DD').toDate());
|
||||
expect(tasks[2].endTime).toEqual(moment('2014-01-17', 'YYYY-MM-DD').toDate());
|
||||
expect(tasks[2].order).toEqual(2);
|
||||
expect(tasks[2].id).toEqual('des3');
|
||||
expect(tasks[2].task).toEqual('Future task');
|
||||
|
||||
expect(tasks[3].startTime).toEqual(moment('2014-01-17', 'YYYY-MM-DD').toDate());
|
||||
expect(tasks[3].endTime).toEqual(moment('2014-01-22', 'YYYY-MM-DD').toDate());
|
||||
expect(tasks[3].order).toEqual(3);
|
||||
expect(tasks[3].id).toEqual('des4');
|
||||
expect(tasks[3].task).toEqual('Future task2');
|
||||
|
||||
// Section - Critical tasks
|
||||
expect(tasks[4].startTime).toEqual(moment('2014-01-06', 'YYYY-MM-DD').toDate());
|
||||
expect(tasks[4].endTime).toEqual(moment('2014-01-07', 'YYYY-MM-DD').toDate());
|
||||
expect(tasks[4].order).toEqual(4);
|
||||
expect(tasks[4].id).toEqual('task1');
|
||||
expect(tasks[4].task).toEqual('Completed task in the critical line');
|
||||
|
||||
expect(tasks[5].startTime).toEqual(moment('2014-01-08', 'YYYY-MM-DD').toDate());
|
||||
expect(tasks[5].endTime).toEqual(moment('2014-01-10', 'YYYY-MM-DD').toDate());
|
||||
expect(tasks[5].order).toEqual(5);
|
||||
expect(tasks[5].id).toEqual('task2');
|
||||
expect(tasks[5].task).toEqual('Implement parser and jison');
|
||||
|
||||
expect(tasks[6].startTime).toEqual(moment('2014-01-10', 'YYYY-MM-DD').toDate());
|
||||
expect(tasks[6].endTime).toEqual(moment('2014-01-13', 'YYYY-MM-DD').toDate());
|
||||
expect(tasks[6].order).toEqual(6);
|
||||
expect(tasks[6].id).toEqual('task3');
|
||||
expect(tasks[6].task).toEqual('Create tests for parser');
|
||||
|
||||
expect(tasks[7].startTime).toEqual(moment('2014-01-13', 'YYYY-MM-DD').toDate());
|
||||
expect(tasks[7].endTime).toEqual(moment('2014-01-18', 'YYYY-MM-DD').toDate());
|
||||
expect(tasks[7].order).toEqual(7);
|
||||
expect(tasks[7].id).toEqual('task4');
|
||||
expect(tasks[7].task).toEqual('Future task in critical line');
|
||||
|
||||
expect(tasks[8].startTime).toEqual(moment('2014-01-18', 'YYYY-MM-DD').toDate());
|
||||
expect(tasks[8].endTime).toEqual(moment('2014-01-20', 'YYYY-MM-DD').toDate());
|
||||
expect(tasks[8].order).toEqual(8);
|
||||
expect(tasks[8].id).toEqual('task5');
|
||||
expect(tasks[8].task).toEqual('Create tests for renderer');
|
||||
|
||||
expect(tasks[9].startTime).toEqual(moment('2014-01-20', 'YYYY-MM-DD').toDate());
|
||||
expect(tasks[9].endTime).toEqual(moment('2014-01-21', 'YYYY-MM-DD').toDate());
|
||||
expect(tasks[9].order).toEqual(9);
|
||||
expect(tasks[9].id).toEqual('task6');
|
||||
expect(tasks[9].task).toEqual('Add to mermaid');
|
||||
|
||||
// Section - Documentation
|
||||
expect(tasks[10].startTime).toEqual(moment('2014-01-08', 'YYYY-MM-DD').toDate());
|
||||
expect(tasks[10].endTime).toEqual(moment('2014-01-11', 'YYYY-MM-DD').toDate());
|
||||
expect(tasks[10].order).toEqual(10);
|
||||
expect(tasks[10].id).toEqual('a1');
|
||||
expect(tasks[10].task).toEqual('Describe gantt syntax');
|
||||
|
||||
expect(tasks[11].startTime).toEqual(moment('2014-01-11', 'YYYY-MM-DD').toDate());
|
||||
expect(tasks[11].endTime).toEqual(moment('2014-01-11 20:00:00', 'YYYY-MM-DD HH:mm:ss').toDate());
|
||||
expect(tasks[11].order).toEqual(11);
|
||||
expect(tasks[11].id).toEqual('task7');
|
||||
expect(tasks[11].task).toEqual('Add gantt diagram to demo page');
|
||||
|
||||
expect(tasks[12].startTime).toEqual(moment('2014-01-11', 'YYYY-MM-DD').toDate());
|
||||
expect(tasks[12].endTime).toEqual(moment('2014-01-13', 'YYYY-MM-DD').toDate());
|
||||
expect(tasks[12].order).toEqual(12);
|
||||
expect(tasks[12].id).toEqual('doc1');
|
||||
expect(tasks[12].task).toEqual('Add another diagram to demo page');
|
||||
|
||||
// Section - Last section
|
||||
expect(tasks[13].startTime).toEqual(moment('2014-01-13', 'YYYY-MM-DD').toDate());
|
||||
expect(tasks[13].endTime).toEqual(moment('2014-01-16', 'YYYY-MM-DD').toDate());
|
||||
expect(tasks[13].order).toEqual(13);
|
||||
expect(tasks[13].id).toEqual('task8');
|
||||
expect(tasks[13].task).toEqual('Describe gantt syntax');
|
||||
|
||||
expect(tasks[14].startTime).toEqual(moment('2014-01-16', 'YYYY-MM-DD').toDate());
|
||||
expect(tasks[14].endTime).toEqual(moment('2014-01-16 20:00:00', 'YYYY-MM-DD HH:mm:ss').toDate());
|
||||
expect(tasks[14].order).toEqual(14);
|
||||
expect(tasks[14].id).toEqual('task9');
|
||||
expect(tasks[14].task).toEqual('Add gantt diagram to demo page');
|
||||
|
||||
expect(tasks[15].startTime).toEqual(moment('2014-01-16 20:00:00', 'YYYY-MM-DD HH:mm:ss').toDate());
|
||||
expect(tasks[15].endTime).toEqual(moment('2014-01-18 20:00:00', 'YYYY-MM-DD HH:mm:ss').toDate());
|
||||
expect(tasks[15].order).toEqual(15);
|
||||
expect(tasks[15].id).toEqual('task10');
|
||||
expect(tasks[15].task).toEqual('Add another diagram to demo page');
|
||||
});
|
||||
|
||||
|
||||
it('should work when end date is the 31st', function() {
|
||||
ganttDb.setDateFormat('YYYY-MM-DD');
|
||||
ganttDb.addSection('Task endTime is on the 31st day of the month');
|
||||
|
@ -80,6 +80,22 @@ export const draw = function(text, id) {
|
||||
|
||||
categories = checkUnique(categories);
|
||||
|
||||
function taskCompare(a, b) {
|
||||
const taskA = a.startTime;
|
||||
const taskB = b.startTime;
|
||||
let result = 0;
|
||||
if (taskA > taskB) {
|
||||
result = 1;
|
||||
} else if (taskA < taskB) {
|
||||
result = -1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Sort the task array using the above taskCompare() so that
|
||||
// tasks are created based on their order of startTime
|
||||
taskArray.sort(taskCompare);
|
||||
|
||||
makeGant(taskArray, w, h);
|
||||
if (typeof conf.useWidth !== 'undefined') {
|
||||
elem.setAttribute('width', w);
|
||||
@ -119,6 +135,8 @@ export const draw = function(text, id) {
|
||||
.append('rect')
|
||||
.attr('x', 0)
|
||||
.attr('y', function(d, i) {
|
||||
// Ignore the incoming i value and use our order instead
|
||||
i = d.order;
|
||||
return i * theGap + theTopPad - 2;
|
||||
})
|
||||
.attr('width', function() {
|
||||
@ -160,6 +178,8 @@ export const draw = function(text, id) {
|
||||
return timeScale(d.startTime) + theSidePad;
|
||||
})
|
||||
.attr('y', function(d, i) {
|
||||
// Ignore the incoming i value and use our order instead
|
||||
i = d.order;
|
||||
return i * theGap + theTopPad;
|
||||
})
|
||||
.attr('width', function(d) {
|
||||
@ -263,6 +283,8 @@ export const draw = function(text, id) {
|
||||
}
|
||||
})
|
||||
.attr('y', function(d, i) {
|
||||
// Ignore the incoming i value and use our order instead
|
||||
i = d.order;
|
||||
return i * theGap + conf.barHeight / 2 + (conf.fontSize / 2 - 2) + theTopPad;
|
||||
})
|
||||
.attr('text-height', theBarHeight)
|
||||
@ -280,6 +302,7 @@ export const draw = function(text, id) {
|
||||
}
|
||||
|
||||
let secNum = 0;
|
||||
console.log(conf);
|
||||
for (let i = 0; i < categories.length; i++) {
|
||||
if (d.type === categories[i]) {
|
||||
secNum = i % conf.numberSectionStyles;
|
||||
|
261
src/diagrams/gantt/styles.js
Normal file
261
src/diagrams/gantt/styles.js
Normal file
@ -0,0 +1,261 @@
|
||||
const getStyles = options =>
|
||||
`
|
||||
.mermaid-main-font {
|
||||
font-family: "trebuchet ms", verdana, arial;
|
||||
font-family: var(--mermaid-font-family);
|
||||
}
|
||||
|
||||
.section {
|
||||
stroke: none;
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
.section0 {
|
||||
fill: ${options.sectionBkgColor};
|
||||
}
|
||||
|
||||
.section2 {
|
||||
fill: ${options.sectionBkgColor2};
|
||||
}
|
||||
|
||||
.section1,
|
||||
.section3 {
|
||||
fill: ${options.altSectionBkgColor};
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
.sectionTitle0 {
|
||||
fill: ${options.titleColor};
|
||||
}
|
||||
|
||||
.sectionTitle1 {
|
||||
fill: ${options.titleColor};
|
||||
}
|
||||
|
||||
.sectionTitle2 {
|
||||
fill: ${options.titleColor};
|
||||
}
|
||||
|
||||
.sectionTitle3 {
|
||||
fill: ${options.titleColor};
|
||||
}
|
||||
|
||||
.sectionTitle {
|
||||
text-anchor: start;
|
||||
font-size: 11px;
|
||||
text-height: 14px;
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
font-family: var(--mermaid-font-family);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Grid and axis */
|
||||
|
||||
.grid .tick {
|
||||
stroke: ${options.gridColor};
|
||||
opacity: 0.8;
|
||||
shape-rendering: crispEdges;
|
||||
text {
|
||||
font-family: ${options.fontFamily};
|
||||
fill: ${options.textColor};
|
||||
}
|
||||
}
|
||||
|
||||
.grid path {
|
||||
stroke-width: 0;
|
||||
}
|
||||
|
||||
|
||||
/* Today line */
|
||||
|
||||
.today {
|
||||
fill: none;
|
||||
stroke: ${options.todayLineColor};
|
||||
stroke-width: 2px;
|
||||
}
|
||||
|
||||
|
||||
/* Task styling */
|
||||
|
||||
/* Default task */
|
||||
|
||||
.task {
|
||||
stroke-width: 2;
|
||||
}
|
||||
|
||||
.taskText {
|
||||
text-anchor: middle;
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
font-family: var(--mermaid-font-family);
|
||||
}
|
||||
|
||||
.taskText:not([font-size]) {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.taskTextOutsideRight {
|
||||
fill: ${options.taskTextDarkColor};
|
||||
text-anchor: start;
|
||||
font-size: 11px;
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
font-family: var(--mermaid-font-family);
|
||||
|
||||
}
|
||||
|
||||
.taskTextOutsideLeft {
|
||||
fill: ${options.taskTextDarkColor};
|
||||
text-anchor: end;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
/* Special case clickable */
|
||||
.task.clickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
.taskText.clickable {
|
||||
cursor: pointer;
|
||||
fill: ${options.taskTextClickableColor} !important;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.taskTextOutsideLeft.clickable {
|
||||
cursor: pointer;
|
||||
fill: ${options.taskTextClickableColor} !important;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.taskTextOutsideRight.clickable {
|
||||
cursor: pointer;
|
||||
fill: ${options.taskTextClickableColor} !important;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Specific task settings for the sections*/
|
||||
|
||||
.taskText0,
|
||||
.taskText1,
|
||||
.taskText2,
|
||||
.taskText3 {
|
||||
fill: ${options.taskTextColor};
|
||||
}
|
||||
|
||||
.task0,
|
||||
.task1,
|
||||
.task2,
|
||||
.task3 {
|
||||
fill: ${options.taskBkgColor};
|
||||
stroke: ${options.taskBorderColor};
|
||||
}
|
||||
|
||||
.taskTextOutside0,
|
||||
.taskTextOutside2
|
||||
{
|
||||
fill: ${options.taskTextOutsideColor};
|
||||
}
|
||||
|
||||
.taskTextOutside1,
|
||||
.taskTextOutside3 {
|
||||
fill: ${options.taskTextOutsideColor};
|
||||
}
|
||||
|
||||
|
||||
/* Active task */
|
||||
|
||||
.active0,
|
||||
.active1,
|
||||
.active2,
|
||||
.active3 {
|
||||
fill: ${options.activeTaskBkgColor};
|
||||
stroke: ${options.activeTaskBorderColor};
|
||||
}
|
||||
|
||||
.activeText0,
|
||||
.activeText1,
|
||||
.activeText2,
|
||||
.activeText3 {
|
||||
fill: ${options.taskTextDarkColor} !important;
|
||||
}
|
||||
|
||||
|
||||
/* Completed task */
|
||||
|
||||
.done0,
|
||||
.done1,
|
||||
.done2,
|
||||
.done3 {
|
||||
stroke: ${options.doneTaskBorderColor};
|
||||
fill: ${options.doneTaskBkgColor};
|
||||
stroke-width: 2;
|
||||
}
|
||||
|
||||
.doneText0,
|
||||
.doneText1,
|
||||
.doneText2,
|
||||
.doneText3 {
|
||||
fill: ${options.taskTextDarkColor} !important;
|
||||
}
|
||||
|
||||
|
||||
/* Tasks on the critical line */
|
||||
|
||||
.crit0,
|
||||
.crit1,
|
||||
.crit2,
|
||||
.crit3 {
|
||||
stroke: ${options.critBorderColor};
|
||||
fill: ${options.critBkgColor};
|
||||
stroke-width: 2;
|
||||
}
|
||||
|
||||
.activeCrit0,
|
||||
.activeCrit1,
|
||||
.activeCrit2,
|
||||
.activeCrit3 {
|
||||
stroke: ${options.critBorderColor};
|
||||
fill: ${options.activeTaskBkgColor};
|
||||
stroke-width: 2;
|
||||
}
|
||||
|
||||
.doneCrit0,
|
||||
.doneCrit1,
|
||||
.doneCrit2,
|
||||
.doneCrit3 {
|
||||
stroke: ${options.critBorderColor};
|
||||
fill: ${options.doneTaskBkgColor};
|
||||
stroke-width: 2;
|
||||
cursor: pointer;
|
||||
shape-rendering: crispEdges;
|
||||
}
|
||||
|
||||
.milestone {
|
||||
transform: rotate(45deg) scale(0.8,0.8);
|
||||
}
|
||||
|
||||
.milestoneText {
|
||||
font-style: italic;
|
||||
}
|
||||
.doneCritText0,
|
||||
.doneCritText1,
|
||||
.doneCritText2,
|
||||
.doneCritText3 {
|
||||
fill: ${options.taskTextDarkColor} !important;
|
||||
}
|
||||
|
||||
.activeCritText0,
|
||||
.activeCritText1,
|
||||
.activeCritText2,
|
||||
.activeCritText3 {
|
||||
fill: ${options.taskTextDarkColor} !important;
|
||||
}
|
||||
|
||||
.titleText {
|
||||
text-anchor: middle;
|
||||
font-size: 18px;
|
||||
fill: ${options.taskTextDarkColor} ;
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
font-family: var(--mermaid-font-family);
|
||||
}
|
||||
`;
|
||||
|
||||
export default getStyles;
|
@ -1,5 +1,5 @@
|
||||
import { logger } from '../../logger';
|
||||
|
||||
import { random } from '../../utils';
|
||||
let commits = {};
|
||||
let head = null;
|
||||
let branches = { master: head };
|
||||
@ -7,18 +7,8 @@ let curBranch = 'master';
|
||||
let direction = 'LR';
|
||||
let seq = 0;
|
||||
|
||||
function makeid(length) {
|
||||
var result = '';
|
||||
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
var charactersLength = characters.length;
|
||||
for (var i = 0; i < length; i++) {
|
||||
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function getId() {
|
||||
return makeid(7);
|
||||
return random({ length: 7 });
|
||||
}
|
||||
|
||||
function isfastforwardable(currentCommit, otherCommit) {
|
||||
|
@ -1,10 +1,9 @@
|
||||
|
||||
/*
|
||||
* Parse following
|
||||
* gitGraph:
|
||||
* commit
|
||||
* commit
|
||||
* branch
|
||||
* branch
|
||||
*/
|
||||
%lex
|
||||
|
||||
@ -14,28 +13,28 @@
|
||||
|
||||
%%
|
||||
|
||||
(\r?\n)+ return 'NL';
|
||||
\s+ /* skip all whitespace */
|
||||
\#[^\n]* /* skip comments */
|
||||
\%%[^\n]* /* skip comments */
|
||||
"gitGraph" return 'GG';
|
||||
"commit" return 'COMMIT';
|
||||
"branch" return 'BRANCH';
|
||||
"merge" return 'MERGE';
|
||||
"reset" return 'RESET';
|
||||
"checkout" return 'CHECKOUT';
|
||||
"LR" return 'DIR';
|
||||
"BT" return 'DIR';
|
||||
":" return ':';
|
||||
"^" return 'CARET'
|
||||
"options"\r?\n this.begin("options");
|
||||
<options>"end"\r?\n this.popState();
|
||||
<options>[^\n]+\r?\n return 'OPT';
|
||||
["] this.begin("string");
|
||||
<string>["] this.popState();
|
||||
<string>[^"]* return 'STR';
|
||||
[a-zA-Z][a-zA-Z0-9_]+ return 'ID';
|
||||
<<EOF>> return 'EOF';
|
||||
(\r?\n)+ return 'NL';
|
||||
\s+ /* skip all whitespace */
|
||||
\#[^\n]* /* skip comments */
|
||||
\%%[^\n]* /* skip comments */
|
||||
"gitGraph" return 'GG';
|
||||
"commit" return 'COMMIT';
|
||||
"branch" return 'BRANCH';
|
||||
"merge" return 'MERGE';
|
||||
"reset" return 'RESET';
|
||||
"checkout" return 'CHECKOUT';
|
||||
"LR" return 'DIR';
|
||||
"BT" return 'DIR';
|
||||
":" return ':';
|
||||
"^" return 'CARET'
|
||||
"options"\r?\n this.begin("options");
|
||||
<options>"end"\r?\n this.popState();
|
||||
<options>[^\n]+\r?\n return 'OPT';
|
||||
["] this.begin("string");
|
||||
<string>["] this.popState();
|
||||
<string>[^"]* return 'STR';
|
||||
[a-zA-Z][-_\.a-zA-Z0-9]*[-_a-zA-Z0-9] return 'ID';
|
||||
<<EOF>> return 'EOF';
|
||||
|
||||
/lex
|
||||
|
||||
|
13
src/diagrams/git/styles.js
Normal file
13
src/diagrams/git/styles.js
Normal file
@ -0,0 +1,13 @@
|
||||
const getStyles = () =>
|
||||
`
|
||||
.commit-id,
|
||||
.commit-msg,
|
||||
.branch-label {
|
||||
fill: lightgrey;
|
||||
color: lightgrey;
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
font-family: var(--mermaid-font-family);
|
||||
}
|
||||
`;
|
||||
|
||||
export default getStyles;
|
3
src/diagrams/info/styles.js
Normal file
3
src/diagrams/info/styles.js
Normal file
@ -0,0 +1,3 @@
|
||||
const getStyles = () => ``;
|
||||
|
||||
export default getStyles;
|
20
src/diagrams/pie/styles.js
Normal file
20
src/diagrams/pie/styles.js
Normal file
@ -0,0 +1,20 @@
|
||||
const getStyles = options =>
|
||||
`.pieTitleText {
|
||||
text-anchor: middle;
|
||||
font-size: 25px;
|
||||
fill: ${options.taskTextDarkColor};
|
||||
font-family: ${options.fontFamily};
|
||||
}
|
||||
.slice {
|
||||
font-family: ${options.fontFamily};
|
||||
fill: ${options.textColor};
|
||||
// fill: white;
|
||||
}
|
||||
.legend text {
|
||||
fill: ${options.taskTextDarkColor};
|
||||
font-family: ${options.fontFamily};
|
||||
font-size: 17px;
|
||||
}
|
||||
`;
|
||||
|
||||
export default getStyles;
|
@ -230,7 +230,7 @@ argDirective
|
||||
;
|
||||
|
||||
closeDirective
|
||||
: close_directive { yy.parseDirective('}%%', 'close_directive'); }
|
||||
: close_directive { yy.parseDirective('}%%', 'close_directive', 'sequence'); }
|
||||
;
|
||||
|
||||
%%
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { logger } from '../../logger';
|
||||
import { getConfig, setConfig } from '../../config';
|
||||
import mermaidAPI from '../../mermaidAPI';
|
||||
import configApi from '../../config';
|
||||
import common from '../common/common';
|
||||
import { logger } from '../../logger';
|
||||
|
||||
let prevActor = undefined;
|
||||
let actors = {};
|
||||
@ -10,58 +11,9 @@ let title = '';
|
||||
let titleWrapped = false;
|
||||
let sequenceNumbersEnabled = false;
|
||||
let wrapEnabled = false;
|
||||
let configUpdated = false;
|
||||
let currentDirective = {};
|
||||
|
||||
export const parseDirective = function(statement, context) {
|
||||
try {
|
||||
if (statement !== undefined) {
|
||||
statement = statement.trim();
|
||||
switch (context) {
|
||||
case 'open_directive':
|
||||
currentDirective = {};
|
||||
break;
|
||||
case 'type_directive':
|
||||
currentDirective.type = statement.toLowerCase();
|
||||
break;
|
||||
case 'arg_directive':
|
||||
currentDirective.args = JSON.parse(statement);
|
||||
break;
|
||||
case 'close_directive':
|
||||
handleDirective(currentDirective);
|
||||
currentDirective = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error(
|
||||
`Error while rendering sequenceDiagram directive: ${statement} jison context: ${context}`
|
||||
);
|
||||
logger.error(error.message);
|
||||
}
|
||||
};
|
||||
|
||||
const handleDirective = function(directive) {
|
||||
logger.debug(`Directive type=${directive.type} with args:`, directive.args);
|
||||
switch (directive.type) {
|
||||
case 'init':
|
||||
case 'initialize':
|
||||
mermaidAPI.initialize(directive.args);
|
||||
break;
|
||||
case 'config':
|
||||
updateConfig(directive.args);
|
||||
break;
|
||||
case 'wrap':
|
||||
case 'nowrap':
|
||||
wrapEnabled = directive.type === 'wrap';
|
||||
break;
|
||||
default:
|
||||
logger.warn(
|
||||
`Unrecognized directive: source: '%%{${directive.type}: ${directive.args}}%%`,
|
||||
directive
|
||||
);
|
||||
break;
|
||||
}
|
||||
export const parseDirective = function(statement, context, type) {
|
||||
mermaidAPI.parseDirective(statement, context, type);
|
||||
};
|
||||
|
||||
export const addActor = function(id, name, description) {
|
||||
@ -77,7 +29,7 @@ export const addActor = function(id, name, description) {
|
||||
actors[id] = {
|
||||
name: name,
|
||||
description: description.text,
|
||||
wrap: (description.wrap === null && autoWrap()) || !!description.wrap,
|
||||
wrap: (description.wrap === undefined && autoWrap()) || !!description.wrap,
|
||||
prevActor: prevActor
|
||||
};
|
||||
if (prevActor && actors[prevActor]) {
|
||||
@ -111,28 +63,19 @@ export const addMessage = function(idFrom, idTo, message, answer) {
|
||||
from: idFrom,
|
||||
to: idTo,
|
||||
message: message.text,
|
||||
wrap: (message.wrap === null && autoWrap()) || !!message.wrap,
|
||||
wrap: (message.wrap === undefined && autoWrap()) || !!message.wrap,
|
||||
answer: answer
|
||||
});
|
||||
};
|
||||
|
||||
export const addSignal = function(idFrom, idTo, message = { text: null, wrap: null }, messageType) {
|
||||
logger.debug(
|
||||
'Adding message from=' +
|
||||
idFrom +
|
||||
' to=' +
|
||||
idTo +
|
||||
' message=' +
|
||||
message.text +
|
||||
' wrap=' +
|
||||
message.wrap +
|
||||
' type=' +
|
||||
messageType
|
||||
);
|
||||
|
||||
export const addSignal = function(
|
||||
idFrom,
|
||||
idTo,
|
||||
message = { text: undefined, wrap: undefined },
|
||||
messageType
|
||||
) {
|
||||
if (messageType === LINETYPE.ACTIVE_END) {
|
||||
const cnt = activationCount(idFrom.actor);
|
||||
logger.debug('Adding message from=', messages, cnt);
|
||||
if (cnt < 1) {
|
||||
// Bail out as there is an activation signal from an inactive participant
|
||||
let error = new Error('Trying to inactivate an inactive participant (' + idFrom.actor + ')');
|
||||
@ -150,7 +93,7 @@ export const addSignal = function(idFrom, idTo, message = { text: null, wrap: nu
|
||||
from: idFrom,
|
||||
to: idTo,
|
||||
message: message.text,
|
||||
wrap: (message.wrap === null && autoWrap()) || !!message.wrap,
|
||||
wrap: (message.wrap === undefined && autoWrap()) || !!message.wrap,
|
||||
type: messageType
|
||||
});
|
||||
return true;
|
||||
@ -180,12 +123,8 @@ export const enableSequenceNumbers = function() {
|
||||
};
|
||||
export const showSequenceNumbers = () => sequenceNumbersEnabled;
|
||||
|
||||
export const enableWrap = function() {
|
||||
wrapEnabled = true;
|
||||
};
|
||||
|
||||
export const disableWrap = function() {
|
||||
wrapEnabled = false;
|
||||
export const setWrap = function(wrapSetting) {
|
||||
wrapEnabled = wrapSetting;
|
||||
};
|
||||
|
||||
export const autoWrap = () => wrapEnabled;
|
||||
@ -193,22 +132,23 @@ export const autoWrap = () => wrapEnabled;
|
||||
export const clear = function() {
|
||||
actors = {};
|
||||
messages = [];
|
||||
configUpdated = false;
|
||||
};
|
||||
|
||||
export const parseMessage = function(str) {
|
||||
const _str = str.trim();
|
||||
return {
|
||||
const message = {
|
||||
text: _str.replace(/^[:]?(?:no)?wrap:/, '').trim(),
|
||||
wrap:
|
||||
_str.match(/^[:]?(?:no)?wrap:/) === null
|
||||
? autoWrap()
|
||||
? common.hasBreaks(_str) || autoWrap()
|
||||
: _str.match(/^[:]?wrap:/) !== null
|
||||
? true
|
||||
: _str.match(/^[:]?nowrap:/) !== null
|
||||
? false
|
||||
: autoWrap()
|
||||
};
|
||||
logger.debug('parseMessage:', message);
|
||||
return message;
|
||||
};
|
||||
|
||||
export const LINETYPE = {
|
||||
@ -251,7 +191,7 @@ export const addNote = function(actor, placement, message) {
|
||||
actor: actor,
|
||||
placement: placement,
|
||||
message: message.text,
|
||||
wrap: (message.wrap === null && autoWrap()) || !!message.wrap
|
||||
wrap: (message.wrap === undefined && autoWrap()) || !!message.wrap
|
||||
};
|
||||
|
||||
// Coerce actor into a [to, from, ...] array
|
||||
@ -262,7 +202,7 @@ export const addNote = function(actor, placement, message) {
|
||||
from: actors[0],
|
||||
to: actors[1],
|
||||
message: message.text,
|
||||
wrap: (message.wrap === null && autoWrap()) || !!message.wrap,
|
||||
wrap: (message.wrap === undefined && autoWrap()) || !!message.wrap,
|
||||
type: LINETYPE.NOTE,
|
||||
placement: placement
|
||||
});
|
||||
@ -270,20 +210,7 @@ export const addNote = function(actor, placement, message) {
|
||||
|
||||
export const setTitle = function(titleWrap) {
|
||||
title = titleWrap.text;
|
||||
titleWrapped = (titleWrap.wrap === null && autoWrap()) || !!titleWrap.wrap;
|
||||
};
|
||||
|
||||
export const updateConfig = function(config = getConfig()) {
|
||||
try {
|
||||
setConfig(config);
|
||||
configUpdated = true;
|
||||
} catch (error) {
|
||||
logger.error('Error: unable to parse config');
|
||||
}
|
||||
};
|
||||
|
||||
export const hasConfigChange = function() {
|
||||
return configUpdated;
|
||||
titleWrapped = (titleWrap.wrap === undefined && autoWrap()) || !!titleWrap.wrap;
|
||||
};
|
||||
|
||||
export const apply = function(param) {
|
||||
@ -355,20 +282,17 @@ export default {
|
||||
addActor,
|
||||
addMessage,
|
||||
addSignal,
|
||||
enableWrap,
|
||||
disableWrap,
|
||||
autoWrap,
|
||||
setWrap,
|
||||
enableSequenceNumbers,
|
||||
showSequenceNumbers,
|
||||
autoWrap,
|
||||
getMessages,
|
||||
getActors,
|
||||
getActor,
|
||||
getActorKeys,
|
||||
getTitle,
|
||||
parseDirective,
|
||||
hasConfigChange,
|
||||
getConfig,
|
||||
updateConfig,
|
||||
getConfig: () => configApi.getConfig().sequence,
|
||||
getTitleWrapped,
|
||||
clear,
|
||||
parseMessage,
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
100
src/diagrams/sequence/styles.js
Normal file
100
src/diagrams/sequence/styles.js
Normal file
@ -0,0 +1,100 @@
|
||||
const getStyles = options =>
|
||||
`.actor {
|
||||
stroke: ${options.actorBorder};
|
||||
fill: ${options.actorBkg};
|
||||
}
|
||||
|
||||
text.actor > tspan {
|
||||
fill: ${options.actorTextColor};
|
||||
stroke: none;
|
||||
}
|
||||
|
||||
.actor-line {
|
||||
stroke: ${options.actorLineColor};
|
||||
}
|
||||
|
||||
.messageLine0 {
|
||||
stroke-width: 1.5;
|
||||
stroke-dasharray: none;
|
||||
stroke: ${options.signalColor};
|
||||
}
|
||||
|
||||
.messageLine1 {
|
||||
stroke-width: 1.5;
|
||||
stroke-dasharray: 2, 2;
|
||||
stroke: ${options.signalColor};
|
||||
}
|
||||
|
||||
#arrowhead path {
|
||||
fill: ${options.signalColor};
|
||||
stroke: ${options.signalColor};
|
||||
}
|
||||
|
||||
.sequenceNumber {
|
||||
fill: ${options.sequenceNumberColor};
|
||||
}
|
||||
|
||||
#sequencenumber {
|
||||
fill: ${options.signalColor};
|
||||
}
|
||||
|
||||
#crosshead path {
|
||||
fill: ${options.signalColor};
|
||||
stroke: ${options.signalColor};
|
||||
}
|
||||
|
||||
.messageText {
|
||||
fill: ${options.signalTextColor};
|
||||
stroke: ${options.signalTextColor};
|
||||
}
|
||||
|
||||
.labelBox {
|
||||
stroke: ${options.labelBoxBorderColor};
|
||||
fill: ${options.labelBoxBkgColor};
|
||||
}
|
||||
|
||||
.labelText, .labelText > tspan {
|
||||
fill: ${options.labelTextColor};
|
||||
stroke: none;
|
||||
}
|
||||
|
||||
.loopText, .loopText > tspan {
|
||||
fill: ${options.loopTextColor};
|
||||
stroke: none;
|
||||
}
|
||||
|
||||
.loopLine {
|
||||
stroke-width: 2px;
|
||||
stroke-dasharray: 2, 2;
|
||||
stroke: ${options.labelBoxBorderColor};
|
||||
fill: ${options.labelBoxBorderColor};
|
||||
}
|
||||
|
||||
.note {
|
||||
//stroke: #decc93;
|
||||
stroke: ${options.noteBorderColor};
|
||||
fill: ${options.noteBkgColor};
|
||||
}
|
||||
|
||||
.noteText, .noteText > tspan {
|
||||
fill: ${options.noteTextColor};
|
||||
stroke: none;
|
||||
}
|
||||
|
||||
.activation0 {
|
||||
fill: ${options.activationBkgColor};
|
||||
stroke: ${options.activationBorderColor};
|
||||
}
|
||||
|
||||
.activation1 {
|
||||
fill: ${options.activationBkgColor};
|
||||
stroke: ${options.activationBorderColor};
|
||||
}
|
||||
|
||||
.activation2 {
|
||||
fill: ${options.activationBkgColor};
|
||||
stroke: ${options.activationBorderColor};
|
||||
}
|
||||
`;
|
||||
|
||||
export default getStyles;
|
@ -19,27 +19,133 @@ export const drawRect = function(elem, rectData) {
|
||||
};
|
||||
|
||||
export const drawText = function(elem, textData) {
|
||||
// Remove and ignore br:s
|
||||
const nText = textData.text.replace(common.lineBreakRegex, ' ');
|
||||
let prevTextHeight = 0,
|
||||
textHeight = 0;
|
||||
const lines = textData.wrap
|
||||
? textData.text.split(common.lineBreakRegex)
|
||||
: [textData.text.replace(common.lineBreakRegex, ' ')];
|
||||
|
||||
const textElem = elem.append('text');
|
||||
textElem.attr('x', textData.x);
|
||||
textElem.attr('y', textData.y);
|
||||
textElem.style('text-anchor', textData.anchor);
|
||||
textElem.style('font-family', textData.fontFamily);
|
||||
textElem.style('font-size', textData.fontSize);
|
||||
textElem.style('font-weight', textData.fontWeight);
|
||||
textElem.attr('fill', textData.fill);
|
||||
if (typeof textData.class !== 'undefined') {
|
||||
textElem.attr('class', textData.class);
|
||||
let textElems = [];
|
||||
let dy = 0;
|
||||
let yfunc = () => textData.y;
|
||||
if (
|
||||
typeof textData.valign !== 'undefined' &&
|
||||
typeof textData.textMargin !== 'undefined' &&
|
||||
textData.textMargin > 0
|
||||
) {
|
||||
switch (textData.valign) {
|
||||
case 'top':
|
||||
case 'start':
|
||||
yfunc = () => Math.round(textData.y + textData.textMargin);
|
||||
break;
|
||||
case 'middle':
|
||||
case 'center':
|
||||
yfunc = () =>
|
||||
Math.round(textData.y + (prevTextHeight + textHeight + textData.textMargin) / 2);
|
||||
break;
|
||||
case 'bottom':
|
||||
case 'end':
|
||||
yfunc = () =>
|
||||
Math.round(
|
||||
textData.y +
|
||||
(prevTextHeight + textHeight + 2 * textData.textMargin) -
|
||||
textData.textMargin
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (
|
||||
typeof textData.anchor !== 'undefined' &&
|
||||
typeof textData.textMargin !== 'undefined' &&
|
||||
typeof textData.width !== 'undefined'
|
||||
) {
|
||||
switch (textData.anchor) {
|
||||
case 'left':
|
||||
case 'start':
|
||||
textData.x = Math.round(textData.x + textData.textMargin);
|
||||
textData.anchor = 'start';
|
||||
textData.dominantBaseline = 'text-after-edge';
|
||||
textData.alignmentBaseline = 'middle';
|
||||
break;
|
||||
case 'middle':
|
||||
case 'center':
|
||||
textData.x = Math.round(textData.x + textData.width / 2);
|
||||
textData.anchor = 'middle';
|
||||
textData.dominantBaseline = 'middle';
|
||||
textData.alignmentBaseline = 'middle';
|
||||
break;
|
||||
case 'right':
|
||||
case 'end':
|
||||
textData.x = Math.round(textData.x + textData.width - textData.textMargin);
|
||||
textData.anchor = 'end';
|
||||
textData.dominantBaseline = 'text-before-edge';
|
||||
textData.alignmentBaseline = 'middle';
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
let line = lines[i];
|
||||
if (
|
||||
typeof textData.textMargin !== 'undefined' &&
|
||||
textData.textMargin === 0 &&
|
||||
typeof textData.fontSize !== 'undefined'
|
||||
) {
|
||||
dy = i * textData.fontSize;
|
||||
}
|
||||
|
||||
const textElem = elem.append('text');
|
||||
textElem.attr('x', textData.x);
|
||||
textElem.attr('y', yfunc());
|
||||
if (typeof textData.anchor !== 'undefined') {
|
||||
textElem
|
||||
.attr('text-anchor', textData.anchor)
|
||||
.attr('dominant-baseline', textData.dominantBaseline)
|
||||
.attr('alignment-baseline', textData.alignmentBaseline);
|
||||
}
|
||||
if (typeof textData.fontFamily !== 'undefined') {
|
||||
textElem.style('font-family', textData.fontFamily);
|
||||
}
|
||||
if (typeof textData.fontSize !== 'undefined') {
|
||||
textElem.style('font-size', textData.fontSize);
|
||||
}
|
||||
if (typeof textData.fontWeight !== 'undefined') {
|
||||
textElem.style('font-weight', textData.fontWeight);
|
||||
}
|
||||
if (typeof textData.fill !== 'undefined') {
|
||||
textElem.attr('fill', textData.fill);
|
||||
}
|
||||
if (typeof textData.class !== 'undefined') {
|
||||
textElem.attr('class', textData.class);
|
||||
}
|
||||
if (typeof textData.dy !== 'undefined') {
|
||||
textElem.attr('dy', textData.dy);
|
||||
} else if (dy !== 0) {
|
||||
textElem.attr('dy', dy);
|
||||
}
|
||||
|
||||
if (textData.tspan) {
|
||||
const span = textElem.append('tspan');
|
||||
span.attr('x', textData.x);
|
||||
if (typeof textData.fill !== 'undefined') {
|
||||
span.attr('fill', textData.fill);
|
||||
}
|
||||
span.text(line);
|
||||
} else {
|
||||
textElem.text(line);
|
||||
}
|
||||
if (
|
||||
typeof textData.valign !== 'undefined' &&
|
||||
typeof textData.textMargin !== 'undefined' &&
|
||||
textData.textMargin > 0
|
||||
) {
|
||||
textHeight += (textElem._groups || textElem)[0][0].getBBox().height;
|
||||
prevTextHeight = textHeight;
|
||||
}
|
||||
|
||||
textElems.push(textElem);
|
||||
}
|
||||
|
||||
const span = textElem.append('tspan');
|
||||
span.attr('x', textData.x + textData.textMargin * 2);
|
||||
span.attr('fill', textData.fill);
|
||||
span.text(nText);
|
||||
|
||||
return textElem;
|
||||
return textElems;
|
||||
};
|
||||
|
||||
export const drawLabel = function(elem, txtObject) {
|
||||
@ -67,17 +173,18 @@ export const drawLabel = function(elem, txtObject) {
|
||||
);
|
||||
}
|
||||
const polygon = elem.append('polygon');
|
||||
polygon.attr('points', genPoints(txtObject.x, txtObject.y, 50, 20, 7));
|
||||
polygon.attr('points', genPoints(txtObject.x, txtObject.y, txtObject.width, txtObject.height, 7));
|
||||
polygon.attr('class', 'labelBox');
|
||||
|
||||
txtObject.y = txtObject.y + txtObject.labelMargin;
|
||||
txtObject.x = txtObject.x + 0.5 * txtObject.labelMargin;
|
||||
txtObject.y = txtObject.y + txtObject.height / 2;
|
||||
|
||||
drawText(elem, txtObject);
|
||||
return polygon;
|
||||
};
|
||||
|
||||
let actorCnt = -1;
|
||||
/**
|
||||
* Draws an actor in the diagram with the attaced line
|
||||
* Draws an actor in the diagram with the attached line
|
||||
* @param elem - The diagram we'll draw to.
|
||||
* @param actor - The actor to draw.
|
||||
* @param conf - drawText implementation discriminator object
|
||||
@ -147,11 +254,20 @@ export const drawActivation = function(elem, bounds, verticalPos, conf, actorAct
|
||||
/**
|
||||
* Draws a loop in the diagram
|
||||
* @param elem - elemenet to append the loop to.
|
||||
* @param bounds - bounds of the given loop.
|
||||
* @param loopModel - loopModel of the given loop.
|
||||
* @param labelText - Text within the loop.
|
||||
* @param conf
|
||||
* @param conf - diagrom configuration
|
||||
*/
|
||||
export const drawLoop = function(elem, bounds, labelText, conf) {
|
||||
export const drawLoop = function(elem, loopModel, labelText, conf) {
|
||||
const {
|
||||
boxMargin,
|
||||
boxTextMargin,
|
||||
labelBoxHeight,
|
||||
labelBoxWidth,
|
||||
messageFontFamily: fontFamily,
|
||||
messageFontSize: fontSize,
|
||||
messageFontWeight: fontWeight
|
||||
} = conf;
|
||||
const g = elem.append('g');
|
||||
const drawLoopLine = function(startx, starty, stopx, stopy) {
|
||||
return g
|
||||
@ -162,56 +278,77 @@ export const drawLoop = function(elem, bounds, labelText, conf) {
|
||||
.attr('y2', stopy)
|
||||
.attr('class', 'loopLine');
|
||||
};
|
||||
drawLoopLine(bounds.startx, bounds.starty, bounds.stopx, bounds.starty);
|
||||
drawLoopLine(bounds.stopx, bounds.starty, bounds.stopx, bounds.stopy);
|
||||
drawLoopLine(bounds.startx, bounds.stopy, bounds.stopx, bounds.stopy);
|
||||
drawLoopLine(bounds.startx, bounds.starty, bounds.startx, bounds.stopy);
|
||||
if (typeof bounds.sections !== 'undefined') {
|
||||
bounds.sections.forEach(function(item) {
|
||||
drawLoopLine(bounds.startx, item, bounds.stopx, item).style('stroke-dasharray', '3, 3');
|
||||
drawLoopLine(loopModel.startx, loopModel.starty, loopModel.stopx, loopModel.starty);
|
||||
drawLoopLine(loopModel.stopx, loopModel.starty, loopModel.stopx, loopModel.stopy);
|
||||
drawLoopLine(loopModel.startx, loopModel.stopy, loopModel.stopx, loopModel.stopy);
|
||||
drawLoopLine(loopModel.startx, loopModel.starty, loopModel.startx, loopModel.stopy);
|
||||
if (typeof loopModel.sections !== 'undefined') {
|
||||
loopModel.sections.forEach(function(item) {
|
||||
drawLoopLine(loopModel.startx, item.y, loopModel.stopx, item.y).style(
|
||||
'stroke-dasharray',
|
||||
'3, 3'
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
let minSize =
|
||||
Math.round((3 * conf.fontSize) / 4) < 10 ? conf.fontSize : Math.round((3 * conf.fontSize) / 4);
|
||||
|
||||
let txt = getTextObj();
|
||||
txt.text = labelText;
|
||||
txt.x = bounds.startx;
|
||||
txt.y = bounds.starty;
|
||||
txt.labelMargin = 1.5 * 10; // This is the small box that says "loop"
|
||||
txt.fontFamily = conf.fontFamily;
|
||||
txt.fontSize = minSize;
|
||||
txt.fontWeight = conf.fontWeight;
|
||||
txt.class = 'labelText'; // Its size & position are fixed.
|
||||
txt.x = loopModel.startx;
|
||||
txt.y = loopModel.starty;
|
||||
txt.fontFamily = fontFamily;
|
||||
txt.fontSize = fontSize;
|
||||
txt.fontWeight = fontWeight;
|
||||
txt.anchor = 'middle';
|
||||
txt.valign = 'middle';
|
||||
txt.tspan = false;
|
||||
txt.width = labelBoxWidth || 50;
|
||||
txt.height = labelBoxHeight || 20;
|
||||
txt.textMargin = boxTextMargin;
|
||||
txt.class = 'labelText';
|
||||
|
||||
drawLabel(g, txt);
|
||||
|
||||
txt = getTextObj();
|
||||
txt.text = '[ ' + bounds.title + ' ]';
|
||||
txt.x = bounds.startx + (bounds.stopx - bounds.startx) / 2;
|
||||
txt.y = bounds.starty + 1.5 * conf.boxMargin;
|
||||
txt.text = loopModel.title;
|
||||
txt.x = loopModel.startx + labelBoxWidth / 2 + (loopModel.stopx - loopModel.startx) / 2;
|
||||
txt.y = loopModel.starty + boxMargin + boxTextMargin;
|
||||
txt.anchor = 'middle';
|
||||
txt.valign = 'middle';
|
||||
txt.textMargin = boxTextMargin;
|
||||
txt.class = 'loopText';
|
||||
txt.fontFamily = conf.fontFamily;
|
||||
txt.fontSize = minSize;
|
||||
txt.fontWeight = conf.fontWeight;
|
||||
txt.fontFamily = fontFamily;
|
||||
txt.fontSize = fontSize;
|
||||
txt.fontWeight = fontWeight;
|
||||
txt.wrap = true;
|
||||
|
||||
let textElem = drawText(g, txt);
|
||||
let textHeight = (textElem._groups || textElem)[0][0].getBBox().height;
|
||||
|
||||
if (typeof bounds.sectionTitles !== 'undefined') {
|
||||
bounds.sectionTitles.forEach(function(item, idx) {
|
||||
if (item !== '') {
|
||||
txt.text = '[ ' + item + ' ]';
|
||||
txt.y = bounds.sections[idx] + 1.5 * conf.boxMargin;
|
||||
if (typeof loopModel.sectionTitles !== 'undefined') {
|
||||
loopModel.sectionTitles.forEach(function(item, idx) {
|
||||
if (item.message) {
|
||||
txt.text = item.message;
|
||||
txt.x = loopModel.startx + (loopModel.stopx - loopModel.startx) / 2;
|
||||
txt.y = loopModel.sections[idx].y + boxMargin + boxTextMargin;
|
||||
txt.class = 'loopText';
|
||||
txt.anchor = 'middle';
|
||||
txt.valign = 'middle';
|
||||
txt.tspan = false;
|
||||
txt.fontFamily = fontFamily;
|
||||
txt.fontSize = fontSize;
|
||||
txt.fontWeight = fontWeight;
|
||||
txt.wrap = loopModel.wrap;
|
||||
textElem = drawText(g, txt);
|
||||
textHeight += (textElem._groups || textElem)[0][0].getBBox().height;
|
||||
let sectionHeight = Math.round(
|
||||
textElem
|
||||
.map(te => (te._groups || te)[0][0].getBBox().height)
|
||||
.reduce((acc, curr) => acc + curr)
|
||||
);
|
||||
loopModel.sections[idx].height += sectionHeight - (boxMargin + boxTextMargin);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return textHeight + 4;
|
||||
loopModel.height = Math.round(loopModel.stopy - loopModel.starty);
|
||||
return g;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -300,23 +437,24 @@ export const insertArrowCrossHead = function(elem) {
|
||||
};
|
||||
|
||||
export const getTextObj = function() {
|
||||
const txt = {
|
||||
return {
|
||||
x: 0,
|
||||
y: 0,
|
||||
fill: undefined,
|
||||
'text-anchor': 'start',
|
||||
anchor: undefined,
|
||||
style: '#666',
|
||||
width: 100,
|
||||
height: 100,
|
||||
width: undefined,
|
||||
height: undefined,
|
||||
textMargin: 0,
|
||||
rx: 0,
|
||||
ry: 0
|
||||
ry: 0,
|
||||
tspan: true,
|
||||
valign: undefined
|
||||
};
|
||||
return txt;
|
||||
};
|
||||
|
||||
export const getNoteRect = function() {
|
||||
const rect = {
|
||||
return {
|
||||
x: 0,
|
||||
y: 0,
|
||||
fill: '#EDF2AE',
|
||||
@ -327,7 +465,6 @@ export const getNoteRect = function() {
|
||||
rx: 0,
|
||||
ry: 0
|
||||
};
|
||||
return rect;
|
||||
};
|
||||
|
||||
const _drawTextCandidateFunc = (function() {
|
||||
|
164
src/diagrams/state/styles.js
Normal file
164
src/diagrams/state/styles.js
Normal file
@ -0,0 +1,164 @@
|
||||
const getStyles = options =>
|
||||
`g.stateGroup text {
|
||||
fill: ${options.nodeBorder};
|
||||
stroke: none;
|
||||
font-size: 10px;
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
font-family: var(--mermaid-font-family);
|
||||
}
|
||||
g.stateGroup text {
|
||||
fill: ${options.textColor};
|
||||
stroke: none;
|
||||
font-size: 10px;
|
||||
|
||||
}
|
||||
g.stateGroup .state-title {
|
||||
font-weight: bolder;
|
||||
fill: ${options.labelColor};
|
||||
}
|
||||
|
||||
g.stateGroup rect {
|
||||
fill: ${options.nodeBkg};
|
||||
stroke: ${options.nodeBorder};
|
||||
}
|
||||
|
||||
g.stateGroup line {
|
||||
stroke: ${options.lineColor};
|
||||
stroke-width: 1;
|
||||
}
|
||||
|
||||
.transition {
|
||||
stroke: ${options.lineColor};
|
||||
stroke-width: 1;
|
||||
fill: none;
|
||||
}
|
||||
|
||||
.stateGroup .composit {
|
||||
fill: ${options.background};
|
||||
border-bottom: 1px
|
||||
}
|
||||
|
||||
.stateGroup .alt-composit {
|
||||
fill: #e0e0e0;
|
||||
border-bottom: 1px
|
||||
}
|
||||
|
||||
.state-note {
|
||||
stroke: ${options.noteBorderColor};
|
||||
fill: ${options.noteBkgColor};
|
||||
|
||||
text {
|
||||
fill: black;
|
||||
stroke: none;
|
||||
font-size: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.stateLabel .box {
|
||||
stroke: none;
|
||||
stroke-width: 0;
|
||||
fill: ${options.nodeBkg};
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.stateLabel text {
|
||||
fill: ${options.labelColor};
|
||||
font-size: 10px;
|
||||
font-weight: bold;
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
font-family: var(--mermaid-font-family);
|
||||
}
|
||||
|
||||
.node circle.state-start {
|
||||
fill: black;
|
||||
stroke: black;
|
||||
}
|
||||
.node circle.state-end {
|
||||
fill: black;
|
||||
stroke: white;
|
||||
stroke-width: 1.5
|
||||
}
|
||||
|
||||
.node rect {
|
||||
fill: ${options.mainBkg};
|
||||
stroke: ${options.nodeBorder};
|
||||
stroke-width: 1px;
|
||||
}
|
||||
#statediagram-barbEnd {
|
||||
fill: ${options.lineColor};
|
||||
}
|
||||
|
||||
.statediagram-cluster rect {
|
||||
fill: ${options.nodeBkg};
|
||||
stroke: ${options.nodeBorder};
|
||||
stroke-width: 1px;
|
||||
}
|
||||
|
||||
.cluster-label, .nodeLabel {
|
||||
color: ${options.textColor};
|
||||
}
|
||||
|
||||
.statediagram-cluster rect.outer {
|
||||
rx: 5px;
|
||||
ry: 5px;
|
||||
}
|
||||
.statediagram-state .divider {
|
||||
stroke: ${options.nodeBorder};
|
||||
}
|
||||
|
||||
.statediagram-state .title-state {
|
||||
rx: 5px;
|
||||
ry: 5px;
|
||||
}
|
||||
.statediagram-cluster.statediagram-cluster .inner {
|
||||
fill: ${options.background};
|
||||
}
|
||||
.statediagram-cluster.statediagram-cluster-alt .inner {
|
||||
fill: #e0e0e0;
|
||||
}
|
||||
|
||||
.statediagram-cluster .inner {
|
||||
rx:0;
|
||||
ry:0;
|
||||
}
|
||||
|
||||
.statediagram-state rect.basic {
|
||||
rx: 5px;
|
||||
ry: 5px;
|
||||
}
|
||||
.statediagram-state rect.divider {
|
||||
stroke-dasharray: 10,10;
|
||||
fill: ${options.altBackground ? options.altBackground : '#efefef'};
|
||||
}
|
||||
|
||||
.note-edge {
|
||||
stroke-dasharray: 5;
|
||||
}
|
||||
|
||||
.statediagram-note rect {
|
||||
fill: ${options.noteBkgColor};
|
||||
stroke: ${options.noteBorderColor};
|
||||
stroke-width: 1px;
|
||||
rx: 0;
|
||||
ry: 0;
|
||||
}
|
||||
.statediagram-note rect {
|
||||
fill: ${options.noteBkgColor};
|
||||
stroke: ${options.noteBorderColor};
|
||||
stroke-width: 1px;
|
||||
rx: 0;
|
||||
ry: 0;
|
||||
}
|
||||
|
||||
.statediagram-note .nodeLabel {
|
||||
color: ${options.noteTextColor};
|
||||
}
|
||||
|
||||
#dependencyStart, #dependencyEnd {
|
||||
fill: ${options.lineColor};
|
||||
stroke: ${options.lineColor};
|
||||
stroke-width: 1;
|
||||
}
|
||||
`;
|
||||
|
||||
export default getStyles;
|
@ -232,12 +232,14 @@ export const drawTasks = function(diagram, tasks, verticalPos) {
|
||||
let sectionNumber = 0;
|
||||
let fill = '#CCC';
|
||||
let colour = 'black';
|
||||
let num = 0;
|
||||
|
||||
// Draw the tasks
|
||||
for (let i = 0; i < tasks.length; i++) {
|
||||
let task = tasks[i];
|
||||
if (lastSection !== task.section) {
|
||||
fill = fills[sectionNumber % fills.length];
|
||||
num = sectionNumber % fills.length;
|
||||
colour = textColours[sectionNumber % textColours.length];
|
||||
|
||||
const section = {
|
||||
@ -245,6 +247,7 @@ export const drawTasks = function(diagram, tasks, verticalPos) {
|
||||
y: 50,
|
||||
text: task.section,
|
||||
fill,
|
||||
num,
|
||||
colour
|
||||
};
|
||||
|
||||
@ -269,6 +272,7 @@ export const drawTasks = function(diagram, tasks, verticalPos) {
|
||||
task.height = conf.diagramMarginY;
|
||||
task.colour = colour;
|
||||
task.fill = fill;
|
||||
task.num = num;
|
||||
task.actors = taskActors;
|
||||
|
||||
// Draw the box with the attached line
|
||||
|
121
src/diagrams/user-journey/styles.js
Normal file
121
src/diagrams/user-journey/styles.js
Normal file
@ -0,0 +1,121 @@
|
||||
const getStyles = options =>
|
||||
`.label {
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
font-family: var(--mermaid-font-family);
|
||||
color: ${options.textColor};
|
||||
}
|
||||
.mouth {
|
||||
stroke: #666;
|
||||
}
|
||||
|
||||
line {
|
||||
stroke: ${options.textColor}
|
||||
}
|
||||
|
||||
.legend {
|
||||
fill: ${options.textColor};
|
||||
}
|
||||
|
||||
.label text {
|
||||
fill: #333;
|
||||
}
|
||||
.label {
|
||||
color: ${options.textColor}
|
||||
}
|
||||
|
||||
.face {
|
||||
fill: #FFF8DC;
|
||||
stroke: #999;
|
||||
}
|
||||
|
||||
.node rect,
|
||||
.node circle,
|
||||
.node ellipse,
|
||||
.node polygon,
|
||||
.node path {
|
||||
fill: ${options.mainBkg};
|
||||
stroke: ${options.nodeBorder};
|
||||
stroke-width: 1px;
|
||||
}
|
||||
|
||||
.node .label {
|
||||
text-align: center;
|
||||
}
|
||||
.node.clickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.arrowheadPath {
|
||||
fill: ${options.arrowheadColor};
|
||||
}
|
||||
|
||||
.edgePath .path {
|
||||
stroke: ${options.lineColor};
|
||||
stroke-width: 1.5px;
|
||||
}
|
||||
|
||||
.flowchart-link {
|
||||
stroke: ${options.lineColor};
|
||||
fill: none;
|
||||
}
|
||||
|
||||
.edgeLabel {
|
||||
background-color: ${options.edgeLabelBackground};
|
||||
rect {
|
||||
opacity: 0.5;
|
||||
}
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.cluster rect {
|
||||
fill: ${options.secondBkg};
|
||||
stroke: ${options.clusterBorder};
|
||||
stroke-width: 1px;
|
||||
}
|
||||
|
||||
.cluster text {
|
||||
fill: ${options.titleColor};
|
||||
}
|
||||
|
||||
div.mermaidTooltip {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
max-width: 200px;
|
||||
padding: 2px;
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
font-family: var(--mermaid-font-family);
|
||||
font-size: 12px;
|
||||
background: ${options.secondBkg};
|
||||
border: 1px solid ${options.border2};
|
||||
border-radius: 2px;
|
||||
pointer-events: none;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.task-type-0, .section-type-0 {
|
||||
${options.fillType0 ? `fill: ${options.fillType0}` : ''};
|
||||
}
|
||||
.task-type-1, .section-type-1 {
|
||||
${options.fillType0 ? `fill: ${options.fillType1}` : ''};
|
||||
}
|
||||
.task-type-2, .section-type-2 {
|
||||
${options.fillType0 ? `fill: ${options.fillType2}` : ''};
|
||||
}
|
||||
.task-type-3, .section-type-3 {
|
||||
${options.fillType0 ? `fill: ${options.fillType3}` : ''};
|
||||
}
|
||||
.task-type-4, .section-type-4 {
|
||||
${options.fillType0 ? `fill: ${options.fillType4}` : ''};
|
||||
}
|
||||
.task-type-5, .section-type-5 {
|
||||
${options.fillType0 ? `fill: ${options.fillType5}` : ''};
|
||||
}
|
||||
.task-type-6, .section-type-6 {
|
||||
${options.fillType0 ? `fill: ${options.fillType6}` : ''};
|
||||
}
|
||||
.task-type-7, .section-type-7 {
|
||||
${options.fillType0 ? `fill: ${options.fillType7}` : ''};
|
||||
}
|
||||
`;
|
||||
|
||||
export default getStyles;
|
@ -24,8 +24,7 @@ export const drawFace = function(element, faceData) {
|
||||
.append('circle')
|
||||
.attr('cx', faceData.cx)
|
||||
.attr('cy', faceData.cy)
|
||||
.attr('fill', '#FFF8DC')
|
||||
.attr('stroke', '#999')
|
||||
.attr('class', 'face')
|
||||
.attr('r', radius)
|
||||
.attr('stroke-width', 2)
|
||||
.attr('overflow', 'visible');
|
||||
@ -61,6 +60,7 @@ export const drawFace = function(element, faceData) {
|
||||
//mouth
|
||||
face
|
||||
.append('path')
|
||||
.attr('class', 'mouth')
|
||||
.attr('d', arc)
|
||||
.attr('transform', 'translate(' + faceData.cx + ',' + (faceData.cy + 2) + ')');
|
||||
}
|
||||
@ -74,6 +74,7 @@ export const drawFace = function(element, faceData) {
|
||||
//mouth
|
||||
face
|
||||
.append('path')
|
||||
.attr('class', 'mouth')
|
||||
.attr('d', arc)
|
||||
.attr('transform', 'translate(' + faceData.cx + ',' + (faceData.cy + 7) + ')');
|
||||
}
|
||||
@ -81,12 +82,13 @@ export const drawFace = function(element, faceData) {
|
||||
function ambivalent(face) {
|
||||
face
|
||||
.append('line')
|
||||
.attr('class', 'mouth')
|
||||
.attr('stroke', 2)
|
||||
.attr('x1', faceData.cx - 5)
|
||||
.attr('y1', faceData.cy + 7)
|
||||
.attr('x2', faceData.cx + 5)
|
||||
.attr('y2', faceData.cy + 7)
|
||||
.attr('class', 'task-line')
|
||||
.attr('class', 'mouth')
|
||||
.attr('stroke-width', '1px')
|
||||
.attr('stroke', '#666');
|
||||
}
|
||||
@ -128,7 +130,8 @@ export const drawText = function(elem, textData) {
|
||||
const textElem = elem.append('text');
|
||||
textElem.attr('x', textData.x);
|
||||
textElem.attr('y', textData.y);
|
||||
textElem.attr('fill', textData.fill);
|
||||
textElem.attr('class', 'legend');
|
||||
|
||||
textElem.style('text-anchor', textData.anchor);
|
||||
|
||||
if (typeof textData.class !== 'undefined') {
|
||||
@ -184,7 +187,7 @@ export const drawSection = function(elem, section, conf) {
|
||||
rect.fill = section.fill;
|
||||
rect.width = conf.width;
|
||||
rect.height = conf.height;
|
||||
rect.class = 'journey-section';
|
||||
rect.class = 'journey-section section-type-' + section.num;
|
||||
rect.rx = 3;
|
||||
rect.ry = 3;
|
||||
drawRect(g, rect);
|
||||
@ -196,7 +199,7 @@ export const drawSection = function(elem, section, conf) {
|
||||
rect.y,
|
||||
rect.width,
|
||||
rect.height,
|
||||
{ class: 'journey-section' },
|
||||
{ class: 'journey-section section-type-' + section.num },
|
||||
conf,
|
||||
section.colour
|
||||
);
|
||||
@ -237,7 +240,7 @@ export const drawTask = function(elem, task, conf) {
|
||||
rect.fill = task.fill;
|
||||
rect.width = conf.width;
|
||||
rect.height = conf.height;
|
||||
rect.class = 'task';
|
||||
rect.class = 'task task-type-' + task.num;
|
||||
rect.rx = 3;
|
||||
rect.ry = 3;
|
||||
drawRect(g, rect);
|
||||
@ -356,7 +359,7 @@ const _drawTextCandidateFunc = (function() {
|
||||
}
|
||||
}
|
||||
|
||||
function byFo(content, g, x, y, width, height, textAttrs, conf, colour) {
|
||||
function byFo(content, g, x, y, width, height, textAttrs, conf) {
|
||||
const body = g.append('switch');
|
||||
const f = body
|
||||
.append('foreignObject')
|
||||
@ -374,10 +377,11 @@ const _drawTextCandidateFunc = (function() {
|
||||
|
||||
text
|
||||
.append('div')
|
||||
.attr('class', 'label')
|
||||
.style('display', 'table-cell')
|
||||
.style('text-align', 'center')
|
||||
.style('vertical-align', 'middle')
|
||||
.style('color', colour)
|
||||
// .style('color', colour)
|
||||
.text(content);
|
||||
|
||||
byTspan(content, body, x, y, width, height, textAttrs, conf);
|
||||
|
@ -6,6 +6,8 @@
|
||||
import decode from 'entity-decode/browser';
|
||||
import mermaidAPI from './mermaidAPI';
|
||||
import { logger } from './logger';
|
||||
import utils from './utils';
|
||||
|
||||
/**
|
||||
* ## init
|
||||
* Function that goes through the document to find the chart definitions in there and render them.
|
||||
@ -29,7 +31,7 @@ import { logger } from './logger';
|
||||
*/
|
||||
const init = function() {
|
||||
const conf = mermaidAPI.getConfig();
|
||||
logger.debug('Starting rendering diagrams');
|
||||
// console.log('Starting rendering diagrams (init) - mermaid.init');
|
||||
let nodes;
|
||||
if (arguments.length >= 2) {
|
||||
/*! sequence config was passed as #1 */
|
||||
@ -98,6 +100,11 @@ const init = function() {
|
||||
.trim()
|
||||
.replace(/<br\s*\/?>/gi, '<br/>');
|
||||
|
||||
const init = utils.detectInit(txt);
|
||||
if (init) {
|
||||
logger.debug('Detected early reinit: ', init);
|
||||
}
|
||||
|
||||
try {
|
||||
mermaidAPI.render(
|
||||
id,
|
||||
@ -122,6 +129,7 @@ const init = function() {
|
||||
};
|
||||
|
||||
const initialize = function(config) {
|
||||
mermaidAPI.reset();
|
||||
if (typeof config.mermaid !== 'undefined') {
|
||||
if (typeof config.mermaid.startOnLoad !== 'undefined') {
|
||||
mermaid.startOnLoad = config.mermaid.startOnLoad;
|
||||
@ -131,7 +139,7 @@ const initialize = function(config) {
|
||||
}
|
||||
}
|
||||
mermaidAPI.initialize(config);
|
||||
logger.debug('Initializing mermaid ');
|
||||
// mermaidAPI.reset();
|
||||
};
|
||||
|
||||
/**
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,10 +1,12 @@
|
||||
/* eslint-env jasmine */
|
||||
import mermaidAPI from './mermaidAPI';
|
||||
import { assignWithDepth } from './utils';
|
||||
|
||||
describe('when using mermaidAPI and ', function() {
|
||||
describe('doing initialize ', function() {
|
||||
beforeEach(function() {
|
||||
document.body.innerHTML = '';
|
||||
mermaidAPI.globalReset();
|
||||
});
|
||||
|
||||
it('should copy a literal into the configuration', function() {
|
||||
@ -26,13 +28,121 @@ describe('when using mermaidAPI and ', function() {
|
||||
};
|
||||
|
||||
mermaidAPI.initialize({ testObject: object });
|
||||
let config = mermaidAPI.getConfig();
|
||||
|
||||
expect(config.testObject.test1).toBe(1);
|
||||
mermaidAPI.initialize({ testObject: { test3: true } });
|
||||
const config = mermaidAPI.getConfig();
|
||||
config = mermaidAPI.getConfig();
|
||||
|
||||
expect(config.testObject.test1).toBe(1);
|
||||
expect(config.testObject.test2).toBe(false);
|
||||
expect(config.testObject.test3).toBe(true);
|
||||
});
|
||||
it('should reset mermaid config to global defaults', function() {
|
||||
let config = {
|
||||
logLevel: 0,
|
||||
securityLevel: 'loose'
|
||||
};
|
||||
mermaidAPI.initialize(config);
|
||||
expect(mermaidAPI.getConfig().logLevel).toBe(0);
|
||||
expect(mermaidAPI.getConfig().securityLevel).toBe('loose');
|
||||
mermaidAPI.globalReset();
|
||||
expect(mermaidAPI.getConfig()).toEqual(mermaidAPI.defaultConfig);
|
||||
});
|
||||
it('should reset mermaid config to site defaults', function() {
|
||||
let config = {
|
||||
logLevel: 0
|
||||
};
|
||||
mermaidAPI.initialize(config);
|
||||
const siteConfig = mermaidAPI.getSiteConfig();
|
||||
expect(mermaidAPI.getConfig().logLevel).toBe(0);
|
||||
config.logLevel = 3;
|
||||
config.securityLevel = 'loose';
|
||||
mermaidAPI.reinitialize(config);
|
||||
expect(mermaidAPI.getConfig().logLevel).toBe(3);
|
||||
expect(mermaidAPI.getConfig().securityLevel).toBe('strict');
|
||||
mermaidAPI.reset();
|
||||
expect(mermaidAPI.getSiteConfig()).toEqual(siteConfig)
|
||||
expect(mermaidAPI.getConfig()).toEqual(siteConfig);
|
||||
});
|
||||
it('should allow site config secure to global defaults', function() {
|
||||
let config = {
|
||||
logLevel: 0,
|
||||
secure: ['foo']
|
||||
};
|
||||
mermaidAPI.initialize(config);
|
||||
const siteConfig = mermaidAPI.getSiteConfig();
|
||||
expect(mermaidAPI.getConfig().logLevel).toBe(0);
|
||||
expect(mermaidAPI.getConfig().secure).toContain('foo');
|
||||
config = {
|
||||
logLevel: 3,
|
||||
securityLevel: 'loose',
|
||||
secure: ['foo', 'bar']
|
||||
};
|
||||
mermaidAPI.reinitialize(config);
|
||||
expect(mermaidAPI.getConfig().secure).toEqual(mermaidAPI.getSiteConfig().secure);
|
||||
expect(mermaidAPI.getConfig().securityLevel).toBe('strict');
|
||||
expect(mermaidAPI.getConfig().secure).not.toContain('bar');
|
||||
mermaidAPI.reset();
|
||||
expect(mermaidAPI.getSiteConfig()).toEqual(siteConfig)
|
||||
expect(mermaidAPI.getConfig()).toEqual(siteConfig);
|
||||
});
|
||||
it('should prevent changes to site defaults (sneaky)', function() {
|
||||
let config = {
|
||||
logLevel: 0
|
||||
};
|
||||
mermaidAPI.initialize(config);
|
||||
const siteConfig = mermaidAPI.getSiteConfig();
|
||||
expect(mermaidAPI.getConfig().logLevel).toBe(0);
|
||||
config.secure = {
|
||||
toString: function() {
|
||||
mermaidAPI.initialize({ securityLevel: 'loose' });
|
||||
}
|
||||
};
|
||||
mermaidAPI.reinitialize(config);
|
||||
expect(mermaidAPI.getConfig().secure).toEqual(mermaidAPI.getSiteConfig().secure);
|
||||
expect(mermaidAPI.getConfig().securityLevel).toBe('strict');
|
||||
mermaidAPI.reset();
|
||||
expect(mermaidAPI.getSiteConfig()).toEqual(siteConfig)
|
||||
expect(mermaidAPI.getConfig()).toEqual(siteConfig);
|
||||
});
|
||||
it('should prevent clobbering global defaults (direct)', function() {
|
||||
let config = assignWithDepth({}, mermaidAPI.defaultConfig);
|
||||
assignWithDepth(config, { logLevel: 0 });
|
||||
|
||||
let error = { message: '' };
|
||||
try {
|
||||
mermaidAPI['defaultConfig'] = config;
|
||||
} catch(e) {
|
||||
error = e;
|
||||
}
|
||||
expect(error.message).toBe('Cannot assign to read only property \'defaultConfig\' of object \'#<Object>\'');
|
||||
expect(mermaidAPI.defaultConfig['logLevel']).toBe(5);
|
||||
});
|
||||
it('should prevent changes to global defaults (direct)', function() {
|
||||
let error = { message: '' };
|
||||
try {
|
||||
mermaidAPI.defaultConfig['logLevel'] = 0;
|
||||
} catch(e) {
|
||||
error = e;
|
||||
}
|
||||
expect(error.message).toBe('Cannot assign to read only property \'logLevel\' of object \'#<Object>\'');
|
||||
expect(mermaidAPI.defaultConfig['logLevel']).toBe(5);
|
||||
});
|
||||
it('should prevent sneaky changes to global defaults (assignWithDepth)', function() {
|
||||
let config = {
|
||||
logLevel: 0
|
||||
};
|
||||
let error = { message: '' };
|
||||
try {
|
||||
assignWithDepth(mermaidAPI.defaultConfig, config);
|
||||
} catch(e) {
|
||||
error = e;
|
||||
}
|
||||
expect(error.message).toBe('Cannot assign to read only property \'logLevel\' of object \'#<Object>\'');
|
||||
expect(mermaidAPI.defaultConfig['logLevel']).toBe(5);
|
||||
});
|
||||
|
||||
});
|
||||
describe('checking validity of input ', function() {
|
||||
it('it should throw for an invalid definiton', function() {
|
||||
|
83
src/styles.js
Normal file
83
src/styles.js
Normal file
@ -0,0 +1,83 @@
|
||||
import classDiagram from './diagrams/class/styles';
|
||||
import er from './diagrams/er/styles';
|
||||
import flowchart from './diagrams/flowchart/styles';
|
||||
import gantt from './diagrams/gantt/styles';
|
||||
import git from './diagrams/git/styles';
|
||||
import info from './diagrams/info/styles';
|
||||
import pie from './diagrams/pie/styles';
|
||||
import sequence from './diagrams/sequence/styles';
|
||||
import stateDiagram from './diagrams/state/styles';
|
||||
import journey from './diagrams/user-journey/styles';
|
||||
|
||||
const themes = {
|
||||
flowchart,
|
||||
'flowchart-v2': flowchart,
|
||||
sequence,
|
||||
gantt,
|
||||
class: classDiagram,
|
||||
stateDiagram,
|
||||
state: stateDiagram,
|
||||
git,
|
||||
info,
|
||||
pie,
|
||||
er,
|
||||
journey
|
||||
};
|
||||
|
||||
export const calcThemeVariables = (theme, userOverRides) => theme.calcColors(userOverRides);
|
||||
|
||||
const getStyles = (type, userStyles, options) => {
|
||||
return ` {
|
||||
font-family: ${options.fontFamily};
|
||||
font-size: ${options.fontSize};
|
||||
fill: ${options.textColor}
|
||||
}
|
||||
|
||||
/* Classes common for multiple diagrams */
|
||||
|
||||
.error-icon {
|
||||
fill: ${options.errorBkgColor};
|
||||
}
|
||||
.error-text {
|
||||
fill: ${options.errorTextColor};
|
||||
stroke: ${options.errorTextColor};
|
||||
}
|
||||
|
||||
.edge-thickness-normal {
|
||||
stroke-width: 2px;
|
||||
}
|
||||
.edge-thickness-thick {
|
||||
stroke-width: 3.5px
|
||||
}
|
||||
.edge-pattern-solid {
|
||||
stroke-dasharray: 0;
|
||||
}
|
||||
|
||||
.edge-pattern-dashed{
|
||||
stroke-dasharray: 3;
|
||||
}
|
||||
.edge-pattern-dotted {
|
||||
stroke-dasharray: 2;
|
||||
}
|
||||
|
||||
.marker {
|
||||
fill: ${options.lineColor};
|
||||
}
|
||||
.marker.cross {
|
||||
stroke: ${options.lineColor};
|
||||
}
|
||||
|
||||
svg {
|
||||
font-family: ${options.fontFamily};
|
||||
font-size: ${options.fontSize};
|
||||
}
|
||||
|
||||
${themes[type](options)}
|
||||
|
||||
${userStyles}
|
||||
|
||||
${type} { fill: apa;}
|
||||
`;
|
||||
};
|
||||
|
||||
export default getStyles;
|
@ -10,7 +10,7 @@ $arrowheadColor: $mainContrastColor;
|
||||
/* Flowchart variables */
|
||||
|
||||
$nodeBkg: $mainBkg;
|
||||
$nodeBorder: purple;
|
||||
$nodeBorder: $border1;
|
||||
$clusterBkg: $secondBkg;
|
||||
$clusterBorder: $border2;
|
||||
$defaultLinkColor: $lineColor;
|
||||
@ -34,7 +34,7 @@ $noteBkgColor: #fff5ad;
|
||||
$noteTextColor: $mainBkg;
|
||||
$activationBorderColor: $border1;
|
||||
$activationBkgColor: $secondBkg;
|
||||
$sequenceNumberColor: white;
|
||||
$sequenceNumberColor: black;
|
||||
|
||||
/* Gantt chart variables */
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
@import 'flowchart';
|
||||
// @import 'flowchart';
|
||||
@import 'sequence';
|
||||
@import 'gantt';
|
||||
@import 'class';
|
||||
@ -13,8 +13,9 @@
|
||||
|
||||
:root {
|
||||
--mermaid-font-family: '"trebuchet ms", verdana, arial';
|
||||
--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive;
|
||||
// --mermaid-alt-font-family: '"Lucida Console", Monaco, monospace';
|
||||
font-family: '"trebuchet ms", verdana, arial';
|
||||
font-family: var(--mermaid-font-family);
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
/* Classes common for multiple diagrams */
|
||||
@ -52,3 +53,8 @@
|
||||
.marker.cross {
|
||||
stroke: $lineColor;
|
||||
}
|
||||
|
||||
svg {
|
||||
font-family: var(--mermaid-font-family);
|
||||
font-size: 24px;
|
||||
}
|
@ -9,3 +9,8 @@
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
font-family: var(--mermaid-font-family);
|
||||
}
|
||||
.legend text {
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
font-family: var(--mermaid-font-family);
|
||||
font-size: 17px;
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ g.stateGroup line {
|
||||
}
|
||||
|
||||
.statediagram-cluster rect {
|
||||
fill: $nodeBkg;
|
||||
// fill: $nodeBkg;
|
||||
stroke: $nodeBorder;
|
||||
stroke-width: 1px;
|
||||
}
|
||||
|
136
src/themes/theme-base.js
Normal file
136
src/themes/theme-base.js
Normal file
@ -0,0 +1,136 @@
|
||||
import { darken, lighten, adjust } from 'khroma';
|
||||
|
||||
class Theme {
|
||||
constructor() {
|
||||
/* Base variables */
|
||||
this.primaryColor = '#039fbe';
|
||||
this.secondaryColor = '#b20238';
|
||||
this.tertiaryColor = lighten('#e8d21d', 30);
|
||||
this.relationColor = '#000';
|
||||
this.primaryColor = '#fa255e';
|
||||
this.secondaryColor = '#c39ea0';
|
||||
this.tertiaryColor = '#f8e5e5';
|
||||
|
||||
this.primaryColor = '#ECECFF';
|
||||
this.secondaryColor = '#ffffde';
|
||||
this.tertiaryColor = '#ffffde';
|
||||
|
||||
this.background = 'white';
|
||||
this.lineColor = '#333333';
|
||||
this.border1 = '#9370DB';
|
||||
this.arrowheadColor = '#333333';
|
||||
this.fontFamily = '"trebuchet ms", verdana, arial';
|
||||
this.fontSize = '16px';
|
||||
this.labelBackground = '#e8e8e8';
|
||||
this.textColor = '#333';
|
||||
this.noteBkgColor = '#fff5ad';
|
||||
this.noteBorderColor = '#aaaa33';
|
||||
this.updateColors();
|
||||
}
|
||||
updateColors() {
|
||||
this.secondBkg = this.tertiaryColor;
|
||||
|
||||
/* Flowchart variables */
|
||||
|
||||
this.nodeBkg = this.primaryColor;
|
||||
this.mainBkg = this.primaryColor;
|
||||
this.nodeBorder = darken(this.primaryColor, 23); // border 1
|
||||
this.clusterBkg = this.tertiaryColor;
|
||||
this.clusterBorder = darken(this.tertiaryColor, 10);
|
||||
this.defaultLinkColor = this.lineColor;
|
||||
this.titleColor = this.textColor;
|
||||
this.edgeLabelBackground = this.labelBackground;
|
||||
|
||||
/* Sequence Diagram variables */
|
||||
|
||||
// this.actorBorder = lighten(this.border1, 0.5);
|
||||
this.actorBorder = lighten(this.border1, 23);
|
||||
this.actorBkg = this.mainBkg;
|
||||
this.actorTextColor = 'black';
|
||||
this.actorLineColor = 'grey';
|
||||
this.labelBoxBkgColor = this.actorBkg;
|
||||
this.signalColor = this.textColor;
|
||||
this.signalTextColor = this.textColor;
|
||||
this.labelBoxBorderColor = this.actorBorder;
|
||||
this.labelTextColor = this.actorTextColor;
|
||||
this.loopTextColor = this.actorTextColor;
|
||||
this.noteBorderColor = this.border2;
|
||||
this.noteTextColor = this.actorTextColor;
|
||||
this.activationBorderColor = darken(this.secondaryColor, 10);
|
||||
this.activationBkgColor = this.secondaryColor;
|
||||
this.sequenceNumberColor = 'white';
|
||||
|
||||
/* Gantt chart variables */
|
||||
|
||||
this.taskTextColor = this.taskTextLightColor;
|
||||
this.taskTextOutsideColor = this.taskTextDarkColor;
|
||||
this.sectionBkgColor = this.tertiaryColor;
|
||||
this.altSectionBkgColor = 'white';
|
||||
this.sectionBkgColor = this.secondaryColor;
|
||||
this.sectionBkgColor2 = this.tertiaryColor;
|
||||
this.altSectionBkgColor = 'white';
|
||||
this.sectionBkgColor2 = this.primaryColor;
|
||||
this.taskBorderColor = lighten(this.primaryColor, 23);
|
||||
this.taskBkgColor = this.primaryColor;
|
||||
this.taskTextLightColor = 'white';
|
||||
this.taskTextColor = 'calculated';
|
||||
this.taskTextDarkColor = 'black';
|
||||
this.taskTextOutsideColor = 'calculated';
|
||||
this.taskTextClickableColor = '#003163';
|
||||
this.activeTaskBorderColor = this.primaryColor;
|
||||
this.activeTaskBkgColor = lighten(this.primaryColor, 23);
|
||||
this.gridColor = 'lightgrey';
|
||||
this.doneTaskBkgColor = 'lightgrey';
|
||||
this.doneTaskBorderColor = 'grey';
|
||||
this.critBorderColor = '#ff8888';
|
||||
this.critBkgColor = 'red';
|
||||
this.todayLineColor = 'red';
|
||||
|
||||
/* state colors */
|
||||
this.labelColor = 'black';
|
||||
this.errorBkgColor = '#552222';
|
||||
this.errorTextColor = '#552222';
|
||||
|
||||
/* state colors */
|
||||
|
||||
/* class */
|
||||
this.classText = this.textColor;
|
||||
|
||||
/* user-journey */
|
||||
this.fillType0 = this.primaryColor;
|
||||
this.fillType1 = this.secondaryColor;
|
||||
this.fillType2 = adjust(this.primaryColor, { h: 64 });
|
||||
this.fillType3 = adjust(this.secondaryColor, { h: 64 });
|
||||
this.fillType4 = adjust(this.primaryColor, { h: -64 });
|
||||
this.fillType5 = adjust(this.secondaryColor, { h: -64 });
|
||||
this.fillType6 = adjust(this.primaryColor, { h: 128 });
|
||||
this.fillType7 = adjust(this.secondaryColor, { h: 128 });
|
||||
}
|
||||
calculate(overrides) {
|
||||
if (typeof overrides !== 'object') {
|
||||
// Calculate colors form base colors
|
||||
this.updateColors();
|
||||
return;
|
||||
}
|
||||
|
||||
const keys = Object.keys(overrides);
|
||||
|
||||
// Copy values from overrides, this is mainly for base colors
|
||||
keys.forEach(k => {
|
||||
this[k] = overrides[k];
|
||||
});
|
||||
|
||||
// Calculate colors form base colors
|
||||
this.updateColors();
|
||||
// Copy values from overrides again in case of an override of derived value
|
||||
keys.forEach(k => {
|
||||
this[k] = overrides[k];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const getThemeVariables = userOverrides => {
|
||||
const theme = new Theme();
|
||||
theme.calculate(userOverrides);
|
||||
return theme;
|
||||
};
|
159
src/themes/theme-dark.js
Normal file
159
src/themes/theme-dark.js
Normal file
@ -0,0 +1,159 @@
|
||||
import { invert, lighten, darken, rgba, adjust } from 'khroma';
|
||||
|
||||
class Theme {
|
||||
constructor() {
|
||||
this.background = '#333';
|
||||
this.primaryColor = '#1f2020';
|
||||
this.secondaryColor = lighten(this.primaryColor, 16);
|
||||
this.mainBkg = '#1f2020';
|
||||
this.secondBkg = 'calculated';
|
||||
this.mainContrastColor = 'lightgrey';
|
||||
this.darkTextColor = lighten(invert('#323D47'), 10);
|
||||
this.lineColor = 'calculated';
|
||||
this.border1 = '#81B1DB';
|
||||
this.border2 = rgba(255, 255, 255, 0.25);
|
||||
this.arrowheadColor = 'calculated';
|
||||
this.fontFamily = '"trebuchet ms", verdana, arial';
|
||||
this.fontSize = '16px';
|
||||
this.labelBackground = '#181818';
|
||||
this.textColor = '#ccc';
|
||||
/* Flowchart variables */
|
||||
|
||||
this.nodeBkg = 'calculated';
|
||||
this.nodeBorder = 'calculated';
|
||||
this.clusterBkg = 'calculated';
|
||||
this.clusterBorder = 'calculated';
|
||||
this.defaultLinkColor = 'calculated';
|
||||
this.titleColor = '#F9FFFE';
|
||||
this.edgeLabelBackground = 'calculated';
|
||||
|
||||
/* Sequence Diagram variables */
|
||||
|
||||
this.actorBorder = 'calculated';
|
||||
this.actorBkg = 'calculated';
|
||||
this.actorTextColor = 'calculated';
|
||||
this.actorLineColor = 'calculated';
|
||||
this.signalColor = 'calculated';
|
||||
this.signalTextColor = 'calculated';
|
||||
this.labelBoxBkgColor = 'calculated';
|
||||
this.labelBoxBorderColor = 'calculated';
|
||||
this.labelTextColor = 'calculated';
|
||||
this.loopTextColor = 'calculated';
|
||||
this.noteBorderColor = 'calculated';
|
||||
this.noteBkgColor = '#fff5ad';
|
||||
this.noteTextColor = 'calculated';
|
||||
this.activationBorderColor = 'calculated';
|
||||
this.activationBkgColor = 'calculated';
|
||||
this.sequenceNumberColor = 'black';
|
||||
|
||||
/* Gantt chart variables */
|
||||
|
||||
this.sectionBkgColor = darken('#EAE8D9', 30);
|
||||
this.altSectionBkgColor = 'calculated';
|
||||
this.sectionBkgColor2 = '#EAE8D9';
|
||||
this.taskBorderColor = rgba(255, 255, 255, 70);
|
||||
this.taskBkgColor = 'calculated';
|
||||
this.taskTextColor = 'calculated';
|
||||
this.taskTextLightColor = 'calculated';
|
||||
this.taskTextOutsideColor = 'calculated';
|
||||
this.taskTextClickableColor = '#003163';
|
||||
this.activeTaskBorderColor = rgba(255, 255, 255, 50);
|
||||
this.activeTaskBkgColor = '#81B1DB';
|
||||
this.gridColor = 'calculated';
|
||||
this.doneTaskBkgColor = 'calculated';
|
||||
this.doneTaskBorderColor = 'grey';
|
||||
this.critBorderColor = '#E83737';
|
||||
this.critBkgColor = '#E83737';
|
||||
this.taskTextDarkColor = 'calculated';
|
||||
this.todayLineColor = '#DB5757';
|
||||
|
||||
/* state colors */
|
||||
this.labelColor = 'calculated';
|
||||
|
||||
this.errorBkgColor = '#a44141';
|
||||
this.errorTextColor = '#ddd';
|
||||
}
|
||||
updateColors() {
|
||||
this.secondBkg = lighten(this.mainBkg, 16);
|
||||
this.lineColor = this.mainContrastColor;
|
||||
this.arrowheadColor = this.mainContrastColor;
|
||||
/* Flowchart variables */
|
||||
|
||||
this.nodeBkg = this.mainBkg;
|
||||
this.nodeBorder = this.border1;
|
||||
this.clusterBkg = this.secondBkg;
|
||||
this.clusterBorder = this.border2;
|
||||
this.defaultLinkColor = this.lineColor;
|
||||
this.edgeLabelBackground = lighten(this.labelBackground, 25);
|
||||
|
||||
/* Sequence Diagram variables */
|
||||
|
||||
this.actorBorder = this.border1;
|
||||
this.actorBkg = this.mainBkg;
|
||||
this.actorTextColor = this.mainContrastColor;
|
||||
this.actorLineColor = this.mainContrastColor;
|
||||
this.signalColor = this.mainContrastColor;
|
||||
this.signalTextColor = this.mainContrastColor;
|
||||
this.labelBoxBkgColor = this.actorBkg;
|
||||
this.labelBoxBorderColor = this.actorBorder;
|
||||
this.labelTextColor = this.mainContrastColor;
|
||||
this.loopTextColor = this.mainContrastColor;
|
||||
this.noteBorderColor = this.border2;
|
||||
this.noteTextColor = this.mainBkg;
|
||||
this.activationBorderColor = this.border1;
|
||||
this.activationBkgColor = this.secondBkg;
|
||||
|
||||
/* Gantt chart variables */
|
||||
|
||||
this.altSectionBkgColor = this.background;
|
||||
this.taskBkgColor = lighten(this.mainBkg, 23);
|
||||
this.taskTextColor = this.darkTextColor;
|
||||
this.taskTextLightColor = this.mainContrastColor;
|
||||
this.taskTextOutsideColor = this.taskTextLightColor;
|
||||
this.gridColor = this.mainContrastColor;
|
||||
this.doneTaskBkgColor = this.mainContrastColor;
|
||||
this.taskTextDarkColor = this.darkTextColor;
|
||||
|
||||
/* state colors */
|
||||
this.labelColor = this.textColor;
|
||||
this.altBackground = lighten(this.background, 20);
|
||||
|
||||
this.fillType0 = this.primaryColor;
|
||||
this.fillType1 = this.secondaryColor;
|
||||
this.fillType2 = adjust(this.primaryColor, { h: 64 });
|
||||
this.fillType3 = adjust(this.secondaryColor, { h: 64 });
|
||||
this.fillType4 = adjust(this.primaryColor, { h: -64 });
|
||||
this.fillType5 = adjust(this.secondaryColor, { h: -64 });
|
||||
this.fillType6 = adjust(this.primaryColor, { h: 128 });
|
||||
this.fillType7 = adjust(this.secondaryColor, { h: 128 });
|
||||
/* class */
|
||||
this.classText = this.nodeBorder;
|
||||
}
|
||||
calculate(overrides) {
|
||||
if (typeof overrides !== 'object') {
|
||||
// Calculate colors form base colors
|
||||
this.updateColors();
|
||||
return;
|
||||
}
|
||||
|
||||
const keys = Object.keys(overrides);
|
||||
|
||||
// Copy values from overrides, this is mainly for base colors
|
||||
keys.forEach(k => {
|
||||
this[k] = overrides[k];
|
||||
});
|
||||
|
||||
// Calculate colors form base colors
|
||||
this.updateColors();
|
||||
// Copy values from overrides again in case of an override of derived value
|
||||
keys.forEach(k => {
|
||||
this[k] = overrides[k];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const getThemeVariables = userOverrides => {
|
||||
const theme = new Theme();
|
||||
theme.calculate(userOverrides);
|
||||
return theme;
|
||||
};
|
165
src/themes/theme-default.js
Normal file
165
src/themes/theme-default.js
Normal file
@ -0,0 +1,165 @@
|
||||
import { lighten, rgba, adjust } from 'khroma';
|
||||
|
||||
class Theme {
|
||||
constructor() {
|
||||
/* Base variables */
|
||||
this.primaryColor = '#ECECFF';
|
||||
this.secondaryColor = '#ffffde';
|
||||
this.background = 'white';
|
||||
this.mainBkg = '#ECECFF';
|
||||
this.secondBkg = '#ffffde';
|
||||
this.lineColor = '#333333';
|
||||
this.border1 = '#9370DB';
|
||||
this.border2 = '#aaaa33';
|
||||
this.arrowheadColor = '#333333';
|
||||
this.fontFamily = '"trebuchet ms", verdana, arial';
|
||||
this.fontSize = '16px';
|
||||
this.labelBackground = '#e8e8e8';
|
||||
this.textColor = '#333';
|
||||
|
||||
/* Flowchart variables */
|
||||
|
||||
this.nodeBkg = 'calculated';
|
||||
this.nodeBorder = 'calculated';
|
||||
this.clusterBkg = 'calculated';
|
||||
this.clusterBorder = 'calculated';
|
||||
this.defaultLinkColor = 'calculated';
|
||||
this.titleColor = 'calculated';
|
||||
this.edgeLabelBackground = 'calculated';
|
||||
|
||||
/* Sequence Diagram variables */
|
||||
|
||||
this.actorBorder = 'calculated';
|
||||
this.actorBkg = 'calculated';
|
||||
this.actorTextColor = 'black';
|
||||
this.actorLineColor = 'grey';
|
||||
this.signalColor = 'calculated';
|
||||
this.signalTextColor = 'calculated';
|
||||
this.labelBoxBkgColor = 'calculated';
|
||||
this.labelBoxBorderColor = 'calculated';
|
||||
this.labelTextColor = 'calculated';
|
||||
this.loopTextColor = 'calculated';
|
||||
this.noteBorderColor = 'calculated';
|
||||
this.noteBkgColor = '#fff5ad';
|
||||
this.noteTextColor = 'calculated';
|
||||
this.activationBorderColor = '#666';
|
||||
this.activationBkgColor = '#f4f4f4';
|
||||
this.sequenceNumberColor = 'white';
|
||||
|
||||
/* Gantt chart variables */
|
||||
|
||||
this.sectionBkgColor = 'calculated';
|
||||
this.altSectionBkgColor = 'calculated';
|
||||
this.sectionBkgColor2 = 'calculated';
|
||||
this.taskBorderColor = 'calculated';
|
||||
this.taskBkgColor = 'calculated';
|
||||
this.taskTextLightColor = 'calculated';
|
||||
this.taskTextColor = this.taskTextLightColor;
|
||||
this.taskTextDarkColor = 'calculated';
|
||||
this.taskTextOutsideColor = this.taskTextDarkColor;
|
||||
this.taskTextClickableColor = 'calculated';
|
||||
this.activeTaskBorderColor = 'calculated';
|
||||
this.activeTaskBkgColor = 'calculated';
|
||||
this.gridColor = 'calculated';
|
||||
this.doneTaskBkgColor = 'calculated';
|
||||
this.doneTaskBorderColor = 'calculated';
|
||||
this.critBorderColor = 'calculated';
|
||||
this.critBkgColor = 'calculated';
|
||||
this.todayLineColor = 'calculated';
|
||||
|
||||
this.sectionBkgColor = rgba(102, 102, 255, 0.49);
|
||||
this.altSectionBkgColor = 'white';
|
||||
this.sectionBkgColor2 = '#fff400';
|
||||
this.taskBorderColor = '#534fbc';
|
||||
this.taskBkgColor = '#8a90dd';
|
||||
this.taskTextLightColor = 'white';
|
||||
this.taskTextColor = 'calculated';
|
||||
this.taskTextDarkColor = 'black';
|
||||
this.taskTextOutsideColor = 'calculated';
|
||||
this.taskTextClickableColor = '#003163';
|
||||
this.activeTaskBorderColor = '#534fbc';
|
||||
this.activeTaskBkgColor = '#bfc7ff';
|
||||
this.gridColor = 'lightgrey';
|
||||
this.doneTaskBkgColor = 'lightgrey';
|
||||
this.doneTaskBorderColor = 'grey';
|
||||
this.critBorderColor = '#ff8888';
|
||||
this.critBkgColor = 'red';
|
||||
this.todayLineColor = 'red';
|
||||
|
||||
/* state colors */
|
||||
this.labelColor = 'black';
|
||||
this.errorBkgColor = '#552222';
|
||||
this.errorTextColor = '#552222';
|
||||
this.updateColors();
|
||||
}
|
||||
updateColors() {
|
||||
/* Flowchart variables */
|
||||
|
||||
this.nodeBkg = this.mainBkg;
|
||||
this.nodeBorder = this.border1; // border 1
|
||||
this.clusterBkg = this.secondBkg;
|
||||
this.clusterBorder = this.border2;
|
||||
this.defaultLinkColor = this.lineColor;
|
||||
this.titleColor = this.textColor;
|
||||
this.edgeLabelBackground = this.labelBackground;
|
||||
|
||||
/* Sequence Diagram variables */
|
||||
|
||||
// this.actorBorder = lighten(this.border1, 0.5);
|
||||
this.actorBorder = lighten(this.border1, 23);
|
||||
this.actorBkg = this.mainBkg;
|
||||
this.labelBoxBkgColor = this.actorBkg;
|
||||
this.signalColor = this.textColor;
|
||||
this.signalTextColor = this.textColor;
|
||||
this.labelBoxBorderColor = this.actorBorder;
|
||||
this.labelTextColor = this.actorTextColor;
|
||||
this.loopTextColor = this.actorTextColor;
|
||||
this.noteBorderColor = this.border2;
|
||||
this.noteTextColor = this.actorTextColor;
|
||||
|
||||
/* Gantt chart variables */
|
||||
|
||||
this.taskTextColor = this.taskTextLightColor;
|
||||
this.taskTextOutsideColor = this.taskTextDarkColor;
|
||||
|
||||
/* state colors */
|
||||
/* class */
|
||||
this.classText = this.nodeBorder;
|
||||
/* journey */
|
||||
this.fillType0 = this.primaryColor;
|
||||
this.fillType1 = this.secondaryColor;
|
||||
this.fillType2 = adjust(this.primaryColor, { h: 64 });
|
||||
this.fillType3 = adjust(this.secondaryColor, { h: 64 });
|
||||
this.fillType4 = adjust(this.primaryColor, { h: -64 });
|
||||
this.fillType5 = adjust(this.secondaryColor, { h: -64 });
|
||||
this.fillType6 = adjust(this.primaryColor, { h: 128 });
|
||||
this.fillType7 = adjust(this.secondaryColor, { h: 128 });
|
||||
}
|
||||
calculate(overrides) {
|
||||
if (typeof overrides !== 'object') {
|
||||
// Calculate colors form base colors
|
||||
this.updateColors();
|
||||
return;
|
||||
}
|
||||
|
||||
const keys = Object.keys(overrides);
|
||||
|
||||
// Copy values from overrides, this is mainly for base colors
|
||||
keys.forEach(k => {
|
||||
this[k] = overrides[k];
|
||||
});
|
||||
|
||||
// Calculate colors form base colors
|
||||
this.updateColors();
|
||||
// Copy values from overrides again in case of an override of derived value
|
||||
keys.forEach(k => {
|
||||
this[k] = overrides[k];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const getThemeVariables = userOverrides => {
|
||||
const theme = new Theme();
|
||||
theme.calculate(userOverrides);
|
||||
return theme;
|
||||
};
|
140
src/themes/theme-forest.js
Normal file
140
src/themes/theme-forest.js
Normal file
@ -0,0 +1,140 @@
|
||||
import { darken, adjust } from 'khroma';
|
||||
class Theme {
|
||||
constructor() {
|
||||
/* Base vales */
|
||||
this.primaryColor = '#cde498';
|
||||
this.secondaryColor = '#cdffb2';
|
||||
this.background = 'white';
|
||||
this.mainBkg = '#cde498';
|
||||
this.secondBkg = '#cdffb2';
|
||||
this.lineColor = 'green';
|
||||
this.border1 = '#13540c';
|
||||
this.border2 = '#6eaa49';
|
||||
this.arrowheadColor = 'green';
|
||||
this.fontFamily = '"trebuchet ms", verdana, arial';
|
||||
this.fontSize = '16px';
|
||||
|
||||
/* Flowchart variables */
|
||||
|
||||
this.nodeBkg = 'calculated';
|
||||
this.nodeBorder = 'calculated';
|
||||
this.clusterBkg = 'calculated';
|
||||
this.clusterBorder = 'calculated';
|
||||
this.defaultLinkColor = 'calculated';
|
||||
this.titleColor = '#333';
|
||||
this.edgeLabelBackground = '#e8e8e8';
|
||||
|
||||
/* Sequence Diagram variables */
|
||||
|
||||
this.actorBorder = 'calculated';
|
||||
this.actorBkg = 'calculated';
|
||||
this.actorTextColor = 'black';
|
||||
this.actorLineColor = 'grey';
|
||||
this.signalColor = '#333';
|
||||
this.signalTextColor = '#333';
|
||||
this.labelBoxBkgColor = 'calculated';
|
||||
this.labelBoxBorderColor = '#326932';
|
||||
this.labelTextColor = 'calculated';
|
||||
this.loopTextColor = 'calculated';
|
||||
this.noteBorderColor = 'calculated';
|
||||
this.noteBkgColor = '#fff5ad';
|
||||
this.noteTextColor = 'calculated';
|
||||
this.activationBorderColor = '#666';
|
||||
this.activationBkgColor = '#f4f4f4';
|
||||
this.sequenceNumberColor = 'white';
|
||||
|
||||
/* Gantt chart variables */
|
||||
|
||||
this.sectionBkgColor = '#6eaa49';
|
||||
this.altSectionBkgColor = 'white';
|
||||
this.sectionBkgColor2 = '#6eaa49';
|
||||
this.taskBorderColor = 'calculated';
|
||||
this.taskBkgColor = '#487e3a';
|
||||
this.taskTextLightColor = 'white';
|
||||
this.taskTextColor = 'calculated';
|
||||
this.taskTextDarkColor = 'black';
|
||||
this.taskTextOutsideColor = 'calculated';
|
||||
this.taskTextClickableColor = '#003163';
|
||||
this.activeTaskBorderColor = 'calculated';
|
||||
this.activeTaskBkgColor = 'calculated';
|
||||
this.gridColor = 'lightgrey';
|
||||
this.doneTaskBkgColor = 'lightgrey';
|
||||
this.doneTaskBorderColor = 'grey';
|
||||
this.critBorderColor = '#ff8888';
|
||||
this.critBkgColor = 'red';
|
||||
this.todayLineColor = 'red';
|
||||
|
||||
/* state colors */
|
||||
this.labelColor = 'black';
|
||||
|
||||
this.errorBkgColor = '#552222';
|
||||
this.errorTextColor = '#552222';
|
||||
}
|
||||
updateColors() {
|
||||
/* Flowchart variables */
|
||||
|
||||
this.nodeBkg = this.mainBkg;
|
||||
this.nodeBorder = this.border1;
|
||||
this.clusterBkg = this.secondBkg;
|
||||
this.clusterBorder = this.border2;
|
||||
this.defaultLinkColor = this.lineColor;
|
||||
|
||||
/* Sequence Diagram variables */
|
||||
|
||||
this.actorBorder = darken(this.mainBkg, 20);
|
||||
this.actorBkg = this.mainBkg;
|
||||
this.labelBoxBkgColor = this.actorBkg;
|
||||
this.labelTextColor = this.actorTextColor;
|
||||
this.loopTextColor = this.actorTextColor;
|
||||
this.noteBorderColor = this.border2;
|
||||
this.noteTextColor = this.actorTextColor;
|
||||
|
||||
/* Gantt chart variables */
|
||||
|
||||
this.taskBorderColor = this.border1;
|
||||
this.taskTextColor = this.taskTextLightColor;
|
||||
this.taskTextOutsideColor = this.taskTextDarkColor;
|
||||
this.activeTaskBorderColor = this.taskBorderColor;
|
||||
this.activeTaskBkgColor = this.mainBkg;
|
||||
|
||||
/* state colors */
|
||||
/* class */
|
||||
this.classText = this.nodeBorder;
|
||||
/* journey */
|
||||
this.fillType0 = this.primaryColor;
|
||||
this.fillType1 = this.secondaryColor;
|
||||
this.fillType2 = adjust(this.primaryColor, { h: 64 });
|
||||
this.fillType3 = adjust(this.secondaryColor, { h: 64 });
|
||||
this.fillType4 = adjust(this.primaryColor, { h: -64 });
|
||||
this.fillType5 = adjust(this.secondaryColor, { h: -64 });
|
||||
this.fillType6 = adjust(this.primaryColor, { h: 128 });
|
||||
this.fillType7 = adjust(this.secondaryColor, { h: 128 });
|
||||
}
|
||||
calculate(overrides) {
|
||||
if (typeof overrides !== 'object') {
|
||||
// Calculate colors form base colors
|
||||
this.updateColors();
|
||||
return;
|
||||
}
|
||||
|
||||
const keys = Object.keys(overrides);
|
||||
|
||||
// Copy values from overrides, this is mainly for base colors
|
||||
keys.forEach(k => {
|
||||
this[k] = overrides[k];
|
||||
});
|
||||
|
||||
// Calculate colors form base colors
|
||||
this.updateColors();
|
||||
// Copy values from overrides again in case of an override of derived value
|
||||
keys.forEach(k => {
|
||||
this[k] = overrides[k];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const getThemeVariables = userOverrides => {
|
||||
const theme = new Theme();
|
||||
theme.calculate(userOverrides);
|
||||
return theme;
|
||||
};
|
173
src/themes/theme-neutral.js
Normal file
173
src/themes/theme-neutral.js
Normal file
@ -0,0 +1,173 @@
|
||||
import { darken, lighten, adjust } from 'khroma';
|
||||
|
||||
// const Color = require ( 'khroma/dist/color' ).default
|
||||
// Color.format.hex.stringify(Color.parse('hsl(210, 66.6666666667%, 95%)')); // => "#EAF2FB"
|
||||
|
||||
class Theme {
|
||||
constructor() {
|
||||
this.primaryColor = '#eee';
|
||||
this.contrast = '#26a';
|
||||
this.secondaryColor = lighten(this.contrast, 55);
|
||||
this.background = 'white';
|
||||
this.mainBkg = '#eee';
|
||||
this.secondBkg = 'calculated';
|
||||
this.lineColor = '#666';
|
||||
this.border1 = '#999';
|
||||
this.border2 = 'calculated';
|
||||
this.note = '#ffa';
|
||||
this.text = '#333';
|
||||
this.critical = '#d42';
|
||||
this.done = '#bbb';
|
||||
this.arrowheadColor = '#333333';
|
||||
this.fontFamily = '"trebuchet ms", verdana, arial';
|
||||
this.fontSize = '16px';
|
||||
|
||||
/* Flowchart variables */
|
||||
|
||||
this.nodeBkg = 'calculated';
|
||||
this.nodeBorder = 'calculated';
|
||||
this.clusterBkg = 'calculated';
|
||||
this.clusterBorder = 'calculated';
|
||||
this.defaultLinkColor = 'calculated';
|
||||
this.titleColor = 'calculated';
|
||||
this.edgeLabelBackground = 'white';
|
||||
|
||||
/* Sequence Diagram variables */
|
||||
|
||||
this.actorBorder = 'calculated';
|
||||
this.actorBkg = 'calculated';
|
||||
this.actorTextColor = 'calculated';
|
||||
this.actorLineColor = 'calculated';
|
||||
this.signalColor = 'calculated';
|
||||
this.signalTextColor = 'calculated';
|
||||
this.labelBoxBkgColor = 'calculated';
|
||||
this.labelBoxBorderColor = 'calculated';
|
||||
this.labelTextColor = 'calculated';
|
||||
this.loopTextColor = 'calculated';
|
||||
this.noteBorderColor = 'calculated';
|
||||
this.noteBkgColor = 'calculated';
|
||||
this.noteTextColor = 'calculated';
|
||||
this.activationBorderColor = '#666';
|
||||
this.activationBkgColor = '#f4f4f4';
|
||||
this.sequenceNumberColor = 'white';
|
||||
|
||||
/* Gantt chart variables */
|
||||
|
||||
this.sectionBkgColor = 'calculated';
|
||||
this.altSectionBkgColor = 'white';
|
||||
this.sectionBkgColor2 = 'calculated';
|
||||
this.taskBorderColor = 'calculated';
|
||||
this.taskBkgColor = 'calculated';
|
||||
this.taskTextLightColor = 'white';
|
||||
this.taskTextColor = 'calculated';
|
||||
this.taskTextDarkColor = 'calculated';
|
||||
this.taskTextOutsideColor = 'calculated';
|
||||
this.taskTextClickableColor = '#003163';
|
||||
this.activeTaskBorderColor = 'calculated';
|
||||
this.activeTaskBkgColor = 'calculated';
|
||||
this.gridColor = 'calculated';
|
||||
this.doneTaskBkgColor = 'calculated';
|
||||
this.doneTaskBorderColor = 'calculated';
|
||||
this.critBkgColor = 'calculated';
|
||||
this.critBorderColor = 'calculated';
|
||||
this.todayLineColor = 'calculated';
|
||||
|
||||
/* state colors */
|
||||
this.labelColor = 'black';
|
||||
|
||||
this.errorBkgColor = '#552222';
|
||||
this.errorTextColor = '#552222';
|
||||
}
|
||||
updateColors() {
|
||||
this.secondBkg = lighten(this.contrast, 55);
|
||||
this.border2 = this.contrast;
|
||||
|
||||
/* Flowchart variables */
|
||||
|
||||
this.nodeBkg = this.mainBkg;
|
||||
this.nodeBorder = this.border1;
|
||||
this.clusterBkg = this.secondBkg;
|
||||
this.clusterBorder = this.border2;
|
||||
this.defaultLinkColor = this.lineColor;
|
||||
this.titleColor = this.text;
|
||||
|
||||
/* Sequence Diagram variables */
|
||||
|
||||
this.actorBorder = lighten(this.border1, 23);
|
||||
this.actorBkg = this.mainBkg;
|
||||
this.actorTextColor = this.text;
|
||||
this.actorLineColor = this.lineColor;
|
||||
this.signalColor = this.text;
|
||||
this.signalTextColor = this.text;
|
||||
this.labelBoxBkgColor = this.actorBkg;
|
||||
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;
|
||||
|
||||
/* Gantt chart variables */
|
||||
|
||||
this.sectionBkgColor = lighten(this.contrast, 30);
|
||||
this.sectionBkgColor2 = lighten(this.contrast, 30);
|
||||
|
||||
this.taskBorderColor = darken(this.contrast, 10);
|
||||
|
||||
this.taskBkgColor = this.contrast;
|
||||
this.taskTextColor = this.taskTextLightColor;
|
||||
this.taskTextDarkColor = this.text;
|
||||
this.taskTextOutsideColor = this.taskTextDarkColor;
|
||||
this.activeTaskBorderColor = this.taskBorderColor;
|
||||
this.activeTaskBkgColor = this.mainBkg;
|
||||
this.gridColor = lighten(this.border1, 30);
|
||||
|
||||
this.doneTaskBkgColor = this.done;
|
||||
this.doneTaskBorderColor = this.lineColor;
|
||||
this.critBkgColor = this.critical;
|
||||
this.critBorderColor = darken(this.critBkgColor, 10);
|
||||
|
||||
this.todayLineColor = this.critBkgColor;
|
||||
|
||||
/* state colors */
|
||||
/* class */
|
||||
this.classText = this.nodeBorder;
|
||||
/* journey */
|
||||
this.fillType0 = this.primaryColor;
|
||||
this.fillType1 = this.secondaryColor;
|
||||
this.fillType2 = adjust(this.primaryColor, { h: 64 });
|
||||
this.fillType3 = adjust(this.secondaryColor, { h: 64 });
|
||||
this.fillType4 = adjust(this.primaryColor, { h: -64 });
|
||||
this.fillType5 = adjust(this.secondaryColor, { h: -64 });
|
||||
this.fillType6 = adjust(this.primaryColor, { h: 128 });
|
||||
this.fillType7 = adjust(this.secondaryColor, { h: 128 });
|
||||
}
|
||||
calculate(overrides) {
|
||||
if (typeof overrides !== 'object') {
|
||||
// Calculate colors form base colors
|
||||
this.updateColors();
|
||||
return;
|
||||
}
|
||||
|
||||
const keys = Object.keys(overrides);
|
||||
|
||||
// Copy values from overrides, this is mainly for base colors
|
||||
keys.forEach(k => {
|
||||
this[k] = overrides[k];
|
||||
});
|
||||
|
||||
// Calculate colors form base colors
|
||||
this.updateColors();
|
||||
// Copy values from overrides again in case of an override of derived value
|
||||
keys.forEach(k => {
|
||||
this[k] = overrides[k];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const getThemeVariables = userOverrides => {
|
||||
const theme = new Theme();
|
||||
theme.calculate(userOverrides);
|
||||
console.info('Theme', userOverrides, theme);
|
||||
return theme;
|
||||
};
|
351
src/utils.js
351
src/utils.js
@ -9,10 +9,13 @@ import {
|
||||
curveNatural,
|
||||
curveStep,
|
||||
curveStepAfter,
|
||||
curveStepBefore
|
||||
curveStepBefore,
|
||||
select
|
||||
} from 'd3';
|
||||
import { logger } from './logger';
|
||||
import { sanitizeUrl } from '@braintree/sanitize-url';
|
||||
import common from './diagrams/common/common';
|
||||
// import cryptoRandomString from 'crypto-random-string';
|
||||
|
||||
// Effectively an enum of the supported curve types, accessible by name
|
||||
const d3CurveTypes = {
|
||||
@ -60,17 +63,29 @@ const anyComment = /\s*%%.*\n/gm;
|
||||
* ```
|
||||
*
|
||||
* @param {string} text The text defining the graph
|
||||
* @returns {object} the json object representing the init to pass to mermaid.initialize()
|
||||
* @returns {object} the json object representing the init passed to mermaid.initialize()
|
||||
*/
|
||||
export const detectInit = function(text) {
|
||||
let inits = detectDirective(text, /(?:init\b)|(?:initialize\b)/);
|
||||
let results = {};
|
||||
if (Array.isArray(inits)) {
|
||||
let args = inits.map(init => init.args);
|
||||
results = Object.assign(results, ...args);
|
||||
results = assignWithDepth(results, [...args]);
|
||||
} else {
|
||||
results = inits.args;
|
||||
}
|
||||
if (results) {
|
||||
let type = detectType(text);
|
||||
['config'].forEach(prop => {
|
||||
if (typeof results[prop] !== 'undefined') {
|
||||
if (type === 'flowchart-v2') {
|
||||
type = 'flowchart';
|
||||
}
|
||||
results[type] = results[prop];
|
||||
delete results[prop];
|
||||
}
|
||||
});
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
@ -91,8 +106,8 @@ export const detectInit = function(text) {
|
||||
* ```
|
||||
*
|
||||
* @param {string} text The text defining the graph
|
||||
* @param {string|RegExp} type The directive to return (default: null
|
||||
* @returns {object | Array} An object or Array representing the directive(s): { type: string, args: object|null } matchd by the input type
|
||||
* @param {string|RegExp} type The directive to return (default: null)
|
||||
* @returns {object | Array} An object or Array representing the directive(s): { type: string, args: object|null } matched by the input type
|
||||
* if a single directive was found, that directive object will be returned.
|
||||
*/
|
||||
export const detectDirective = function(text, type = null) {
|
||||
@ -209,6 +224,20 @@ export const detectType = function(text) {
|
||||
return 'flowchart';
|
||||
};
|
||||
|
||||
const memoize = (fn, resolver) => {
|
||||
let cache = {};
|
||||
return (...args) => {
|
||||
let n = resolver ? resolver.apply(this, args) : args[0];
|
||||
if (n in cache) {
|
||||
return cache[n];
|
||||
} else {
|
||||
let result = fn(...args);
|
||||
cache[n] = result;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @function isSubstringInArray
|
||||
* Detects whether a substring in present in a given array
|
||||
@ -244,13 +273,13 @@ export const formatUrl = (linkStr, config) => {
|
||||
};
|
||||
|
||||
export const runFunc = (functionName, ...params) => {
|
||||
var arrPaths = functionName.split('.');
|
||||
const arrPaths = functionName.split('.');
|
||||
|
||||
var len = arrPaths.length - 1;
|
||||
var fnName = arrPaths[len];
|
||||
const len = arrPaths.length - 1;
|
||||
const fnName = arrPaths[len];
|
||||
|
||||
var obj = window;
|
||||
for (var i = 0; i < len; i++) {
|
||||
let obj = window;
|
||||
for (let i = 0; i < len; i++) {
|
||||
obj = obj[arrPaths[i]];
|
||||
if (!obj) return;
|
||||
}
|
||||
@ -271,10 +300,8 @@ const traverseEdge = points => {
|
||||
});
|
||||
|
||||
// Traverse half of total distance along points
|
||||
const distanceToLabel = totalDistance / 2;
|
||||
|
||||
let remainingDistance = distanceToLabel;
|
||||
let center;
|
||||
let remainingDistance = totalDistance / 2;
|
||||
let center = undefined;
|
||||
prevPoint = undefined;
|
||||
points.forEach(point => {
|
||||
if (prevPoint && !center) {
|
||||
@ -301,8 +328,7 @@ const traverseEdge = points => {
|
||||
};
|
||||
|
||||
const calcLabelPosition = points => {
|
||||
const p = traverseEdge(points);
|
||||
return p;
|
||||
return traverseEdge(points);
|
||||
};
|
||||
|
||||
const calcCardinalityPosition = (isRelationTypePresent, points, initialPosition) => {
|
||||
@ -320,7 +346,7 @@ const calcCardinalityPosition = (isRelationTypePresent, points, initialPosition)
|
||||
const distanceToCardinalityPoint = 25;
|
||||
|
||||
let remainingDistance = distanceToCardinalityPoint;
|
||||
let center;
|
||||
let center = { x: 0, y: 0 };
|
||||
prevPoint = undefined;
|
||||
points.forEach(point => {
|
||||
if (prevPoint && !center) {
|
||||
@ -385,7 +411,296 @@ export const generateId = () => {
|
||||
);
|
||||
};
|
||||
|
||||
function makeid(length) {
|
||||
var result = '';
|
||||
var characters = '0123456789abcdef';
|
||||
var charactersLength = characters.length;
|
||||
for (var i = 0; i < length; i++) {
|
||||
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export const random = options => {
|
||||
return makeid(options.length);
|
||||
};
|
||||
|
||||
/**
|
||||
* @function assignWithDepth
|
||||
* Extends the functionality of {@link ObjectConstructor.assign} with the ability to merge arbitrary-depth objects
|
||||
* For each key in src with path `k` (recursively) performs an Object.assign(dst[`k`], src[`k`]) with
|
||||
* a slight change from the typical handling of undefined for dst[`k`]: instead of raising an error,
|
||||
* dst[`k`] is auto-initialized to {} and effectively merged with src[`k`]
|
||||
* <p>
|
||||
* Additionally, dissimilar types will not clobber unless the config.clobber parameter === true. Example:
|
||||
* ```
|
||||
* let config_0 = { foo: { bar: 'bar' }, bar: 'foo' };
|
||||
* let config_1 = { foo: 'foo', bar: 'bar' };
|
||||
* let result = assignWithDepth(config_0, config_1);
|
||||
* console.log(result);
|
||||
* //-> result: { foo: { bar: 'bar' }, bar: 'bar' }
|
||||
* ```
|
||||
* <p>
|
||||
* Traditional Object.assign would have clobbered foo in config_0 with foo in config_1.
|
||||
* <p>
|
||||
* If src is a destructured array of objects and dst is not an array, assignWithDepth will apply each element of src to dst
|
||||
* in order.
|
||||
* @param dst:any - the destination of the merge
|
||||
* @param src:any - the source object(s) to merge into destination
|
||||
* @param config:{ depth: number, clobber: boolean } - depth: depth to traverse within src and dst for merging -
|
||||
* clobber: should dissimilar types clobber (default: { depth: 2, clobber: false })
|
||||
* @returns {*}
|
||||
*/
|
||||
export const assignWithDepth = function(dst, src, config) {
|
||||
const { depth, clobber } = Object.assign({ depth: 2, clobber: false }, config);
|
||||
if (Array.isArray(src) && !Array.isArray(dst)) {
|
||||
src.forEach(s => assignWithDepth(dst, s, config));
|
||||
return dst;
|
||||
} else if (Array.isArray(src) && Array.isArray(dst)) {
|
||||
src.forEach(s => {
|
||||
if (dst.indexOf(s) === -1) {
|
||||
dst.push(s);
|
||||
}
|
||||
});
|
||||
return dst;
|
||||
}
|
||||
if (typeof dst === 'undefined' || depth <= 0) {
|
||||
if (dst !== undefined && dst !== null && typeof dst === 'object' && typeof src === 'object') {
|
||||
return Object.assign(dst, src);
|
||||
} else {
|
||||
return src;
|
||||
}
|
||||
}
|
||||
if (typeof src !== 'undefined' && typeof dst === 'object' && typeof src === 'object') {
|
||||
Object.keys(src).forEach(key => {
|
||||
if (
|
||||
typeof src[key] === 'object' &&
|
||||
(dst[key] === undefined || typeof dst[key] === 'object')
|
||||
) {
|
||||
if (dst[key] === undefined) {
|
||||
dst[key] = Array.isArray(src[key]) ? [] : {};
|
||||
}
|
||||
dst[key] = assignWithDepth(dst[key], src[key], { depth: depth - 1, clobber });
|
||||
} else if (clobber || (typeof dst[key] !== 'object' && typeof src[key] !== 'object')) {
|
||||
dst[key] = src[key];
|
||||
}
|
||||
});
|
||||
}
|
||||
return dst;
|
||||
};
|
||||
|
||||
export const getTextObj = function() {
|
||||
return {
|
||||
x: 0,
|
||||
y: 0,
|
||||
fill: undefined,
|
||||
anchor: 'start',
|
||||
style: '#666',
|
||||
width: 100,
|
||||
height: 100,
|
||||
textMargin: 0,
|
||||
rx: 0,
|
||||
ry: 0,
|
||||
valign: undefined
|
||||
};
|
||||
};
|
||||
|
||||
export const drawSimpleText = function(elem, textData) {
|
||||
// Remove and ignore br:s
|
||||
const nText = textData.text.replace(common.lineBreakRegex, ' ');
|
||||
|
||||
const textElem = elem.append('text');
|
||||
textElem.attr('x', textData.x);
|
||||
textElem.attr('y', textData.y);
|
||||
textElem.style('text-anchor', textData.anchor);
|
||||
textElem.style('font-family', textData.fontFamily);
|
||||
textElem.style('font-size', textData.fontSize);
|
||||
textElem.style('font-weight', textData.fontWeight);
|
||||
textElem.attr('fill', textData.fill);
|
||||
if (typeof textData.class !== 'undefined') {
|
||||
textElem.attr('class', textData.class);
|
||||
}
|
||||
|
||||
const span = textElem.append('tspan');
|
||||
span.attr('x', textData.x + textData.textMargin * 2);
|
||||
span.attr('fill', textData.fill);
|
||||
span.text(nText);
|
||||
|
||||
return textElem;
|
||||
};
|
||||
|
||||
export const wrapLabel = memoize(
|
||||
(label, maxWidth, config) => {
|
||||
if (!label) {
|
||||
return label;
|
||||
}
|
||||
config = Object.assign(
|
||||
{ fontSize: 12, fontWeight: 400, fontFamily: 'Arial', joinWith: '<br/>' },
|
||||
config
|
||||
);
|
||||
if (common.lineBreakRegex.test(label)) {
|
||||
return label;
|
||||
}
|
||||
const words = label.split(' ');
|
||||
const completedLines = [];
|
||||
let nextLine = '';
|
||||
words.forEach((word, index) => {
|
||||
const wordLength = calculateTextWidth(`${word} `, config);
|
||||
const nextLineLength = calculateTextWidth(nextLine, config);
|
||||
if (wordLength > maxWidth) {
|
||||
const { hyphenatedStrings, remainingWord } = breakString(word, maxWidth, '-', config);
|
||||
completedLines.push(nextLine, ...hyphenatedStrings);
|
||||
nextLine = remainingWord;
|
||||
} else if (nextLineLength + wordLength >= maxWidth) {
|
||||
completedLines.push(nextLine);
|
||||
nextLine = word;
|
||||
} else {
|
||||
nextLine = [nextLine, word].filter(Boolean).join(' ');
|
||||
}
|
||||
const currentWord = index + 1;
|
||||
const isLastWord = currentWord === words.length;
|
||||
if (isLastWord) {
|
||||
completedLines.push(nextLine);
|
||||
}
|
||||
});
|
||||
return completedLines.filter(line => line !== '').join(config.joinWith);
|
||||
},
|
||||
(label, maxWidth, config) =>
|
||||
`${label}-${maxWidth}-${config.fontSize}-${config.fontWeight}-${config.fontFamily}-${config.joinWith}`
|
||||
);
|
||||
|
||||
const breakString = memoize(
|
||||
(word, maxWidth, hyphenCharacter = '-', config) => {
|
||||
config = Object.assign(
|
||||
{ fontSize: 12, fontWeight: 400, fontFamily: 'Arial', margin: 0 },
|
||||
config
|
||||
);
|
||||
const characters = word.split('');
|
||||
const lines = [];
|
||||
let currentLine = '';
|
||||
characters.forEach((character, index) => {
|
||||
const nextLine = `${currentLine}${character}`;
|
||||
const lineWidth = calculateTextWidth(nextLine, config);
|
||||
if (lineWidth >= maxWidth) {
|
||||
const currentCharacter = index + 1;
|
||||
const isLastLine = characters.length === currentCharacter;
|
||||
const hyphenatedNextLine = `${nextLine}${hyphenCharacter}`;
|
||||
lines.push(isLastLine ? nextLine : hyphenatedNextLine);
|
||||
currentLine = '';
|
||||
} else {
|
||||
currentLine = nextLine;
|
||||
}
|
||||
});
|
||||
return { hyphenatedStrings: lines, remainingWord: currentLine };
|
||||
},
|
||||
(word, maxWidth, hyphenCharacter = '-', config) =>
|
||||
`${word}-${maxWidth}-${hyphenCharacter}-${config.fontSize}-${config.fontWeight}-${config.fontFamily}`
|
||||
);
|
||||
|
||||
/**
|
||||
* This calculates the text's height, taking into account the wrap breaks and
|
||||
* both the statically configured height, width, and the length of the text (in pixels).
|
||||
*
|
||||
* If the wrapped text text has greater height, we extend the height, so it's
|
||||
* value won't overflow.
|
||||
*
|
||||
* @return - The height for the given text
|
||||
* @param text the text to measure
|
||||
* @param config - the config for fontSize, fontFamily, and fontWeight all impacting the resulting size
|
||||
*/
|
||||
export const calculateTextHeight = function(text, config) {
|
||||
config = Object.assign(
|
||||
{ fontSize: 12, fontWeight: 400, fontFamily: 'Arial', margin: 15 },
|
||||
config
|
||||
);
|
||||
return calculateTextDimensions(text, config).height;
|
||||
};
|
||||
|
||||
/**
|
||||
* This calculates the width of the given text, font size and family.
|
||||
*
|
||||
* @return - The width for the given text
|
||||
* @param text - The text to calculate the width of
|
||||
* @param config - the config for fontSize, fontFamily, and fontWeight all impacting the resulting size
|
||||
*/
|
||||
export const calculateTextWidth = function(text, config) {
|
||||
config = Object.assign({ fontSize: 12, fontWeight: 400, fontFamily: 'Arial' }, config);
|
||||
return calculateTextDimensions(text, config).width;
|
||||
};
|
||||
|
||||
/**
|
||||
* This calculates the dimensions of the given text, font size, font family, font weight, and margins.
|
||||
*
|
||||
* @return - The width for the given text
|
||||
* @param text - The text to calculate the width of
|
||||
* @param config - the config for fontSize, fontFamily, fontWeight, and margin all impacting the resulting size
|
||||
*/
|
||||
export const calculateTextDimensions = memoize(
|
||||
function(text, config) {
|
||||
config = Object.assign({ fontSize: 12, fontWeight: 400, fontFamily: 'Arial' }, config);
|
||||
const { fontSize, fontFamily, fontWeight } = config;
|
||||
if (!text) {
|
||||
return { width: 0, height: 0 };
|
||||
}
|
||||
|
||||
// We can't really know if the user supplied font family will render on the user agent;
|
||||
// thus, we'll take the max width between the user supplied font family, and a default
|
||||
// of sans-serif.
|
||||
const fontFamilies = ['sans-serif', fontFamily];
|
||||
const lines = text.split(common.lineBreakRegex);
|
||||
let dims = [];
|
||||
|
||||
const body = select('body');
|
||||
// We don't want to leak DOM elements - if a removal operation isn't available
|
||||
// for any reason, do not continue.
|
||||
if (!body.remove) {
|
||||
return { width: 0, height: 0, lineHeight: 0 };
|
||||
}
|
||||
|
||||
const g = body.append('svg');
|
||||
|
||||
for (let fontFamily of fontFamilies) {
|
||||
let cheight = 0;
|
||||
let dim = { width: 0, height: 0, lineHeight: 0 };
|
||||
for (let line of lines) {
|
||||
const textObj = getTextObj();
|
||||
textObj.text = line;
|
||||
const textElem = drawSimpleText(g, textObj)
|
||||
.style('font-size', fontSize)
|
||||
.style('font-weight', fontWeight)
|
||||
.style('font-family', fontFamily);
|
||||
|
||||
let bBox = (textElem._groups || textElem)[0][0].getBBox();
|
||||
dim.width = Math.round(Math.max(dim.width, bBox.width));
|
||||
cheight = Math.round(bBox.height);
|
||||
dim.height += cheight;
|
||||
dim.lineHeight = Math.round(Math.max(dim.lineHeight, cheight));
|
||||
}
|
||||
dims.push(dim);
|
||||
}
|
||||
|
||||
g.remove();
|
||||
|
||||
let index =
|
||||
isNaN(dims[1].height) ||
|
||||
isNaN(dims[1].width) ||
|
||||
isNaN(dims[1].lineHeight) ||
|
||||
(dims[0].height > dims[1].height &&
|
||||
dims[0].width > dims[1].width &&
|
||||
dims[0].lineHeight > dims[1].lineHeight)
|
||||
? 0
|
||||
: 1;
|
||||
return dims[index];
|
||||
},
|
||||
(text, config) => `${text}-${config.fontSize}-${config.fontWeight}-${config.fontFamily}`
|
||||
);
|
||||
|
||||
export default {
|
||||
assignWithDepth,
|
||||
wrapLabel,
|
||||
calculateTextHeight,
|
||||
calculateTextWidth,
|
||||
calculateTextDimensions,
|
||||
detectInit,
|
||||
detectDirective,
|
||||
detectType,
|
||||
@ -396,5 +711,7 @@ export default {
|
||||
formatUrl,
|
||||
getStylesFromArray,
|
||||
generateId,
|
||||
random,
|
||||
memoize,
|
||||
runFunc
|
||||
};
|
||||
|
@ -1,6 +1,93 @@
|
||||
/* eslint-env jasmine */
|
||||
import utils from './utils';
|
||||
|
||||
describe('when assignWithDepth: should merge objects within objects', function() {
|
||||
it('should handle simple, depth:1 types (identity)', function() {
|
||||
let config_0 = { foo: 'bar', bar: 0 };
|
||||
let config_1 = { foo: 'bar', bar: 0 };
|
||||
let result = utils.assignWithDepth(config_0, config_1);
|
||||
expect(result).toEqual(config_1);
|
||||
});
|
||||
it('should handle simple, depth:1 types (dst: undefined)', function() {
|
||||
let config_0 = undefined;
|
||||
let config_1 = { foo: 'bar', bar: 0 };
|
||||
let result = utils.assignWithDepth(config_0, config_1);
|
||||
expect(result).toEqual(config_1);
|
||||
});
|
||||
it('should handle simple, depth:1 types (src: undefined)', function() {
|
||||
let config_0 = { foo: 'bar', bar: 0 };
|
||||
let config_1 = undefined;
|
||||
let result = utils.assignWithDepth(config_0, config_1);
|
||||
expect(result).toEqual(config_0);
|
||||
});
|
||||
it('should handle simple, depth:1 types (merge)', function() {
|
||||
let config_0 = { foo: 'bar', bar: 0 };
|
||||
let config_1 = { foo: 'foo' };
|
||||
let result = utils.assignWithDepth(config_0, config_1);
|
||||
expect(result).toEqual({ foo: 'foo', bar: 0});
|
||||
});
|
||||
it('should handle depth:2 types (dst: orphan)', function() {
|
||||
let config_0 = { foo: 'bar', bar: { foo: 'bar' } };
|
||||
let config_1 = { foo: 'bar' };
|
||||
let result = utils.assignWithDepth(config_0, config_1);
|
||||
expect(result).toEqual(config_0);
|
||||
});
|
||||
it('should handle depth:2 types (dst: object, src: simple type)', function() {
|
||||
let config_0 = { foo: 'bar', bar: { foo: 'bar' } };
|
||||
let config_1 = { foo: 'foo', bar: 'should NOT clobber'};
|
||||
let result = utils.assignWithDepth(config_0, config_1);
|
||||
expect(result).toEqual({ foo: 'foo', bar: { foo: 'bar' } } );
|
||||
});
|
||||
it('should handle depth:2 types (src: orphan)', function() {
|
||||
let config_0 = { foo: 'bar' };
|
||||
let config_1 = { foo: 'bar', bar: { foo: 'bar' } };
|
||||
let result = utils.assignWithDepth(config_0, config_1);
|
||||
expect(result).toEqual(config_1);
|
||||
});
|
||||
it('should handle depth:2 types (merge)', function() {
|
||||
let config_0 = { foo: 'bar', bar: { foo: 'bar' }, boofar: 1 };
|
||||
let config_1 = { foo: 'foo', bar: { bar: 0 }, foobar: 'foobar' };
|
||||
let result = utils.assignWithDepth(config_0, config_1);
|
||||
expect(result).toEqual({ foo: "foo", bar: { foo: "bar", bar: 0 }, foobar: "foobar", boofar: 1 });
|
||||
});
|
||||
it('should handle depth:3 types (merge with clobber because assignWithDepth::depth == 2)', function() {
|
||||
let config_0 = { foo: 'bar', bar: { foo: 'bar', bar: { foo: { message: 'this', willbe: 'clobbered' } } }, boofar: 1 };
|
||||
let config_1 = { foo: 'foo', bar: { foo: 'foo', bar: { foo: { message: 'clobbered other foo' } } }, foobar: 'foobar' };
|
||||
let result = utils.assignWithDepth(config_0, config_1);
|
||||
expect(result).toEqual({ foo: "foo", bar: { foo: 'foo', bar: { foo: { message: 'clobbered other foo' } } }, foobar: "foobar", boofar: 1 });
|
||||
});
|
||||
it('should handle depth:3 types (merge with clobber because assignWithDepth::depth == 1)', function() {
|
||||
let config_0 = { foo: 'bar', bar: { foo: 'bar', bar: { foo: { message: '', willNotbe: 'present' }, bar: 'shouldNotBePresent' } }, boofar: 1 };
|
||||
let config_1 = { foo: 'foo', bar: { foo: 'foo', bar: { foo: { message: 'this' } } }, foobar: 'foobar' };
|
||||
let result = utils.assignWithDepth(config_0, config_1, { depth: 1 });
|
||||
expect(result).toEqual({ foo: "foo", bar: { foo: 'foo', bar: { foo: { message: 'this' } } }, foobar: "foobar", boofar: 1 });
|
||||
});
|
||||
it('should handle depth:3 types (merge with no clobber because assignWithDepth::depth == 3)', function() {
|
||||
let config_0 = { foo: 'bar', bar: { foo: 'bar', bar: { foo: { message: '', willbe: 'present' } } }, boofar: 1 };
|
||||
let config_1 = { foo: 'foo', bar: { foo: 'foo', bar: { foo: { message: 'this' } } }, foobar: 'foobar' };
|
||||
let result = utils.assignWithDepth(config_0, config_1, { depth: 3 });
|
||||
expect(result).toEqual({ foo: "foo", bar: { foo: 'foo', bar: { foo: { message: 'this', willbe: 'present' } } }, foobar: "foobar", boofar: 1 });
|
||||
});
|
||||
});
|
||||
describe('when memoizing', function() {
|
||||
it('should return the same value', function() {
|
||||
const fib = utils.memoize(function(n, canary) {
|
||||
canary.flag = true;
|
||||
if (n < 2){
|
||||
return 1;
|
||||
}else{
|
||||
//We'll console.log a loader every time we have to recurse
|
||||
return fib(n-2, canary) + fib(n-1, canary);
|
||||
}
|
||||
});
|
||||
let canary = {flag: false};
|
||||
fib(10, canary);
|
||||
expect(canary.flag).toBe(true);
|
||||
canary = {flag: false};
|
||||
fib(10, canary);
|
||||
expect(canary.flag).toBe(false);
|
||||
});
|
||||
})
|
||||
describe('when detecting chart type ', function() {
|
||||
it('should handle a graph definition', function() {
|
||||
const str = 'graph TB\nbfs1:queue';
|
||||
@ -27,6 +114,16 @@ Alice->Bob: hi`;
|
||||
expect(type).toBe('sequence');
|
||||
expect(init).toEqual({logLevel:0,theme:"dark"});
|
||||
});
|
||||
it('should handle an init definition with config converted to the proper diagram configuration', function() {
|
||||
const str = `
|
||||
%%{init: { 'logLevel': 0, 'theme': 'dark', 'config': {'wrapEnabled': true} } }%%
|
||||
sequenceDiagram
|
||||
Alice->Bob: hi`;
|
||||
const type = utils.detectType(str);
|
||||
const init = utils.detectInit(str);
|
||||
expect(type).toBe('sequence');
|
||||
expect(init).toEqual({logLevel:0, theme:"dark", sequence: { wrapEnabled: true }});
|
||||
});
|
||||
it('should handle a multiline init definition', function() {
|
||||
const str = `
|
||||
%%{
|
||||
|
308795
stats.json
Normal file
308795
stats.json
Normal file
File diff suppressed because one or more lines are too long
56
yarn.lock
56
yarn.lock
@ -2890,6 +2890,14 @@ color@3.0.x:
|
||||
color-convert "^1.9.1"
|
||||
color-string "^1.5.2"
|
||||
|
||||
color@^3.1.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/color/-/color-3.1.2.tgz#68148e7f85d41ad7649c5fa8c8106f098d229e10"
|
||||
integrity sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==
|
||||
dependencies:
|
||||
color-convert "^1.9.1"
|
||||
color-string "^1.5.2"
|
||||
|
||||
colornames@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/colornames/-/colornames-1.1.1.tgz#f8889030685c7c4ff9e2a559f5077eb76a816f96"
|
||||
@ -3188,13 +3196,6 @@ crypto-browserify@^3.11.0:
|
||||
randombytes "^2.0.0"
|
||||
randomfill "^1.0.3"
|
||||
|
||||
crypto-random-string@^3.0.1:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-3.1.0.tgz#0368382de82e914179ad2ca9c7a788e260184bae"
|
||||
integrity sha512-Tip3yGB+bA7B0W8E4K4mNf2rZhu5r2G5Tb89/utEl5tP1QuLjTF/S9a1b8ifDrR4ORc9Utf6tscpSEtBY3YcPQ==
|
||||
dependencies:
|
||||
type-fest "^0.8.1"
|
||||
|
||||
css-b64-images@~0.2.5:
|
||||
version "0.2.5"
|
||||
resolved "https://registry.yarnpkg.com/css-b64-images/-/css-b64-images-0.2.5.tgz#42005d83204b2b4a5d93b6b1a5644133b5927a02"
|
||||
@ -4125,11 +4126,6 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
||||
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
|
||||
|
||||
escaper@^2.5.3:
|
||||
version "2.5.3"
|
||||
resolved "https://registry.yarnpkg.com/escaper/-/escaper-2.5.3.tgz#8b8fe90ba364054151ab7eff18b4ce43b1e13ab5"
|
||||
integrity sha512-QGb9sFxBVpbzMggrKTX0ry1oiI4CSDAl9vIL702hzl1jGW8VZs7qfqTRX7WDOjoNDoEVGcEtu1ZOQgReSfT2kQ==
|
||||
|
||||
escodegen@1.3.x:
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.3.3.tgz#f024016f5a88e046fd12005055e939802e6c5f23"
|
||||
@ -6039,11 +6035,6 @@ is-regex@^1.0.4, is-regex@^1.0.5:
|
||||
dependencies:
|
||||
has "^1.0.3"
|
||||
|
||||
is-regexp@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069"
|
||||
integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk=
|
||||
|
||||
is-relative@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d"
|
||||
@ -6722,6 +6713,11 @@ jssha@^2.1.0:
|
||||
resolved "https://registry.yarnpkg.com/jssha/-/jssha-2.3.1.tgz#147b2125369035ca4b2f7d210dc539f009b3de9a"
|
||||
integrity sha1-FHshJTaQNcpLL30hDcU58Amz3po=
|
||||
|
||||
khroma@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/khroma/-/khroma-1.1.0.tgz#cc17723eb719c5245ea66d23dd577d5695452db5"
|
||||
integrity sha512-aTO+YX22tYOLEQJYFiatAj1lc5QZ+H5sHWFRBWNCiKwc5NWNUJZyeSeiHEPeURJ2a1GEVYcmyMUwGjjLe5ec5A==
|
||||
|
||||
killable@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892"
|
||||
@ -9347,15 +9343,6 @@ schema-utils@^2.6.4:
|
||||
ajv "^6.10.2"
|
||||
ajv-keywords "^3.4.1"
|
||||
|
||||
scope-css@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/scope-css/-/scope-css-1.2.1.tgz#c35768bc900cad030a3e0d663a818c0f6a57f40e"
|
||||
integrity sha512-UjLRmyEYaDNiOS673xlVkZFlVCtckJR/dKgr434VMm7Lb+AOOqXKdAcY7PpGlJYErjXXJzKN7HWo4uRPiZZG0Q==
|
||||
dependencies:
|
||||
escaper "^2.5.3"
|
||||
slugify "^1.3.1"
|
||||
strip-css-comments "^3.0.0"
|
||||
|
||||
scss-tokenizer@^0.2.3:
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1"
|
||||
@ -9563,11 +9550,6 @@ slice-ansi@^2.1.0:
|
||||
astral-regex "^1.0.0"
|
||||
is-fullwidth-code-point "^2.0.0"
|
||||
|
||||
slugify@^1.3.1:
|
||||
version "1.3.6"
|
||||
resolved "https://registry.yarnpkg.com/slugify/-/slugify-1.3.6.tgz#ba5fd6159b570fe4811d02ea9b1f4906677638c3"
|
||||
integrity sha512-wA9XS475ZmGNlEnYYLPReSfuz/c3VQsEMoU43mi6OnKMCdbnFXd4/Yg7J0lBv8jkPolacMpOrWEaoYxuE1+hoQ==
|
||||
|
||||
snapdragon-node@^2.0.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"
|
||||
@ -10019,13 +10001,6 @@ strip-bom@^3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
|
||||
integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=
|
||||
|
||||
strip-css-comments@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-css-comments/-/strip-css-comments-3.0.0.tgz#7a5625eff8a2b226cf8947a11254da96e13dae89"
|
||||
integrity sha1-elYl7/iisibPiUehElTaluE9rok=
|
||||
dependencies:
|
||||
is-regexp "^1.0.0"
|
||||
|
||||
strip-eof@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
|
||||
@ -10053,6 +10028,11 @@ strip-json-comments@^3.0.1:
|
||||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7"
|
||||
integrity sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==
|
||||
|
||||
stylis@^3.5.2:
|
||||
version "3.5.4"
|
||||
resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.5.4.tgz#f665f25f5e299cf3d64654ab949a57c768b73fbe"
|
||||
integrity sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q==
|
||||
|
||||
subarg@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/subarg/-/subarg-1.0.0.tgz#f62cf17581e996b48fc965699f54c06ae268b8d2"
|
||||
|
Loading…
x
Reference in New Issue
Block a user