Compare commits
58 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
1ecf0f4c23 | ||
![]() |
fa7d1ac554 | ||
![]() |
48ce7a9b78 | ||
![]() |
09bf54f9af | ||
![]() |
43b9bcdb0b | ||
![]() |
a3017b8456 | ||
![]() |
1f8480f0af | ||
![]() |
3674e27e0f | ||
![]() |
e4486420ce | ||
![]() |
fe64cc697b | ||
![]() |
97177dffd6 | ||
![]() |
061a02dddc | ||
![]() |
1f72c3e720 | ||
![]() |
8270469652 | ||
![]() |
5e6590a0f7 | ||
![]() |
06dfd13927 | ||
![]() |
486cc92f2e | ||
![]() |
e8d649b152 | ||
![]() |
e96bd14d21 | ||
![]() |
e4a2d2a290 | ||
![]() |
d8d5d0fa61 | ||
![]() |
e010a03dd5 | ||
![]() |
427aea73e7 | ||
![]() |
c4436b7a1e | ||
![]() |
d098051047 | ||
![]() |
034a7c424d | ||
![]() |
b113436055 | ||
![]() |
e550d974da | ||
![]() |
bc34ef4b66 | ||
![]() |
a5cc1e804b | ||
![]() |
aac51979cc | ||
![]() |
8f8638fb7c | ||
![]() |
d1c74070ab | ||
![]() |
ee01d09af5 | ||
![]() |
caaf4e3e40 | ||
![]() |
34037e58e5 | ||
![]() |
66152b42ae | ||
![]() |
76c8737485 | ||
![]() |
4a1eb55127 | ||
![]() |
c87637c6f4 | ||
![]() |
364b81a1b9 | ||
![]() |
d4c8cf66ef | ||
![]() |
08762bc066 | ||
![]() |
0add11a257 | ||
![]() |
ca5e60b38b | ||
![]() |
0e7876536d | ||
![]() |
be61a03a98 | ||
![]() |
50c707ba51 | ||
![]() |
2a2fd7a8b1 | ||
![]() |
ad126c838e | ||
![]() |
cafc18a78f | ||
![]() |
ffca12a8b0 | ||
![]() |
137f57ad9c | ||
![]() |
153b3322a6 | ||
![]() |
575535bdbd | ||
![]() |
61a3802494 | ||
![]() |
c3db9032f3 | ||
![]() |
42b8ac1235 |
1
.eslintignore
Normal file
@@ -0,0 +1 @@
|
||||
**/*.spec.js
|
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es6": true
|
||||
"es6": true,
|
||||
"node": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaFeatures": {
|
||||
@@ -10,7 +11,7 @@
|
||||
},
|
||||
"sourceType": "module"
|
||||
},
|
||||
"extends": ["prettier"],
|
||||
"extends": ["prettier", "eslint:recommended"],
|
||||
"plugins": ["prettier"],
|
||||
"rules": {
|
||||
"prettier/prettier": ["error"]
|
||||
|
@@ -33,8 +33,8 @@ jobs:
|
||||
echo $VERSION
|
||||
npm version --no-git-tag-version --allow-same-version $VERSION
|
||||
npm set //npm.pkg.github.com/:_authToken ${{ secrets.GITHUB_TOKEN }}
|
||||
npm set registry https://npm.pkg.github.com/knsv
|
||||
json -I -f package.json -e 'this.name="@knsv/mermaid"' # Package name needs to be set to a scoped one because GitHub registry requires this
|
||||
json -I -f package.json -e 'this.repository="git://github.com/knsv/mermaid"' # Repo url needs to have a specific format too
|
||||
npm set registry https://npm.pkg.github.com/mermaid-js
|
||||
json -I -f package.json -e 'this.name="@mermaid-js/mermaid"' # Package name needs to be set to a scoped one because GitHub registry requires this
|
||||
json -I -f package.json -e 'this.repository="git://github.com/mermaid-js/mermaid"' # Repo url needs to have a specific format too
|
||||
npm publish
|
||||
|
||||
|
2
.gitignore
vendored
@@ -10,3 +10,5 @@ dist/*.map
|
||||
yarn-error.log
|
||||
.npmrc
|
||||
token
|
||||
|
||||
package-lock.json
|
||||
|
@@ -86,7 +86,7 @@ Finally, if it is not in the documentation, no one will know about it and then *
|
||||
|
||||
The docs are located in the docs folder and are ofc written in markdown. Just pick the right section and start typing. If you want to add to the structure as in adding a new section and new file you do that via the _navbar.md.
|
||||
|
||||
The changes in master is reflected in http://knsv.github.io/mermaid/ once released the updates are commited to https://mermaidjs.github.io/#/
|
||||
The changes in master is reflected in http://mermaid-js.github.io/mermaid/ once released the updates are commited to https://mermaid-js.github.io/#/
|
||||
|
||||
## Last words
|
||||
|
||||
|
362
README.md
@@ -1,92 +1,89 @@
|
||||
<!-- <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 [](https://travis-ci.org/mermaid-js/mermaid) [](https://www.npmjs.com/package/mermaid) [](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [](https://percy.io/Mermaid/mermaid)
|
||||
<!-- <Main description> -->
|
||||
__Generate diagrams, charts, graphs or flows from markdown-like text via javascript.__
|
||||
See our [documentation](http://mermaid-js.github.io/mermaid/) and start simplifying yours. Play in 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> -->
|
||||
|
||||
# mermaid [](https://travis-ci.org/knsv/mermaid) [](https://coveralls.io/github/knsv/mermaid?branch=master) [](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [](https://percy.io/Mermaid/mermaid)
|
||||
:trophy: _"The most exciting use of technology"_ - [JS Open Source Awards (2019)](https://osawards.com/javascript/#nominees)
|
||||
|
||||
## 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.
|
||||
|
||||
* **`strict`**: (default) tags in text are encoded, click functionality is disabled
|
||||
* `loose`: tags in text are allowed, click functionality is enabled
|
||||
|
||||
⚠️ **Note** : This changes the default behaviour of mermaid so that after upgrade to 8.2, if the securityLevel is not configured, tags in flowcharts are encoded as tags and clicking is prohibited.
|
||||
|
||||
If your application is taking 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'
|
||||
});
|
||||
```
|
||||
|
||||
**🖖 Keep a steady pulse: mermaid needs more Collaborators [#866](https://github.com/knsv/mermaid/issues/866)**
|
||||
|
||||

|
||||
|
||||
Generation of diagrams and flowcharts from text in a similar manner as markdown.
|
||||
|
||||
Ever wanted to simplify documentation and avoid heavy tools like Visio when explaining your code?
|
||||
|
||||
This is why mermaid was born, a simple markdown-like script language for generating charts from text via javascript.
|
||||
|
||||
**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.**
|
||||
|
||||
### Flowchart
|
||||
|
||||
```
|
||||
graph TD;
|
||||
A-->B;
|
||||
A-->C;
|
||||
B-->D;
|
||||
C-->D;
|
||||
```
|
||||

|
||||
|
||||
|
||||
### Sequence diagram
|
||||
|
||||
```
|
||||
<table>
|
||||
<!-- <Flowchart> -->
|
||||
<tr><td colspan=2 align="center">
|
||||
<b>Flow</b></br>
|
||||
[<a href="http://mermaid-js.github.io/mermaid/#/flowchart">docs</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ3JhcGggVERcbiAgICBBW0hhcmRdIC0tPnxUZXh0fCBCKFJvdW5kKVxuICAgIEIgLS0-IEN7RGVjaXNpb259XG4gICAgQyAtLT58T25lfCBEW1Jlc3VsdCAxXVxuICAgIEMgLS0-fFR3b3wgRVtSZXN1bHQgMl0iLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9fQ">live editor</a>]
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td><pre>
|
||||
graph TD
|
||||
A[Hard] -->|Text| B(Round)
|
||||
B --> C{Decision}
|
||||
C -->|One| D[Result 1]
|
||||
C -->|Two| E[Result 2]
|
||||
</pre></td>
|
||||
<td align="center">
|
||||
<img src="./img/gray-flow.png" />
|
||||
</td>
|
||||
</tr>
|
||||
<!-- </Flowchart> -->
|
||||
<!-- <Sequence> -->
|
||||
<tr><td colspan=2 align="center">
|
||||
<b>Sequence</b><br />
|
||||
[<a href="http://mermaid-js.github.io/mermaid/#/sequenceDiagram">docs</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoic2VxdWVuY2VEaWFncmFtXG5BbGljZS0-PkpvaG46IEhlbGxvIEpvaG4sIGhvdyBhcmUgeW91P1xubG9vcCBIZWFsdGhjaGVja1xuICAgIEpvaG4tPj5Kb2huOiBGaWdodCBhZ2FpbnN0IGh5cG9jaG9uZHJpYVxuZW5kXG5Ob3RlIHJpZ2h0IG9mIEpvaG46IFJhdGlvbmFsIHRob3VnaHRzIVxuSm9obi0tPj5BbGljZTogR3JlYXQhXG5Kb2huLT4-Qm9iOiBIb3cgYWJvdXQgeW91P1xuQm9iLS0-PkpvaG46IEpvbGx5IGdvb2QhIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0">live editor</a>]
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td><pre>
|
||||
sequenceDiagram
|
||||
participant Alice
|
||||
participant Bob
|
||||
Alice->>John: Hello John, how are you?
|
||||
loop Healthcheck
|
||||
John->>John: Fight against hypochondria
|
||||
end
|
||||
Note right of John: Rational thoughts <br/>prevail!
|
||||
John-->>Alice: Great!
|
||||
John->>Bob: How about you?
|
||||
Bob-->>John: Jolly good!
|
||||
```
|
||||

|
||||
|
||||
|
||||
### Gantt diagram
|
||||
|
||||
```
|
||||
Alice->>John: Hello John, how are you?
|
||||
loop Healthcheck
|
||||
John->>John: Fight against hypochondria
|
||||
end
|
||||
Note right of John: Rational thoughts!
|
||||
John-->>Alice: Great!
|
||||
John->>Bob: How about you?
|
||||
Bob-->>John: Jolly good!
|
||||
</pre></td>
|
||||
<td align="center">
|
||||
<img src="./img/gray-sequence.png" />
|
||||
</td>
|
||||
</tr>
|
||||
<!-- </Sequence> -->
|
||||
<!-- <Gantt> -->
|
||||
<tr><td colspan=2 align="center">
|
||||
<b>Gantt</b><br />
|
||||
[<a href="http://mermaid-js.github.io/mermaid/#/gantt">docs</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ2FudHRcbnNlY3Rpb24gU2VjdGlvblxuQ29tcGxldGVkIDpkb25lLCAgICBkZXMxLCAyMDE0LTAxLTA2LDIwMTQtMDEtMDhcbkFjdGl2ZSAgICAgICAgOmFjdGl2ZSwgIGRlczIsIDIwMTQtMDEtMDcsIDNkXG5QYXJhbGxlbCAxICAgOiAgICAgICAgIGRlczMsIGFmdGVyIGRlczEsIDFkXG5QYXJhbGxlbCAyICAgOiAgICAgICAgIGRlczQsIGFmdGVyIGRlczEsIDFkXG5QYXJhbGxlbCAzICAgOiAgICAgICAgIGRlczUsIGFmdGVyIGRlczMsIDFkXG5QYXJhbGxlbCA0ICAgOiAgICAgICAgIGRlczYsIGFmdGVyIGRlczQsIDFkIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0">live editor</a>]
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td><pre>
|
||||
gantt
|
||||
dateFormat YYYY-MM-DD
|
||||
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
|
||||
```
|
||||

|
||||
|
||||
|
||||
### Class diagram - :exclamation: experimental
|
||||
|
||||
```
|
||||
section Section
|
||||
Completed :done, des1, 2014-01-06,2014-01-08
|
||||
Active :active, des2, 2014-01-07, 3d
|
||||
Parallel 1 : des3, after des1, 1d
|
||||
Parallel 2 : des4, after des1, 1d
|
||||
Parallel 3 : des5, after des3, 1d
|
||||
Parallel 4 : des6, after des4, 1d
|
||||
</pre></td>
|
||||
<td align="center">
|
||||
<img src="./img/gray-gantt.png" />
|
||||
</td>
|
||||
</tr>
|
||||
<!-- </Gantt> -->
|
||||
<!-- <Class> -->
|
||||
<tr><td colspan=2 align="center">
|
||||
<b>Class</b><br />
|
||||
[<a href="http://mermaid-js.github.io/mermaid/#/classDiagram">docs</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiY2xhc3NEaWFncmFtXG5DbGFzczAxIDx8LS0gQXZlcnlMb25nQ2xhc3MgOiBDb29sXG48PGludGVyZmFjZT4-IENsYXNzMDFcbkNsYXNzMDkgLS0-IEMyIDogV2hlcmUgYW0gaT9cbkNsYXNzMDkgLS0qIEMzXG5DbGFzczA5IC0tfD4gQ2xhc3MwN1xuQ2xhc3MwNyA6IGVxdWFscygpXG5DbGFzczA3IDogT2JqZWN0W10gZWxlbWVudERhdGFcbkNsYXNzMDEgOiBzaXplKClcbkNsYXNzMDEgOiBpbnQgY2hpbXBcbkNsYXNzMDEgOiBpbnQgZ29yaWxsYVxuY2xhc3MgQ2xhc3MxMCB7XG4gID4-c2VydmljZT4-XG4gIGludCBpZFxuICBzaXplKClcbn0iLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9fQ">live editor</a>]
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td><pre>
|
||||
classDiagram
|
||||
Class01 <|-- AveryLongClass : Cool
|
||||
<<interface>> Class01
|
||||
Class03 *-- Class04
|
||||
Class05 o-- Class06
|
||||
Class07 .. Class08
|
||||
Class01 <|-- AveryLongClass : Cool
|
||||
<<interface>> Class01
|
||||
Class09 --> C2 : Where am i?
|
||||
Class09 --* C3
|
||||
Class09 --|> Class07
|
||||
@@ -95,147 +92,84 @@ Class07 : Object[] elementData
|
||||
Class01 : size()
|
||||
Class01 : int chimp
|
||||
Class01 : int gorilla
|
||||
Class08 <--> C2: Cool label
|
||||
class Class10 {
|
||||
<<service>>
|
||||
<<service>>
|
||||
int id
|
||||
size()
|
||||
}
|
||||
```
|
||||

|
||||
</pre></td>
|
||||
<td align="center">
|
||||
<img src="./img/gray-class.png" />
|
||||
</td>
|
||||
</tr>
|
||||
<!-- </Class> -->
|
||||
<!-- <State> -->
|
||||
<tr><td colspan=2 align="center">
|
||||
<b>State</b><br />
|
||||
[<a href="http://mermaid-js.github.io/mermaid/#/stateDiagram">docs</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoic3RhdGVEaWFncmFtXG4gICAgWypdIC0tPiBTdGlsbFxuICAgIFN0aWxsIC0tPiBbKl1cbiAgICBTdGlsbCAtLT4gTW92aW5nXG4gICAgTW92aW5nIC0tPiBTdGlsbFxuICAgIE1vdmluZyAtLT4gQ3Jhc2hcbiAgICBDcmFzaCAtLT4gWypdIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0">live editor</a>]
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td><pre>
|
||||
stateDiagram
|
||||
[*] --> Still
|
||||
Still --> [*]
|
||||
Still --> Moving
|
||||
Moving --> Still
|
||||
Moving --> Crash
|
||||
Crash --> [*]
|
||||
</pre></td>
|
||||
<td align="center">
|
||||
<img src="./img/gray-state.png" />
|
||||
</td>
|
||||
</tr>
|
||||
<!-- </State> -->
|
||||
<!-- <Pie> -->
|
||||
<tr><td colspan=2 align="center">
|
||||
<b>Pie</b><br />
|
||||
[<a href="http://mermaid-js.github.io/mermaid/#/pie">docs</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoicGllXG5cIkRvZ3NcIiA6IDQyLjk2XG5cIkNhdHNcIiA6IDUwLjA1XG5cIlJhdHNcIiA6IDEwLjAxIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0">live editor</a>]
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td><pre>
|
||||
pie
|
||||
"Dogs" : 386
|
||||
"Cats" : 85
|
||||
"Rats" : 15
|
||||
</pre></td>
|
||||
<td align="center">
|
||||
<img src="./img/gray-pie.png" />
|
||||
</td>
|
||||
</tr>
|
||||
<!-- </Pie> -->
|
||||
<!-- <Git> -->
|
||||
<tr><td colspan=2 align="center">
|
||||
<b>Git</b><br />
|
||||
[experimental - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ2l0R3JhcGg6XG5vcHRpb25zXG57XG4gICAgXCJub2RlU3BhY2luZ1wiOiAxNTAsXG4gICAgXCJub2RlUmFkaXVzXCI6IDEwXG59XG5lbmRcbmNvbW1pdFxuYnJhbmNoIG5ld2JyYW5jaFxuY2hlY2tvdXQgbmV3YnJhbmNoXG5jb21taXRcbmNvbW1pdFxuY2hlY2tvdXQgbWFzdGVyXG5jb21taXRcbmNvbW1pdFxubWVyZ2UgbmV3YnJhbmNoXG4iLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9fQ">live editor</a>]
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td colspan="2" align="center"><i>Coming soon!</i></td>
|
||||
</tr>
|
||||
<!-- </Git> -->
|
||||
</table>
|
||||
|
||||
## Related projects
|
||||
|
||||
### Git graph - :exclamation: experimental
|
||||
- [Command Line Interface](https://github.com/mermaid-js/mermaid.cli)
|
||||
- [Live Editor](https://github.com/mermaid-js/mermaid-live-editor)
|
||||
|
||||
```
|
||||
gitGraph:
|
||||
options
|
||||
{
|
||||
"nodeSpacing": 150,
|
||||
"nodeRadius": 10
|
||||
}
|
||||
end
|
||||
commit
|
||||
branch newbranch
|
||||
checkout newbranch
|
||||
commit
|
||||
commit
|
||||
checkout master
|
||||
commit
|
||||
commit
|
||||
merge newbranch
|
||||
# Contributors [](https://github.com/mermaid-js/mermaid/issues?q=is%3Aissue+is%3Aopen+label%3A%22Help+wanted%21%22) [](https://github.com/mermaid-js/mermaid/graphs/contributors) [](https://github.com/mermaid-js/mermaid/graphs/contributors)
|
||||
|
||||
```
|
||||
Mermaid is a growing community and is always accepting new contributors. There's a lot of different ways to help out and we're always looking for extra hands! Look at [this issue](https://github.com/mermaid-js/mermaid/issues/866) if you want to know where to start helping out.
|
||||
|
||||

|
||||
Detailed information about how to contribute can be found in the [contribution guide](CONTRIBUTING.md)
|
||||
|
||||
# Appreciation
|
||||
A quick note from Knut Sveidqvist:
|
||||
>*Many thanks to the [d3](http://d3js.org/) and [dagre-d3](https://github.com/cpettitt/dagre-d3) projects for providing the graphical layout and drawing libraries!*
|
||||
>*Thanks also to the [js-sequence-diagram](http://bramp.github.io/js-sequence-diagrams) project for usage of the grammar for the sequence diagrams. Thanks to Jessica Peter for inspiration and starting point for gantt rendering.*
|
||||
>*Thank you to [Tyler Long](https://github.com/tylerlong) who has been a collaborator since April 2017.*
|
||||
>
|
||||
>*Thank you to the ever-growing list of [contributors](https://github.com/knsv/mermaid/graphs/contributors) that brought the project this far!*
|
||||
|
||||
## Installation
|
||||
|
||||
### CDN
|
||||
|
||||
https://unpkg.com/mermaid@<version>/dist/
|
||||
|
||||
Replace `<version>` with expected version number.
|
||||
|
||||
Example: https://unpkg.com/mermaid@7.1.0/dist/
|
||||
|
||||
### Node.js
|
||||
|
||||
yarn add mermaid
|
||||
|
||||
### Preview builds
|
||||
Preview builds are created automatically for each release. They can be found in the [GitHub registry](https://github.com/knsv/mermaid/packages).
|
||||
Make sure to configure npm to use the GitHub package registry. Steps for that can be found [here](https://help.github.com/en/articles/configuring-npm-for-use-with-github-package-registry).
|
||||
|
||||
If you want to get the latest preview for the next release
|
||||
```
|
||||
yarn add @knsv/mermaid
|
||||
```
|
||||
|
||||
|
||||
If you want to get the latest preview for a specific version
|
||||
```
|
||||
yarn add @knsv/mermaid@<version>
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
https://mermaidjs.github.io
|
||||
|
||||
|
||||
## Sibling projects
|
||||
|
||||
- [mermaid CLI](https://github.com/mermaidjs/mermaid.cli)
|
||||
- [mermaid live editor](https://github.com/mermaidjs/mermaid-live-editor)
|
||||
- [mermaid webpack demo](https://github.com/mermaidjs/mermaid-webpack-demo)
|
||||
- [mermaid Parcel demo](https://github.com/mermaidjs/mermaid-parcel-demo)
|
||||
|
||||
|
||||
# Request for assistance
|
||||
|
||||
Things are piling up and I have hard time keeping up. To remedy this
|
||||
it would be great if we could form a core team of developers to cooperate
|
||||
with the future development mermaid.
|
||||
|
||||
As part of this team you would get write access to the repository and would
|
||||
represent the project when answering questions and issues.
|
||||
|
||||
Together we could continue the work with things like:
|
||||
* adding more types of diagrams like mindmaps, ert diagrams etc
|
||||
* improving existing diagrams
|
||||
|
||||
Don't hesitate to contact me if you want to get involved.
|
||||
|
||||
|
||||
# For contributors
|
||||
Detailed information about contributing can be found in the [Contribution guide](CONTRIBUTING.md)
|
||||
## Setup
|
||||
|
||||
yarn install
|
||||
|
||||
|
||||
## Build
|
||||
|
||||
yarn build:watch
|
||||
|
||||
|
||||
## Lint
|
||||
|
||||
yarn lint
|
||||
|
||||
We use [eslint](https://eslint.org/).
|
||||
We recommend you installing [editor plugins](https://eslint.org/docs/user-guide/integrations) so you can get real time lint result.
|
||||
|
||||
|
||||
## Test
|
||||
|
||||
yarn test
|
||||
|
||||
Manual test in browser:
|
||||
|
||||
open dist/index.html
|
||||
|
||||
|
||||
## Release
|
||||
|
||||
For those who have the permission to do so:
|
||||
|
||||
Update version number in `package.json`.
|
||||
|
||||
npm publish
|
||||
|
||||
Command above generates files into the `dist` folder and publishes them to npmjs.org.
|
||||
|
||||
|
||||
# Credits
|
||||
|
||||
Many thanks to the [d3](http://d3js.org/) and [dagre-d3](https://github.com/cpettitt/dagre-d3) projects for providing the graphical layout and drawing libraries!
|
||||
|
||||
Thanks also to the [js-sequence-diagram](http://bramp.github.io/js-sequence-diagrams) project for usage of the grammar for the sequence diagrams. Thanks to Jessica Peter for inspiration and starting point for gantt rendering.
|
||||
---
|
||||
|
||||
*Mermaid was created by Knut Sveidqvist for easier documentation.*
|
||||
|
||||
*[Tyler Long](https://github.com/tylerlong) has became a collaborator since April 2017.*
|
||||
|
||||
Here is the full list of the projects [contributors](https://github.com/knsv/mermaid/graphs/contributors).
|
||||
|
@@ -16,7 +16,7 @@ describe('Interaction', () => {
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body')
|
||||
.find('g#s1Function')
|
||||
.find('g#mermaid-dom-id-1Function')
|
||||
.click();
|
||||
|
||||
cy.get('.created-by-click').should('have.text', 'Clicked By Flow');
|
||||
@@ -38,7 +38,7 @@ describe('Interaction', () => {
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body')
|
||||
.find('g#s2URL')
|
||||
.find('g#mermaid-dom-id-2URL')
|
||||
.click();
|
||||
|
||||
cy.location().should(location => {
|
||||
@@ -108,7 +108,7 @@ describe('Interaction', () => {
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body')
|
||||
.find('g#s1Function')
|
||||
.find('g#mermaid-dom-id-1Function')
|
||||
.click();
|
||||
|
||||
cy.get('.created-by-click').should('not.have.text', 'Clicked By Flow');
|
||||
@@ -130,7 +130,7 @@ describe('Interaction', () => {
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body')
|
||||
.find('g#s2URL')
|
||||
.find('g#mermaid-dom-id-2URL')
|
||||
.click();
|
||||
|
||||
cy.location().should(location => {
|
||||
@@ -200,7 +200,7 @@ describe('Interaction', () => {
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body')
|
||||
.find('g#s1Function')
|
||||
.find('g#mermaid-dom-id-1Function')
|
||||
.click();
|
||||
|
||||
cy.get('.created-by-click').should('not.have.text', 'Clicked By Flow');
|
||||
|
20
cypress/integration/rendering/current.spec.js
Normal file
@@ -0,0 +1,20 @@
|
||||
/* eslint-env jest */
|
||||
import { imgSnapshotTest } from '../../helpers/util';
|
||||
|
||||
describe('State diagram', () => {
|
||||
it('should render a flowchart full of circles', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram
|
||||
State1: The state with a note
|
||||
note right of State1
|
||||
Important information! You\ncan write
|
||||
notes with multiple lines...
|
||||
Here is another line...
|
||||
And another line...
|
||||
end note
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
});
|
@@ -2,7 +2,7 @@
|
||||
import { imgSnapshotTest } from '../../helpers/util';
|
||||
|
||||
describe('Flowcart', () => {
|
||||
it('should render a simple flowchart no htmlLabels', () => {
|
||||
it('1: should render a simple flowchart no htmlLabels', () => {
|
||||
imgSnapshotTest(
|
||||
`graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
@@ -14,7 +14,7 @@ describe('Flowcart', () => {
|
||||
{ flowchart: { htmlLabels: false } }
|
||||
);
|
||||
});
|
||||
it('should render a simple flowchart with htmlLabels', () => {
|
||||
it('2: should render a simple flowchart with htmlLabels', () => {
|
||||
imgSnapshotTest(
|
||||
`graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
@@ -26,7 +26,7 @@ describe('Flowcart', () => {
|
||||
{ flowchart: { htmlLabels: true } }
|
||||
);
|
||||
});
|
||||
it('should render a simple flowchart with line breaks', () => {
|
||||
it('3: should render a simple flowchart with line breaks', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
graph TD
|
||||
@@ -40,7 +40,7 @@ describe('Flowcart', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should render a simple flowchart with trapezoid and inverse trapezoid vertex options.', () => {
|
||||
it('4: should render a simple flowchart with trapezoid and inverse trapezoid vertex options.', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
graph TD
|
||||
@@ -55,7 +55,7 @@ describe('Flowcart', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should style nodes via a class.', () => {
|
||||
it('4: should style nodes via a class.', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
graph TD
|
||||
@@ -71,7 +71,7 @@ describe('Flowcart', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should render a flowchart full of circles', () => {
|
||||
it('5: should render a flowchart full of circles', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
graph LR
|
||||
@@ -99,7 +99,7 @@ describe('Flowcart', () => {
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render a flowchart full of icons', () => {
|
||||
it('6: should render a flowchart full of icons', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
graph TD
|
||||
@@ -170,7 +170,7 @@ describe('Flowcart', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should render labels with numbers at the start', () => {
|
||||
it('7: should render labels with numbers at the start', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
graph TB;subgraph "number as labels";1;end;
|
||||
@@ -178,7 +178,7 @@ describe('Flowcart', () => {
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render subgraphs', () => {
|
||||
it('8: should render subgraphs', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
graph TB
|
||||
@@ -190,7 +190,7 @@ describe('Flowcart', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should render subgraphs with a title startign with a digit', () => {
|
||||
it('9: should render subgraphs with a title startign with a digit', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
graph TB
|
||||
@@ -202,7 +202,7 @@ describe('Flowcart', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should render styled subgraphs', () => {
|
||||
it('10: should render styled subgraphs', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
graph TB
|
||||
@@ -237,7 +237,7 @@ describe('Flowcart', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should render a flowchart with ling sames and class definitoins', () => {
|
||||
it('11: should render a flowchart with ling sames and class definitoins', () => {
|
||||
imgSnapshotTest(
|
||||
`graph LR
|
||||
sid-B3655226-6C29-4D00-B685-3D5C734DC7E1["
|
||||
@@ -339,7 +339,7 @@ describe('Flowcart', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should render color of styled nodes', () => {
|
||||
it('12: should render color of styled nodes', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
graph LR
|
||||
@@ -356,4 +356,25 @@ describe('Flowcart', () => {
|
||||
}
|
||||
);
|
||||
});
|
||||
it('13: should render hexagons', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{{Let me think...<br />Do I want something for work,<br />something to spend every free second with,<br />or something to get around?}}
|
||||
C -->|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[Car]
|
||||
click A "index.html#link-clicked" "link test"
|
||||
click B testClick "click test"
|
||||
classDef someclass fill:#f96;
|
||||
class A someclass;
|
||||
`,
|
||||
{
|
||||
listUrl: false,
|
||||
listId: 'color styling',
|
||||
logLevel: 0
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@@ -12,5 +12,29 @@ describe('Pie Chart', () => {
|
||||
`,
|
||||
{}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should render a simple pie diagram with long labels', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
pie title NETFLIX
|
||||
"Time spent looking for movie" : 90
|
||||
"Time spent watching it" : 10
|
||||
`,
|
||||
{}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should render a simple pie diagram with capital letters for labels', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
pie title What Voldemort doesn't have?
|
||||
"FRIENDS" : 2
|
||||
"FAMILY" : 3
|
||||
"NOSE" : 45
|
||||
`,
|
||||
{}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
});
|
||||
|
@@ -13,6 +13,30 @@ describe('State diagram', () => {
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should render a long descriptions instead of id when available', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram
|
||||
|
||||
[*] --> S1
|
||||
state "Some long name" as S1
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should render a long descriptions with additional descriptions', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram
|
||||
|
||||
[*] --> S1
|
||||
state "Some long name" as S1: The description
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should render a single state with short descr', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
@@ -24,6 +48,20 @@ describe('State diagram', () => {
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should render a transition descrions with new lines', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram
|
||||
|
||||
[*] --> S1
|
||||
S1 --> S2: long line using<br/>should work
|
||||
S1 --> S3: long line using <br>should work
|
||||
S1 --> S4: long line using \\nshould work
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should render a state with a note', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<script src="/e2e.js"></script>
|
||||
<link href="https://fonts.googleapis.com/css?family=Mansalva&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css?family=Mansalva&display=swap" rel="stylesheet" />
|
||||
<style>
|
||||
body {
|
||||
/* font-family: 'Mansalva', cursive;
|
||||
@@ -17,6 +17,9 @@
|
||||
--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive;
|
||||
--mermaid-font-family: '"Lucida Console", Monaco, monospace';
|
||||
} */
|
||||
svg {
|
||||
border: 2px solid darkred;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
@@ -4,12 +4,20 @@
|
||||
|
||||
# mermaid
|
||||
|
||||
## New diagrams in 8.4
|
||||
|
||||
With version 8.4 class diagrams has got some new features, bug fixes and documentation. Another new feature in 8.4 is the new diagram
|
||||
type, state diagrams.
|
||||
|
||||

|
||||
|
||||
|
||||
## Special note regarding version 8.2
|
||||
|
||||
In version 8.2 a security improvement was introduced. A securityLevel configuration was introduced wich sets the level of trust to be used on the parsed diagrams.
|
||||
|
||||
* **true**: (default) tags in text are encoded, click functionality is disabled
|
||||
* false: tags in text are allowed, click functionality is enabledClosed issues:
|
||||
* false: tags in text are allowed, click functionality is enabledClosed 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.
|
||||
|
||||
|
@@ -44,7 +44,7 @@ Mermaid can render class diagrams.
|
||||
+String beakColor
|
||||
+swim()
|
||||
+quack()
|
||||
}
|
||||
}
|
||||
class Fish{
|
||||
-int sizeInFeet
|
||||
-canEat()
|
||||
@@ -69,7 +69,7 @@ A single instance of a class in the diagram contains three compartments:
|
||||
```
|
||||
classDiagram
|
||||
class BankAccount
|
||||
BankAccount : +String onwer
|
||||
BankAccount : +String owner
|
||||
BankAccount : +Bigdecimal balance
|
||||
BankAccount : +deposit(amount)
|
||||
BankAccount : +withdrawl(amount)
|
||||
@@ -77,7 +77,7 @@ classDiagram
|
||||
```mermaid
|
||||
classDiagram
|
||||
class BankAccount
|
||||
BankAccount : +String onwer
|
||||
BankAccount : +String owner
|
||||
BankAccount : +BigDecimal balance
|
||||
BankAccount : +deposit(amount)
|
||||
BankAccount : +withdrawl(amount)
|
||||
@@ -98,6 +98,9 @@ classDiagram
|
||||
class Animal
|
||||
Vehicle <|-- Car
|
||||
```
|
||||
|
||||
Naming convention: a class name should be composed of alphanumeric (unicode allowed) and underscore characters.
|
||||
|
||||
## Defining Members of a class
|
||||
|
||||
UML provides mechanisms to represent class members, such as attributes and methods, and additional information about them.
|
||||
@@ -117,7 +120,7 @@ There are two ways to define the members of a class, and regardless of the which
|
||||
|
||||
```
|
||||
class BankAccount
|
||||
BankAccount : +String onwer
|
||||
BankAccount : +String owner
|
||||
BankAccount : +BigDecimal balance
|
||||
BankAccount : +deposit(amount)
|
||||
BankAccount : +withdrawl(amount)
|
||||
@@ -125,7 +128,7 @@ There are two ways to define the members of a class, and regardless of the which
|
||||
```mermaid
|
||||
classDiagram
|
||||
class BankAccount
|
||||
BankAccount : +String onwer
|
||||
BankAccount : +String owner
|
||||
BankAccount : +BigDecimal balance
|
||||
BankAccount : +deposit(amount)
|
||||
BankAccount : +withdrawl(amount)
|
||||
@@ -134,7 +137,7 @@ There are two ways to define the members of a class, and regardless of the which
|
||||
- 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 onwer
|
||||
+String owner
|
||||
+BigDecimal balance
|
||||
+deposit(amount)
|
||||
+withdrawl(amount)
|
||||
@@ -143,7 +146,7 @@ class BankAccount{
|
||||
```mermaid
|
||||
classDiagram
|
||||
class BankAccount{
|
||||
+String onwer
|
||||
+String owner
|
||||
+BigDecimal balance
|
||||
+deposit(amount)
|
||||
+withdrawl(amount)
|
||||
|
@@ -1,3 +1,27 @@
|
||||
## Basic Pie Chart
|
||||
|
||||
```
|
||||
pie title NETFLIX
|
||||
"Time spent looking for movie" : 90
|
||||
"Time spent watching it" : 10
|
||||
```
|
||||
``` mermaid
|
||||
pie title NETFLIX
|
||||
"Time spent looking for movie" : 90
|
||||
"Time spent watching it" : 10
|
||||
```
|
||||
```
|
||||
pie title What Voldemort doesn't have?
|
||||
"FRIENDS" : 2
|
||||
"FAMILY" : 3
|
||||
"NOSE" : 45
|
||||
```
|
||||
```mermaid
|
||||
pie title What Voldemort doesn't have?
|
||||
"FRIENDS" : 2
|
||||
"FAMILY" : 3
|
||||
"NOSE" : 45
|
||||
```
|
||||
## Basic sequence diagram
|
||||
|
||||
```
|
||||
|
BIN
docs/img/new-diagrams.png
Normal file
After Width: | Height: | Size: 33 KiB |
@@ -7,7 +7,7 @@
|
||||
<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">
|
||||
<script src="//cdn.jsdelivr.net/npm/mermaid@8.4.0/dist/mermaid.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/mermaid@8.4.1/dist/mermaid.min.js"></script>
|
||||
<!-- <script src="//localhost:9000/mermaid.js"></script> -->
|
||||
<style>
|
||||
.markdown-section {
|
||||
|
24
docs/pie.md
@@ -1,11 +1,12 @@
|
||||
# Pie chart diagrams
|
||||
|
||||
> A pie chart (or a circle chart) is a circular statistical graphic, which is divided into slices to illustrate numerical proportion. In a pie chart, the arc length of each slice (and consequently its central angle and area), is proportional to the quantity it represents. While it is named for its resemblance to a pie which has been sliced, there are variations on the way it can be presented. The earliest known pie chart is generally credited to William Playfair's Statistical Breviary of 1801
|
||||
-Wikipedia
|
||||
|
||||
Mermaid can render Pie Chart diagrams.
|
||||
|
||||
```
|
||||
pie
|
||||
pie title Pets adopted by volunteers
|
||||
"Dogs" : 386
|
||||
"Cats" : 85
|
||||
"Rats" : 15
|
||||
@@ -19,17 +20,34 @@ pie title Pets adopted by volunteers
|
||||
|
||||
|
||||
## Syntax
|
||||
Drawing a pie chart is really simple in mermaid.
|
||||
- Start with `pie` keyword to begin the diagram
|
||||
- Followed by `title` keyword and its value in string to give a title to the pie-chart. This is ***OPTIONAL***
|
||||
- Followed by dataSet
|
||||
- `label` for a section in the pie diagram within `" "` quotes.
|
||||
- Followed by `:` semi-colon as separator
|
||||
- Followed by `positive numeric value` (supported upto two decimal places)
|
||||
|
||||
[pie]
|
||||
[title] [titlevalue] (OPTIONAL)
|
||||
"[datakey1]" : [dataValue1]
|
||||
"[datakey2]" : [dataValue2]
|
||||
"[datakey3]" : [dataValue3]
|
||||
.
|
||||
.
|
||||
|
||||
## Example
|
||||
```
|
||||
pie
|
||||
"DataKey1" : Positive numeric value (upto two decimal places)
|
||||
title Key elements in Product X
|
||||
"Calcium" : 42.96
|
||||
"Potassium" : 50.05
|
||||
"Magnesium" : 10.01
|
||||
"Iron" : 5
|
||||
```
|
||||
```mermaid
|
||||
pie title Key elements in Product X
|
||||
pie
|
||||
title Key elements in Product X
|
||||
"Calcium" : 42.96
|
||||
"Potassium" : 50.05
|
||||
"Magnesium" : 25.01
|
||||
|
@@ -2,10 +2,9 @@
|
||||
|
||||
> "A state diagram is a type of diagram used in computer science and related fields to describe the behavior of systems. State diagrams require that the system described is composed of a finite number of states; sometimes, this is indeed the case, while at other times this is a reasonable abstraction." Wikipedia
|
||||
|
||||
Mermaid can render state diagrams. The syntax tries to be compliant with the syntax used in plantUml as this will make it easier for users to
|
||||
share diagrams between mermaid and plantUml.
|
||||
Mermaid can render state diagrams. The syntax tries to be compliant with the syntax used in plantUml as this will make it easier for users to share diagrams between mermaid and plantUml.
|
||||
|
||||
```
|
||||
```markdown
|
||||
stateDiagram
|
||||
[*] --> Still
|
||||
Still --> [*]
|
||||
@@ -15,6 +14,7 @@ stateDiagram
|
||||
Moving --> Crash
|
||||
Crash --> [*]
|
||||
```
|
||||
|
||||
```mermaid
|
||||
stateDiagram
|
||||
[*] --> Still
|
||||
@@ -25,53 +25,58 @@ stateDiagram
|
||||
Moving --> Crash
|
||||
Crash --> [*]
|
||||
```
|
||||
|
||||
In state diagrams systems are described in terms of its states and how the systems state can change to another state via a transitions. The example diagram above shows three states **Still**, **Moving** and **Crash**. You start in the state of Still. From Still you can change the state to Moving. In Moving you can change the state either back to Still or to Crash. There is no transition from Still to Crash.
|
||||
|
||||
## States
|
||||
|
||||
A state can be declares in multiple ways. The simplest way is to define a state id as a description.
|
||||
|
||||
```
|
||||
```markdown
|
||||
stateDiagram
|
||||
s1
|
||||
```
|
||||
|
||||
```mermaid
|
||||
stateDiagram
|
||||
s1
|
||||
```
|
||||
|
||||
Another way is by using the state keyword with a description as per below:
|
||||
```
|
||||
|
||||
```markdown
|
||||
stateDiagram
|
||||
state "This ia state decription" as s2
|
||||
state "This is a state description" as s2
|
||||
```
|
||||
|
||||
```mermaid
|
||||
stateDiagram
|
||||
state "This ia state decription" as s2
|
||||
state "This is a state description" as s2
|
||||
```
|
||||
|
||||
Another way to define a state with a description is to define the state id followed by a colon and the description:
|
||||
```
|
||||
|
||||
```markdown
|
||||
stateDiagram
|
||||
s2 : This ia state decription
|
||||
```
|
||||
```mermaid
|
||||
stateDiagram
|
||||
s2 : This ia state decription
|
||||
s2 : This is a state description
|
||||
```
|
||||
|
||||
```mermaid
|
||||
stateDiagram
|
||||
s2 : This is a state description
|
||||
```
|
||||
|
||||
## Transitions
|
||||
|
||||
Transitions are path/edges when one state passes into another. This is represented using text arrow, "-->".
|
||||
Transitions are path/edges when one state passes into another. This is represented using text arrow, "\-\-\>".
|
||||
|
||||
When you define a transition between two states and the states are not already defined the undefined states are defined with the id
|
||||
from the transition. You can later add descriptions to states defined this way.
|
||||
When you define a transition between two states and the states are not already defined the undefined states are defined with the id from the transition. You can later add descriptions to states defined this way.
|
||||
|
||||
```
|
||||
```markdown
|
||||
stateDiagram
|
||||
s1 --> s2
|
||||
```
|
||||
|
||||
```mermaid
|
||||
stateDiagram
|
||||
s1 --> s2
|
||||
@@ -79,39 +84,40 @@ stateDiagram
|
||||
|
||||
It is possible to add text to a transition. To describe what it represents.
|
||||
|
||||
```
|
||||
```markdown
|
||||
stateDiagram
|
||||
s1 --> s2: A transition
|
||||
```
|
||||
|
||||
```mermaid
|
||||
stateDiagram
|
||||
s1 --> s2: A transition
|
||||
```
|
||||
|
||||
## Start and end
|
||||
## Start and End
|
||||
|
||||
There are two special states indicating the start and stop of the diagram. These are written with the [*] syntax and the direction of the transition to it defines it either as a start or a stop state.
|
||||
There are two special states indicating the start and stop of the diagram. These are written with the [\*] syntax and the direction of the transition to it defines it either as a start or a stop state.
|
||||
|
||||
```
|
||||
```markdown
|
||||
stateDiagram
|
||||
[*] --> s1
|
||||
s1 --> [*]
|
||||
```
|
||||
|
||||
```mermaid
|
||||
stateDiagram
|
||||
[*] --> s1
|
||||
s1 --> [*]
|
||||
```
|
||||
|
||||
|
||||
## Composit states
|
||||
## Composite states
|
||||
|
||||
In a real world use of state diagrams you often end up with diagrams that are multi-dimensional as one state can
|
||||
have several internal states. These are called composit states in this terminology.
|
||||
have several internal states. These are called composite states in this terminology.
|
||||
|
||||
In order to define a composit state you need to use the state keyword followed by and id and the body of the composit state between {}. See the example below:
|
||||
In order to define a composite state you need to use the state keyword followed by and id and the body of the composite state between \{\}. See the example below:
|
||||
|
||||
```
|
||||
```markdown
|
||||
stateDiagram
|
||||
[*] --> First
|
||||
state First {
|
||||
@@ -119,6 +125,7 @@ stateDiagram
|
||||
second --> [*]
|
||||
}
|
||||
```
|
||||
|
||||
```mermaid
|
||||
stateDiagram
|
||||
[*] --> First
|
||||
@@ -130,7 +137,7 @@ stateDiagram
|
||||
|
||||
You can do this in several layers:
|
||||
|
||||
```
|
||||
```markdown
|
||||
stateDiagram
|
||||
[*] --> First
|
||||
|
||||
@@ -148,6 +155,7 @@ stateDiagram
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```mermaid
|
||||
stateDiagram
|
||||
[*] --> First
|
||||
@@ -166,9 +174,9 @@ stateDiagram
|
||||
}
|
||||
```
|
||||
|
||||
You can also define transitions also between composit states:
|
||||
You can also define transitions also between composite states:
|
||||
|
||||
```
|
||||
```markdown
|
||||
stateDiagram
|
||||
[*] --> First
|
||||
First --> Second
|
||||
@@ -187,6 +195,7 @@ stateDiagram
|
||||
thi --> [*]
|
||||
}
|
||||
```
|
||||
|
||||
```mermaid
|
||||
stateDiagram
|
||||
[*] --> First
|
||||
@@ -207,13 +216,13 @@ stateDiagram
|
||||
}
|
||||
```
|
||||
|
||||
*You can not define transitions between internal states belonging to different composit states*
|
||||
*You can not define transitions between internal states belonging to different composite states*
|
||||
|
||||
## Forks
|
||||
|
||||
It is possible to specify a fork in the diagram using <<fork>> <<join>>.
|
||||
|
||||
```
|
||||
```markdown
|
||||
stateDiagram
|
||||
state fork_state <<fork>>
|
||||
[*] --> fork_state
|
||||
@@ -226,6 +235,7 @@ It is possible to specify a fork in the diagram using <<fork>> <&
|
||||
join_state --> State4
|
||||
State4 --> [*]
|
||||
```
|
||||
|
||||
```mermaid
|
||||
stateDiagram
|
||||
state fork_state <<fork>>
|
||||
@@ -247,7 +257,7 @@ Sometimes nothing says it better then a Post-it note. That is also the case in s
|
||||
|
||||
Here you can choose to put the note to the *right of* or to the *left of* a node.
|
||||
|
||||
```
|
||||
```markdown
|
||||
stateDiagram
|
||||
State1: The state with a note
|
||||
note right of State1
|
||||
@@ -257,6 +267,7 @@ Here you can choose to put the note to the *right of* or to the *left of* a node
|
||||
State1 --> State2
|
||||
note left of State2 : This is the note to the left.
|
||||
```
|
||||
|
||||
```mermaid
|
||||
stateDiagram
|
||||
State1: The state with a note
|
||||
@@ -272,7 +283,8 @@ Here you can choose to put the note to the *right of* or to the *left of* a node
|
||||
## Concurrency
|
||||
|
||||
As in plantUml you can specify concurrency using the -- symbol.
|
||||
```
|
||||
|
||||
```markdown
|
||||
stateDiagram
|
||||
[*] --> Active
|
||||
|
||||
@@ -291,7 +303,6 @@ As in plantUml you can specify concurrency using the -- symbol.
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
```mermaid
|
||||
stateDiagram
|
||||
[*] --> Active
|
||||
|
BIN
img/class.png
Before Width: | Height: | Size: 141 KiB |
BIN
img/flow.png
Before Width: | Height: | Size: 6.1 KiB |
BIN
img/gantt.png
Before Width: | Height: | Size: 16 KiB |
BIN
img/git.png
Before Width: | Height: | Size: 15 KiB |
BIN
img/gray-class.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
img/gray-flow.png
Normal file
After Width: | Height: | Size: 6.9 KiB |
BIN
img/gray-gantt.png
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
img/gray-pie.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
img/gray-sequence.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
img/gray-state.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
img/sequence.png
Before Width: | Height: | Size: 30 KiB |
18816
package-lock.json
generated
10
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mermaid",
|
||||
"version": "8.4.0",
|
||||
"version": "8.4.2",
|
||||
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
|
||||
"main": "dist/mermaid.core.js",
|
||||
"keywords": [
|
||||
@@ -26,7 +26,7 @@
|
||||
"dev": "webpack-dev-server --config webpack.config.e2e.js",
|
||||
"test": "yarn lint && jest src",
|
||||
"test:watch": "jest --watch src",
|
||||
"prepublishOnly": "yarn build && yarn release && yarn test",
|
||||
"prepublishOnly": "yarn build && yarn release && yarn test && yarn e2e",
|
||||
"prepush": "yarn test"
|
||||
},
|
||||
"repository": {
|
||||
@@ -49,9 +49,9 @@
|
||||
"@braintree/sanitize-url": "^3.1.0",
|
||||
"crypto-random-string": "^3.0.1",
|
||||
"d3": "^5.7.0",
|
||||
"dagre-d3-renderer": "^0.5.8",
|
||||
"dagre-layout": "^0.8.8",
|
||||
"graphlibrary": "^2.2.0",
|
||||
"dagre-d3": "dagrejs/dagre-d3",
|
||||
"dagre": "^0.8.4",
|
||||
"graphlib": "^2.1.7",
|
||||
"he": "^1.2.0",
|
||||
"lodash": "^4.17.11",
|
||||
"minify": "^4.1.1",
|
||||
|
@@ -64,7 +64,7 @@ describe('class diagram, ', function() {
|
||||
it('should handle parsing of method statements grouped by brackets', function() {
|
||||
const str =
|
||||
'classDiagram\n' +
|
||||
'class Dummy {\n' +
|
||||
'class Dummy_Class {\n' +
|
||||
'String data\n' +
|
||||
' void methods()\n' +
|
||||
'}\n' +
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import * as d3 from 'd3';
|
||||
import dagre from 'dagre-layout';
|
||||
import graphlib from 'graphlibrary';
|
||||
import dagre from 'dagre';
|
||||
import graphlib from 'graphlib';
|
||||
import { logger } from '../../logger';
|
||||
import classDb from './classDb';
|
||||
import utils from '../../utils';
|
||||
@@ -204,14 +204,12 @@ const drawEdge = function(elem, path, relation) {
|
||||
x = labalPosition.x;
|
||||
y = labalPosition.y;
|
||||
|
||||
let p1_card_x,
|
||||
p1_card_y,
|
||||
p1_card_padd_x = conf.padding * 2,
|
||||
p1_card_padd_y = conf.padding;
|
||||
let p2_card_x,
|
||||
p2_card_y,
|
||||
p2_card_padd_x = conf.padding * 2,
|
||||
p2_card_padd_y = -conf.padding / 2;
|
||||
let p1_card_x, p1_card_y;
|
||||
// p1_card_padd_x = conf.padding * 2,
|
||||
// p1_card_padd_y = conf.padding;
|
||||
let p2_card_x, p2_card_y;
|
||||
// p2_card_padd_x = conf.padding * 2,
|
||||
// p2_card_padd_y = -conf.padding / 2;
|
||||
if (l % 2 !== 0 && l > 1) {
|
||||
let cardinality_1_point = utils.calcCardinalityPosition(
|
||||
relation.relation.type1 !== 'none',
|
||||
@@ -258,8 +256,7 @@ const drawEdge = function(elem, path, relation) {
|
||||
logger.info('Rendering relation ' + JSON.stringify(relation));
|
||||
if (typeof relation.relationTitle1 !== 'undefined' && relation.relationTitle1 !== 'none') {
|
||||
const g = elem.append('g').attr('class', 'cardinality');
|
||||
const label = g
|
||||
.append('text')
|
||||
g.append('text')
|
||||
.attr('class', 'type1')
|
||||
.attr('x', p1_card_x)
|
||||
.attr('y', p1_card_y)
|
||||
@@ -269,8 +266,7 @@ const drawEdge = function(elem, path, relation) {
|
||||
}
|
||||
if (typeof relation.relationTitle2 !== 'undefined' && relation.relationTitle2 !== 'none') {
|
||||
const g = elem.append('g').attr('class', 'cardinality');
|
||||
const label = g
|
||||
.append('text')
|
||||
g.append('text')
|
||||
.attr('class', 'type2')
|
||||
.attr('x', p2_card_x)
|
||||
.attr('y', p2_card_y)
|
||||
@@ -323,8 +319,6 @@ const drawClass = function(elem, classDef) {
|
||||
isFirst = false;
|
||||
});
|
||||
|
||||
console.warn('classDef.id', classDef.id);
|
||||
console.warn('isFirst', isFirst);
|
||||
// add class title
|
||||
const classTitle = title
|
||||
.append('tspan')
|
||||
@@ -348,7 +342,6 @@ const drawClass = function(elem, classDef) {
|
||||
.attr('y', titleHeight + conf.dividerMargin + conf.textHeight)
|
||||
.attr('fill', 'white')
|
||||
.attr('class', 'classText');
|
||||
console.warn(classDef.id, titleHeight, conf.dividerMargin, conf.textHeight);
|
||||
|
||||
isFirst = true;
|
||||
classDef.members.forEach(function(member) {
|
||||
|
@@ -43,8 +43,8 @@
|
||||
\% return 'PCT';
|
||||
"=" return 'EQUALS';
|
||||
\= return 'EQUALS';
|
||||
[A-Za-z]+ return 'ALPHA';
|
||||
[!"#$%&'*+,-.`?\\_/] return 'PUNCTUATION';
|
||||
\w+ return 'ALPHA';
|
||||
[!"#$%&'*+,-.`?\\/] return 'PUNCTUATION';
|
||||
[0-9]+ return 'NUM';
|
||||
[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|
|
||||
[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|
|
||||
@@ -163,7 +163,7 @@ members
|
||||
methodStatement
|
||||
: className {/*console.log('Rel found',$1);*/}
|
||||
| className LABEL {yy.addMember($1,yy.cleanupLabel($2));}
|
||||
| MEMBER {console.warn('Member',$1);}
|
||||
| MEMBER {/*console.warn('Member',$1);*/}
|
||||
| SEPARATOR {/*console.log('sep found',$1);*/}
|
||||
;
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import dagreD3 from 'dagre-d3-renderer';
|
||||
import dagreD3 from 'dagre-d3';
|
||||
|
||||
function question(parent, bbox, node) {
|
||||
const w = bbox.width;
|
||||
|
@@ -4,6 +4,8 @@ import { logger } from '../../logger';
|
||||
import utils from '../../utils';
|
||||
import { getConfig } from '../../config';
|
||||
|
||||
const MERMAID_DOM_ID_PREFIX = 'mermaid-dom-id-';
|
||||
|
||||
const config = getConfig();
|
||||
let vertices = {};
|
||||
let edges = [];
|
||||
@@ -48,7 +50,7 @@ export const addVertex = function(_id, text, type, style, classes) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (id[0].match(/\d/)) id = 's' + id;
|
||||
if (id[0].match(/\d/)) id = MERMAID_DOM_ID_PREFIX + id;
|
||||
|
||||
if (typeof vertices[id] === 'undefined') {
|
||||
vertices[id] = { id: id, styles: [], classes: [] };
|
||||
@@ -96,8 +98,8 @@ export const addVertex = function(_id, text, type, style, classes) {
|
||||
export const addLink = function(_start, _end, type, linktext) {
|
||||
let start = _start;
|
||||
let end = _end;
|
||||
if (start[0].match(/\d/)) start = 's' + start;
|
||||
if (end[0].match(/\d/)) end = 's' + end;
|
||||
if (start[0].match(/\d/)) start = MERMAID_DOM_ID_PREFIX + start;
|
||||
if (end[0].match(/\d/)) end = MERMAID_DOM_ID_PREFIX + end;
|
||||
logger.info('Got edge...', start, end);
|
||||
|
||||
const edge = { start: start, end: end, type: undefined, text: '' };
|
||||
@@ -194,7 +196,7 @@ export const setDirection = function(dir) {
|
||||
export const setClass = function(ids, className) {
|
||||
ids.split(',').forEach(function(_id) {
|
||||
let id = _id;
|
||||
if (_id[0].match(/\d/)) id = 's' + id;
|
||||
if (_id[0].match(/\d/)) id = MERMAID_DOM_ID_PREFIX + id;
|
||||
if (typeof vertices[id] !== 'undefined') {
|
||||
vertices[id].classes.push(className);
|
||||
}
|
||||
@@ -215,7 +217,7 @@ const setTooltip = function(ids, tooltip) {
|
||||
|
||||
const setClickFun = function(_id, functionName) {
|
||||
let id = _id;
|
||||
if (_id[0].match(/\d/)) id = 's' + id;
|
||||
if (_id[0].match(/\d/)) id = MERMAID_DOM_ID_PREFIX + id;
|
||||
if (config.securityLevel !== 'loose') {
|
||||
return;
|
||||
}
|
||||
@@ -223,7 +225,7 @@ const setClickFun = function(_id, functionName) {
|
||||
return;
|
||||
}
|
||||
if (typeof vertices[id] !== 'undefined') {
|
||||
funs.push(function(element) {
|
||||
funs.push(function() {
|
||||
const elem = document.querySelector(`[id="${id}"]`);
|
||||
if (elem !== null) {
|
||||
elem.addEventListener(
|
||||
@@ -247,7 +249,7 @@ const setClickFun = function(_id, functionName) {
|
||||
export const setLink = function(ids, linkStr, tooltip) {
|
||||
ids.split(',').forEach(function(_id) {
|
||||
let id = _id;
|
||||
if (_id[0].match(/\d/)) id = 's' + id;
|
||||
if (_id[0].match(/\d/)) id = MERMAID_DOM_ID_PREFIX + id;
|
||||
if (typeof vertices[id] !== 'undefined') {
|
||||
if (config.securityLevel !== 'loose') {
|
||||
vertices[id].link = sanitizeUrl(linkStr); // .replace(/javascript:.*/g, '')
|
||||
@@ -395,7 +397,7 @@ export const addSubGraph = function(_id, list, _title) {
|
||||
return false;
|
||||
}
|
||||
if (type in prims) {
|
||||
return prims[type].hasOwnProperty(item) ? false : (prims[type][item] = true);
|
||||
return prims[type].hasOwnProperty(item) ? false : (prims[type][item] = true); // eslint-disable-line
|
||||
} else {
|
||||
return objs.indexOf(item) >= 0 ? false : objs.push(item);
|
||||
}
|
||||
@@ -406,11 +408,11 @@ export const addSubGraph = function(_id, list, _title) {
|
||||
|
||||
nodeList = uniq(nodeList.concat.apply(nodeList, list));
|
||||
for (let i = 0; i < nodeList.length; i++) {
|
||||
if (nodeList[i][0].match(/\d/)) nodeList[i] = 's' + nodeList[i];
|
||||
if (nodeList[i][0].match(/\d/)) nodeList[i] = MERMAID_DOM_ID_PREFIX + nodeList[i];
|
||||
}
|
||||
|
||||
id = id || 'subGraph' + subCount;
|
||||
if (id[0].match(/\d/)) id = 's' + id;
|
||||
if (id[0].match(/\d/)) id = MERMAID_DOM_ID_PREFIX + id;
|
||||
title = title || '';
|
||||
title = sanitize(title);
|
||||
subCount = subCount + 1;
|
||||
|
@@ -1,11 +1,16 @@
|
||||
import graphlib from 'graphlibrary';
|
||||
import graphlib from 'graphlib';
|
||||
import * as d3 from 'd3';
|
||||
|
||||
import flowDb from './flowDb';
|
||||
import flow from './parser/flow';
|
||||
import { getConfig } from '../../config';
|
||||
import dagreD3 from 'dagre-d3-renderer';
|
||||
import addHtmlLabel from 'dagre-d3-renderer/lib/label/add-html-label.js';
|
||||
|
||||
const newDagreD3 = true;
|
||||
import dagreD3 from 'dagre-d3';
|
||||
// const newDagreD3 = false;
|
||||
// import dagreD3 from '../../../../dagre-d3-renderer/dist/dagre-d3.core.js';
|
||||
|
||||
import addHtmlLabel from 'dagre-d3/lib/label/add-html-label.js';
|
||||
import { logger } from '../../logger';
|
||||
import { interpolateToCurve } from '../../utils';
|
||||
import flowChartShapes from './flowChartShapes';
|
||||
@@ -291,18 +296,35 @@ export const draw = function(text, id) {
|
||||
}
|
||||
|
||||
// Create the input mermaid.graph
|
||||
const g = new graphlib.Graph({
|
||||
multigraph: true,
|
||||
compound: true
|
||||
})
|
||||
.setGraph({
|
||||
rankdir: dir,
|
||||
marginx: 20,
|
||||
marginy: 20
|
||||
let g;
|
||||
// Todo remove newDagreD3 when properly verified
|
||||
if (newDagreD3) {
|
||||
g = new graphlib.Graph({
|
||||
multigraph: true,
|
||||
compound: true
|
||||
})
|
||||
.setDefaultEdgeLabel(function() {
|
||||
return {};
|
||||
});
|
||||
.setGraph({
|
||||
rankdir: dir,
|
||||
marginx: 8,
|
||||
marginy: 8
|
||||
})
|
||||
.setDefaultEdgeLabel(function() {
|
||||
return {};
|
||||
});
|
||||
} else {
|
||||
g = new graphlib.Graph({
|
||||
multigraph: true,
|
||||
compound: true
|
||||
})
|
||||
.setGraph({
|
||||
rankdir: dir,
|
||||
marginx: 20,
|
||||
marginy: 20
|
||||
})
|
||||
.setDefaultEdgeLabel(function() {
|
||||
return {};
|
||||
});
|
||||
}
|
||||
|
||||
let subG;
|
||||
const subGraphs = flowDb.getSubGraphs();
|
||||
@@ -354,7 +376,7 @@ export const draw = function(text, id) {
|
||||
};
|
||||
|
||||
// Override normal arrowhead defined in d3. Remove style & add class to allow css styling.
|
||||
render.arrows().normal = function normal(parent, id, edge, type) {
|
||||
render.arrows().normal = function normal(parent, id) {
|
||||
const marker = parent
|
||||
.append('marker')
|
||||
.attr('id', id)
|
||||
@@ -386,22 +408,50 @@ export const draw = function(text, id) {
|
||||
});
|
||||
|
||||
const conf = getConfig().flowchart;
|
||||
|
||||
const padding = 8;
|
||||
const width = g.maxX - g.minX + padding * 2;
|
||||
const height = g.maxY - g.minY + padding * 2;
|
||||
// Todo remove newDagreD3 when properly verified
|
||||
if (newDagreD3) {
|
||||
const svgBounds = svg.node().getBBox();
|
||||
const width = svgBounds.width + padding * 2;
|
||||
const height = svgBounds.height + padding * 2;
|
||||
logger.debug(
|
||||
`new ViewBox 0 0 ${width} ${height}`,
|
||||
`translate(${padding - g._label.marginx}, ${padding - g._label.marginy})`
|
||||
);
|
||||
|
||||
if (conf.useMaxWidth) {
|
||||
svg.attr('width', '100%');
|
||||
svg.attr('style', `max-width: ${width}px;`);
|
||||
if (conf.useMaxWidth) {
|
||||
svg.attr('width', '100%');
|
||||
svg.attr('style', `max-width: ${width}px;`);
|
||||
} else {
|
||||
svg.attr('height', height);
|
||||
svg.attr('width', width);
|
||||
}
|
||||
|
||||
svg.attr('viewBox', `0 0 ${width} ${height}`);
|
||||
svg
|
||||
.select('g')
|
||||
.attr('transform', `translate(${padding - g._label.marginx}, ${padding - svgBounds.y})`);
|
||||
} else {
|
||||
svg.attr('height', height);
|
||||
svg.attr('width', width);
|
||||
const width = g.maxX - g.minX + padding * 2;
|
||||
const height = g.maxY - g.minY + padding * 2;
|
||||
|
||||
if (conf.useMaxWidth) {
|
||||
svg.attr('width', '100%');
|
||||
svg.attr('style', `max-width: ${width}px;`);
|
||||
} else {
|
||||
svg.attr('height', height);
|
||||
svg.attr('width', width);
|
||||
}
|
||||
|
||||
logger.debug(
|
||||
`Org ViewBox 0 0 ${width} ${height}`,
|
||||
`translate(${padding - g.minX}, ${padding - g.minY})\n${location.href}`
|
||||
);
|
||||
|
||||
svg.attr('viewBox', `0 0 ${width} ${height}`);
|
||||
svg.select('g').attr('transform', `translate(${padding - g.minX}, ${padding - g.minY})`);
|
||||
// svg.select('g').attr('transform', `translate(${padding - minX}, ${padding - minY})`);
|
||||
}
|
||||
|
||||
svg.attr('viewBox', `0 0 ${width} ${height}`);
|
||||
svg.select('g').attr('transform', `translate(${padding - g.minX}, ${padding - g.minY})`);
|
||||
|
||||
// Index nodes
|
||||
flowDb.indexNodes('subGraph' + i);
|
||||
|
||||
|
@@ -168,7 +168,7 @@ describe('[Singlenodes] when parsing', () => {
|
||||
const edges = flow.parser.yy.getEdges();
|
||||
|
||||
expect(edges.length).toBe(0);
|
||||
expect(vert['s1'].text).toBe('1');
|
||||
expect(vert['mermaid-dom-id-1'].text).toBe('1');
|
||||
});
|
||||
|
||||
it('should handle a single node with a single digit in a subgraph', function() {
|
||||
@@ -180,7 +180,7 @@ describe('[Singlenodes] when parsing', () => {
|
||||
const edges = flow.parser.yy.getEdges();
|
||||
|
||||
expect(edges.length).toBe(0);
|
||||
expect(vert['s1'].text).toBe('1');
|
||||
expect(vert['mermaid-dom-id-1'].text).toBe('1');
|
||||
});
|
||||
|
||||
it('should handle a single node with alphanumerics starting on a num', function() {
|
||||
@@ -191,7 +191,7 @@ describe('[Singlenodes] when parsing', () => {
|
||||
const edges = flow.parser.yy.getEdges();
|
||||
|
||||
expect(edges.length).toBe(0);
|
||||
expect(vert['s1id'].styles.length).toBe(0);
|
||||
expect(vert['mermaid-dom-id-1id'].styles.length).toBe(0);
|
||||
});
|
||||
|
||||
it('should handle a single node with alphanumerics containing a minus sign', function() {
|
||||
|
@@ -83,7 +83,7 @@ describe('when parsing subgraphs', function() {
|
||||
const subgraph = subgraphs[0];
|
||||
expect(subgraph.nodes.length).toBe(1);
|
||||
expect(subgraph.nodes[0]).toBe('A');
|
||||
expect(subgraph.id).toBe('s1test');
|
||||
expect(subgraph.id).toBe('mermaid-dom-id-1test');
|
||||
});
|
||||
|
||||
it('should handle subgraphs1', function() {
|
||||
|
@@ -387,10 +387,11 @@ const compileTasks = function() {
|
||||
const task = rawTasks[pos];
|
||||
let startTime = '';
|
||||
switch (rawTasks[pos].raw.startTime.type) {
|
||||
case 'prevTaskEnd':
|
||||
case 'prevTaskEnd': {
|
||||
const prevTask = findTaskById(task.prevTaskId);
|
||||
task.startTime = prevTask.endTime;
|
||||
break;
|
||||
}
|
||||
case 'getStartDate':
|
||||
startTime = getStartDate(undefined, dateFormat, rawTasks[pos].raw.startTime.startData);
|
||||
if (startTime) {
|
||||
@@ -501,7 +502,7 @@ const setClickFun = function(id, functionName, functionArgs) {
|
||||
* @param callbackFunction A function to be executed when clicked on the task or the task's text
|
||||
*/
|
||||
const pushFun = function(id, callbackFunction) {
|
||||
funs.push(function(element) {
|
||||
funs.push(function() {
|
||||
// const elem = d3.select(element).select(`[id="${id}"]`)
|
||||
const elem = document.querySelector(`[id="${id}"]`);
|
||||
if (elem !== null) {
|
||||
@@ -510,7 +511,7 @@ const pushFun = function(id, callbackFunction) {
|
||||
});
|
||||
}
|
||||
});
|
||||
funs.push(function(element) {
|
||||
funs.push(function() {
|
||||
// const elem = d3.select(element).select(`[id="${id}-text"]`)
|
||||
const elem = document.querySelector(`[id="${id}-text"]`);
|
||||
if (elem !== null) {
|
||||
|
@@ -102,7 +102,7 @@ export const draw = function(text, id) {
|
||||
drawToday(leftPadding, topPadding, pageWidth, pageHeight);
|
||||
}
|
||||
|
||||
function drawRects(theArray, theGap, theTopPad, theSidePad, theBarHeight, theColorScale, w, h) {
|
||||
function drawRects(theArray, theGap, theTopPad, theSidePad, theBarHeight, theColorScale, w) {
|
||||
// Draw background rects covering the entire width of the graph, these form the section rows.
|
||||
svg
|
||||
.append('g')
|
||||
@@ -401,7 +401,7 @@ export const draw = function(text, id) {
|
||||
const hash = {};
|
||||
const result = [];
|
||||
for (let i = 0, l = arr.length; i < l; ++i) {
|
||||
if (!hash.hasOwnProperty(arr[i])) {
|
||||
if (!hash.hasOwnProperty(arr[i])) { // eslint-disable-line
|
||||
// it works with objects! in FF, at least
|
||||
hash[arr[i]] = true;
|
||||
result.push(arr[i]);
|
||||
|
@@ -21,7 +21,7 @@ export const setConf = function(cnf) {
|
||||
* @param id
|
||||
*/
|
||||
let w;
|
||||
export const draw = (txt, id, ver) => {
|
||||
export const draw = (txt, id) => {
|
||||
try {
|
||||
const parser = pieParser.parser;
|
||||
parser.yy = pieData;
|
||||
@@ -50,6 +50,8 @@ export const draw = (txt, id, ver) => {
|
||||
var width = w; // 450
|
||||
var height = 450;
|
||||
var margin = 40;
|
||||
var legendRectSize = 18;
|
||||
var legendSpacing = 4;
|
||||
|
||||
var radius = Math.min(width, height) / 2 - margin;
|
||||
|
||||
@@ -62,6 +64,10 @@ export const draw = (txt, id, ver) => {
|
||||
.attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')');
|
||||
|
||||
var data = pieData.getSections();
|
||||
var sum = 0;
|
||||
Object.keys(data).forEach(function(key) {
|
||||
sum += data[key];
|
||||
});
|
||||
logger.info(data);
|
||||
|
||||
// set the color scale
|
||||
@@ -75,7 +81,6 @@ export const draw = (txt, id, ver) => {
|
||||
return d.value;
|
||||
});
|
||||
var dataReady = pie(d3.entries(data));
|
||||
// Now I know that group A goes from 0 degrees to x degrees and so on.
|
||||
|
||||
// shape helper to build arcs:
|
||||
var arcGenerator = d3
|
||||
@@ -97,14 +102,14 @@ export const draw = (txt, id, ver) => {
|
||||
.style('stroke-width', '2px')
|
||||
.style('opacity', 0.7);
|
||||
|
||||
// Now add the annotation. Use the centroid method to get the best coordinates
|
||||
// Now add the Percentage. Use the centroid method to get the best coordinates
|
||||
svg
|
||||
.selectAll('mySlices')
|
||||
.data(dataReady)
|
||||
.enter()
|
||||
.append('text')
|
||||
.text(function(d) {
|
||||
return d.data.key;
|
||||
return ((d.data.value / sum) * 100).toFixed(0) + '%';
|
||||
})
|
||||
.attr('transform', function(d) {
|
||||
return 'translate(' + arcGenerator.centroid(d) + ')';
|
||||
@@ -119,6 +124,36 @@ export const draw = (txt, id, ver) => {
|
||||
.attr('x', 0)
|
||||
.attr('y', -(h - 50) / 2)
|
||||
.attr('class', 'pieTitleText');
|
||||
|
||||
//Add the slegend/annotations for each section
|
||||
var legend = svg
|
||||
.selectAll('.legend')
|
||||
.data(color.domain())
|
||||
.enter()
|
||||
.append('g')
|
||||
.attr('class', 'legend')
|
||||
.attr('transform', function(d, i) {
|
||||
var height = legendRectSize + legendSpacing;
|
||||
var offset = (height * color.domain().length) / 2;
|
||||
var horz = 12 * legendRectSize;
|
||||
var vert = i * height - offset;
|
||||
return 'translate(' + horz + ',' + vert + ')';
|
||||
});
|
||||
|
||||
legend
|
||||
.append('rect')
|
||||
.attr('width', legendRectSize)
|
||||
.attr('height', legendRectSize)
|
||||
.style('fill', color)
|
||||
.style('stroke', color);
|
||||
|
||||
legend
|
||||
.append('text')
|
||||
.attr('x', legendRectSize + legendSpacing)
|
||||
.attr('y', legendRectSize - legendSpacing)
|
||||
.text(function(d) {
|
||||
return d;
|
||||
});
|
||||
} catch (e) {
|
||||
logger.error('Error while rendering info diagram');
|
||||
logger.error(e.message);
|
||||
|
@@ -514,11 +514,12 @@ export const draw = function(text, id) {
|
||||
bounds.newLoop(undefined, msg.message);
|
||||
bounds.bumpVerticalPos(conf.boxMargin);
|
||||
break;
|
||||
case parser.yy.LINETYPE.RECT_END:
|
||||
case parser.yy.LINETYPE.RECT_END: {
|
||||
const rectData = bounds.endLoop();
|
||||
svgDraw.drawBackgroundRect(diagram, rectData);
|
||||
bounds.bumpVerticalPos(conf.boxMargin);
|
||||
break;
|
||||
}
|
||||
case parser.yy.LINETYPE.OPT_START:
|
||||
bounds.bumpVerticalPos(conf.boxMargin);
|
||||
bounds.newLoop(msg.message);
|
||||
|
@@ -16,7 +16,7 @@ export const drawRect = function(elem, rectData) {
|
||||
return rectElem;
|
||||
};
|
||||
|
||||
export const drawText = function(elem, textData, width) {
|
||||
export const drawText = function(elem, textData) {
|
||||
// Remove and ignore br:s
|
||||
const nText = textData.text.replace(/<br\/?>/gi, ' ');
|
||||
|
||||
@@ -374,7 +374,7 @@ const _drawTextCandidateFunc = (function() {
|
||||
|
||||
function _setTextAttrs(toText, fromTextAttrsDict) {
|
||||
for (const key in fromTextAttrsDict) {
|
||||
if (fromTextAttrsDict.hasOwnProperty(key)) {
|
||||
if (fromTextAttrsDict.hasOwnProperty(key)) { // eslint-disable-line
|
||||
toText.attr(key, fromTextAttrsDict[key]);
|
||||
}
|
||||
}
|
||||
|
@@ -43,10 +43,10 @@
|
||||
<SCALE>\s+"width" {this.popState();}
|
||||
|
||||
<INITIAL,struct>"state"\s+ { this.pushState('STATE'); }
|
||||
<STATE>.*"<<fork>>" {this.popState();yytext=yytext.slice(0,-8).trim(); console.warn('Fork Fork: ',yytext);return 'FORK';}
|
||||
<STATE>.*"<<join>>" {this.popState();yytext=yytext.slice(0,-8).trim();console.warn('Fork Join: ',yytext);return 'JOIN';}
|
||||
<STATE>.*"[[fork]]" {this.popState();yytext=yytext.slice(0,-8).trim();console.warn('Fork Fork: ',yytext);return 'FORK';}
|
||||
<STATE>.*"[[join]]" {this.popState();yytext=yytext.slice(0,-8).trim();console.warn('Fork Join: ',yytext);return 'JOIN';}
|
||||
<STATE>.*"<<fork>>" {this.popState();yytext=yytext.slice(0,-8).trim(); /*console.warn('Fork Fork: ',yytext);*/return 'FORK';}
|
||||
<STATE>.*"<<join>>" {this.popState();yytext=yytext.slice(0,-8).trim();/*console.warn('Fork Join: ',yytext);*/return 'JOIN';}
|
||||
<STATE>.*"[[fork]]" {this.popState();yytext=yytext.slice(0,-8).trim();/*console.warn('Fork Fork: ',yytext);*/return 'FORK';}
|
||||
<STATE>.*"[[join]]" {this.popState();yytext=yytext.slice(0,-8).trim();/*console.warn('Fork Join: ',yytext);*/return 'JOIN';}
|
||||
<STATE>["] this.begin("STATE_STRING");
|
||||
<STATE>"as"\s* {this.popState();this.pushState('STATE_ID');return "AS";}
|
||||
<STATE_ID>[^\n\{]* {this.popState();/* console.log('STATE_ID', yytext);*/return "ID";}
|
||||
@@ -133,7 +133,17 @@ statement
|
||||
/* console.warn('Adding document for state without id ', $1);*/
|
||||
$$={ stmt: 'state', id: $1, type: 'default', description: '', doc: $3 }
|
||||
}
|
||||
| STATE_DESCR AS ID { $$={stmt: 'state', id: $3, type: 'default', description: $1.trim()};}
|
||||
| STATE_DESCR AS ID {
|
||||
var id=$3;
|
||||
var description = $1.trim();
|
||||
if($3.match(':')){
|
||||
var parts = $3.split(':');
|
||||
id=parts[0];
|
||||
description = [description, parts[1]];
|
||||
}
|
||||
$$={stmt: 'state', id: id, type: 'default', description: description};
|
||||
|
||||
}
|
||||
| STATE_DESCR AS ID STRUCT_START document STRUCT_STOP
|
||||
{
|
||||
//console.warn('Adding document for state with id ', $3, $4); yy.addDocument($3);
|
||||
|
@@ -2,7 +2,7 @@ import * as d3 from 'd3';
|
||||
import idCache from './id-cache.js';
|
||||
import stateDb from './stateDb';
|
||||
import utils from '../../utils';
|
||||
import { getConfig, conf } from '../../config';
|
||||
import { getConfig } from '../../config';
|
||||
|
||||
// let conf;
|
||||
|
||||
@@ -76,7 +76,7 @@ export const drawDescrState = (g, stateDef) => {
|
||||
.attr('y', getConfig().state.textHeight + 1.5 * getConfig().state.padding)
|
||||
.attr('font-size', getConfig().state.fontSize)
|
||||
.attr('class', 'state-title')
|
||||
.text(stateDef.id);
|
||||
.text(stateDef.descriptions[0]);
|
||||
|
||||
const titleBox = title.node().getBBox();
|
||||
const titleHeight = titleBox.height;
|
||||
@@ -94,8 +94,12 @@ export const drawDescrState = (g, stateDef) => {
|
||||
.attr('class', 'state-description');
|
||||
|
||||
let isFirst = true;
|
||||
let isSecond = true;
|
||||
stateDef.descriptions.forEach(function(descr) {
|
||||
addTspan(description, descr, isFirst);
|
||||
if (!isFirst) {
|
||||
addTspan(description, descr, isSecond);
|
||||
isSecond = false;
|
||||
}
|
||||
isFirst = false;
|
||||
});
|
||||
|
||||
@@ -106,7 +110,6 @@ export const drawDescrState = (g, stateDef) => {
|
||||
.attr('y2', getConfig().state.padding + titleHeight + getConfig().state.dividerMargin / 2)
|
||||
.attr('class', 'descr-divider');
|
||||
const descrBox = description.node().getBBox();
|
||||
console.warn(descrBox.width, titleBox.width);
|
||||
const width = Math.max(descrBox.width, titleBox.width);
|
||||
|
||||
descrLine.attr('x2', width + 3 * getConfig().state.padding);
|
||||
@@ -128,15 +131,15 @@ export const drawDescrState = (g, stateDef) => {
|
||||
*/
|
||||
export const addIdAndBox = (g, stateDef) => {
|
||||
// TODO Move hardcodings to conf
|
||||
const addTspan = function(textEl, txt, isFirst) {
|
||||
const tSpan = textEl
|
||||
.append('tspan')
|
||||
.attr('x', 2 * getConfig().state.padding)
|
||||
.text(txt);
|
||||
if (!isFirst) {
|
||||
tSpan.attr('dy', getConfig().state.textHeight);
|
||||
}
|
||||
};
|
||||
// const addTspan = function(textEl, txt, isFirst) {
|
||||
// const tSpan = textEl
|
||||
// .append('tspan')
|
||||
// .attr('x', 2 * getConfig().state.padding)
|
||||
// .text(txt);
|
||||
// if (!isFirst) {
|
||||
// tSpan.attr('dy', getConfig().state.textHeight);
|
||||
// }
|
||||
// };
|
||||
const title = g
|
||||
.append('text')
|
||||
.attr('x', 2 * getConfig().state.padding)
|
||||
@@ -145,7 +148,7 @@ export const addIdAndBox = (g, stateDef) => {
|
||||
.attr('class', 'state-title')
|
||||
.text(stateDef.id);
|
||||
|
||||
const titleHeight = title.node().getBBox().height;
|
||||
const titleBox = title.node().getBBox();
|
||||
|
||||
const lineY = 1 - getConfig().state.textHeight;
|
||||
const descrLine = g
|
||||
@@ -156,7 +159,7 @@ export const addIdAndBox = (g, stateDef) => {
|
||||
.attr('class', 'descr-divider');
|
||||
|
||||
const graphBox = g.node().getBBox();
|
||||
title.attr('x', graphBox.width / 2 - title.node().getBBox().width / 2);
|
||||
title.attr('x', graphBox.width / 2 - titleBox.width / 2);
|
||||
descrLine.attr('x2', graphBox.width + getConfig().state.padding);
|
||||
|
||||
// White color
|
||||
@@ -238,7 +241,7 @@ const drawForkJoinState = (g, stateDef) => {
|
||||
.attr('y', getConfig().state.padding);
|
||||
};
|
||||
|
||||
export const drawText = function(elem, textData, width) {
|
||||
export const drawText = function(elem, textData) {
|
||||
// Remove and ignore br:s
|
||||
const nText = textData.text.replace(/<br\/?>/gi, ' ');
|
||||
|
||||
@@ -261,7 +264,7 @@ export const drawText = function(elem, textData, width) {
|
||||
|
||||
const _drawLongText = (_text, x, y, g) => {
|
||||
let textHeight = 0;
|
||||
let textWidth = 0;
|
||||
|
||||
const textElem = g.append('text');
|
||||
textElem.style('text-anchor', 'start');
|
||||
textElem.attr('class', 'noteText');
|
||||
@@ -269,17 +272,22 @@ const _drawLongText = (_text, x, y, g) => {
|
||||
let text = _text.replace(/\r\n/g, '<br/>');
|
||||
text = text.replace(/\n/g, '<br/>');
|
||||
const lines = text.split(/<br\/?>/gi);
|
||||
|
||||
let tHeight = 1.25 * getConfig().state.noteMargin;
|
||||
for (const line of lines) {
|
||||
const txt = line.trim();
|
||||
|
||||
if (txt.length > 0) {
|
||||
const span = textElem.append('tspan');
|
||||
span.text(txt);
|
||||
const textBounds = span.node().getBBox();
|
||||
textHeight += textBounds.height;
|
||||
if (tHeight === 0) {
|
||||
const textBounds = span.node().getBBox();
|
||||
tHeight += textBounds.height;
|
||||
}
|
||||
// console.warn('textBounds', textBounds);
|
||||
textHeight += tHeight;
|
||||
span.attr('x', x + getConfig().state.noteMargin);
|
||||
span.attr('y', y + textHeight + 1.25 * getConfig().state.noteMargin);
|
||||
// textWidth = Math.max(textBounds.width, textWidth);
|
||||
}
|
||||
}
|
||||
return { textWidth: textElem.node().getBBox().width, textHeight };
|
||||
@@ -314,8 +322,7 @@ export const drawNote = (text, g) => {
|
||||
* @param {*} stateDef
|
||||
*/
|
||||
|
||||
let cnt = 0;
|
||||
export const drawState = function(elem, stateDef, graph, doc) {
|
||||
export const drawState = function(elem, stateDef) {
|
||||
const id = stateDef.id;
|
||||
const stateInfo = {
|
||||
id: id,
|
||||
@@ -347,6 +354,12 @@ export const drawState = function(elem, stateDef, graph, doc) {
|
||||
return stateInfo;
|
||||
};
|
||||
|
||||
const getRows = s => {
|
||||
let str = s.replace(/<br\/?>/gi, '#br#');
|
||||
str = str.replace(/\\n/g, '#br#');
|
||||
return str.split('#br#');
|
||||
};
|
||||
|
||||
let edgeCount = 0;
|
||||
export const drawEdge = function(elem, path, relation) {
|
||||
const getRelationType = function(type) {
|
||||
@@ -401,20 +414,48 @@ export const drawEdge = function(elem, path, relation) {
|
||||
);
|
||||
|
||||
if (typeof relation.title !== 'undefined') {
|
||||
const g = elem.append('g').attr('class', 'stateLabel');
|
||||
const label = g
|
||||
.append('text')
|
||||
.attr('text-anchor', 'middle')
|
||||
.text(relation.title);
|
||||
const label = elem.append('g').attr('class', 'stateLabel');
|
||||
|
||||
const { x, y } = utils.calcLabelPosition(path.points);
|
||||
label.attr('x', x).attr('y', y);
|
||||
|
||||
const rows = getRows(relation.title);
|
||||
|
||||
// console.warn(rows);
|
||||
|
||||
let titleHeight = 0;
|
||||
const titleRows = [];
|
||||
for (let i = 0; i <= rows.length; i++) {
|
||||
const title = label
|
||||
.append('text')
|
||||
.attr('text-anchor', 'middle')
|
||||
.text(rows[i])
|
||||
.attr('x', x)
|
||||
.attr('y', y + titleHeight);
|
||||
|
||||
if (titleHeight === 0) {
|
||||
const titleBox = title.node().getBBox();
|
||||
titleHeight = titleBox.height;
|
||||
}
|
||||
titleRows.push(title);
|
||||
}
|
||||
|
||||
if (rows.length > 1) {
|
||||
const heightAdj = rows.length * titleHeight * 0.25;
|
||||
|
||||
titleRows.forEach((title, i) => title.attr('y', y + i * titleHeight - heightAdj));
|
||||
}
|
||||
|
||||
const bounds = label.node().getBBox();
|
||||
g.insert('rect', ':first-child')
|
||||
label
|
||||
.insert('rect', ':first-child')
|
||||
.attr('class', 'box')
|
||||
.attr('x', bounds.x - getConfig().state.padding / 2)
|
||||
.attr('y', bounds.y - getConfig().state.padding / 2)
|
||||
.attr('width', bounds.width + getConfig().state.padding)
|
||||
.attr('height', bounds.height + getConfig().state.padding);
|
||||
|
||||
//label.attr('transform', '0 -' + (bounds.y / 2));
|
||||
|
||||
// Debug points
|
||||
// path.points.forEach(point => {
|
||||
// g.append('circle')
|
||||
|
@@ -9,7 +9,7 @@ const setRootDoc = o => {
|
||||
const getRootDoc = () => rootDoc;
|
||||
|
||||
const extract = doc => {
|
||||
const res = { states: [], relations: [] };
|
||||
// const res = { states: [], relations: [] };
|
||||
clear();
|
||||
|
||||
doc.forEach(item => {
|
||||
@@ -37,8 +37,8 @@ let documents = {
|
||||
let currentDocument = documents.root;
|
||||
|
||||
let startCnt = 0;
|
||||
let endCnt = 0;
|
||||
let stateCnt = 0;
|
||||
let endCnt = 0; // eslint-disable-line
|
||||
// let stateCnt = 0;
|
||||
|
||||
/**
|
||||
* Function called by parser when a node definition has been found.
|
||||
@@ -64,7 +64,14 @@ export const addState = function(id, type, doc, descr, note) {
|
||||
currentDocument.states[id].type = type;
|
||||
}
|
||||
}
|
||||
if (descr) addDescription(id, descr.trim());
|
||||
if (descr) {
|
||||
if (typeof descr === 'string') addDescription(id, descr.trim());
|
||||
|
||||
if (typeof descr === 'object') {
|
||||
descr.forEach(des => addDescription(id, des.trim()));
|
||||
}
|
||||
}
|
||||
|
||||
if (note) currentDocument.states[id].note = note;
|
||||
};
|
||||
|
||||
|
@@ -1,18 +1,15 @@
|
||||
import * as d3 from 'd3';
|
||||
import dagre from 'dagre-layout';
|
||||
import graphlib from 'graphlibrary';
|
||||
import dagre from 'dagre';
|
||||
import graphlib from 'graphlib';
|
||||
import { logger } from '../../logger';
|
||||
import stateDb from './stateDb';
|
||||
import { parser } from './parser/stateDiagram';
|
||||
import utils from '../../utils';
|
||||
import idCache from './id-cache';
|
||||
import { drawState, addIdAndBox, drawEdge, drawNote } from './shapes';
|
||||
// import idCache from './id-cache';
|
||||
import { drawState, addIdAndBox, drawEdge } from './shapes';
|
||||
import { getConfig } from '../../config';
|
||||
|
||||
parser.yy = stateDb;
|
||||
|
||||
let total = 0;
|
||||
|
||||
// TODO Move conf object to main conf in mermaidAPI
|
||||
let conf;
|
||||
// {
|
||||
@@ -28,20 +25,20 @@ let conf;
|
||||
|
||||
const transformationLog = {};
|
||||
|
||||
export const setConf = function(cnf) {};
|
||||
export const setConf = function() {};
|
||||
|
||||
// Todo optimize
|
||||
const getGraphId = function(label) {
|
||||
const keys = idCache.keys();
|
||||
// const getGraphId = function(label) {
|
||||
// const keys = idCache.keys();
|
||||
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
if (idCache.get(keys[i]).label === label) {
|
||||
return keys[i];
|
||||
}
|
||||
}
|
||||
// for (let i = 0; i < keys.length; i++) {
|
||||
// if (idCache.get(keys[i]).label === label) {
|
||||
// return keys[i];
|
||||
// }
|
||||
// }
|
||||
|
||||
return undefined;
|
||||
};
|
||||
// return undefined;
|
||||
// };
|
||||
|
||||
/**
|
||||
* Setup arrow head and define the marker. The result is appended to the svg.
|
||||
@@ -90,24 +87,49 @@ export const draw = function(text, id) {
|
||||
});
|
||||
|
||||
const rootDoc = stateDb.getRootDoc();
|
||||
const n = renderDoc(rootDoc, diagram);
|
||||
renderDoc(rootDoc, diagram);
|
||||
|
||||
const padding = conf.padding;
|
||||
const bounds = diagram.node().getBBox();
|
||||
|
||||
diagram.attr('height', '100%');
|
||||
diagram.attr('style', `width: ${bounds.width * 3 + conf.padding * 2};`);
|
||||
console.warn(bounds);
|
||||
|
||||
const width = bounds.width + padding * 2;
|
||||
const height = bounds.height + padding * 2;
|
||||
|
||||
// diagram.attr('height', '100%');
|
||||
// diagram.attr('style', `width: ${bounds.width * 3 + conf.padding * 2};`);
|
||||
// diagram.attr('height', height);
|
||||
|
||||
// Zoom in a bit
|
||||
diagram.attr('width', width * 2);
|
||||
// diagram.attr('height', bounds.height * 3 + conf.padding * 2);
|
||||
diagram.attr(
|
||||
'viewBox',
|
||||
`${conf.padding * -1} ${conf.padding * -1} ` +
|
||||
(bounds.width * 1.5 + conf.padding * 2) +
|
||||
' ' +
|
||||
(bounds.height + conf.padding * 5)
|
||||
`${bounds.x - conf.padding} ${bounds.y - conf.padding} ` + width + ' ' + height
|
||||
);
|
||||
// diagram.attr('transform', `translate(, 0)`);
|
||||
|
||||
// diagram.attr(
|
||||
// 'viewBox',
|
||||
// `${conf.padding * -1} ${conf.padding * -1} ` +
|
||||
// (bounds.width * 1.5 + conf.padding * 2) +
|
||||
// ' ' +
|
||||
// (bounds.height + conf.padding * 5)
|
||||
// );
|
||||
};
|
||||
const getLabelWidth = text => {
|
||||
return text ? text.length * conf.fontSizeFactor : 1;
|
||||
};
|
||||
|
||||
/* TODO: REMOVE DUPLICATION, SEE SHAPES */
|
||||
const getRows = s => {
|
||||
if (!s) return 1;
|
||||
let str = s.replace(/<br\/?>/gi, '#br#');
|
||||
str = str.replace(/\\n/g, '#br#');
|
||||
return str.split('#br#');
|
||||
};
|
||||
|
||||
const renderDoc = (doc, diagram, parentId) => {
|
||||
// // Layout graph, Create a new directed graph
|
||||
const graph = new graphlib.Graph({
|
||||
@@ -121,7 +143,6 @@ const renderDoc = (doc, diagram, parentId) => {
|
||||
// multigraph: false,
|
||||
compound: true,
|
||||
// acyclicer: 'greedy',
|
||||
rankdir: 'LR',
|
||||
ranker: 'tight-tree',
|
||||
ranksep: conf.edgeLengthFactor
|
||||
// isMultiGraph: false
|
||||
@@ -151,7 +172,6 @@ const renderDoc = (doc, diagram, parentId) => {
|
||||
|
||||
const keys = Object.keys(states);
|
||||
|
||||
total = keys.length;
|
||||
let first = true;
|
||||
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
@@ -221,7 +241,7 @@ const renderDoc = (doc, diagram, parentId) => {
|
||||
graph.setEdge(relation.id1, relation.id2, {
|
||||
relation: relation,
|
||||
width: getLabelWidth(relation.title),
|
||||
height: conf.labelHeight,
|
||||
height: conf.labelHeight * getRows(relation.title).length,
|
||||
labelpos: 'c'
|
||||
});
|
||||
});
|
||||
@@ -278,7 +298,7 @@ const renderDoc = (doc, diagram, parentId) => {
|
||||
});
|
||||
|
||||
stateBox = svgElem.getBBox();
|
||||
console.warn('Diagram node', svgElem.id);
|
||||
|
||||
const stateInfo = {
|
||||
id: parentId ? parentId : 'root',
|
||||
label: parentId ? parentId : 'root',
|
||||
|
@@ -310,14 +310,13 @@ const config = {
|
||||
state: {
|
||||
dividerMargin: 10,
|
||||
sizeUnit: 5,
|
||||
padding: 5,
|
||||
padding: 8,
|
||||
textHeight: 10,
|
||||
titleShift: -15,
|
||||
noteMargin: 10,
|
||||
forkWidth: 70,
|
||||
forkHeight: 7,
|
||||
// Used
|
||||
padding: 5,
|
||||
miniPadding: 2,
|
||||
// Font size factor, this is used to guess the width of the edges labels before rendering by dagre
|
||||
// layout. This might need updating if/when switching font
|
||||
@@ -366,8 +365,6 @@ function parse(text) {
|
||||
break;
|
||||
case 'info':
|
||||
logger.debug('info info info');
|
||||
console.warn('In API', pkg.version);
|
||||
|
||||
parser = infoParser;
|
||||
parser.parser.yy = infoDb;
|
||||
break;
|
||||
|
@@ -122,7 +122,7 @@ const calcLabelPosition = points => {
|
||||
|
||||
const calcCardinalityPosition = (isRelationTypePresent, points, initialPosition) => {
|
||||
let prevPoint;
|
||||
let totalDistance = 0;
|
||||
let totalDistance = 0; // eslint-disable-line
|
||||
if (points[0] !== initialPosition) {
|
||||
points = points.reverse();
|
||||
}
|
||||
|
37
yarn.lock
@@ -3319,7 +3319,7 @@ d3-zoom@1:
|
||||
d3-selection "1"
|
||||
d3-transition "1"
|
||||
|
||||
d3@^5.7.0:
|
||||
d3@^5.12, d3@^5.7.0:
|
||||
version "5.12.0"
|
||||
resolved "https://registry.yarnpkg.com/d3/-/d3-5.12.0.tgz#0ddeac879c28c882317cd439b495290acd59ab61"
|
||||
integrity sha512-flYVMoVuhPFHd9zVCe2BxIszUWqBcd5fvQGMNRmSiBrgdnh6Vlruh60RJQTouAK9xPbOB0plxMvBm4MoyODXNg==
|
||||
@@ -3356,21 +3356,22 @@ d3@^5.7.0:
|
||||
d3-voronoi "1"
|
||||
d3-zoom "1"
|
||||
|
||||
dagre-d3-renderer@^0.5.8:
|
||||
version "0.5.8"
|
||||
resolved "https://registry.yarnpkg.com/dagre-d3-renderer/-/dagre-d3-renderer-0.5.8.tgz#aa071bb71d3c4d67426925906f3f6ddead49c1a3"
|
||||
integrity sha512-XH2a86isUHRxzIYbjQVEuZtJnWEufb64H5DuXIUmn8esuB40jgLEbUUclulWOW62/ZoXlj2ZDyL8SJ+YRxs+jQ==
|
||||
dagre-d3@dagrejs/dagre-d3:
|
||||
version "0.6.4-pre"
|
||||
resolved "https://codeload.github.com/dagrejs/dagre-d3/tar.gz/e1a00e5cb518f5d2304a35647e024f31d178e55b"
|
||||
dependencies:
|
||||
dagre-layout "^0.8.8"
|
||||
lodash "^4.17.5"
|
||||
d3 "^5.12"
|
||||
dagre "^0.8.4"
|
||||
graphlib "^2.1.7"
|
||||
lodash "^4.17.15"
|
||||
|
||||
dagre-layout@^0.8.8:
|
||||
version "0.8.8"
|
||||
resolved "https://registry.yarnpkg.com/dagre-layout/-/dagre-layout-0.8.8.tgz#9b6792f24229f402441c14162c1049e3f261f6d9"
|
||||
integrity sha512-ZNV15T9za7X+fV8Z07IZquUKugCxm5owoiPPxfEx6OJRD331nkiIaF3vSt0JEY5FkrY0KfRQxcpQ3SpXB7pLPQ==
|
||||
dagre@^0.8.4:
|
||||
version "0.8.4"
|
||||
resolved "https://registry.yarnpkg.com/dagre/-/dagre-0.8.4.tgz#26b9fb8f7bdc60c6110a0458c375261836786061"
|
||||
integrity sha512-Dj0csFDrWYKdavwROb9FccHfTC4fJbyF/oJdL9LNZJ8WUvl968P6PAKEriGqfbdArVJEmmfA+UyumgWEwcHU6A==
|
||||
dependencies:
|
||||
graphlibrary "^2.2.0"
|
||||
lodash "^4.17.5"
|
||||
graphlib "^2.1.7"
|
||||
lodash "^4.17.4"
|
||||
|
||||
dashdash@^1.12.0:
|
||||
version "1.14.1"
|
||||
@@ -5132,10 +5133,10 @@ graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.2.tgz#6f0952605d0140c1cfdb138ed005775b92d67b02"
|
||||
integrity sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==
|
||||
|
||||
graphlibrary@^2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/graphlibrary/-/graphlibrary-2.2.0.tgz#017a14899775228dec4497a39babfdd6bf56eac6"
|
||||
integrity sha512-XTcvT55L8u4MBZrM37zXoUxsgxs/7sow7YSygd9CIwfWTVO8RVu7AYXhhCiTuFEf+APKgx6Jk4SuQbYR0vYKmQ==
|
||||
graphlib@^2.1.7:
|
||||
version "2.1.7"
|
||||
resolved "https://registry.yarnpkg.com/graphlib/-/graphlib-2.1.7.tgz#b6a69f9f44bd9de3963ce6804a2fc9e73d86aecc"
|
||||
integrity sha512-TyI9jIy2J4j0qgPmOOrHTCtpPqJGN/aurBwc6ZT+bRii+di1I+Wv3obRhVrmBEXet+qkMaEX67dXrwsd3QQM6w==
|
||||
dependencies:
|
||||
lodash "^4.17.5"
|
||||
|
||||
@@ -7044,7 +7045,7 @@ lodash@4.17.11:
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
|
||||
integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==
|
||||
|
||||
lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.4, lodash@^4.17.5, lodash@~4.17.10:
|
||||
lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5, lodash@~4.17.10:
|
||||
version "4.17.15"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
|
||||
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
|
||||
|