mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-01-14 06:43:25 +08:00
Merge branch 'mermaid-js-develop' into develop
This commit is contained in:
commit
1d59ae24c6
@ -71,9 +71,9 @@ describe('Class diagram', () => {
|
||||
classDiagram
|
||||
Class01 <|-- AveryLongClass : Cool
|
||||
<<interface>> Class01
|
||||
Class01 : -int privateMethod()
|
||||
Class01 : +int publicMethod()
|
||||
Class01 : #int protectedMethod()
|
||||
Class01 : -privateMethod()
|
||||
Class01 : +publicMethod()
|
||||
Class01 : #protectedMethod()
|
||||
Class01 : -int privateChimp
|
||||
Class01 : +int publicGorilla
|
||||
Class01 : #int protectedMarmoset
|
||||
|
@ -20,223 +20,40 @@
|
||||
</head>
|
||||
<body>
|
||||
<h1>info below</h1>
|
||||
<div class="mermaid" style="width: 100%; height: 20%;">
|
||||
flowchart LR
|
||||
user1[fa:fa-user User 1] -- edit -> folder
|
||||
</div>
|
||||
<div class="mermaid2" style="width: 50%; height: 20%;">
|
||||
flowchart LR
|
||||
A{{A}}-- apa -->B{{B}};
|
||||
click A callback "Tooltip"
|
||||
click B "http://www.github.com" "This is a link"
|
||||
|
||||
</div>
|
||||
<div class="mermaid2" style="width: 50%; height: 20%;">
|
||||
graph LR
|
||||
A{{A}}--apa-->B{{B}};
|
||||
|
||||
</div>
|
||||
<div class="mermaid2" style="width: 50%; height: 20%;">
|
||||
stateDiagram-v2
|
||||
[*]-->TV
|
||||
|
||||
state TV {
|
||||
state fork_state <<fork>>
|
||||
[*] --> fork_state
|
||||
fork_state --> State2
|
||||
fork_state --> State3
|
||||
|
||||
state join_state <<join>>
|
||||
State2 --> join_state
|
||||
State3 --> join_state
|
||||
join_state --> State4
|
||||
State4 --> [*]
|
||||
}
|
||||
</div>
|
||||
<div class="mermaid2" style="width: 100%; height: 100%;">
|
||||
stateDiagram-v2
|
||||
[*] --> Still
|
||||
Still --> [*]
|
||||
Still --> Moving
|
||||
Moving --> Still
|
||||
Moving --> Crash
|
||||
Crash --> [*]
|
||||
</div>
|
||||
<div class="mermaid2" style="width: 100%; height: 100%;">
|
||||
stateDiagram-v2
|
||||
[*] --> First
|
||||
First --> Third
|
||||
First --> sec
|
||||
|
||||
state First {
|
||||
[*] --> fir
|
||||
fir --> [*]
|
||||
}
|
||||
state Second {
|
||||
[*] --> sec
|
||||
sec --> [*]
|
||||
}
|
||||
state Third {
|
||||
[*] --> thi
|
||||
thi --> [*]
|
||||
}
|
||||
thi --> sec
|
||||
</div>
|
||||
<div class="mermaid2" style="width: 100%; height: 100%;">
|
||||
flowchart TD
|
||||
subgraph A
|
||||
a
|
||||
end
|
||||
subgraph B
|
||||
b
|
||||
end
|
||||
subgraph C
|
||||
subgraph D
|
||||
d
|
||||
end
|
||||
end
|
||||
A -- oAo --o B
|
||||
A --> C
|
||||
</div>
|
||||
<div class="mermaid2" style="width: 100%; height: 100%;">
|
||||
flowchart TD
|
||||
subgraph A
|
||||
a
|
||||
end
|
||||
subgraph B
|
||||
b
|
||||
end
|
||||
c-->A
|
||||
c-->B
|
||||
</div>
|
||||
<div class="mermaid2" style="width: 100%; height: 100%;">
|
||||
stateDiagram-v2
|
||||
[*] --> First
|
||||
First --> Second
|
||||
First --> Third
|
||||
|
||||
state First {
|
||||
[*] --> fir
|
||||
fir --> [*]
|
||||
}
|
||||
state Second {
|
||||
[*] --> sec
|
||||
sec --> [*]
|
||||
}
|
||||
state Third {
|
||||
[*] --> thi
|
||||
thi --> [*]
|
||||
}
|
||||
</div>
|
||||
<div class="mermaid2" style="width: 100%; height: 100%;">
|
||||
stateDiagram-v2
|
||||
[*]-->TV
|
||||
|
||||
state TV {
|
||||
[*] --> Off: Off to start with
|
||||
On --> Off : Turn off
|
||||
Off --> On : Turn on
|
||||
}
|
||||
|
||||
TV--> Console
|
||||
|
||||
state Console {
|
||||
[*] --> Off2: Off to start with
|
||||
On2--> Off2 : Turn off
|
||||
Off2 --> On2 : Turn on
|
||||
On2-->Playing
|
||||
|
||||
state Playing {
|
||||
Alive --> Dead
|
||||
Dead-->Alive
|
||||
}
|
||||
}
|
||||
<div class="mermaid" style="width: 50%; height: 20%;">
|
||||
flowchart TB
|
||||
subgraph 1
|
||||
A --> B;
|
||||
A -.-> C;
|
||||
A ==> D;
|
||||
A ==> E;
|
||||
B <--> F
|
||||
C <--> F
|
||||
D <--> F
|
||||
E <--> F
|
||||
end
|
||||
subgraph 2
|
||||
A2 --x B2;
|
||||
A2 -.-x C2;
|
||||
A2 ==x D2;
|
||||
A2 ==x E2;
|
||||
B2 x--x F2
|
||||
C2 x--x F2
|
||||
D2 x--x F2
|
||||
E2 x--x F2
|
||||
end
|
||||
subgraph 3
|
||||
A3 --o B3;
|
||||
A3 -.-o C3;
|
||||
A3 ==o D3;
|
||||
A3 ==o E3;
|
||||
B3 o--o F3
|
||||
C3 o--o F3
|
||||
D3 o--o F3
|
||||
E3 o--o F3
|
||||
end
|
||||
</div>
|
||||
|
||||
<div style="display: flex;flex-direction:column;width: 100%; height: 100%">
|
||||
<div class="mermaid2" style="width: 100%; height: 100%;">
|
||||
stateDiagram-v2
|
||||
state apa {
|
||||
[*] --> Still
|
||||
Still --> [*]
|
||||
|
||||
Still --> Moving
|
||||
Moving --> Still
|
||||
Moving --> Crash
|
||||
Crash --> [*]
|
||||
}
|
||||
|
||||
</div>
|
||||
<div class="mermaid2" style="width: 100%; height: 100%">
|
||||
flowchart TB
|
||||
a --> b
|
||||
|
||||
subgraph id1 [Test]
|
||||
a --apa--> c
|
||||
b
|
||||
c-->b
|
||||
b-->H
|
||||
end
|
||||
G-->H
|
||||
G-->id1
|
||||
id1 --> I
|
||||
I --> G
|
||||
</div>
|
||||
<div class="mermaid2" style="width: 100%; height: 100%">
|
||||
flowchart RL
|
||||
a --> b
|
||||
|
||||
subgraph id1 [Test]
|
||||
a --apa--> c
|
||||
b
|
||||
c-->b
|
||||
b-->H
|
||||
end
|
||||
G-->H
|
||||
G-->id1
|
||||
id1 --> I
|
||||
I --> G
|
||||
</div>
|
||||
<div class="mermaid2" style="width: 100%; height: 100%">
|
||||
flowchart RL
|
||||
|
||||
subgraph id1 [Test]
|
||||
a
|
||||
end
|
||||
b-->id1
|
||||
</div>
|
||||
<div class="mermaid2" style="width: 100%; height: 100%">
|
||||
flowchart RL
|
||||
|
||||
subgraph id1 [Test1]
|
||||
a
|
||||
end
|
||||
subgraph id2 [Test2]
|
||||
b
|
||||
end
|
||||
a --> id2
|
||||
a --> b
|
||||
b-->id1
|
||||
id1 --> id2
|
||||
</div>
|
||||
new:
|
||||
<div class="mermaid2" style="width: 100%; height: 100%">
|
||||
flowchart LR
|
||||
a <--> b
|
||||
b o--o c
|
||||
c x--x d
|
||||
a21([In the box]) --> b2
|
||||
b2((b2)) --o c2
|
||||
c2(c2) --x d2 --> id1{{This is the text in the box}} --> A[(cylindrical<br />shape<br />test)]
|
||||
</div>
|
||||
old:
|
||||
<div class="mermaid2" style="width: 100%; height: 100%">
|
||||
graph LR
|
||||
a((a)) --> b --> id1{{This is the text in the box}}
|
||||
A[(cylindrical<br />shape<br />test)]
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
mermaid.parseError = function (err, hash) {
|
||||
|
1157
dist/mermaid.core.js
vendored
1157
dist/mermaid.core.js
vendored
File diff suppressed because one or more lines are too long
2
dist/mermaid.core.js.map
vendored
2
dist/mermaid.core.js.map
vendored
File diff suppressed because one or more lines are too long
1436
dist/mermaid.js
vendored
1436
dist/mermaid.js
vendored
File diff suppressed because one or more lines are too long
2
dist/mermaid.js.map
vendored
2
dist/mermaid.js.map
vendored
File diff suppressed because one or more lines are too long
@ -33,7 +33,7 @@ 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 resposibility for the diagram source security you can set the securityLevel accordingly. By doing this clicks and tags are again allowed.
|
||||
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({
|
||||
|
@ -3,15 +3,15 @@
|
||||
> A Gantt chart is a type of bar chart, first developed by Karol Adamiecki in 1896, and independently by Henry Gantt in the 1910s, that illustrates a project schedule and the amount of time it would take for any one project to finish. Gantt charts illustrate number of days between the start and finish dates of the terminal elements and summary elements of a project.
|
||||
|
||||
## A note to users
|
||||
Gannt Charts will record each scheduled task as one continuous bar that extends from the left to the right. The x axis represents time and the y records the different tasks and the order in which they are to be completed.
|
||||
Gantt Charts will record each scheduled task as one continuous bar that extends from the left to the right. The x axis represents time and the y records the different tasks and the order in which they are to be completed.
|
||||
|
||||
It is important to remember that when a date, day or collection of dates specific to a task are "excluded", the Gannt Chart will accomodate those changes by extending an equal number of day, towards the right, not by creating a gap inside the task.
|
||||
As shown here ![](https://github.com/NeilCuzon/mermaid/blob/develop/docs/img/Gantt-excluded-days-within.png)
|
||||
It is important to remember that when a date, day, or collection of dates specific to a task are "excluded", the Gantt Chart will accomodate those changes by extending an equal number of day, towards the right, not by creating a gap inside the task.
|
||||
As shown here ![](https://raw.githubusercontent.com/NeilCuzon/mermaid/develop/docs/img/Gantt-excluded-days-within.png)
|
||||
|
||||
However, if the excluded date/s is between two tasks that are set to start consecutively, the excluded dates will be skipped graphically and left blank, and the following task will begin after the end of the excluded date/s.
|
||||
As shown here ![](https://github.com/NeilCuzon/mermaid/blob/develop/docs/img/Gantt-long-weekend-look.png)
|
||||
However, if the excluded dates are between two tasks that are set to start consecutively, the excluded dates will be skipped graphically and left blank, and the following task will begin after the end of the excluded dates.
|
||||
As shown here ![](https://raw.githubusercontent.com/NeilCuzon/mermaid/develop/docs/img/Gantt-long-weekend-look.png)
|
||||
|
||||
A Gantt chart is useful for tracking the amount of time it would take before a project is finished, but it can also be used to graphically represent "non-working days, with a few tweaks.
|
||||
A Gantt chart is useful for tracking the amount of time it would take before a project is finished, but it can also be used to graphically represent "non-working days", with a few tweaks.
|
||||
|
||||
Mermaid can render Gantt diagrams as SVG, PNG or a MarkDown link that can be pasted into docs.
|
||||
|
||||
@ -117,12 +117,14 @@ It is possible to set multiple depenendenies separated by space:
|
||||
|
||||
### Title
|
||||
|
||||
Tbd
|
||||
The `title` is an *optional* string to be displayed at the top of the Gantt chart to describe the chart as a whole.
|
||||
|
||||
|
||||
## Sections statements
|
||||
### Section statements
|
||||
|
||||
Tbd
|
||||
You can divide the chart into various sections, for example to separate different parts of a project like development and documentation.
|
||||
|
||||
To do so, start a line with the `section` keyword and give it a name. (Note that unlike with the [title for the entire chart](#title), this name is *required*.
|
||||
|
||||
|
||||
## Setting dates
|
||||
@ -293,6 +295,19 @@ noteText | Styles for the text on in the note boxes.
|
||||
}
|
||||
```
|
||||
|
||||
## Today marker
|
||||
|
||||
You can style or hide the marker for the current date. To style it, add a value for the `todayMarker` key.
|
||||
|
||||
```
|
||||
todayMarker stroke-width:5px,stroke:#0f0,opacity:0.5
|
||||
```
|
||||
|
||||
To hide the marker, set `todayMarker` to `off`.
|
||||
|
||||
```
|
||||
todayMarker off
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
|
@ -112,6 +112,8 @@ Required edgeData for proper rendering:
|
||||
| label | overlap between label and labelText? |
|
||||
| labelPos | |
|
||||
| labelType | overlap between label and labelText? |
|
||||
| thickness | Sets the thinkess of the edge. Can be ['normal', 'thick'] |
|
||||
| pattern | Sets the pattern of the edge. Can be ['solid', 'dotted', 'dashed'] |
|
||||
|
||||
|
||||
# Markers
|
||||
|
@ -191,11 +191,35 @@ export const insertEdge = function(elem, e, edge, clusterDb, diagramType, graph)
|
||||
})
|
||||
.curve(curveBasis);
|
||||
|
||||
// Contruct stroke classes based on properties
|
||||
let strokeClasses;
|
||||
switch (edge.thickness) {
|
||||
case 'normal':
|
||||
strokeClasses = 'edge-thickness-normal';
|
||||
break;
|
||||
case 'thick':
|
||||
strokeClasses = 'edge-thickness-thick';
|
||||
break;
|
||||
default:
|
||||
strokeClasses = '';
|
||||
}
|
||||
switch (edge.pattern) {
|
||||
case 'solid':
|
||||
strokeClasses += ' edge-pattern-solid';
|
||||
break;
|
||||
case 'dotted':
|
||||
strokeClasses += ' edge-pattern-dotted';
|
||||
break;
|
||||
case 'dashed':
|
||||
strokeClasses += ' edge-pattern-dashed';
|
||||
break;
|
||||
}
|
||||
|
||||
const svgPath = elem
|
||||
.append('path')
|
||||
.attr('d', lineFunction(lineData))
|
||||
.attr('id', edge.id)
|
||||
.attr('class', 'transition' + (edge.classes ? ' ' + edge.classes : ''));
|
||||
.attr('class', ' ' + strokeClasses + (edge.classes ? ' ' + edge.classes : ''));
|
||||
|
||||
// DEBUG code, adds a red circle at each edge coordinate
|
||||
// edge.points.forEach(point => {
|
||||
|
@ -17,7 +17,7 @@ const extension = (elem, type, id) => {
|
||||
.append('defs')
|
||||
.append('marker')
|
||||
.attr('id', type + '-extensionStart')
|
||||
.attr('class', 'extension ' + type)
|
||||
.attr('class', 'marker extension ' + type)
|
||||
.attr('refX', 0)
|
||||
.attr('refY', 7)
|
||||
.attr('markerWidth', 190)
|
||||
@ -30,7 +30,7 @@ const extension = (elem, type, id) => {
|
||||
.append('defs')
|
||||
.append('marker')
|
||||
.attr('id', type + '-extensionEnd ' + type)
|
||||
.attr('class', 'extension ' + type)
|
||||
.attr('class', 'marker extension ' + type)
|
||||
.attr('refX', 19)
|
||||
.attr('refY', 7)
|
||||
.attr('markerWidth', 20)
|
||||
@ -45,7 +45,7 @@ const composition = (elem, type) => {
|
||||
.append('defs')
|
||||
.append('marker')
|
||||
.attr('id', type + '-compositionStart')
|
||||
.attr('class', 'extension ' + type)
|
||||
.attr('class', 'marker extension ' + type)
|
||||
.attr('refX', 0)
|
||||
.attr('refY', 7)
|
||||
.attr('markerWidth', 190)
|
||||
@ -58,7 +58,7 @@ const composition = (elem, type) => {
|
||||
.append('defs')
|
||||
.append('marker')
|
||||
.attr('id', type + '-compositionEnd')
|
||||
.attr('class', 'extension ' + type)
|
||||
.attr('class', 'marker extension ' + type)
|
||||
.attr('refX', 19)
|
||||
.attr('refY', 7)
|
||||
.attr('markerWidth', 20)
|
||||
@ -72,7 +72,7 @@ const aggregation = (elem, type) => {
|
||||
.append('defs')
|
||||
.append('marker')
|
||||
.attr('id', type + '-aggregationStart')
|
||||
.attr('class', 'extension ' + type)
|
||||
.attr('class', 'marker extension ' + type)
|
||||
.attr('refX', 0)
|
||||
.attr('refY', 7)
|
||||
.attr('markerWidth', 190)
|
||||
@ -85,7 +85,7 @@ const aggregation = (elem, type) => {
|
||||
.append('defs')
|
||||
.append('marker')
|
||||
.attr('id', type + '-aggregationEnd')
|
||||
.attr('class', type)
|
||||
.attr('class', 'marker ' + type)
|
||||
.attr('refX', 19)
|
||||
.attr('refY', 7)
|
||||
.attr('markerWidth', 20)
|
||||
@ -99,7 +99,7 @@ const dependency = (elem, type) => {
|
||||
.append('defs')
|
||||
.append('marker')
|
||||
.attr('id', type + '-dependencyStart')
|
||||
.attr('class', 'extension ' + type)
|
||||
.attr('class', 'marker extension ' + type)
|
||||
.attr('refX', 0)
|
||||
.attr('refY', 7)
|
||||
.attr('markerWidth', 190)
|
||||
@ -112,7 +112,7 @@ const dependency = (elem, type) => {
|
||||
.append('defs')
|
||||
.append('marker')
|
||||
.attr('id', type + '-dependencyEnd')
|
||||
.attr('class', type)
|
||||
.attr('class', 'marker ' + type)
|
||||
.attr('refX', 19)
|
||||
.attr('refY', 7)
|
||||
.attr('markerWidth', 20)
|
||||
@ -125,13 +125,13 @@ const point = (elem, type) => {
|
||||
elem
|
||||
.append('marker')
|
||||
.attr('id', type + '-pointEnd')
|
||||
.attr('class', type)
|
||||
.attr('class', 'marker ' + type)
|
||||
.attr('viewBox', '0 0 10 10')
|
||||
.attr('refX', 10)
|
||||
.attr('refX', 9)
|
||||
.attr('refY', 5)
|
||||
.attr('markerUnits', 'strokeWidth')
|
||||
.attr('markerWidth', 8)
|
||||
.attr('markerHeight', 8)
|
||||
.attr('markerUnits', 'userSpaceOnUse')
|
||||
.attr('markerWidth', 12)
|
||||
.attr('markerHeight', 12)
|
||||
.attr('orient', 'auto')
|
||||
.append('path')
|
||||
.attr('d', 'M 0 0 L 10 5 L 0 10 z')
|
||||
@ -141,13 +141,13 @@ const point = (elem, type) => {
|
||||
elem
|
||||
.append('marker')
|
||||
.attr('id', type + '-pointStart')
|
||||
.attr('class', type)
|
||||
.attr('class', 'marker ' + type)
|
||||
.attr('viewBox', '0 0 10 10')
|
||||
.attr('refX', 0)
|
||||
.attr('refY', 5)
|
||||
.attr('markerUnits', 'strokeWidth')
|
||||
.attr('markerWidth', 8)
|
||||
.attr('markerHeight', 8)
|
||||
.attr('markerUnits', 'userSpaceOnUse')
|
||||
.attr('markerWidth', 12)
|
||||
.attr('markerHeight', 12)
|
||||
.attr('orient', 'auto')
|
||||
.append('path')
|
||||
.attr('d', 'M 0 5 L 10 10 L 10 0 z')
|
||||
@ -159,13 +159,13 @@ const circle = (elem, type) => {
|
||||
elem
|
||||
.append('marker')
|
||||
.attr('id', type + '-circleEnd')
|
||||
.attr('class', type)
|
||||
.attr('class', 'marker ' + type)
|
||||
.attr('viewBox', '0 0 10 10')
|
||||
.attr('refX', 11)
|
||||
.attr('refY', 5)
|
||||
.attr('markerUnits', 'strokeWidth')
|
||||
.attr('markerWidth', 7)
|
||||
.attr('markerHeight', 7)
|
||||
.attr('markerUnits', 'userSpaceOnUse')
|
||||
.attr('markerWidth', 11)
|
||||
.attr('markerHeight', 11)
|
||||
.attr('orient', 'auto')
|
||||
.append('circle')
|
||||
.attr('cx', '5')
|
||||
@ -178,13 +178,13 @@ const circle = (elem, type) => {
|
||||
elem
|
||||
.append('marker')
|
||||
.attr('id', type + '-circleStart')
|
||||
.attr('class', type)
|
||||
.attr('class', 'marker ' + type)
|
||||
.attr('viewBox', '0 0 10 10')
|
||||
.attr('refX', -1)
|
||||
.attr('refY', 5)
|
||||
.attr('markerUnits', 'strokeWidth')
|
||||
.attr('markerWidth', 7)
|
||||
.attr('markerHeight', 7)
|
||||
.attr('markerUnits', 'userSpaceOnUse')
|
||||
.attr('markerWidth', 11)
|
||||
.attr('markerHeight', 11)
|
||||
.attr('orient', 'auto')
|
||||
.append('circle')
|
||||
.attr('cx', '5')
|
||||
@ -198,16 +198,16 @@ const cross = (elem, type) => {
|
||||
elem
|
||||
.append('marker')
|
||||
.attr('id', type + '-crossEnd')
|
||||
.attr('class', type)
|
||||
.attr('class', 'marker cross ' + type)
|
||||
.attr('viewBox', '0 0 11 11')
|
||||
.attr('refX', 12)
|
||||
.attr('refY', 5.2)
|
||||
.attr('markerUnits', 'strokeWidth')
|
||||
.attr('markerWidth', 7)
|
||||
.attr('markerHeight', 7)
|
||||
.attr('markerUnits', 'userSpaceOnUse')
|
||||
.attr('markerWidth', 11)
|
||||
.attr('markerHeight', 11)
|
||||
.attr('orient', 'auto')
|
||||
.append('path')
|
||||
.attr('stroke', 'black')
|
||||
// .attr('stroke', 'black')
|
||||
.attr('d', 'M 1,1 l 9,9 M 10,1 l -9,9')
|
||||
.attr('class', 'arrowMarkerPath')
|
||||
.style('stroke-width', 2)
|
||||
@ -216,16 +216,16 @@ const cross = (elem, type) => {
|
||||
elem
|
||||
.append('marker')
|
||||
.attr('id', type + '-crossStart')
|
||||
.attr('class', type)
|
||||
.attr('class', 'marker cross ' + type)
|
||||
.attr('viewBox', '0 0 11 11')
|
||||
.attr('refX', -1)
|
||||
.attr('refY', 5.2)
|
||||
.attr('markerUnits', 'strokeWidth')
|
||||
.attr('markerWidth', 7)
|
||||
.attr('markerHeight', 7)
|
||||
.attr('markerUnits', 'userSpaceOnUse')
|
||||
.attr('markerWidth', 11)
|
||||
.attr('markerHeight', 11)
|
||||
.attr('orient', 'auto')
|
||||
.append('path')
|
||||
.attr('stroke', 'black')
|
||||
// .attr('stroke', 'black')
|
||||
.attr('d', 'M 1,1 l 9,9 M 10,1 l -9,9')
|
||||
.attr('class', 'arrowMarkerPath')
|
||||
.style('stroke-width', 2)
|
||||
|
@ -217,7 +217,7 @@ const setClickFunc = function(domId, functionName, tooltip) {
|
||||
elem.addEventListener(
|
||||
'click',
|
||||
function() {
|
||||
window[functionName](elemId);
|
||||
utils.runFunc(functionName, elemId);
|
||||
},
|
||||
false
|
||||
);
|
||||
@ -272,8 +272,8 @@ const setupToolTips = function(element) {
|
||||
.style('opacity', '.9');
|
||||
tooltipElem
|
||||
.html(el.attr('title'))
|
||||
.style('left', rect.left + (rect.right - rect.left) / 2 + 'px')
|
||||
.style('top', rect.top - 14 + document.body.scrollTop + 'px');
|
||||
.style('left', window.scrollX + rect.left + (rect.right - rect.left) / 2 + 'px')
|
||||
.style('top', window.scrollY + rect.top - 14 + document.body.scrollTop + 'px');
|
||||
el.classed('hover', true);
|
||||
})
|
||||
.on('mouseout', function() {
|
||||
|
@ -10,15 +10,15 @@
|
||||
|
||||
%%
|
||||
\%\%[^\n]*\n* /* do nothing */
|
||||
\n+ return 'NEWLINE';
|
||||
\n+ return 'NEWLINE';
|
||||
\s+ /* skip whitespace */
|
||||
"classDiagram" return 'CLASS_DIAGRAM';
|
||||
[\{] { this.begin("struct"); /*console.log('Starting struct');*/return 'STRUCT_START';}
|
||||
<struct><<EOF>> return "EOF_IN_STRUCT";
|
||||
<struct>[\{] return "OPEN_IN_STRUCT";
|
||||
<struct>\} { /*console.log('Ending struct');*/this.popState(); return 'STRUCT_STOP';}}
|
||||
<struct>\} { /*console.log('Ending struct');*/this.popState(); return 'STRUCT_STOP';}}
|
||||
<struct>[\n] /* nothing */
|
||||
<struct>[^\{\}\n]* { /*console.log('lex-member: ' + yytext);*/ return "MEMBER";}
|
||||
<struct>[^\{\}\n]* { /*console.log('lex-member: ' + yytext);*/ return "MEMBER";}
|
||||
|
||||
|
||||
|
||||
@ -40,7 +40,7 @@
|
||||
\s*\|\> return 'EXTENSION';
|
||||
\s*\> return 'DEPENDENCY';
|
||||
\s*\< return 'DEPENDENCY';
|
||||
\s*\* return 'COMPOSITION';
|
||||
\s*\* return 'COMPOSITION';
|
||||
\s*o return 'AGGREGATION';
|
||||
\-\- return 'LINE';
|
||||
\.\. return 'DOTTED_LINE';
|
||||
@ -53,7 +53,7 @@
|
||||
\= return 'EQUALS';
|
||||
\w+ return 'ALPHA';
|
||||
[!"#$%&'*+,-.`?\\/] return 'PUNCTUATION';
|
||||
[0-9]+ return 'NUM';
|
||||
[0-9]+ return 'NUM';
|
||||
[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|
|
||||
[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|
|
||||
[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|
|
||||
|
@ -278,13 +278,13 @@ export const drawClass = function(elem, classDef, conf) {
|
||||
};
|
||||
|
||||
export const parseMember = function(text) {
|
||||
const fieldRegEx = /^(\+|-|~|#)?(\w+)(~\w+~|\[\])?\s+(\w+)$/;
|
||||
const methodRegEx = /^(\+|-|~|#)?(\w+)\s?\(\s*(\w+(~\w+~|\[\])?\s*(\w+)?)?\s*\)\s?([*|$])?\s?(\w+(~\w+~|\[\])?)?\s*$/;
|
||||
const fieldRegEx = /(\+|-|~|#)?(\w+)(~\w+~|\[\])?\s+(\w+)/;
|
||||
const methodRegEx = /^([+|\-|~|#])?(\w+) *\( *(.*)\) *(\*|\$)? *(\w*[~|[\]]*\s*\w*~?)$/;
|
||||
|
||||
let fieldMatch = text.match(fieldRegEx);
|
||||
let methodMatch = text.match(methodRegEx);
|
||||
|
||||
if (fieldMatch) {
|
||||
if (fieldMatch && !methodMatch) {
|
||||
return buildFieldDisplay(fieldMatch);
|
||||
} else if (methodMatch) {
|
||||
return buildMethodDisplay(methodMatch);
|
||||
@ -294,56 +294,78 @@ export const parseMember = function(text) {
|
||||
};
|
||||
|
||||
const buildFieldDisplay = function(parsedText) {
|
||||
let visibility = parsedText[1] ? parsedText[1].trim() : '';
|
||||
let fieldType = parsedText[2] ? parsedText[2].trim() : '';
|
||||
let genericType = parsedText[3] ? parseGenericTypes(parsedText[3]) : '';
|
||||
let fieldName = parsedText[4] ? parsedText[4].trim() : '';
|
||||
let displayText = '';
|
||||
|
||||
try {
|
||||
let visibility = parsedText[1] ? parsedText[1].trim() : '';
|
||||
let fieldType = parsedText[2] ? parsedText[2].trim() : '';
|
||||
let genericType = parsedText[3] ? parseGenericTypes(parsedText[3].trim()) : '';
|
||||
let fieldName = parsedText[4] ? parsedText[4].trim() : '';
|
||||
|
||||
displayText = visibility + fieldType + genericType + ' ' + fieldName;
|
||||
} catch (err) {
|
||||
displayText = parsedText;
|
||||
}
|
||||
|
||||
return {
|
||||
displayText: visibility + fieldType + genericType + ' ' + fieldName,
|
||||
displayText: displayText,
|
||||
cssStyle: ''
|
||||
};
|
||||
};
|
||||
|
||||
const buildMethodDisplay = function(parsedText) {
|
||||
let cssStyle = '';
|
||||
let displayText = parsedText;
|
||||
let displayText = '';
|
||||
|
||||
let visibility = parsedText[1] ? parsedText[1].trim() : '';
|
||||
let methodName = parsedText[2] ? parsedText[2].trim() : '';
|
||||
let parameters = parsedText[3] ? parseGenericTypes(parsedText[3]) : '';
|
||||
let classifier = parsedText[6] ? parsedText[6].trim() : '';
|
||||
let returnType = parsedText[7] ? ' : ' + parseGenericTypes(parsedText[7]).trim() : '';
|
||||
try {
|
||||
let visibility = parsedText[1] ? parsedText[1].trim() : '';
|
||||
let methodName = parsedText[2] ? parsedText[2].trim() : '';
|
||||
let parameters = parsedText[3] ? parseGenericTypes(parsedText[3].trim()) : '';
|
||||
let classifier = parsedText[4] ? parsedText[4].trim() : '';
|
||||
let returnType = parsedText[5] ? ' : ' + parseGenericTypes(parsedText[5]).trim() : '';
|
||||
|
||||
displayText = visibility + methodName + '(' + parameters + ')' + returnType;
|
||||
displayText = visibility + methodName + '(' + parameters + ')' + returnType;
|
||||
|
||||
cssStyle = parseClassifier(classifier);
|
||||
cssStyle = parseClassifier(classifier);
|
||||
} catch (err) {
|
||||
displayText = parsedText;
|
||||
}
|
||||
|
||||
let member = {
|
||||
return {
|
||||
displayText: displayText,
|
||||
cssStyle: cssStyle
|
||||
};
|
||||
|
||||
return member;
|
||||
};
|
||||
|
||||
const buildLegacyDisplay = function(text) {
|
||||
// if for some reason we dont have any match, use old format to parse text
|
||||
let memberText = '';
|
||||
let displayText = '';
|
||||
let cssStyle = '';
|
||||
let memberText = '';
|
||||
let returnType = '';
|
||||
let methodStart = text.indexOf('(');
|
||||
let methodEnd = text.indexOf(')');
|
||||
|
||||
if (methodStart > 1 && methodEnd > methodStart && methodEnd <= text.length) {
|
||||
let parsedText = text.match(/(\+|-|~|#)?(\w+)/);
|
||||
let visibility = parsedText[1] ? parsedText[1].trim() : '';
|
||||
let methodName = parsedText[2];
|
||||
let visibility = '';
|
||||
let methodName = '';
|
||||
|
||||
let firstChar = text.substring(0, 1);
|
||||
if (firstChar.match(/\w/)) {
|
||||
methodName = text.substring(0, methodStart).trim();
|
||||
} else {
|
||||
if (firstChar.match(/\+|-|~|#/)) {
|
||||
visibility = firstChar;
|
||||
}
|
||||
|
||||
methodName = text.substring(1, methodStart).trim();
|
||||
}
|
||||
|
||||
let parameters = text.substring(methodStart + 1, methodEnd);
|
||||
let classifier = text.substring(methodEnd, methodEnd + 1);
|
||||
let classifier = text.substring(methodEnd + 1, 1);
|
||||
cssStyle = parseClassifier(classifier);
|
||||
|
||||
memberText = visibility + methodName + '(' + parseGenericTypes(parameters.trim()) + ')';
|
||||
displayText = visibility + methodName + '(' + parseGenericTypes(parameters.trim()) + ')';
|
||||
|
||||
if (methodEnd < memberText.length) {
|
||||
returnType = text.substring(methodEnd + 2).trim();
|
||||
@ -353,15 +375,13 @@ const buildLegacyDisplay = function(text) {
|
||||
}
|
||||
} else {
|
||||
// finally - if all else fails, just send the text back as written (other than parsing for generic types)
|
||||
memberText = parseGenericTypes(text);
|
||||
displayText = parseGenericTypes(text);
|
||||
}
|
||||
|
||||
let member = {
|
||||
displayText: memberText + returnType,
|
||||
return {
|
||||
displayText: displayText,
|
||||
cssStyle: cssStyle
|
||||
};
|
||||
|
||||
return member;
|
||||
};
|
||||
|
||||
const addTspan = function(textEl, txt, isFirst, conf) {
|
||||
|
@ -83,6 +83,14 @@ describe('class member Renderer, ', function () {
|
||||
expect(actual.cssStyle).toBe('');
|
||||
});
|
||||
|
||||
it('should handle simple method declaration with multiple parameters', function () {
|
||||
const str = 'foo(int id, object thing)';
|
||||
let actual = svgDraw.parseMember(str);
|
||||
|
||||
expect(actual.displayText).toBe('foo(int id, object thing)');
|
||||
expect(actual.cssStyle).toBe('');
|
||||
});
|
||||
|
||||
it('should handle simple method declaration with single item in parameters', function () {
|
||||
const str = 'foo(id)';
|
||||
let actual = svgDraw.parseMember(str);
|
||||
|
@ -232,7 +232,7 @@ const setClickFun = function(_id, functionName) {
|
||||
elem.addEventListener(
|
||||
'click',
|
||||
function() {
|
||||
window[functionName](id);
|
||||
utils.runFunc(functionName, id);
|
||||
},
|
||||
false
|
||||
);
|
||||
@ -324,6 +324,7 @@ const setupToolTips = function(element) {
|
||||
.on('mouseover', function() {
|
||||
const el = select(this);
|
||||
const title = el.attr('title');
|
||||
|
||||
// Dont try to draw a tooltip if no data is provided
|
||||
if (title === null) {
|
||||
return;
|
||||
@ -336,8 +337,8 @@ const setupToolTips = function(element) {
|
||||
.style('opacity', '.9');
|
||||
tooltipElem
|
||||
.html(el.attr('title'))
|
||||
.style('left', rect.left + (rect.right - rect.left) / 2 + 'px')
|
||||
.style('top', rect.top - 14 + document.body.scrollTop + 'px');
|
||||
.style('left', window.scrollX + rect.left + (rect.right - rect.left) / 2 + 'px')
|
||||
.style('top', window.scrollY + rect.top - 14 + document.body.scrollTop + 'px');
|
||||
el.classed('hover', true);
|
||||
})
|
||||
.on('mouseout', function() {
|
||||
|
@ -181,8 +181,15 @@ export const addEdges = function(edges, g) {
|
||||
|
||||
edges.forEach(function(edge) {
|
||||
cnt++;
|
||||
|
||||
// Identify Link
|
||||
var linkId = 'L-' + edge.start + '-' + edge.end;
|
||||
var linkNameStart = 'LS-' + edge.start;
|
||||
var linkNameEnd = 'LE-' + edge.end;
|
||||
|
||||
const edgeData = {};
|
||||
edgeData.id = 'id' + cnt;
|
||||
//edgeData.id = 'id' + cnt;
|
||||
|
||||
// Set link type for rendering
|
||||
if (edge.type === 'arrow_open') {
|
||||
edgeData.arrowhead = 'none';
|
||||
@ -210,12 +217,16 @@ export const addEdges = function(edges, g) {
|
||||
if (typeof defaultLabelStyle !== 'undefined') {
|
||||
labelStyle = defaultLabelStyle;
|
||||
}
|
||||
edgeData.thickness = 'normal';
|
||||
edgeData.pattern = 'solid';
|
||||
break;
|
||||
case 'dotted':
|
||||
style = 'fill:none;stroke-width:2px;stroke-dasharray:3;';
|
||||
edgeData.thickness = 'normal';
|
||||
edgeData.pattern = 'dotted';
|
||||
break;
|
||||
case 'thick':
|
||||
style = ' stroke-width: 3.5px;fill:none';
|
||||
edgeData.thickness = 'thick';
|
||||
edgeData.pattern = 'solid';
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -241,7 +252,7 @@ export const addEdges = function(edges, g) {
|
||||
|
||||
if (getConfig().flowchart.htmlLabels && false) { // eslint-disable-line
|
||||
edgeData.labelType = 'html';
|
||||
edgeData.label = '<span class="edgeLabel">' + edge.text + '</span>';
|
||||
edgeData.label = `<span id="L-${linkId}" class="edgeLabel L-${linkNameStart}' L-${linkNameEnd}">${edge.text}</span>`;
|
||||
} else {
|
||||
edgeData.labelType = 'text';
|
||||
edgeData.label = edge.text.replace(common.lineBreakRegex, '\n');
|
||||
@ -253,6 +264,10 @@ export const addEdges = function(edges, g) {
|
||||
edgeData.labelStyle = edgeData.labelStyle.replace('color:', 'fill:');
|
||||
}
|
||||
}
|
||||
|
||||
edgeData.id = linkId;
|
||||
edgeData.classes = 'flowchart-link ' + linkNameStart + ' ' + linkNameEnd;
|
||||
|
||||
// Add the edge to the graph
|
||||
g.setEdge(edge.start, edge.end, edgeData, cnt);
|
||||
});
|
||||
|
@ -166,6 +166,12 @@ export const addEdges = function(edges, g) {
|
||||
|
||||
edges.forEach(function(edge) {
|
||||
cnt++;
|
||||
|
||||
// Identify Link
|
||||
var linkId = 'L-' + edge.start + '-' + edge.end;
|
||||
var linkNameStart = 'LS-' + edge.start;
|
||||
var linkNameEnd = 'LE-' + edge.end;
|
||||
|
||||
const edgeData = {};
|
||||
|
||||
// Set link type for rendering
|
||||
@ -223,7 +229,7 @@ export const addEdges = function(edges, g) {
|
||||
|
||||
if (getConfig().flowchart.htmlLabels) {
|
||||
edgeData.labelType = 'html';
|
||||
edgeData.label = '<span class="edgeLabel">' + edge.text + '</span>';
|
||||
edgeData.label = `<span id="L-${linkId}" class="edgeLabel L-${linkNameStart}' L-${linkNameEnd}">${edge.text}</span>`;
|
||||
} else {
|
||||
edgeData.labelType = 'text';
|
||||
edgeData.label = edge.text.replace(common.lineBreakRegex, '\n');
|
||||
@ -235,6 +241,10 @@ export const addEdges = function(edges, g) {
|
||||
edgeData.labelStyle = edgeData.labelStyle.replace('color:', 'fill:');
|
||||
}
|
||||
}
|
||||
|
||||
edgeData.id = linkId;
|
||||
edgeData.class = linkNameStart + ' ' + linkNameEnd;
|
||||
|
||||
// Add the edge to the graph
|
||||
g.setEdge(edge.start, edge.end, edgeData, cnt);
|
||||
});
|
||||
|
@ -2,6 +2,7 @@ import moment from 'moment-mini';
|
||||
import { sanitizeUrl } from '@braintree/sanitize-url';
|
||||
import { logger } from '../../logger';
|
||||
import { getConfig } from '../../config';
|
||||
import utils from '../../utils';
|
||||
|
||||
const config = getConfig();
|
||||
let dateFormat = '';
|
||||
@ -520,7 +521,7 @@ const setClickFun = function(id, functionName, functionArgs) {
|
||||
let rawTask = findTaskById(id);
|
||||
if (typeof rawTask !== 'undefined') {
|
||||
pushFun(id, () => {
|
||||
window[functionName](...argList);
|
||||
utils.runFunc(functionName, ...argList);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -145,10 +145,11 @@ const setupNode = (g, parent, node, altFlag) => {
|
||||
arrowType: '',
|
||||
style: 'fill:none',
|
||||
labelStyle: '',
|
||||
classes: 'note-edge',
|
||||
classes: 'transition note-edge',
|
||||
arrowheadStyle: 'fill: #333',
|
||||
labelpos: 'c',
|
||||
labelType: 'text'
|
||||
labelType: 'text',
|
||||
thickness: 'normal'
|
||||
});
|
||||
} else {
|
||||
g.setNode(node.id, nodeData);
|
||||
@ -184,7 +185,9 @@ const setupDoc = (g, parent, doc, altFlag) => {
|
||||
label: item.description,
|
||||
arrowheadStyle: 'fill: #333',
|
||||
labelpos: 'c',
|
||||
labelType: 'text'
|
||||
labelType: 'text',
|
||||
thickness: 'normal',
|
||||
classes: 'transition'
|
||||
};
|
||||
let startId = item.state1.id;
|
||||
let endId = item.state2.id;
|
||||
|
@ -34,6 +34,11 @@
|
||||
stroke-width: 1.5px;
|
||||
}
|
||||
|
||||
.flowchart-link {
|
||||
stroke: $lineColor;
|
||||
fill: none;
|
||||
}
|
||||
|
||||
.edgeLabel {
|
||||
background-color: $edgeLabelBackground;
|
||||
rect {
|
||||
|
@ -12,10 +12,13 @@
|
||||
// }
|
||||
|
||||
:root {
|
||||
--mermaid-font-family: '"trebuchet ms", verdana, arial, "Comic Sans MS", "Comic Sans", cursive';
|
||||
--mermaid-font-family: '"trebuchet ms", verdana, arial';
|
||||
--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive;
|
||||
// --mermaid-alt-font-family: '"Lucida Console", Monaco, monospace';
|
||||
}
|
||||
|
||||
/* Classes common for multiple diagrams */
|
||||
|
||||
.error-icon {
|
||||
fill: $errorBkgColor;
|
||||
}
|
||||
@ -23,3 +26,29 @@
|
||||
fill: $errorTextColor;
|
||||
stroke: $errorTextColor;
|
||||
}
|
||||
|
||||
.edge-thickness-normal {
|
||||
// stroke: $lineColor;
|
||||
stroke-width: 2px;
|
||||
}
|
||||
.edge-thickness-thick {
|
||||
// stroke: $lineColor;
|
||||
stroke-width: 3.5px
|
||||
}
|
||||
.edge-pattern-solid {
|
||||
stroke-dasharray: 0;
|
||||
}
|
||||
|
||||
.edge-pattern-dashed{
|
||||
stroke-dasharray: 3;
|
||||
}
|
||||
.edge-pattern-dotted {
|
||||
stroke-dasharray: 2;
|
||||
}
|
||||
|
||||
.marker {
|
||||
fill: $lineColor;
|
||||
}
|
||||
.marker.cross {
|
||||
stroke: $lineColor;
|
||||
}
|
||||
|
18
src/utils.js
18
src/utils.js
@ -240,6 +240,21 @@ export const formatUrl = (linkStr, config) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const runFunc = (functionName, ...params) => {
|
||||
var arrPaths = functionName.split('.');
|
||||
|
||||
var len = arrPaths.length - 1;
|
||||
var fnName = arrPaths[len];
|
||||
|
||||
var obj = window;
|
||||
for (var i = 0; i < len; i++) {
|
||||
obj = obj[arrPaths[i]];
|
||||
if (!obj) return;
|
||||
}
|
||||
|
||||
obj[fnName](...params);
|
||||
};
|
||||
|
||||
const distance = (p1, p2) =>
|
||||
p1 && p2 ? Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2)) : 0;
|
||||
|
||||
@ -377,5 +392,6 @@ export default {
|
||||
calcCardinalityPosition,
|
||||
formatUrl,
|
||||
getStylesFromArray,
|
||||
generateId
|
||||
generateId,
|
||||
runFunc
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user