Merge branch 'develop' into 1542_take_two

This commit is contained in:
Ashish Jain 2020-08-13 18:27:37 +02:00
commit 28bc87b873
58 changed files with 2489 additions and 1466 deletions

2
.gitignore vendored
View File

@ -17,4 +17,4 @@ dist/sequenceTest.html
.vscode/
cypress/platform/current.html
cypress/platform/experimental.html
local/
local/

View File

@ -1,24 +1,52 @@
<!-- <Remove this in the future> -->
| :mega: :mega: :mega: |
| :----: |
| * If you're upgrading from a version __< v8.2.0__, there are [non-backward-compatible changes](http://mermaid-js.github.io/mermaid/#/usage?id=to-enable-click-event-and-tags-in-nodes) related to security issues. Default behaviour of the library might have changed for your implementation.|
<!-- </Remove this in the future> -->
# mermaid [![Build Status](https://travis-ci.org/mermaid-js/mermaid.svg?branch=master)](https://travis-ci.org/mermaid-js/mermaid) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![This project is using Percy.io for visual regression testing.](https://percy.io/static/images/percy-badge.svg)](https://percy.io/Mermaid/mermaid)
<!-- <Main description> -->
__mermaid is a Javascript based diagramming and charting tool. It generates diagrams flowcharts and more, using markdown-inspired text for ease and speed.__
Check out the list of [Integrations and Usages of Mermaid](https://github.com/mermaid-js/mermaid/blob/develop/docs/integrations.md)
For more information and help in getting started, please view our [documentation](http://mermaid-js.github.io/mermaid/) and start simplifying yours. Alternatively, you can also play with our [live editor](https://mermaidjs.github.io/mermaid-live-editor/).
<!-- </Main description> -->
![banner](./img/header.png)
**Edit this Page** [![N|Solid](./docs/img/GitHub-Mark-32px.png)](https://github.com/mermaid-js/mermaid/blob/develop/docs/README.md)
:trophy: **Mermaid was nominated and won the [JS Open Source Awards (2019)](https://osawards.com/javascript/#nominees) 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.**
## New diagram
This version comes with a new diagram type, user journey diagrams.
<!-- <Main description> -->
__mermaid is a Javascript based diagramming and charting tool that uses markdown-inspired text definitions and a renderer to create and modify complex diagrams. The main purpose of mermaid is to help Documentation catch up with Development.__
# Doc-Rot is a Catch-22 that Mermaid helps to solve.
### Diagramming and Documentation costs precious developer time and gets outdated quickly.
### But not having diagrams or Docs ruins productivity and hurts organizational learning.
## mermaid addresses this problem by cutting the time, effort and tooling that is required to create modifiable diagrams and charts, for smarter and more reusable content.**
The text definitions for mermaid 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 and laborious task.
## Even non-programmers can create diagrams through the [Mermaid Live Editor](https://github.com/mermaidjs/mermaid-live-editor).
## [mermaid Overview](./n00b-overview.md) has video tutorials.
## Use mermaid with your favorite applications, check out the list of [Integrations and Usages of Mermaid](./integrations.md)**
## For a more detailed introduction to mermaid and some of it's more basic uses, look to the [Beginner's Guide](https://mermaid-js.github.io/mermaid/#/n00b-overview) and [Usage](./usage.md).
## [CDN](https://unpkg.com/mermaid/)
## [Documentation](https://mermaidjs.github.io)
## [Contribution](https://github.com/mermaid-js/mermaid/blob/develop/CONTRIBUTING.md)
## Record of [Mermaid Version Changes](./versionUpdates.md).
# Version News: 8.7.0 Released with Updates to Theme Configuration
## [Version 8.7.0](./docs/theming.md) Mermaid comes out with a System for Dynamic and Integrated Diagram Theme Configuration.
## Mermaid comes out with [New Configuration Protocols in Version 8.6.0](./docs/8.6.0_docs.md)
## New diagrams in 8.4
@ -45,7 +73,6 @@ mermaidAPI.initialize({
});
```
For more information and help in getting started, please view our [documentation](http://mermaid-js.github.io/mermaid/) and start simplifying yours. Play with our [live editor](https://mermaidjs.github.io/mermaid-live-editor/) or jump straight to the [installation and usage](http://mermaid-js.github.io/mermaid/#/usage).
<!-- </Main description> -->
__The following are some examples of the diagrams, charts and graphs that can be made using mermaid and the Markdown-inspired text specific to it. Click here jump into the [text syntax](https://mermaid-js.github.io/mermaid/#/n00b-syntaxReference).__

View File

@ -305,4 +305,52 @@ describe('Class diagram', () => {
);
cy.get('svg');
});
it('13: should render a simple class diagram with css classes applied', () => {
imgSnapshotTest(
`
classDiagram
class Class10 {
int[] id
List~int~ ids
test(List~int~ ids) List~bool~
testArray() bool[]
}
cssClass "Class10" exClass
`,
{}
);
cy.get('svg');
});
it('14: should render a simple class diagram with css classes applied directly', () => {
imgSnapshotTest(
`
classDiagram
class Class10:::exClass {
int[] id
List~int~ ids
test(List~int~ ids) List~bool~
testArray() bool[]
}
`,
{}
);
cy.get('svg');
});
it('15: should render a simple class diagram with css classes applied two multiple classes', () => {
imgSnapshotTest(
`
classDiagram
class Class10
class Class20
cssClass "Class10, class20" exClass
`,
{}
);
cy.get('svg');
});
});

View File

@ -529,17 +529,19 @@ describe('Flowchart', () => {
imgSnapshotTest(
`graph TB
TITLE["Link Click Events<br>(click the nodes below)"]
A[link test]
B[anchor test]
C[mailto test]
D[other protocol test]
E[script test]
TITLE --> A & B & C & D & E
click A "https://mermaid-js.github.io/mermaid/#/" "link test"
click B "#link-clicked" "anchor test"
click C "mailto:user@user.user" "mailto test"
click D "notes://do-your-thing/id" "other protocol test"
click E "javascript:alert('test')" "script test"
A["link test (open in same tab)"]
B["link test (open in new tab)"]
C[anchor test]
D[mailto test]
E[other protocol test]
F[script test]
TITLE --> A & B & C & D & E & F
click A "https://mermaid-js.github.io/mermaid/#/" "link test (open in same tab)"
click B "https://mermaid-js.github.io/mermaid/#/" "link test (open in new tab)" _blank
click C "#link-clicked"
click D "mailto:user@user.user" "mailto test"
click E "notes://do-your-thing/id" "other protocol test"
click F "javascript:alert('test')" "script test"
`,
{ securityLevel: 'loose' }
);

View File

@ -74,15 +74,11 @@ stateDiagram-v2
A --> D: asd123
</div>
</div>
%%{init: {'theme': 'base', 'themeVariables':{ 'primaryColor': '#ff0000'}}}%%
<div class="mermaid" style="width: 50%; height: 20%;">
%%{init: {'theme': 'base'}}%%
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#ff0000'}}}%%
classDiagram
Animal <|-- Duck
flowchart TB
subgraph apa
a --> A %% comment
a --> a{apa} %% comment
end
</div>
<div class="mermaid2" style="width: 50%; height: 20%;">
graph TD
@ -106,8 +102,8 @@ Note over Bob,Alice: Looks back
// console.error('Mermaid error: ', err);
};
mermaid.initialize({
// theme: 'base',
// themeVariables:{primaryColor: '#0000ff'},
// theme: 'forest',
// themeVariables:{primaryColor: '#ff0000'},
// arrowMarkerAbsolute: true,
// themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
logLevel: 0,

View File

@ -11,7 +11,6 @@
body {
/* background: rgb(221, 208, 208); */
background: #f4f4f4;
/* background: #0c0c0c; */
font-family: 'Arial';
height: 100%;
width: 100%;
@ -177,7 +176,7 @@ gantt
</div>
<div class="mermaid width height2">
%%{init2: {'securityLevel': 'loose', 'theme':'base'}}%%
%%{init: {'securityLevel': 'loose', 'theme':'base'}}%%
stateDiagram-v2
[*] --> Active
@ -234,7 +233,7 @@ journey
};
mermaid.initialize({
theme: 'base',
themeVariables: { primaryColor: '#ff0000'},
// themeVariables:
// arrowMarkerAbsolute: true,
// themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
logLevel: 0,

View File

@ -0,0 +1,245 @@
<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: #f4f4f4;
background: #222;
font-family: 'Arial';
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
h1 { color: grey;}
.mermaid2 {
display: none;
}
.height {
min-height: 600px;
height: 600px;
}
.height2 {
min-height: 600px;
height: 1300px;
}
.width {
width: 33%;
border: 1px solid blue;
padding: 10px;
}
</style>
</head>
<body>
<h1>Showcases of diagrams</h1>
<div class="flex flex-wrap">
<div class="mermaid width height">
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 width height">
%%{init2: {'securityLevel': 'loose', 'theme':'base'}}%%
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
</div>
<div class="mermaid width height" >
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
</div>
<div class="mermaid width height" >
classDiagram
Animal "1" <|-- Duck
Animal <|-- Fish
Animal <--o 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()
}
</div>
<div class="mermaid width height">
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
</div>
<div class="mermaid width height2">
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.
SomethingElse --> [*]
</div>
<div class="mermaid width height2">
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.
SomethingElse2 --> [*]
</div>
<div class="mermaid width height2">
erDiagram
CUSTOMER }|..|{ DELIVERY-ADDRESS : has
CUSTOMER ||--o{ ORDER : places
CUSTOMER ||--o{ INVOICE : "liable for"
DELIVERY-ADDRESS ||--o{ ORDER : receives
INVOICE ||--|{ ORDER : covers
ORDER ||--|{ ORDER-ITEM : includes
PRODUCT-CATEGORY ||--|{ PRODUCT : contains
PRODUCT ||--o{ ORDER-ITEM : "ordered in"
</div>
<div class="mermaid width height">
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
</div>
<script src="./mermaid.js"></script>
<script>
mermaid.parseError = function (err, hash) {
// console.error('Mermaid error: ', err);
};
mermaid.initialize({
theme: 'base',
themeVariables: { primaryColor: '#9400D3', darkMode: true, background: '#222', textColor:'white', primaryTextColor: '#f4f4f4', nodeBkg: '#ff0000', mainBkg:'#0000ff', tertiaryColor:'#ffffcc' },
// arrowMarkerAbsolute: true,
// themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
logLevel: 0,
flowchart: { 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>

View File

@ -166,6 +166,7 @@ gantt
}
Active --> SomethingElse
SomethingElse --> [*]
note right of SomethingElse : This is the note to the right.
</div>
<div class="mermaid width height2">
@ -191,6 +192,7 @@ gantt
}
Active --> SomethingElse2
SomethingElse2 --> [*]
note right of SomethingElse2 : This is the note to the right.
</div>
<div class="mermaid width height2">

View File

@ -167,6 +167,7 @@ gantt
Active --> SomethingElse
note right of SomethingElse : This is the note to the right.
SomethingElse --> [*]
</div>
<div class="mermaid width height2">
stateDiagram-v2

24
dist/index.html vendored
View File

@ -393,17 +393,19 @@ graph TB
<div class="mermaid">
graph TB
TITLE["Link Click Events<br>(click the nodes below)"]
A[link test]
B[anchor test]
C[mailto test]
D[other protocol test]
E[script test]
TITLE --> A & B & C & D & E
click A "https://mermaid-js.github.io/mermaid/#/" "link test"
click B "#link-clicked" "anchor test"
click C "mailto:user@user.user" "mailto test"
click D "notes://do-your-thing/id" "other protocol test"
click E "javascript:alert('test')" "script test"
A["link test (open in same tab)"]
B["link test (open in new tab)"]
C[anchor test]
D[mailto test]
E[other protocol test]
F[script test]
TITLE --> A & B & C & D & E & F
click A "https://mermaid-js.github.io/mermaid/#/" "link test (open in same tab)"
click B "https://mermaid-js.github.io/mermaid/#/" "link test (open in new tab)" _blank
click C "#link-clicked"
click D "mailto:user@user.user" "mailto test"
click E "notes://do-your-thing/id" "other protocol test"
click F "javascript:alert('test')" "script test"
</div>
<hr/>
<div class="mermaid">

41
dist/info.html vendored
View File

@ -1,41 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Mermaid Quick Test Page</title>
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=">
</head>
<body>
<div class="mermaid">info
showInfo
</div>
<script src="./mermaid.js"></script>
<script>
mermaid.initialize({
theme: 'forest',
// themeCSS: '.node rect { fill: red; }',
logLevel: 1,
flowchart: { curve: 'linear' },
gantt: { axisFormat: '%m/%d/%Y' },
sequence: { actorMargin: 50 },
// sequenceDiagram: { actorMargin: 300 } // deprecated
});
</script>
<script>
function ganttTestClick(a, b, c){
console.log("a:", a)
console.log("b:", b)
console.log("c:", c)
}
function testClick(nodeId) {
console.log("clicked", nodeId)
var originalBgColor = document.querySelector('body').style.backgroundColor
document.querySelector('body').style.backgroundColor = 'yellow'
setTimeout(function() {
document.querySelector('body').style.backgroundColor = originalBgColor
}, 100)
}
</script>
</body>
</html>

891
dist/mermaid.core.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

891
dist/mermaid.js vendored

File diff suppressed because one or more lines are too long

2
dist/mermaid.js.map vendored

File diff suppressed because one or more lines are too long

10
dist/mermaid.min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

202
dist/xssi.html vendored
View File

@ -1,202 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Mermaid Quick Test Page</title>
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=">
<script>
function xss(x){
alert(x + ' cause an xss attack');
}
</script>
<style>
.label text { fill: red}
</style>
</head>
<body>
<div class="mermaid">
info
</div>
<div class="mermaid">
graph LR;
alert`xss`-->B;
click B "javaSc
ript:alert`salt`" "This is a tooltip for a link"
</div>
<div class="mermaid">
graph LR;
alert`xss`-->B;
click B "java
script:alert`xss`" "This is a tooltip for a link"
</div>
<div class="mermaid">
graph LR;
alert`base64`-->B;
click B "data:image/png;base64,HNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4="
</div>
<img src=xss.png />
<div class="mermaid">
graph TD
A["<strong>If bold then xss</strong>Christmas"] -->|Get <strong>If bold then xss</strong> money| B(Go <strong>If bold then xss</strong> shopping)
B --> C{Let me thinksssss<br/>ssssssssssssssssssssss<br />sssssssssssssssssssssssssss}
C -->|One| D[Laptop]
C -->|Two| E[iPhone]
C -->|Three| F[Car]
</div>
<div class="mermaid">
graph TB
subgraph "<strong>If bold then xss</strong>"
a1-->a2
end
</div>
<div class="mermaid">
graph TD
A[Click on] -->|Get happines| BBBB(Clickable)
BBBB --> C{Let me think}
C -->|One| D[Laptop]
C -->|Two| E[iPhone]
C -->|Three| F[Car]
click A "http://localhost:9000/index.html#link-clicked" "link test"
click BBBB testClick "click test"
click C "javascript:alert" "link test"
classDef someclass fill:#f96;
class A someclass;
</div>
<div class="mermaid">
graph LR;
alert`md5_salt`-->B;
click alert`md5_salt` eval "Tooltip for a callback"
click B "javascript:alert`salt`" "This is a tooltip for a link"
</div>
<div class="mermaid">
gantt
dateFormat YYYY-MM-DD
axisFormat %d/%m
title Adding GANTT diagram to mermaid
excludes weekdays 2014-01-10
section A section
Completed task :done, des1, 2014-01-06,2014-01-08
Active task :active, des2, 2014-01-09, 3d
Future task : des3, after des2, 5d
Future task2 : des4, after des3, 5d
section Critical tasks
Completed task in the critical line :crit, done, 2014-01-06,24h
Implement parser and jison :crit, done, after des1, 2d
Create tests for parser :crit, active, 3d
Future task in critical line :crit, 5d
Create tests for renderer :2d
Add to mermaid :1d
section Documentation
Describe gantt syntax :active, a1, after des1, 3d
Add gantt diagram to demo page :after a1 , 20h
Add another diagram to demo page :doc1, after a1 , 48h
section Clickable
Visit mermaidjs :active, cl1, 2014-01-07,2014-01-10
Calling a Callback (look at the console log) :cl2, after cl1, 3d
click cl1 href "javascript:alert`salt`"
click cl2 call ganttTestClick("test", test, test)
section Last section
Describe gantt syntax :after doc1, 3d
Add gantt diagram to demo page : 20h
Add another diagram to demo page : 48h
</div>
<div class="mermaid">
sequenceDiagram
participant "Alice"
participant Bob
participant John as John<br/>Second Line
Alice ->> Bob: Hello Bob, how are you?
Bob-->>John: How about you <strong>If bold then xss</strong>John?
Bob--x Alice: I am good thanks!
Bob-x John: I am good thanks!
Note right of John: Bob thinks a long<br/>long time, so long<br/>that the text does<br/>not fit on a row.
Bob-->Alice: Checking with John...
alt either this
Alice->>John: Yes
else or this
Alice->>John: No
else or this will happen
Alice->John: Maybe
end
par this happens in parallel
Alice -->> Bob: Parallel message 1
and
Alice -->> John: Parallel message 2
end
</div>
<div class="mermaid">
classDiagram
Class01 <|-- AveryLongClass : Co<strong>If bold then xss</strong>ol
Class03 "0" *-- "0..n" Class04
Class05 "1" o-- "many" Class06
Class07 .. Class08
Class09 "many" --> "1" C2 : Where am i?
Class09 "0" --* "1..n" C3
Class09 --|> Class07
Class07 : equals()
Class07 : Object[] elementData
Class01 : size()
Class01 : int chimp
Class01 : int gorilla
Class08 <--> C2: Cool label
</div>
<div class="mermaid">
graph LR
SavePropertyController --> SavePropertyCommand
SavePropertyCommand --> SavePropertyCommandHandler
SavePropertyCommandHandler --> EventElastica[elastica.postupdate]
SavePropertyCommandHandler --> EventProperty[property.postdisable]
SavePropertyController --> Exceptions
Exceptions --> ExceptionList(SecurityException<br/>EmptyRequestBodyException<br/>Throwable)
classDef Ui fill:#FFFFFF
classDef object fill:#1E98EC
classDef event fill:#ECB11E
class EventElastica,EventProperty event
class SavePropertyCommand,SavePropertyCommandHandler object
class SavePropertyController Ui
</div>
<script src="./mermaid.js"></script>
<!-- <script src="//cdn.jsdelivr.net/npm/mermaid@8.2.1/dist/mermaid.min.js"></script> -->
<script>
mermaid.initialize({
theme: 'forest',
// themeCSS: '.node rect { fill: red; }',
logLevel: 4,
flowchart: { htmlLabels: false, curve: 'linear' },
gantt: { axisFormat: '%m/%d/%Y' },
sequence: { actorMargin: 50 },
// sequenceDiagram: { actorMargin: 300 } // deprecated
securityLevel:'strict',
});
</script>
<script>
function ganttTestClick(a, b, c){
console.log("a:", a)
console.log("b:", b)
console.log("c:", c)
}
function testClick(nodeId) {
console.log("clicked", nodeId)
var originalBgColor = document.querySelector('body').style.backgroundColor
document.querySelector('body').style.backgroundColor = 'yellow'
setTimeout(function() {
document.querySelector('body').style.backgroundColor = originalBgColor
}, 100)
}
</script>
</body>
</html>

View File

@ -25,7 +25,7 @@ The three levels of are Configuration, Global, Site and Current.
# Limits to Modifying Configurations
secure Array
**secure Array**
| Parameter | Description |Type | Required | Values|
| --- | --- | --- | --- | --- |

View File

@ -11,20 +11,22 @@
**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.**
# Doc-Rot is a Catch-22 that Mermaid helps to solve.
Mermaid is a tool that generates diagrams and charts, from markdown-inspired text definitions
### Diagramming and Documentation costs precious developer time and gets outdated quickly.
### But not having diagrams or Docs ruins productivity and hurts organizational learning.
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 addresses this problem by cutting the time, effort and tooling that is required to create modifiable diagrams and charts, for smarter and more reusable content.**
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.
The text definitions that create mermaid diagrams allows for easy updates, 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 and laborious task.
Even non-programmers can create diagrams through the [mermaid live editor](https://github.com/mermaidjs/mermaid-live-editor).
## 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 can watch some popular mermaid Live Editor tutorials on [mermaid Overview](./n00b-overview.md) for a quick intro.
You should also Check out the list of [Integrations and Usages of Mermaid](./integrations.md)
## To use mermaid with your favorite applications, 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)
## For a more detailed introduction to mermaid and some of it's more basic uses, look to the [Beginner's Guide](https://mermaid-js.github.io/mermaid/#/n00b-overview) and [Usage](./usage.md).
## [CDN](https://unpkg.com/mermaid/)
@ -32,47 +34,18 @@ You can also watch some popular mermaid tutorials on the [mermaid Overview](./n0
## [Contribution](https://github.com/mermaid-js/mermaid/blob/develop/CONTRIBUTING.md)
## [Recent Mermaid Versions](./versionUpdates.md).
# New in Version 8.6.0
# Most Recent Version News: Version 8.7.0
## [New and Expanded Mermaid Theme and Styling Configurations](./theming.md)
## [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](./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.
![Image showing the new ER diagram type](./img/er.png)
## 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.
## 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
Closed issues:
⚠️ **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 responsibility 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'
});
```
## [Version Record](./versionUpdates.md)
**🖖 Keep a steady pulse: mermaid needs more Collaborators [#866](https://github.com/knsv/mermaid/issues/866)**
@ -196,7 +169,10 @@ journey
```
![Journey diagram](./img/user-journey.png)
## Installation
# Installation
## In depth guides and examples can be found in [Getting Started](./n00b-gettingStarted.md) and [Usage](./usage.md).
## It would also be helpful to learn more about mermaid's [Syntax](./n00b-syntaxReference.md).
### CDN
@ -212,33 +188,32 @@ 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 Mermaids JavaScript package
## Incorporating mermaid to a website
To support mermaid on your website, all you have to do is add Mermaids JavaScript package
```
1.You will need to isntall node v10 or 12, which would have npm
2. download yarn using npm.
2. enter the following command:
3. enter the following command:
yarn add mermaid
3. You can then add mermaid as a dev dependency using this command:
4. You can then add mermaid as a dev dependency using this command:
yarn add --dev mermaid
```
## To install mermaid without a bundler, one can use the script tag like so:
<script src="https://unpkg.com/mermaid/"></script>
## To deploy mermaid without a bundler, one can insert a `script` tag with an absolute address and a `mermaidAPI` call into the HTML like so:
```
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
<script>mermaid.initialize({startOnLoad:true});</script>
```
## doing so will command the mermaid parser to look for the `<div>` tags with `class="mermaid"` in your HTML Document. From these tags mermaid will try to read the diagram/chart definitons and render them as svg charts.
## 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).
## Examples can be found in [Getting Started](./n00b-gettingStarted.md)
## 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
# Sibling projects
- [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)

View File

@ -23,7 +23,9 @@
- [Development](development.md)
- [Configurations](Setup.md)
- [Mermaid Versions](versionUpdates.md)
- [Changelog](CHANGELOG.md)
- [Mermaid Versions](versionUpdate.md)
- Beginner's Guide
- [overview](n00b-overview.md)

View File

@ -1,8 +1,9 @@
# 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
> Wikipedia
The class diagram is the main building block of object-oriented modeling. It is used for general conceptual modeling of the structure of the application, and for detailed modeling translating the models into programming code. Class diagrams can also be used for data modeling. The classes in a class diagram represent both the main elements, interactions in the application, and the classes to be programmed.
@ -32,6 +33,7 @@ Mermaid can render class diagrams.
}
```
```mermaid
classDiagram
Animal <|-- Duck
@ -63,9 +65,10 @@ Mermaid can render class diagrams.
UML provides mechanisms to represent class members, such as attributes and methods, and additional information about them.
A single instance of a class in the diagram contains three compartments:
- The top compartment contains the name of the class. It is printed in bold and centered, and the first letter is capitalized. It may also contain optional annotation text describing the nature of the class.
- The middle compartment contains the attributes of the class. They are left-aligned and the first letter is lowercase.
- The bottom compartment contains the operations the class can execute. They are also left-aligned and the first letter is lowercase.
- The top compartment contains the name of the class. It is printed in bold and centered, and the first letter is capitalized. It may also contain optional annotation text describing the nature of the class.
- The middle compartment contains the attributes of the class. They are left-aligned and the first letter is lowercase.
The bottom compartment contains the operations the class can execute. They are also left-aligned and the first letter is lowercase.
```
classDiagram
@ -74,7 +77,9 @@ classDiagram
BankAccount : +Bigdecimal balance
BankAccount : +deposit(amount)
BankAccount : +withdrawl(amount)
```
```mermaid
classDiagram
class BankAccount
@ -83,9 +88,11 @@ classDiagram
BankAccount : +deposit(amount)
BankAccount : +withdrawl(amount)
```
## Define a class
There are two ways to define a class:
- Explicitly defining a class using keyword **class** like `class Animal`. This defines the Animal class
- Define two classes via a **relationship** between them `Vehicle <|-- Car`. This defines two classes Vehicle and Car along with their relationship.
@ -94,6 +101,7 @@ classDiagram
class Animal
Vehicle <|-- Car
```
```mermaid
classDiagram
class Animal
@ -108,28 +116,29 @@ UML provides mechanisms to represent class members, such as attributes and metho
Mermaid distinguishes between attributes and functions/methods based on if the **parenthesis** `()` are present or not. The ones with `()` are treated as functions/methods, and others as attributes.
There are two ways to define the members of a class, and regardless of whichever syntax is used to define the members, the output will still be same. The two different ways are :
- Associate a member of a class using **:** (colon) followed by member name, useful to define one member at a time. For example:
```
```
class BankAccount
BankAccount : +String owner
BankAccount : +BigDecimal balance
BankAccount : +deposit(amount)
BankAccount : +withdrawal(amount)
```
```mermaid
classDiagram
class BankAccount
BankAccount : +String owner
BankAccount : +BigDecimal balance
BankAccount : +deposit(amount)
BankAccount : +withdrawal(amount)
```
``` mermaid
classDiagram
class BankAccount
BankAccount : +String owner
BankAccount : +BigDecimal balance
BankAccount : +deposit(amount)
BankAccount : +withdrawl(amount)
```
BankAccount : +withdrawl(amount)
```
- Associate members of a class using **{}** brackets, where members are grouped within curly brackets. Suitable for defining multiple members at once. For example:
```
class BankAccount{
+String owner
@ -138,6 +147,7 @@ class BankAccount{
+withdrawl(amount)
}
```
```mermaid
classDiagram
class BankAccount{
@ -149,8 +159,10 @@ class BankAccount{
```
#### Return Type
Optionally you can end the method/function definition with the data type that will be returned (note: there must be a space between the final `)` of the method definition and return type
example:
```
class BankAccount{
+String owner
@ -159,6 +171,7 @@ class BankAccount{
+withdrawl(amount) int
}
```
```mermaid
classDiagram
class BankAccount{
@ -170,6 +183,7 @@ class BankAccount{
```
#### Generic Types
Members can be defined using generic types, such as `List<int>`, for fields, parameters and return types by enclosing the type within `~` (**tilde**). Note: **nested** type declarations (such as `List<List<int>>`) are not currently supported
This can be done as part of either class definition method:
@ -203,39 +217,43 @@ Square : +getMessages() List~string~
```
#### Return Type
Optionally you can end the method/function definition with the data type that will be returned
#### Visibility
To specify the visibility of a class member (i.e. any attribute or method), these notations may be placed before the member's name, but it is optional:
- `+` Public
- `-` Private
- `#` Protected
- `~` Package/Internal
- `+` Public
- `-` Private
- `#` Protected
- `~` Package/Internal
> _note_ you can also include additional _classifers_ to a method definition by adding the following notations to the end of the method, i.e.: after the `()`:
>_note_ you can also include additional _classifers_ to a method definition by adding the following notations to the end of the method, i.e.: after the `()`:
> - `*` Abstract e.g.: `someAbstractMethod()*`
> - `$` Static e.g.: `someStaticMethod()$`
## Defining Relationship
A relationship is a general term covering the specific types of logical connections found on class and object diagrams.
```
[classA][Arrow][ClassB]:LabelText
```
There are different types of relations defined for classes under UML which are currently supported:
Type | Description
--- | ---
<\|-- | Inheritance
*-- | Composition
o-- | Aggregation
--> | Association
-- | Link (Solid)
..> | Dependency
..\|> | Realization
.. | Link (Dashed)
| Type | Description |
| ----- | ------------- |
| <\|-- | Inheritance |
| \*-- | Composition |
| o-- | Aggregation |
| --> | Association |
| -- | Link (Solid) |
| ..> | Dependency |
| ..\|> | Realization |
| .. | Link (Dashed) |
```
classDiagram
@ -262,7 +280,9 @@ classM <|.. classN
classO .. classP
```
We can use the labels to describe nature of relation between two classes. Also, arrowheads can be used in opposite directions as well :
```
classDiagram
classA --|> classB : Inheritance
@ -286,68 +306,80 @@ classI -- classJ : Link(Solid)
classK ..> classL : Dependency
classM ..|> classN : Realization
classO .. classP : Link(Dashed)
```
## Labels on Relations
It is possible to add a label text to a relation:
```
[classA][Arrow][ClassB]:LabelText
```
```
classDiagram
classA <|-- classB : implements
classC *-- classD : composition
classE o-- classF : association
```
```mermaid
classDiagram
classA <|-- classB : implements
classE o-- classF : association
```
## Cardinality / Multiplicity on relations
Multiplicity or cardinality in class diagrams indicates the number of instances of one class linked to one instance of the other class. For example, one company will have one or more employees, but each employee works for just one company.
Multiplicity notations are placed near the ends of an association.
The different cardinality options are :
- `0..1` Zero or one
- `1` Only 1
- `0..1` Zero or One
- `1..*` One or more
- `*` Many
- `n` n {where n>1}
- `0..n` zero to n {where n>1}
- `1..n` one to n {where n>1}
- `0..1` Zero or one
- `1` Only 1
- `0..1` Zero or One
- `1..*` One or more
- `*` Many
- `n` n {where n>1}
- `0..n` zero to n {where n>1}
- `1..n` one to n {where n>1}
Cardinality can be easily defined by placing cardinality text within qoutes `"` before(optional) and after(optional) a given arrow.
```
[classA] "cardinality1" [Arrow] "cardinality2" [ClassB]:LabelText
```
```
classDiagram
Customer "1" --> "*" Ticket
Student "1" --> "1..*" Course
Galaxy --> "many" Star : Contains
```
```mermaid
classDiagram
Customer "1" --> "*" Ticket
Student "1" --> "1..*" Course
Galaxy --> "many" Star : Contains
```
## Annotations on classes
It is possible to annotate classes with a specific marker text which is like meta-data for the class, giving a clear indication about its nature. Some common annotations examples could be:
- `<<Interface>>` To represent an Interface class
- `<<abstract>>` To represent an abstract class
- `<<Service>>` To represent a service class
- `<<Interface>>` To represent an Interface class
- `<<abstract>>` To represent an abstract class
- `<<Service>>` To represent a service class
- `<<enumeration>>` To represent an enum
Annotations are defined within the opening `<<` and closing `>>`. There are two ways to add an annotation to a class and regardless of the syntax used output will be same. The two ways are :
- In a ***separate line*** after a class is defined. For example:
- In a **_separate line_** after a class is defined. For example:
```
classDiagram
class Shape
@ -361,7 +393,8 @@ class Shape
Shape : noOfVertices
Shape : draw()
```
- In a ***nested structure*** along with class definition. For example:
- In a **_nested structure_** along with class definition. For example:
```
classDiagram
@ -400,7 +433,7 @@ class Color{
## Comments
Comments can be entered within a class diagram, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any class diagram syntax
Comments can be entered within a class diagram, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any class diagram syntax
```
classDiagram
@ -423,14 +456,14 @@ You would define these actions on a separate line after all classes have been de
action className "reference" "tooltip"
```
* _action_ is either `link` or `callback`, depending on which type of interaction you want to have called
* _className_ is the id of the node that the action will be associated with
* _reference_ is either the url link, or the function name for callback. (note: callback function will be called with the nodeId as parameter).
* (_optional_) tooltip is a string to be displayed when hovering over element (note: The styles of the tooltip are set by the class .mermaidTooltip.)
- _action_ is either `link` or `callback`, depending on which type of interaction you want to have called
- _className_ is the id of the node that the action will be associated with
- _reference_ is either the url link, or the function name for callback. (note: callback function will be called with the nodeId as parameter).
- (_optional_) tooltip is a string to be displayed when hovering over element (note: The styles of the tooltip are set by the class .mermaidTooltip.)
### Examples:
### Examples
*URL Link:*
_URL Link:_
```
classDiagram
@ -438,7 +471,7 @@ class Shape
link Shape "http://www.github.com" "This is a tooltip for a link"
```
*Callback:*
_Callback:_
```
classDiagram
@ -465,6 +498,7 @@ classDiagram
> **Success** The tooltip functionality and the ability to link to urls are available from version 0.5.2.
Beginners tip, a full example using interactive links in an html context:
```
<body>
<div class="mermaid">
@ -490,12 +524,12 @@ Beginners tip, a full example using interactive links in an html context:
+run()
}
callback Duck callback "Tooltip"
click Zebra "http://www.github.com" "This is a link"
callback Duck callback "Tooltip"
click Zebra "http://www.github.com" "This is a link"
</div>
<script>
var callback = function(){
var callback = function(){
alert('A callback was triggered');
}
var config = {
@ -510,26 +544,71 @@ Beginners tip, a full example using interactive links in an html context:
## Styling
Styling of the class diagram is done by defining a number of css classes. During rendering these classes are extracted from the file located at src/themes/class.scss
### Styling a node
### Styling Classes used
It is possible to apply specific styles such as a thicker border or a different background color to individual nodes. This is done by predefining classes in css styles that can be applied from the graph definition as in the example
below:
Class | Description
--- | ---
g.classGroup text | Styles for general class text
classGroup .title | Styles for general class title
g.classGroup rect | Styles for class diagram rectangle
g.classGroup line | Styles for class diagram line
.classLabel .box | Styles for class label box
.classLabel .label | Styles for class label text
composition | Styles for componsition arrow head and arrow line
aggregation | Styles for aggregation arrow head and arrow line(dashed or solid)
dependency | Styles for dependency arrow head and arrow line
```html
<style>
.cssClass > rect{
fill:#FF0000;
stroke:#FFFF00;
stroke-width:4px;
}
</style>
```
Then attaching that class to a specific node as per below:
```
cssClass "nodeId1" cssClass;
```
### Sample stylesheet
It is also possible to attach a class to a list of nodes in one statement:
```
cssClass "nodeId1,nodeId2" cssClass;
```
A shorter form of adding a class is to attach the classname to the node using the `:::` operator as per below:
```
classDiagram
class Animal:::cssClass
```
Or:
```
classDiagram
class Animal:::cssClass {
-int sizeInFeet
-canEat()
}
```
?> cssClasses cannot be added using this shorthand method at the same time as a relation statement.
?> Due to limitations with existing markup for class diagrams, it is not currently possible to define css classes within the diagram itself. ***Coming soon!***
### Default Styles
The main styling of the class diagram is done with a preset number of css classes. During rendering these classes are extracted from the file located at src/themes/class.scss. The classes used here are described below:
| Class | Description |
| ------------------ | ----------------------------------------------------------------- |
| g.classGroup text | Styles for general class text |
| classGroup .title | Styles for general class title |
| g.classGroup rect | Styles for class diagram rectangle |
| g.classGroup line | Styles for class diagram line |
| .classLabel .box | Styles for class label box |
| .classLabel .label | Styles for class label text |
| composition | Styles for componsition arrow head and arrow line |
| aggregation | Styles for aggregation arrow head and arrow line(dashed or solid) |
| dependency | Styles for dependency arrow head and arrow line |
#### Sample stylesheet
```css
body {
@ -537,92 +616,90 @@ body {
}
g.classGroup text {
fill: $nodeBorder;
stroke: none;
font-family: 'trebuchet ms', verdana, arial;
font-family: var(--mermaid-font-family);
font-size: 10px;
fill: $nodeBorder;
stroke: none;
font-family: 'trebuchet ms', verdana, arial;
font-family: var(--mermaid-font-family);
font-size: 10px;
.title {
font-weight: bolder;
}
.title {
font-weight: bolder;
}
}
g.classGroup rect {
fill: $nodeBkg;
stroke: $nodeBorder;
fill: $nodeBkg;
stroke: $nodeBorder;
}
g.classGroup line {
stroke: $nodeBorder;
stroke-width: 1;
stroke: $nodeBorder;
stroke-width: 1;
}
.classLabel .box {
stroke: none;
stroke-width: 0;
fill: $nodeBkg;
opacity: 0.5;
stroke: none;
stroke-width: 0;
fill: $nodeBkg;
opacity: 0.5;
}
.classLabel .label {
fill: $nodeBorder;
font-size: 10px;
fill: $nodeBorder;
font-size: 10px;
}
.relation {
stroke: $nodeBorder;
stroke-width: 1;
fill: none;
stroke: $nodeBorder;
stroke-width: 1;
fill: none;
}
@mixin composition {
fill: $nodeBorder;
stroke: $nodeBorder;
stroke-width: 1;
fill: $nodeBorder;
stroke: $nodeBorder;
stroke-width: 1;
}
#compositionStart {
@include composition;
@include composition;
}
#compositionEnd {
@include composition;
@include composition;
}
@mixin aggregation {
fill: $nodeBkg;
stroke: $nodeBorder;
stroke-width: 1;
fill: $nodeBkg;
stroke: $nodeBorder;
stroke-width: 1;
}
#aggregationStart {
@include aggregation;
@include aggregation;
}
#aggregationEnd {
@include aggregation;
@include aggregation;
}
#dependencyStart {
@include composition;
@include composition;
}
#dependencyEnd {
@include composition;
@include composition;
}
#extensionStart {
@include composition;
@include composition;
}
#extensionEnd {
@include composition;
@include composition;
}
```
## Configuration
`Coming soon`
`Coming soon`

View File

@ -1,5 +1,7 @@
## Directives
**Edit this Page** [![N|Solid](./img/GitHub-Mark-32px.png)](./directives.md)
**Edit this Page** [![N|Solid](/img/GitHub-Mark-32px.png)](./directives.md)
Directives were added in [Version 8.6.0](/8.6.0_docs.md)
## Directives were added in [Version 8.6.0](/8.6.0_docs.md). Please Read it for more information.
@ -72,9 +74,8 @@ Multiline directives, however, will pose an issue and will render an error. This
### 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.
# Wrap
| Parameter | Description |Type | Required | Values|
| --- | --- | --- | --- | --- |
| wrap | a callable text-wrap function| Directive| Optional | %%{wrap}%%|

View File

@ -562,6 +562,23 @@ graph LR
?> Due to limitations with how Docsify handles JavaScript callback functions, an alternate working demo for the above code can be viewed at [this jsfiddle](https://jsfiddle.net/s37cjoau/3/).
Links are opened in the same browser tab/window by default. It is possible to change this by adding a link target to the click definition (`_self`, `_blank`, `_parent` and `_top` are supported):
```
graph LR;
A-->B;
B-->C;
click A "http://www.github.com" _blank
click B "http://www.github.com" "Open this in a new tab" _blank
```
```mermaid
graph LR;
A-->B;
B-->C;
click A "http://www.github.com" _blank
click B "http://www.github.com" "Open this in a new tab" _blank
```
Beginners tip, a full example using interactive links in a html context:
```
<body>
@ -623,13 +640,13 @@ It is possible to apply specific styles such as a thicker border or a different
graph LR
id1(Start)-->id2(Stop)
style id1 fill:#f9f,stroke:#333,stroke-width:4px
style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5, 5
style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5
```
```mermaid
graph LR
id1(Start)-->id2(Stop)
style id1 fill:#f9f,stroke:#333,stroke-width:4px
style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5, 5
style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5
```

View File

@ -7,9 +7,8 @@
<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="theme.css">
<!-- <script src="//cdn.jsdelivr.net/npm/mermaid@8.6.4/dist/mermaid.min.js"></script> -->
<script src="http://localhost:9000/mermaid.js"></script>
<link rel="stylesheet" href="theme.css"> <script src="//cdn.jsdelivr.net/npm/mermaid@8.7.0/dist/mermaid.min.js"></script>
<!-- <script src="http://localhost:9000/mermaid.js"></script> -->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),

View File

@ -1,3 +1,3 @@
# mermaid CLI
mermaid CLI has been moved to [mermaid.cli](https://github.com/mermaidjs/mermaid.cli). Please read its documentation instead.
mermaid CLI has been moved to [mermaid-cli](https://github.com/mermaid-js/mermaid-cli). Please read its documentation instead.

View File

@ -36,14 +36,16 @@ And they are rendered into this and made part of the documentation:
## Advantages of Using 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
- Ease of generation, modification and rendering.
- The number of integrations and plugins it has.
- It can be added to your or your company's website.
## Diagramming and charting is a gigantic waste of developer time, but not having diagrams ruins productivity.
## The catch-22 of Diagrams and Charts:
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.
**Diagramming and charting is a gigantic waste of developer time, but not having diagrams ruins productivity. **
mermaid solves this by cutting the time, effort and tooling that is required to create diagrams and charts.
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.

View File

@ -1,14 +1,27 @@
# Theming
# Version 8.7.0: Theme Configuration
Mermaid as a system for theming in place. With it a site integrator can override a vast majority of attributes used when rendering a diagram.
**Edit this Page** [![N|Solid](./img/GitHub-Mark-32px.png)](https://github.com/mermaid-js/mermaid/blob/develop/docs/theming.md)
The settings for a theme can be set globally for the site with the initialize call. The example below highlights how that can look:
With Version 8.7.0 Mermaid comes out with a system for dynamic and integrated configuration of the diagram themes. The objective of this is to increase the customizability of mermaid and the ease of Styling, with the customization of themes through the `%%init%%` directive and `initialize` calls.
Themes follow and build upon the Levels of Configuration and employ `directives` to modify and create custom configurations, as they were introduced in Version [8.6.0](./8.6.0_docs.md).
**These Theming Configurations, similar to directives, will also be made applicable in the Live-Editor, to maximize customizability.
## Site-wide Themes
Site-wide themes are still declared via `initialize` by site owners.
Example of `Initalize` call setting `theme` to `base`:
```
// example
mermaidAPI.initialize({
'securityLevel': 'loose', 'theme': 'base'
});
```
**Notes**: Only site owners can use the `mermaidAPI.initialize` call, to set values. Site-Users will have to use `%%init%%` to modify or create the theme for their diagrams.
## Themes at the Local or Current Level
When Generating a diagram using on a webpage that supports mermaid. It is also possible to override site-wide theme settings locally, for a specific diagram, using directives, as long as it is not prohibited by the `secure` array.
It is also possible to override theme settings locally in a diagram using directives.
```
%%{init: {'theme':'base'}}%%
@ -16,14 +29,9 @@ It is also possible to override theme settings locally in a diagram using direct
a --> b
```
The easiest way to make a custom theme is to start with the base theme, the theme named base and just modify these variables:
* primaryColor - the base color for the theme
More specific color variables it is possible to change:
* lineColor
* textColor
Here is an example of how `%%init%%` can set the theme to 'base', this assumes that `themeVariables` are set to default:
Here is an example of a showcase flowchart with theme set to base, with the default variables set:
```mermaid
%%{init: {'theme':'base'}}%%
graph TD
@ -42,9 +50,19 @@ Here is an example of a showcase flowchart with theme set to base, with the defa
end
```
Here is an example of overriding the primary color and giving everything a little different look.
```mermaid
%%{init: {'theme':'base', 'themeVariables': {primaryColor: '#ff0000'}}%%
# Making a Custom Theme with `themeVariables`
The easiest way to make a custom theme is to start with the base theme, and just modify theme variables through `themeVariables`, via `%%init%%`.
| Parameter | Description | Type | Required | Objects contained |
| -------------- | ------------------------------------------------------------------ | ----- | -------- | ---------------------------------- |
| themeVariables | Array containing objects, modifiable with the `%%init%%` directive | Array | Required | primaryColor, lineColor, textColor |
## Here is an example of overriding `primaryColor` through `themeVariables` and giving everything a different look, using `%%init%%`.
```
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#ff0000'}}}%%
graph TD
A[Christmas] -->|Get money| B(Go shopping)
B --> C{Let me think}
@ -60,13 +78,221 @@ Here is an example of overriding the primary color and giving everything a littl
G
end
```
As the theming engine is using color codes to calculate values from the base color/base colors it needs proper color values contrain the actual color data. Aliases like color names is not supported so for instance, the color value 'red' will not work but '#ff0000' will work.
## Showcases
```mermaid
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#00ff00'}}}%%
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
```
When adjusting a theme it might be helpful to look at the theme with these diagrams to evaluate that everything is visiable and looks good.
### flowchart
**Notes:
Leaving it empty will set all variable values to default.
## Color and Color Calculation:
Color definitions have certain interactions in mermaid, this is in order to ensure visibility for diagrams. mermaid will adjust some variables automatically, when colors are changed in order to compensate and maintain readability.
**The Default Value Column** to the right of the Variable coloumn will denote the Variable paired/associated with the Variable on the left and the nature of this pairing or association. If it for instance says primaryColor it means that it gets primaryColor as default value. If it says "based on primaryColor" it means that it is calculated/ derived from primaryColor. This calculation can be primary color inversion, a change of hue, darkening or lightening by 10%, etc.
You can create your own themes, by changing any of the given variables below. If you are using a dark background, set dark mode to true to adjust the colors. It is possible to override the calculations using the variable names below, with `%%init%%` if you wish to style it differently.
## Theme Variables Reference Table
**Notes: Variables that are unique to some diagrams can be affected by changes in Theme Variables.
| Variable | Default/Base/Factor value | Calc | Description |
| -------------------- | ------------------------------ | ---- | -------------------------------------------------------------------------------------------------------------------------------- |
| darkMode | false | | Boolean Value that dictates how to calculate colors. "true" will activate darkmode. |
| background | #f4f4f4 | | Used to calculate color for items that should either be background colored or contrasting to the background. |
| primaryColor | #fff4dd | | Color to be used as background in nodes, other colors will be derived from this |
| fontFamily | "trebuchet ms", verdana, arial | | |
| fontSize | 16px | | Font Size, in pixels |
| secondaryColor | based on primaryColor | * | |
| tertiaryColor | based on primaryColor | * | |
| primaryBorderColor | based on primaryColor | * | Color to be used as border in nodes using primaryColor |
| primaryTextColor | based on darkMode #ddd/#333 | * | Color to be used as text color in nodesusing primaryColor |
| secondaryBorderColor | based on secondaryColor | * | Color to be used as border in nodes using secondaryColor |
| secondaryTextColor | based on secondaryColor | * | Color to be used as text color in nodesusing secondaryColor |
| tertiaryBorderColor | based on tertiaryColor | * | Color to be used as border in nodes using tertiaryColor |
| tertiaryTextColor | based on tertiaryColor | * | Color to be used as text color in nodesusing tertiaryColor |
| noteBkgColor | #fff5ad | | Color used as background in notes |
| noteTextColor | #333 | | Text color in note rectangless. |
| noteBorderColor | based on noteBkgColor | * | Border color in note rectangless. |
| lineColor | based on background | * | |
| textColor | based on primaryTextColor | * | Text in diagram over the background for instance text on labels and on signals in sequence diagram or the title in gantt diagram |
| mainBkg | based on primaryColor | * | Background in flowchart objects like rects/circles, class diagram classes, sequence diagram etc |
| errorBkgColor | tertiaryColor | * | Color for syntax error message |
| errorTextColor | tertiaryTextColor | * | Color for syntax error message |
# What follows are Variables, specific to different diagrams and charts.
## Some Theme Variables serve as, or affect the Default Values for Specific Diagram Variables, unless changed using `%%init%%` .
## Flowchart
| Variable | Default/ Associated Value | Calc | Description |
| -------------------- | ------------------------------ | ---- | -------------------------------------------------------------------------------------------------------------------------------- |
| nodeBorder | primaryBorderColor | * | Node Border Color |
| clusterBkg | tertiaryColor | * | Background in subgraphs |
| clusterBorder | tertiaryBorderColor | * | Cluster Border Color |
| defaultLinkColor | lineColor | * | Link Color |
| titleColor | tertiaryTextColor | * | Title Color |
| edgeLabelBackground | based on secondaryColor | * | |
| nodeTextColor | primaryTextColor | * | Color for text inside Nodes. |
# sequence diagram
| name | Default value | Calc | Description |
| --------------------- | ----------------------- | ---- | ----------- |
| actorBorder | primaryBorderColor | * | Actor Border Color |
| actorBkg | mainBkg | * | Actor Background Color |
| actorTextColor | primaryTextColor | * | Actor Text Color |
| actorLineColor | grey | * | Actor Line Color |
| labelBoxBkgColor | actorBkg | * | Label Box Background Color |
| signalColor | textColor | * | Signal Color |
| signalTextColor | textColor | * | Signal Text Color |
| labelBoxBorderColor | actorBorder | * | Label Box Border Color |
| labelTextColor | actorTextColor | * | Label Text Color |
| loopTextColor | actorTextColor | * | Loop ext Color |
| activationBorderColor | based on secondaryColor | * | Activation Border Color |
| activationBkgColor | secondaryColor | * | Activation Background Color |
| sequenceNumberColor | based on lineColor | * | Sequence Number Color |
# state colors
| name | Default value | Calc | Description |
| ------------- | ---------------- | ---- | ------------------------------------------- |
| labelColor | primaryTextColor | * | |
| altBackground | tertiaryColor | * | Used for background in deep composite states |
# class colors
| name | Default value | Calc | Description |
| --------- | ------------- | ---- | ---------------------- |
| classText | textColor | * | Color of Text in class diagrams |
# User journey colors
| name | Default value | Calc | Description |
| --------- | ------------------------ | ---- | --------------------------------------- |
| fillType0 | primaryColor | * | Fill for 1st section in journey diagram |
| fillType1 | secondaryColor | * | Fill for 2nd section in journey diagram |
| fillType2 | based on primaryColor | * | Fill for 3rd section in journey diagram |
| fillType3 | based on secondaryColor | * | Fill for 4th section in journey diagram |
| fillType4 | based on primaryColor | * | Fill for 5th section in journey diagram |
| fillType5 | based on secondaryColor | * | Fill for 6th section in journey diagram |
| fillType6 | based on primaryColor | * | Fill for 7th section in journey diagram |
| fillType7 | based on secondaryColor | * | Fill for 8th section in journey diagram |
**Notes: Values are meant to create an alternating look.
# Here is an example of overriding `primaryColor` and giving everything a different look, using `%%init%%`.
```
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#ff0000'}}}%%
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
```
```mermaid
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#ff0000'}}}%%
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
```
**This got a bit too dark and bit too colorful. With some easy steps this can be fixed:
* Make the primary color a little lighter
* set the teriary color to a redish shade as well
* make the edge label background differ from the subgraph by setting the edgeLabelBackground
```
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#ffcccc', 'edgeLabelBackground':'#ffffee', 'tertiaryColor': '#fff0f0'}}}%%
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
```
```mermaid
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#ffcccc', 'edgeLabelBackground':'#ffffee', 'tertiaryColor': '#fff0f0'}}}%%
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
```
The Theming Engine does not admit color codes and will only accept proper color values. Color Names is not supported so for instance, the color value 'red' will not work, but '#ff0000' will work.
# Common theming activities
## How to change the color of the arrows
# Examples:
When adjusting a theme it might be helpful to look at how your preferred theme goes with the diagrams, to evaluate whether everything is visible and looks good.
In the following examples, the directive `init` is used, with the `theme` being declared as `base`. For more information on using directives, read the documentation for [Version 8.6.0](/8.6.0_docs.md)
### Flowchart
```
%%{init: {'securityLevel': 'loose', 'theme':'base'}}%%
graph TD
@ -102,8 +328,9 @@ When adjusting a theme it might be helpful to look at the theme with these diagr
end
```
### flowchart (beta)
```mermaid
### Flowchart (beta)
```
mermaid
%%{init: {'securityLevel': 'loose', 'theme':'base'}}%%
flowchart TD
A[Christmas] -->|Get money| B(Go shopping)
@ -173,6 +400,35 @@ classDiagram
```
### Gantt
```
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
```
```mermaid
gantt
@ -205,6 +461,36 @@ gantt
```
### State diagram
```
mermaid
%%{init: {'securityLevel': 'loose', 'theme':'base'}}%%
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.
SomethingElse --> [*]
```
```mermaid
%%{init: {'securityLevel': 'loose', 'theme':'base'}}%%
stateDiagram
@ -237,6 +523,34 @@ gantt
### State diagram (beta)
```
%%{init: {'securityLevel': 'loose', 'theme':'base'}}%%
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.
SomethingElse2 --> [*]
```
```mermaid
%%{init: {'securityLevel': 'loose', 'theme':'base'}}%%
stateDiagram-v2
@ -268,6 +582,17 @@ stateDiagram-v2
### Entity Relations diagram
```
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"
```
```mermaid
erDiagram
CUSTOMER }|..|{ DELIVERY-ADDRESS : has
@ -280,7 +605,19 @@ stateDiagram-v2
PRODUCT ||--o{ ORDER-ITEM : "ordered in"
```
### User journet diagram
### User journey diagram
```
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
```
```mermaid
journey
title My working day
@ -291,4 +628,4 @@ journey
section Go home
Go downstairs: 5: Me
Sit down: 5: Me
```
```

View File

@ -87,12 +87,14 @@ An id attribute is also added to mermaid tags without one.
Mermaid can load multiple diagrams, in the same page.
### Try it out, save this code as HTML and load it using any browser.(Please don't use Internet Explorer though.)
### Try it out, save this code as HTML and load it using any browser.(Except Internet Explorer, please don't use Internet Explorer.)
## To enable click event and tags in nodes
A `securityLevel` configuration has to first be cleared, `securityLevel` sets the level of trust for the parsed diagrams. This was introduce in version 8.2 as a security improvement, aimed at preventing malicious use.
A `securityLevel` configuration has to first be cleared, `securityLevel` sets the level of trust for the parsed diagrams and limits click functionality. This was introduce in version 8.2 as a security improvement, aimed at preventing malicious use.
**It is the site owner's resposniblity to discriminate between trustworthy and untrustworthy user-bases and we encourage the use of discretion.**
## securityLevel
@ -109,7 +111,7 @@ Mermaid can load multiple diagrams, in the same page.
⚠️ **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 you are taking resposibility for the diagram source security you can set the `securityLevel` to a value of your choosing . By doing this clicks and tags are again allowed.
**If you are taking resposibility for the diagram source security you can set the `securityLevel` to a value of your choosing . By doing this clicks and tags are allowed.**
## To chage `securityLevel` with `mermaidAPI.initialize`:

111
docs/versionUpdates.md Normal file
View File

@ -0,0 +1,111 @@
# Version News and Updates
**Edit this Page** [![N|Solid](./img/GitHub-Mark-32px.png)](https://github.com/mermaid-js/mermaid/blob/develop/docs/8.6.0_docs.md)
**This file will track the changes to mermaid and its evolution over time.**
## Here is the list of the newest versions in Descending Order, beginning from the latest version.
# [Version 8.7.0](./theming.md) brings with it a system for dynamic and integrated configuration of the diagram themes. The objective of this is to increase the customizability of mermaid and the ease of Styling, with the customization of themes through the `%%init%%` directive and `initialize` calls.
Themes follow and build upon the Levels of Configuration and employ `directives` to modify and create custom configurations, as they were introduced in Version [8.6.0](./8.6.0_docs.md).
**These Theming Configurations, similar to directives, will also be made applicable in the Live-Editor, for easier styling.
### Site-wide Themes
Site-wide themes are still declared via `initialize` by site owners.
Example of `Initalize` call setting `theme` to `base`:
```
mermaidAPI.initialize({
'securityLevel': 'loose', 'theme': 'base'
});
```
**Notes**: Only site owners can use the `mermaidAPI.initialize` call, to set values. Site-Users will have to use `%%init%%` to modify or create the theme for their diagrams.
## Themes at the Local or Current Level
When Generating a diagram using on a webpage that supports mermaid. It is also possible to override site-wide theme settings locally, for a specific diagram, using directives, as long as it is not prohibited by the `secure` array.
**Following is an example:
```
%%{init: {'theme':'base'}}%%
graph TD
a --> b
```
### Making a Custom Theme with `themeVariables`
The easiest way to make a custom theme is to start with the base theme, and just modify theme variables through `themeVariables`, via `%%init%%`.
| Parameter | Description | Type | Required | Objects contained |
| -------------- | ------------------------------------------------------------------ | ----- | -------- | ---------------------------------- |
| themeVariables | Array containing objects, modifiable with the `%%init%%` directive | Array | Required | primaryColor, lineColor, textColor |
### Here is an example of overriding `primaryColor` and giving everything a different look, using `%%init%%`.
```
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#ff0000'}}}%%
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
```
**Notes:
Leaving it empty will set all variable values to default.
# [Version 8.6.0](./8.6.0_docs.md) introduces New Configuration Protocols and Directives and a Beta for the [New Mermaid Live-Editor](https://mermaid-js.github.io/docs/mermaid-live-editor-beta/#/edit/eyJjb2RlIjoiJSV7aW5pdDoge1widGhlbWVcIjogXCJmb3Jlc3RcIiwgXCJsb2dMZXZlbFwiOiAxIH19JSVcbmdyYXBoIFREXG4gIEFbQ2hyaXN0bWFzXSAtLT58R2V0IG1vbmV5fCBCKEdvIHNob3BwaW5nKVxuICBCIC0tPiBDe0xldCBtZSB0aGlua31cbiAgQyAtLT58T25lfCBEW0xhcHRvcF1cbiAgQyAtLT58VHdvfCBFW2lQaG9uZV1cbiAgQyAtLT58VGhyZWV8IEZbZmE6ZmEtY2FyIENhcl1cblx0XHQiLCJtZXJtYWlkIjp7InRoZW1lIjoiZGFyayJ9fQ)
**With version 8.6.0 comes the release of directives for mermaid, a new system for modifying configurations, with the aim of establishing centralized, sane defaults and simple implementation.
directives allow for a diagram specific overriding of config, as it has been discussed in Configurations. This allows site users to input modifications to config alongside diagram definitions, when creating diagrams on a private webpage that supports mermaid.
# Version 8.5.0, introduces New diagrams
**New diagrams in 8.5**
With version 8.5 there are some bug fixes and enhancements, plus a new diagram type, entity relationship diagrams.
![Image showing the new ER diagram type](./img/er.png)
# Version 8.2.0, introduces a security improvement
A `securityLevel` configuration has to first be cleared, `securityLevel` sets the level of trust for the parsed diagrams and limits click functionality. This was introduce in version 8.2 as a security improvement, aimed at preventing malicious use.
## 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
⚠️ **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 you are taking resposibility for the diagram source security you can set the `securityLevel` to a value of your choosing . By doing this clicks and tags are again allowed.
## To chage `securityLevel` with `mermaidAPI.initialize`:
```javascript
mermaidAPI.initialize({
securityLevel: 'loose'
});

View File

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

View File

@ -20,22 +20,18 @@ export const updateCurrentConfig = (siteCfg, _directives) => {
const d = _directives[i];
sanitize(d);
cfg = assignWithDepth(cfg, d);
if (d.themeVariables) {
themeVariables = d.themeVariables;
if (d.theme) {
cfg.themeVariables = theme[cfg.theme].getThemeVariables(d.themeVariables);
}
}
if (cfg.theme && theme[cfg.theme]) {
// console.warn('cfg beeing updated main bkg', themeVariables, cfg.theme);
const variables = theme[cfg.theme].getThemeVariables(themeVariables);
// console.warn('cfg beeing updated 2 main bkg', variables.mainBkg);
let tVars = assignWithDepth({}, cfg.themeVariables);
tVars = assignWithDepth(tVars, themeVariables);
const variables = theme[cfg.theme].getThemeVariables(tVars);
cfg.themeVariables = variables;
}
// else {
// console.warn('cfg not beeing updated main bkg', themeVariables, cfg.theme);
// }
currentConfig = cfg;
// console.warn('cfg updated main bkg', cfg.sequence);
return cfg;
};
/**
@ -53,23 +49,20 @@ export const updateCurrentConfig = (siteCfg, _directives) => {
* @returns {*} - the siteConfig
*/
export const setSiteConfig = conf => {
// siteConfig = { ...defaultConfig, ...conf };
console.warn('Setting site config');
siteConfig = assignWithDepth({}, defaultConfig);
siteConfig = assignWithDepth(siteConfig, conf);
if (conf.theme) {
siteConfig.themeVariables = theme[conf.theme].getThemeVariables(conf.themeVariables);
}
currentConfig = updateCurrentConfig(siteConfig, directives);
return siteConfig;
};
export const updateSiteConfig = conf => {
// Object.keys(conf).forEach(key => {
// const manipulator = manipulators[key];
// conf[key] = manipulator ? manipulator(conf[key]) : conf[key];
// });
siteConfig = assignWithDepth(siteConfig, conf);
console.log('updateSiteConfig', siteConfig);
updateCurrentConfig(siteConfig, directives);
// assignWithDesetpth(currentConfig, conf, { clobber: true });
// // Set theme variables if user has set the theme option
// assignWithDepth(siteConfig, conf);
return siteConfig;
};
@ -161,27 +154,10 @@ export const addDirective = directive => {
*
**Notes :
(default: current siteConfig ) (optional, default `getSiteConfig()`)
* @param conf - the base currentConfig to reset to (default: current siteConfig )
* @param conf the base currentConfig to reset to (default: current siteConfig ) (optional, default `getSiteConfig()`)
*/
export const reset = () => {
// 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 });
// Replace current config with siteConfig
directives = [];
// console.warn(siteConfig.sequence);
updateCurrentConfig(siteConfig, directives);
};
// const configApi = Object.freeze({
// sanitize,
// setSiteConfig,
// getSiteConfig,
// setConfig,
// getConfig,
// reset,
// defaultConfig
// });
// export default configApi;

View File

@ -1,6 +1,6 @@
module.exports = intersectNode;
function intersectNode(node, point) {
console.info('Intersect Node');
// console.info('Intersect Node');
return node.intersect(point);
}

View File

@ -44,7 +44,7 @@ function intersectPolygon(node, polyPoints, point) {
}
if (!intersections.length) {
console.log('NO INTERSECTION FOUND, RETURN NODE CENTER', node);
// console.log('NO INTERSECTION FOUND, RETURN NODE CENTER', node);
return node;
}

View File

@ -26,6 +26,7 @@ const splitClassNameAndType = function(id) {
if (id.indexOf('~') > 0) {
let split = id.split('~');
className = split[0];
genericType = split[1];
}
@ -51,6 +52,7 @@ export const addClass = function(id) {
annotations: [],
domId: MERMAID_DOM_ID_PREFIX + classId.className + '-' + classCounter
};
classCounter++;
};

View File

@ -0,0 +1,60 @@
/* eslint-env jasmine */
import { parser } from './parser/classDiagram';
import classDb from './classDb';
describe('class diagram, ', function() {
describe('when parsing data from a classDiagram it', function() {
beforeEach(function() {
parser.yy = classDb;
parser.yy.clear();
});
it('should be possible to apply a css class to a class directly', function() {
const str = 'classDiagram\n' + 'class Class01:::exClass';
parser.parse(str);
expect(parser.yy.getClass('Class01').cssClasses[0]).toBe('exClass');
});
it('should be possible to apply a css class to a class directly with struct', function () {
const str =
'classDiagram\n' +
'class Class1:::exClass {\n' +
'int : test\n' +
'string : foo\n' +
'test()\n' +
'foo()\n' +
'}';
parser.parse(str);
const testClass = parser.yy.getClass('Class1');
expect(testClass.cssClasses[0]).toBe('exClass');
});
it('should be possible to apply a css class to a class with relations', function() {
const str = 'classDiagram\n' + 'Class01 <|-- Class02\ncssClass "Class01" exClass';
parser.parse(str);
expect(parser.yy.getClass('Class01').cssClasses[0]).toBe('exClass');
});
it('should be possible to apply a cssClass to a class', function() {
const str = 'classDiagram\n' + 'class Class01\n cssClass "Class01" exClass';
parser.parse(str);
expect(parser.yy.getClass('Class01').cssClasses[0]).toBe('exClass');
});
it('should be possible to apply a cssClass to a comma separated list of classes', function() {
const str = 'classDiagram\n' + 'class Class01\n class Class02\n cssClass "Class01,Class02" exClass';
parser.parse(str);
expect(parser.yy.getClass('Class01').cssClasses[0]).toBe('exClass');
expect(parser.yy.getClass('Class02').cssClasses[0]).toBe('exClass');
});
});
});

View File

@ -14,7 +14,7 @@
<type_directive>":" { this.popState(); this.begin('arg_directive'); return ':'; }
<type_directive,arg_directive>\}\%\% { this.popState(); this.popState(); return 'close_directive'; }
<arg_directive>((?:(?!\}\%\%).|\n)*) return 'arg_directive';
\%\%(?!\{)*[^\n]*(\r?\n)+ /* skip comments */
\%\%(?!\{)*[^\n]*(\r?\n?)+ /* skip comments */
\%\%[^\n]*(\r?\n)* /* skip comments */
(\r?\n)+ return 'NEWLINE';
\s+ /* skip whitespace */
@ -27,10 +27,8 @@
<struct>[\n] /* nothing */
<struct>[^{}\n]* { /*console.log('lex-member: ' + yytext);*/ return "MEMBER";}
"class" return 'CLASS';
//"click" return 'CLICK';
"cssClass" return 'CSSCLASS';
"callback" return 'CALLBACK';
"link" return 'LINK';
"<<" return 'ANNOTATION_START';
@ -51,7 +49,8 @@
\s*o return 'AGGREGATION';
\-\- return 'LINE';
\.\. return 'DOTTED_LINE';
":"[^\n;]+ return 'LABEL';
":"{1}[^:\n;]+ return 'LABEL';
":"{3} return 'STYLE_SEPARATOR';
\- return 'MINUS';
"." return 'DOT';
\+ return 'PLUS';
@ -177,8 +176,8 @@ statements
;
className
: alphaNumToken className { $$=$1+$2; }
| alphaNumToken { $$=$1; }
: alphaNumToken { $$=$1; }
| alphaNumToken className { $$=$1+$2; }
| alphaNumToken GENERICTYPE className { $$=$1+'~'+$2+$3; }
| alphaNumToken GENERICTYPE { $$=$1+'~'+$2; }
;
@ -190,12 +189,15 @@ statement
| methodStatement
| annotationStatement
| clickStatement
| cssClassStatement
| directive
;
classStatement
: CLASS className {yy.addClass($2);}
| CLASS className STYLE_SEPARATOR alphaNumToken {yy.addClass($2);yy.setCssClass($2, $4);}
| CLASS className STRUCT_START members STRUCT_STOP {/*console.log($2,JSON.stringify($4));*/yy.addClass($2);yy.addMembers($2,$4);}
| CLASS className STYLE_SEPARATOR alphaNumToken STRUCT_START members STRUCT_STOP {yy.addClass($2);yy.setCssClass($2, $4);yy.addMembers($2,$6);}
;
annotationStatement
@ -241,10 +243,14 @@ lineType
;
clickStatement
: CALLBACK className STR {$$ = $1;yy.setClickEvent($2, $3, undefined);}
| CALLBACK className STR STR {$$ = $1;yy.setClickEvent($2, $3, $4);}
| LINK className STR {$$ = $1;yy.setLink($2, $3, undefined);}
| LINK className STR STR {$$ = $1;yy.setLink($2, $3, $4);}
: CALLBACK className STR {$$ = $1;yy.setClickEvent($2, $3, undefined);}
| CALLBACK className STR STR {$$ = $1;yy.setClickEvent($2, $3, $4);}
| LINK className STR {$$ = $1;yy.setLink($2, $3, undefined);}
| LINK className STR STR {$$ = $1;yy.setLink($2, $3, $4);}
;
cssClassStatement
: CSSCLASS STR alphaNumToken {yy.setCssClass($2, $3);}
;
commentToken : textToken | graphCodeTokens ;
@ -254,4 +260,5 @@ textToken : textNoTagsToken | TAGSTART | TAGEND | '==' | '--' | PCT | DEFA
textNoTagsToken: alphaNumToken | SPACE | MINUS | keywords ;
alphaNumToken : UNICODE_TEXT | NUM | ALPHA;
%%

View File

@ -31,7 +31,7 @@ g.clickable {
}
g.classGroup rect {
fill: ${options.nodeBkg};
fill: ${options.mainBkg};
stroke: ${options.nodeBorder};
}
@ -43,7 +43,7 @@ g.classGroup line {
.classLabel .box {
stroke: none;
stroke-width: 0;
fill: ${options.nodeBkg};
fill: ${options.mainBkg};
opacity: 0.5;
}
@ -99,13 +99,13 @@ g.classGroup line {
}
#aggregationStart, .aggregation {
fill: ${options.nodeBkg} !important;
fill: ${options.mainBkg} !important;
stroke: ${options.lineColor} !important;
stroke-width: 1;
}
#aggregationEnd, .aggregation {
fill: ${options.nodeBkg} !important;
fill: ${options.mainBkg} !important;
stroke: ${options.lineColor} !important;
stroke-width: 1;
}

View File

@ -147,11 +147,6 @@ export const drawEdge = function(elem, path, relation, conf) {
export const drawClass = function(elem, classDef, conf) {
logger.info('Rendering class ' + classDef);
let cssClassStr = 'classGroup ';
if (classDef.cssClasses.length > 0) {
cssClassStr = cssClassStr + classDef.cssClasses.join(' ');
}
const id = classDef.id;
const classInfo = {
id: id,
@ -164,7 +159,7 @@ export const drawClass = function(elem, classDef, conf) {
const g = elem
.append('g')
.attr('id', lookUpDomId(id))
.attr('class', cssClassStr);
.attr('class', 'classGroup');
// add title
let title;
@ -249,12 +244,19 @@ export const drawClass = function(elem, classDef, conf) {
});
const classBox = g.node().getBBox();
var cssClassStr = ' ';
if (classDef.cssClasses.length > 0) {
cssClassStr = cssClassStr + classDef.cssClasses.join(' ');
}
const rect = g
.insert('rect', ':first-child')
.attr('x', 0)
.attr('y', 0)
.attr('width', classBox.width + 2 * conf.padding)
.attr('height', classBox.height + conf.padding + 0.5 * conf.dividerMargin);
.attr('height', classBox.height + conf.padding + 0.5 * conf.dividerMargin)
.attr('class', cssClassStr);
const rectWidth = rect.node().getBBox().width;

View File

@ -7,7 +7,7 @@ const getStyles = options =>
.relationshipLabelBox {
fill: ${options.tertiaryColor};
opacity: 0.3;
opacity: 0.7;
background-color: ${options.tertiaryColor};
rect {
opacity: 0.5;

View File

@ -252,12 +252,13 @@ const setClickFun = function(_id, functionName) {
* @param linkStr URL to create a link for
* @param tooltip Tooltip for the clickable element
*/
export const setLink = function(ids, linkStr, tooltip) {
export const setLink = function(ids, linkStr, tooltip, target) {
ids.split(',').forEach(function(_id) {
let id = _id;
if (_id[0].match(/\d/)) id = MERMAID_DOM_ID_PREFIX + id;
if (typeof vertices[id] !== 'undefined') {
vertices[id].link = utils.formatUrl(linkStr, config);
vertices[id].linkTarget = target;
}
});
setTooltip(ids, tooltip);

View File

@ -468,7 +468,7 @@ export const draw = function(text, id) {
rect.setAttribute('ry', 0);
rect.setAttribute('width', dim.width);
rect.setAttribute('height', dim.height);
rect.setAttribute('style', 'fill:#e8e8e8;');
// rect.setAttribute('style', 'fill:#e8e8e8;');
label.insertBefore(rect, label.firstChild);
}
@ -486,6 +486,9 @@ export const draw = function(text, id) {
link.setAttributeNS('http://www.w3.org/2000/svg', 'class', vertex.classes.join(' '));
link.setAttributeNS('http://www.w3.org/2000/svg', 'href', vertex.link);
link.setAttributeNS('http://www.w3.org/2000/svg', 'rel', 'noopener');
if (vertex.linkTarget) {
link.setAttributeNS('http://www.w3.org/2000/svg', 'target', vertex.linkTarget);
}
const linkNode = node.insert(function() {
return link;

View File

@ -451,7 +451,7 @@ export const draw = function(text, id) {
rect.setAttribute('ry', 0);
rect.setAttribute('width', dim.width);
rect.setAttribute('height', dim.height);
rect.setAttribute('style', 'fill:#e8e8e8;');
// rect.setAttribute('style', 'fill:#e8e8e8;');
label.insertBefore(rect, label.firstChild);
}
@ -469,6 +469,9 @@ export const draw = function(text, id) {
link.setAttributeNS('http://www.w3.org/2000/svg', 'class', vertex.classes.join(' '));
link.setAttributeNS('http://www.w3.org/2000/svg', 'href', vertex.link);
link.setAttributeNS('http://www.w3.org/2000/svg', 'rel', 'noopener');
if (vertex.linkTarget) {
link.setAttributeNS('http://www.w3.org/2000/svg', 'target', vertex.linkTarget);
}
const linkNode = node.insert(function() {
return link;

View File

@ -39,7 +39,7 @@ describe('[Interactions] when parsing', () => {
const vert = flow.parser.yy.getVertices();
const edges = flow.parser.yy.getEdges();
expect(flowDb.setLink).toHaveBeenCalledWith('A', 'click.html', undefined);
expect(flowDb.setLink).toHaveBeenCalledWith('A', 'click.html', undefined, undefined);
});
it('should handle interaction - click to a link with tooltip', function() {
@ -49,6 +49,26 @@ describe('[Interactions] when parsing', () => {
const vert = flow.parser.yy.getVertices();
const edges = flow.parser.yy.getEdges();
expect(flowDb.setLink).toHaveBeenCalledWith('A', 'click.html', 'tooltip');
expect(flowDb.setLink).toHaveBeenCalledWith('A', 'click.html', 'tooltip', undefined);
});
it('should handle interaction - click to a link with target', function() {
spyOn(flowDb, 'setLink');
const res = flow.parser.parse('graph TD\nA-->B\nclick A "click.html" _blank');
const vert = flow.parser.yy.getVertices();
const edges = flow.parser.yy.getEdges();
expect(flowDb.setLink).toHaveBeenCalledWith('A', 'click.html', undefined, '_blank');
});
it('should handle interaction - click to a link with tooltip and target', function() {
spyOn(flowDb, 'setLink');
const res = flow.parser.parse('graph TD\nA-->B\nclick A "click.html" "tooltip" _blank');
const vert = flow.parser.yy.getVertices();
const edges = flow.parser.yy.getEdges();
expect(flowDb.setLink).toHaveBeenCalledWith('A', 'click.html', 'tooltip', '_blank');
});
});

View File

@ -36,6 +36,12 @@
"flowchart" {if(yy.lex.firstGraph()){this.begin("dir");} return 'GRAPH';}
"subgraph" return 'subgraph';
"end"\b\s* return 'end';
"_self" return 'LINK_TARGET';
"_blank" return 'LINK_TARGET';
"_parent" return 'LINK_TARGET';
"_top" return 'LINK_TARGET';
<dir>(\r?\n)*\s*\n { this.popState(); return 'NODIR'; }
<dir>\s*"LR" { this.popState(); return 'DIR'; }
<dir>\s*"RL" { this.popState(); return 'DIR'; }
@ -439,10 +445,12 @@ classStatement:CLASS SPACE alphaNum SPACE alphaNum
;
clickStatement
: CLICK SPACE alphaNum SPACE alphaNum {$$ = $1;yy.setClickEvent($3, $5, undefined);}
| CLICK SPACE alphaNum SPACE alphaNum SPACE STR {$$ = $1;yy.setClickEvent($3, $5, $7) ;}
| CLICK SPACE alphaNum SPACE STR {$$ = $1;yy.setLink($3, $5, undefined);}
| CLICK SPACE alphaNum SPACE STR SPACE STR {$$ = $1;yy.setLink($3, $5, $7 );}
: CLICK SPACE alphaNum SPACE alphaNum {$$ = $1;yy.setClickEvent($3, $5, undefined);}
| CLICK SPACE alphaNum SPACE alphaNum SPACE STR {$$ = $1;yy.setClickEvent($3, $5, $7) ;}
| CLICK SPACE alphaNum SPACE STR {$$ = $1;yy.setLink($3, $5, undefined, undefined);}
| CLICK SPACE alphaNum SPACE STR SPACE STR {$$ = $1;yy.setLink($3, $5, $7, undefined );}
| CLICK SPACE alphaNum SPACE STR SPACE LINK_TARGET {$$ = $1;yy.setLink($3, $5, undefined, $7 );}
| CLICK SPACE alphaNum SPACE STR SPACE STR SPACE LINK_TARGET {$$ = $1;yy.setLink($3, $5, $7, $9 );}
;
styleStatement:STYLE SPACE alphaNum SPACE stylesOpt

View File

@ -1,11 +1,11 @@
const getStyles = options =>
`.label {
font-family: ${options.fontFamily};
color: ${options.textColor};
color: ${options.nodeTextColor || options.textColor};
}
.label text {
fill: ${options.textColor};
fill: ${options.nodeTextColor || options.textColor};
}
.node rect,
@ -43,6 +43,8 @@ const getStyles = options =>
background-color: ${options.edgeLabelBackground};
rect {
opacity: 0.5;
background-color: ${options.edgeLabelBackground};
fill: ${options.edgeLabelBackground};
}
text-align: center;
}
@ -64,7 +66,7 @@ const getStyles = options =>
padding: 2px;
font-family: ${options.fontFamily};
font-size: 12px;
background: ${options.secondBkg};
background: ${options.tertiaryColor};
border: 1px solid ${options.border2};
border-radius: 2px;
pointer-events: none;

View File

@ -14,8 +14,9 @@ import { logger } from '../../logger';
export const drawStartState = g =>
g
.append('circle')
.style('stroke', 'black')
.style('fill', 'black')
// .style('stroke', 'black')
// .style('fill', 'black')
.attr('class', 'start-state')
.attr('r', getConfig().state.sizeUnit)
.attr('cx', getConfig().state.padding + getConfig().state.sizeUnit)
.attr('cy', getConfig().state.padding + getConfig().state.sizeUnit);
@ -241,8 +242,9 @@ export const addTitleAndBox = (g, stateDef, altBkg) => {
const drawEndState = g => {
g.append('circle')
.style('stroke', 'black')
.style('fill', 'white')
// .style('stroke', 'black')
// .style('fill', 'white')
.attr('class', 'end-state-outer')
.attr('r', getConfig().state.sizeUnit + getConfig().state.miniPadding)
.attr(
'cx',
@ -253,13 +255,16 @@ const drawEndState = g => {
getConfig().state.padding + getConfig().state.sizeUnit + getConfig().state.miniPadding
);
return g
.append('circle')
.style('stroke', 'black')
.style('fill', 'black')
.attr('r', getConfig().state.sizeUnit)
.attr('cx', getConfig().state.padding + getConfig().state.sizeUnit + 2)
.attr('cy', getConfig().state.padding + getConfig().state.sizeUnit + 2);
return (
g
.append('circle')
// .style('stroke', 'black')
// .style('fill', 'black')
.attr('class', 'end-state-inner')
.attr('r', getConfig().state.sizeUnit)
.attr('cx', getConfig().state.padding + getConfig().state.sizeUnit + 2)
.attr('cy', getConfig().state.padding + getConfig().state.sizeUnit + 2)
);
};
const drawForkJoinState = (g, stateDef) => {
let width = getConfig().state.forkWidth;

View File

@ -18,7 +18,7 @@ g.stateGroup .state-title {
}
g.stateGroup rect {
fill: ${options.nodeBkg};
fill: ${options.mainBkg};
stroke: ${options.nodeBorder};
}
@ -57,17 +57,20 @@ g.stateGroup line {
.stateLabel .box {
stroke: none;
stroke-width: 0;
fill: ${options.nodeBkg};
fill: ${options.mainBkg};
opacity: 0.5;
}
.edgeLabel .label rect {
fill: ${options.tertiaryColor};
opacity: 0.2;
opacity: 0.5;
}
.edgeLabel .label text {
fill: ${options.tertiaryTextColor};
}
.label div .edgeLabel {
color: ${options.tertiaryTextColor};
}
.stateLabel text {
fill: ${options.labelColor};
@ -78,7 +81,7 @@ g.stateGroup line {
}
.node circle.state-start {
fill: ${options.primaryBorderColor};
fill: ${options.lineColor};
stroke: black;
}
.node circle.state-end {
@ -86,6 +89,11 @@ g.stateGroup line {
stroke: ${options.background};
stroke-width: 1.5
}
.end-state-inner {
fill: ${options.background};
// stroke: ${options.background};
stroke-width: 1.5
}
.node rect {
fill: ${options.mainBkg};
@ -97,7 +105,7 @@ g.stateGroup line {
}
.statediagram-cluster rect {
fill: ${options.nodeBkg};
fill: ${options.mainBkg};
stroke: ${options.nodeBorder};
stroke-width: 1px;
}

View File

@ -68,9 +68,6 @@ const getStyles = options =>
}
.cluster rect {
fill: ${options.secondBkg};
stroke: ${options.clusterBorder};
stroke-width: 1px;
}
.cluster text {
@ -85,7 +82,7 @@ const getStyles = options =>
font-family: 'trebuchet ms', verdana, arial;
font-family: var(--mermaid-font-family);
font-size: 12px;
background: ${options.secondBkg};
background: ${options.tertiaryColor};
border: 1px solid ${options.border2};
border-radius: 2px;
pointer-events: none;

View File

@ -31,7 +31,7 @@ import utils from './utils';
*/
const init = function() {
const conf = mermaidAPI.getConfig();
console.log('Starting rendering diagrams (init) - mermaid.init', conf);
// console.log('Starting rendering diagrams (init) - mermaid.init', conf);
let nodes;
if (arguments.length >= 2) {
/*! sequence config was passed as #1 */
@ -129,7 +129,7 @@ const init = function() {
};
const initialize = function(config) {
mermaidAPI.reset();
// mermaidAPI.reset();
if (typeof config.mermaid !== 'undefined') {
if (typeof config.mermaid.startOnLoad !== 'undefined') {
mermaid.startOnLoad = config.mermaid.startOnLoad;

View File

@ -220,7 +220,7 @@ const render = function(id, _txt, cb, container) {
// console.warn('Render fetching config');
const cnf = configApi.getConfig();
// console.warn('Render with config after adding new directives', cnf.themeVariables.mainBkg);
console.warn('Render with config after adding new directives', cnf.themeVariables.primaryColor);
// Check the maximum allowed text size
if (_txt.length > cnf.maxTextSize) {
txt = 'graph TB;a[Maximum text size in diagram exceeded];style a fill:#faa';
@ -552,7 +552,7 @@ function reinitialize() {
}
function initialize(options) {
logger.debug(`mermaidAPI.initialize: v${pkg.version} ${options}`);
console.warn(`mermaidAPI.initialize: v${pkg.version} `, options);
// Set default options
if (options && options.theme && theme[options.theme]) {
@ -581,7 +581,7 @@ const mermaidAPI = Object.freeze({
getSiteConfig: configApi.getSiteConfig,
updateSiteConfig: configApi.updateSiteConfig,
reset: () => {
console.warn('reset');
// console.warn('reset');
configApi.reset();
// const siteConfig = configApi.getSiteConfig();
// updateRendererConfigs(siteConfig);

View File

@ -1,133 +1,131 @@
import { darken, lighten, adjust, invert } from 'khroma';
const mkBorder = (col, darkMode) =>
darkMode ? adjust(col, { s: -40, l: 10 }) : adjust(col, { s: -40, l: -10 });
import { mkBorder } from './theme-helpers';
class Theme {
constructor() {
/** # Base variables */
/** * background - used to know what the background color is of the diagram. This is used for deducing colors for istance line color. Defaulr value is #f4f4f4. */
this.background = '#f4f4f4';
// this.background = '#0c0c0c';
/** * darkMode -In darkMode the color generation deduces other colors from the primary colors */
this.darkMode = false;
// this.background = '#0c0c0c';
// this.darkMode = true;
this.primaryColor = '#fff4dd';
// this.background = '#0c0c0c';
// this.primaryColor = '#1f1f00';
this.noteBkgColor = '#fff5ad';
this.noteTextColor = '#333';
// dark
// this.primaryColor = '#034694';
// this.primaryColor = '#f2ee7e';
// this.primaryColor = '#9f33be';
this.primaryColor = '#f0fff0';
// this.primaryColor = '#f0fff0';
// this.primaryColor = '#fa255e';
// this.primaryColor = '#ECECFF';
// this.secondaryColor = '#c39ea0';
// this.tertiaryColor = '#f8e5e5';
this.secondaryColor = '#dfdfde';
this.tertiaryColor = '#CCCCFF';
// this.secondaryColor = '#dfdfde';
// this.tertiaryColor = '#CCCCFF';
this.border1 = '#9370DB';
this.arrowheadColor = '#333333';
this.fontFamily = '"trebuchet ms", verdana, arial';
this.fontSize = '16px';
this.textColor = '#333';
this.updateColors();
this.relationColor = '#000';
// this.updateColors();
}
updateColors() {
this.secondBkg = this.tertiaryColor;
// The || is to make sure that if the variable has been defiend by a user override that value is to be used
/* Main */
this.secondaryColor = adjust(this.primaryColor, { h: 120 });
this.tertiaryColor = adjust(this.primaryColor, { h: -160 });
console.warn('primary color', this.primaryColor, 'tertiary - color', this.tertiaryColor);
this.primaryBorderColor = mkBorder(this.primaryColor, this.darkMode);
this.secondaryBorderColor = mkBorder(this.secondaryColor, this.darkMode);
this.tertiaryBorderColor = mkBorder(this.tertiaryColor, this.darkMode);
this.noteBorderColor = mkBorder(this.noteBkgColor, this.darkMode);
this.primaryTextColor = this.primaryTextColor || (this.darkMode ? '#ddd' : '#333'); // invert(this.primaryColor);
this.secondaryColor = this.secondaryColor || adjust(this.primaryColor, { h: -120 });
this.tertiaryColor = this.tertiaryColor || adjust(this.primaryColor, { h: 180, l: 5 });
this.primaryTextColor = invert(this.primaryColor);
this.secondaryTextColor = invert(this.secondaryColor);
this.tertiaryTextColor = invert(this.tertiaryColor);
this.lineColor = invert(this.background);
this.textColor = invert(this.background);
this.primaryBorderColor = this.primaryBorderColor || mkBorder(this.primaryColor, this.darkMode);
this.secondaryBorderColor =
this.secondaryBorderColor || mkBorder(this.secondaryColor, this.darkMode);
this.tertiaryBorderColor =
this.tertiaryBorderColor || mkBorder(this.tertiaryColor, this.darkMode);
this.noteBorderColor = this.noteBorderColor || mkBorder(this.noteBkgColor, this.darkMode);
this.secondaryTextColor = this.secondaryTextColor || invert(this.secondaryColor);
this.tertiaryTextColor = this.tertiaryTextColor || invert(this.tertiaryColor);
this.lineColor = this.lineColor || invert(this.background);
this.textColor = this.textColor || this.primaryTextColor;
/* Flowchart variables */
this.nodeBkg = this.primaryColor;
this.mainBkg = this.primaryColor;
// console.warn('main bkg ', this.mainBkg);
this.nodeBorder = this.primaryBorderColor;
this.clusterBkg = this.tertiaryColor;
this.clusterBorder = this.tertiaryBorderColor;
this.defaultLinkColor = this.lineColor;
this.titleColor = this.tertiaryTextColor;
this.edgeLabelBackground = this.labelBackground;
this.nodeBkg = this.nodeBkg || this.primaryColor;
this.mainBkg = this.mainBkg || this.primaryColor;
this.nodeBorder = this.nodeBorder || this.primaryBorderColor;
this.clusterBkg = this.clusterBkg || this.tertiaryColor;
this.clusterBorder = this.clusterBorder || this.tertiaryBorderColor;
this.defaultLinkColor = this.defaultLinkColor || this.lineColor;
this.titleColor = this.titleColor || this.tertiaryTextColor;
this.edgeLabelBackground =
this.edgeLabelBackground || this.darkMode
? darken(this.secondaryColor, 30)
: this.secondaryColor;
this.nodeTextColor = this.nodeTextColor || this.primaryTextColor;
/* Sequence Diagram variables */
// this.actorBorder = lighten(this.border1, 0.5);
this.actorBorder = this.primaryBorderColor;
this.actorBkg = this.mainBkg;
this.actorTextColor = this.primaryTextColor;
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.noteTextColor = this.actorTextColor;
this.activationBorderColor = darken(this.secondaryColor, 10);
this.activationBkgColor = this.secondaryColor;
this.sequenceNumberColor = 'white';
this.actorBorder = this.actorBorder || this.primaryBorderColor;
this.actorBkg = this.actorBkg || this.mainBkg;
this.actorTextColor = this.actorTextColor || this.primaryTextColor;
this.actorLineColor = this.actorLineColor || 'grey';
this.labelBoxBkgColor = this.labelBoxBkgColor || this.actorBkg;
this.signalColor = this.signalColor || this.textColor;
this.signalTextColor = this.signalTextColor || this.textColor;
this.labelBoxBorderColor = this.labelBoxBorderColor || this.actorBorder;
this.labelTextColor = this.labelTextColor || this.actorTextColor;
this.loopTextColor = this.loopTextColor || this.actorTextColor;
this.activationBorderColor = this.activationBorderColor || darken(this.secondaryColor, 10);
this.activationBkgColor = this.activationBkgColor || this.secondaryColor;
this.sequenceNumberColor = this.sequenceNumberColor || invert(this.lineColor);
/* Gantt chart variables */
this.sectionBkgColor = this.tertiaryColor;
this.altSectionBkgColor = 'white';
this.sectionBkgColor = this.secondaryColor;
this.sectionBkgColor2 = this.tertiaryColor;
this.altSectionBkgColor = 'white';
this.sectionBkgColor2 = this.primaryColor;
this.taskBorderColor = this.primaryBorderColor;
this.taskBkgColor = this.primaryColor;
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';
this.taskTextColor = this.textColor;
this.taskTextOutsideColor = this.textColor;
this.taskTextLightColor = this.textColor;
this.taskTextColor = this.primaryTextColor;
this.taskTextDarkColor = this.textColor;
this.taskTextOutsideColor = 'calculated';
this.taskTextClickableColor = '#003163';
/* state colors */
this.labelColor = this.primaryTextColor;
this.altBackground = this.tertiaryColor;
this.errorBkgColor = '#552222';
this.errorTextColor = '#552222';
this.sectionBkgColor = this.sectionBkgColor || this.tertiaryColor;
this.altSectionBkgColor = this.altSectionBkgColor || 'white';
this.sectionBkgColor = this.sectionBkgColor || this.secondaryColor;
this.sectionBkgColor2 = this.sectionBkgColor2 || this.primaryColor;
this.taskBorderColor = this.taskBorderColor || this.primaryBorderColor;
this.taskBkgColor = this.taskBkgColor || this.primaryColor;
this.activeTaskBorderColor = this.activeTaskBorderColor || this.primaryColor;
this.activeTaskBkgColor = this.activeTaskBkgColor || lighten(this.primaryColor, 23);
this.gridColor = this.gridColor || 'lightgrey';
this.doneTaskBkgColor = this.doneTaskBkgColor || 'lightgrey';
this.doneTaskBorderColor = this.doneTaskBorderColor || 'grey';
this.critBorderColor = this.critBorderColor || '#ff8888';
this.critBkgColor = this.critBkgColor || 'red';
this.todayLineColor = this.todayLineColor || 'red';
this.taskTextColor = this.taskTextColor || this.textColor;
this.taskTextOutsideColor = this.taskTextOutsideColor || this.textColor;
this.taskTextLightColor = this.taskTextLightColor || this.textColor;
this.taskTextColor = this.taskTextColor || this.primaryTextColor;
this.taskTextDarkColor = this.taskTextDarkColor || this.textColor;
this.taskTextClickableColor = this.taskTextClickableColor || '#003163';
/* state colors */
this.labelColor = this.labelColor || this.primaryTextColor;
this.altBackground = this.altBackground || this.tertiaryColor;
this.errorBkgColor = this.errorBkgColor || this.tertiaryColor;
this.errorTextColor = this.errorTextColor || this.tertiaryTextColor;
/* class */
this.classText = this.textColor;
this.classText = 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 });
this.fillType0 = this.fillType0 || this.primaryColor;
this.fillType1 = this.fillType1 || this.secondaryColor;
this.fillType2 = this.fillType2 || adjust(this.primaryColor, { h: 64 });
this.fillType3 = this.fillType3 || adjust(this.secondaryColor, { h: 64 });
this.fillType4 = this.fillType4 || adjust(this.primaryColor, { h: -64 });
this.fillType5 = this.fillType5 || adjust(this.secondaryColor, { h: -64 });
this.fillType6 = this.fillType6 || adjust(this.primaryColor, { h: 128 });
this.fillType7 = this.fillType7 || adjust(this.secondaryColor, { h: 128 });
}
calculate(overrides) {
if (typeof overrides !== 'object') {

View File

@ -1,10 +1,21 @@
import { invert, lighten, darken, rgba, adjust } from 'khroma';
import { mkBorder } from './theme-helpers';
class Theme {
constructor() {
this.background = '#333';
this.primaryColor = '#1f2020';
this.secondaryColor = lighten(this.primaryColor, 16);
this.tertiaryColor = adjust(this.primaryColor, { h: -160 });
this.primaryBorderColor = mkBorder(this.primaryColor, this.darkMode);
this.secondaryBorderColor = mkBorder(this.secondaryColor, this.darkMode);
this.tertiaryBorderColor = mkBorder(this.tertiaryColor, this.darkMode);
this.primaryTextColor = invert(this.primaryColor);
this.secondaryTextColor = invert(this.secondaryColor);
this.tertiaryTextColor = invert(this.tertiaryColor);
this.lineColor = invert(this.background);
this.textColor = invert(this.background);
this.mainBkg = '#1f2020';
this.secondBkg = 'calculated';
this.mainContrastColor = 'lightgrey';
@ -127,7 +138,7 @@ class Theme {
this.fillType6 = adjust(this.primaryColor, { h: 128 });
this.fillType7 = adjust(this.secondaryColor, { h: 128 });
/* class */
this.classText = this.nodeBorder;
this.classText = this.primaryTextColor;
}
calculate(overrides) {
if (typeof overrides !== 'object') {

View File

@ -1,10 +1,26 @@
import { lighten, rgba, adjust } from 'khroma';
import { invert, lighten, rgba, adjust } from 'khroma';
import { mkBorder } from './theme-helpers';
class Theme {
constructor() {
/* Base variables */
this.background = '#f4f4f4';
this.primaryColor = '#ECECFF';
this.secondaryColor = adjust(this.primaryColor, { h: 120 });
this.secondaryColor = '#ffffde';
this.tertiaryColor = adjust(this.primaryColor, { h: -160 });
this.primaryBorderColor = mkBorder(this.primaryColor, this.darkMode);
this.secondaryBorderColor = mkBorder(this.secondaryColor, this.darkMode);
this.tertiaryBorderColor = mkBorder(this.tertiaryColor, this.darkMode);
// this.noteBorderColor = mkBorder(this.noteBkgColor, this.darkMode);
this.primaryTextColor = invert(this.primaryColor);
this.secondaryTextColor = invert(this.secondaryColor);
this.tertiaryTextColor = invert(this.tertiaryColor);
this.lineColor = invert(this.background);
this.textColor = invert(this.background);
this.background = 'white';
this.mainBkg = '#ECECFF';
this.secondBkg = '#ffffde';
@ -124,7 +140,7 @@ class Theme {
/* state colors */
/* class */
this.classText = this.nodeBorder;
this.classText = this.primaryTextColor;
/* journey */
this.fillType0 = this.primaryColor;
this.fillType1 = this.secondaryColor;

View File

@ -1,7 +1,9 @@
import { darken, adjust } from 'khroma';
import { darken, lighten, adjust, invert } from 'khroma';
import { mkBorder } from './theme-helpers';
class Theme {
constructor() {
/* Base vales */
this.background = '#f4f4f4';
this.primaryColor = '#cde498';
this.secondaryColor = '#cdffb2';
this.background = 'white';
@ -14,8 +16,17 @@ class Theme {
this.fontFamily = '"trebuchet ms", verdana, arial';
this.fontSize = '16px';
/* Flowchart variables */
this.tertiaryColor = lighten('#cde498', 10);
this.primaryBorderColor = mkBorder(this.primaryColor, this.darkMode);
this.secondaryBorderColor = mkBorder(this.secondaryColor, this.darkMode);
this.tertiaryBorderColor = mkBorder(this.tertiaryColor, this.darkMode);
this.primaryTextColor = invert(this.primaryColor);
this.secondaryTextColor = invert(this.secondaryColor);
this.tertiaryTextColor = invert(this.primaryColor);
this.lineColor = invert(this.background);
this.textColor = invert(this.background);
/* Flowchart variables */
this.nodeBkg = 'calculated';
this.nodeBorder = 'calculated';
this.clusterBkg = 'calculated';
@ -99,7 +110,7 @@ class Theme {
/* state colors */
/* class */
this.classText = this.nodeBorder;
this.classText = this.primaryTextColor;
/* journey */
this.fillType0 = this.primaryColor;
this.fillType1 = this.secondaryColor;

View File

@ -0,0 +1,4 @@
import { adjust } from 'khroma';
export const mkBorder = (col, darkMode) =>
darkMode ? adjust(col, { s: -40, l: 10 }) : adjust(col, { s: -40, l: -10 });

View File

@ -1,4 +1,5 @@
import { darken, lighten, adjust } from 'khroma';
import { invert, darken, lighten, adjust } from 'khroma';
import { mkBorder } from './theme-helpers';
// const Color = require ( 'khroma/dist/color' ).default
// Color.format.hex.stringify(Color.parse('hsl(210, 66.6666666667%, 95%)')); // => "#EAF2FB"
@ -8,7 +9,23 @@ class Theme {
this.primaryColor = '#eee';
this.contrast = '#26a';
this.secondaryColor = lighten(this.contrast, 55);
this.background = 'white';
this.background = '#ffffff';
// this.secondaryColor = adjust(this.primaryColor, { h: 120 });
this.tertiaryColor = adjust(this.primaryColor, { h: -160 });
console.warn('primary color', this.primaryColor, 'tertiary - color', this.tertiaryColor);
this.primaryBorderColor = mkBorder(this.primaryColor, this.darkMode);
this.secondaryBorderColor = mkBorder(this.secondaryColor, this.darkMode);
this.tertiaryBorderColor = mkBorder(this.tertiaryColor, this.darkMode);
// this.noteBorderColor = mkBorder(this.noteBkgColor, this.darkMode);
this.primaryTextColor = invert(this.primaryColor);
this.secondaryTextColor = invert(this.secondaryColor);
this.tertiaryTextColor = invert(this.tertiaryColor);
this.lineColor = invert(this.background);
this.textColor = invert(this.background);
this.altBackground = lighten(this.contrast, 55);
this.mainBkg = '#eee';
this.secondBkg = 'calculated';
this.lineColor = '#666';
@ -131,7 +148,7 @@ class Theme {
/* state colors */
/* class */
this.classText = this.nodeBorder;
this.classText = this.primaryTextColor;
/* journey */
this.fillType0 = this.primaryColor;
this.fillType1 = this.secondaryColor;

View File

@ -2280,9 +2280,9 @@ bluebird@3.7.2, bluebird@^3.5.0, bluebird@^3.5.1, bluebird@^3.5.5:
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0:
version "4.11.8"
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f"
integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==
version "4.11.9"
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828"
integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==
body-parser@1.19.0, body-parser@^1.18.3:
version "1.19.0"
@ -4066,9 +4066,9 @@ elegant-spinner@^1.0.1:
integrity sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=
elliptic@^6.0.0:
version "6.5.2"
resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762"
integrity sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==
version "6.5.3"
resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.3.tgz#cb59eb2efdaf73a0bd78ccd7015a62ad6e0f93d6"
integrity sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==
dependencies:
bn.js "^4.4.0"
brorand "^1.0.1"