Merge pull request #13 from mermaid-js/develop

sync
This commit is contained in:
Justin Greywolf
2020-01-13 16:01:40 -08:00
committed by GitHub
7 changed files with 123 additions and 36 deletions

View File

@@ -274,4 +274,19 @@ describe('Class diagram', () => {
); );
cy.get('svg'); cy.get('svg');
}); });
it('11: should render a simple class diagram with return type on method', () => {
imgSnapshotTest(
`
classDiagram
class Class10~T~ {
int[] id
test(int[] ids) bool
testArray() bool[]
}
`,
{}
);
cy.get('svg');
});
}); });

View File

@@ -105,7 +105,7 @@ Naming convention: a class name should be composed of alphanumeric (unicode allo
UML provides mechanisms to represent class members, such as attributes and methods, and additional information about them. UML provides mechanisms to represent class members, such as attributes and methods, and additional information about them.
Mermaid distinguishes between attributes and functions/methods based on if the **parenthesis** `()` are present or not. The ones with `()` are treated as functions/methods, and others as attributes. Mermaid distinguishes between attributes and functions/methods based on if the **parenthesis** `()` are present or not. The ones with `()` are treated as functions/methods, and others as attributes. To indicate a return type for a method, enclose the type within **square brackets** `[]`
There are two ways to define the members of a class, and regardless of whichever syntax is used to define the members, the output will still be same. The two different ways are : There are two ways to define the members of a class, and regardless of whichever syntax is used to define the members, the output will still be same. The two different ways are :
@@ -115,24 +115,25 @@ There are two ways to define the members of a class, and regardless of whichever
class BankAccount class BankAccount
BankAccount : +String owner BankAccount : +String owner
BankAccount : +BigDecimal balance BankAccount : +BigDecimal balance
BankAccount : +deposit(amount) BankAccount : +deposit(amount) bool
BankAccount : +withdrawl(amount) BankAccount : +withdrawal(amount)
``` ```
``` mermaid ``` mermaid
classDiagram classDiagram
class BankAccount class BankAccount
BankAccount : +String owner BankAccount : +String owner
BankAccount : +BigDecimal balance BankAccount : +BigDecimal balance
BankAccount : +deposit(amount) BankAccount : +deposit(amount) : bool
BankAccount : +withdrawl(amount) BankAccount : +withdrawl(amount)
``` ```
- Associate members of a class using **{}** brackets, where members are grouped within curly brackets. Suitable for defining multiple members at once. For example: - 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{ class BankAccount{
+String owner +String owner
+BigDecimal balance +BigDecimal balance
+deposit(amount) +deposit(amount) bool
+withdrawl(amount) +withdrawl(amount)
} }
``` ```
@@ -141,12 +142,15 @@ class BankAccount{
class BankAccount{ class BankAccount{
+String owner +String owner
+BigDecimal balance +BigDecimal balance
+deposit(amount) +deposit(amount) : bool
+withdrawl(amount) +withdrawl(amount)
} }
``` ```
#### Return Type
Optionally you can end the method/function definition with the data type that will be returned
#### Visibility #### Visibility
To specify the visibility of a class member (i.e. any attribute or method), these notations may be placed before the member's name, but it is optional: To specify the visibility of a class member (i.e. any attribute or method), these notations may be placed before the member's name, but it is optional:

View File

@@ -7,7 +7,7 @@
<meta name="description" content="Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs."> <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"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/vue.css"> <link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/vue.css">
<script src="//cdn.jsdelivr.net/npm/mermaid@8.4.4/dist/mermaid.min.js"></script> <script src="//cdn.jsdelivr.net/npm/mermaid@8.4.5/dist/mermaid.min.js"></script>
<script> <script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),

View File

@@ -27,6 +27,7 @@ mermaid.initialize({
**Example 2:** **Example 2:**
<pre> <pre>
<script>
var config = { var config = {
startOnLoad:true, startOnLoad:true,
flowchart:{ flowchart:{
@@ -38,6 +39,8 @@ mermaid.initialize({
securityLevel:'loose', securityLevel:'loose',
}; };
mermaid.initialize(config); mermaid.initialize(config);
</script>
</pre> </pre>
A summary of all options and their defaults is found [here](https://github.com/knsv/mermaid/blob/master/docs/mermaidAPI.md#mermaidapi-configuration-defaults). A description of each option follows below. A summary of all options and their defaults is found [here](https://github.com/knsv/mermaid/blob/master/docs/mermaidAPI.md#mermaidapi-configuration-defaults). A description of each option follows below.

View File

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

View File

@@ -121,6 +121,36 @@ describe('class diagram, ', function () {
parser.parse(str); parser.parse(str);
}); });
it('should handle return types on methods', function () {
const str =
'classDiagram\n' +
'Object <|-- ArrayList\n' +
'Object : equals()\n' +
'Object : -Object[] objects\n' +
'Object : +getObjects() Object[]\n' +
'ArrayList : Dummy elementData\n' +
'ArrayList : getDummy() Dummy';
parser.parse(str);
});
it('should handle return types on methods grouped by brackets', function () {
const str =
'classDiagram\n' +
'class Dummy_Class {\n' +
'string data\n' +
'getDummy() Dummy\n' +
'}\n' +
'\n' +
'class Flight {\n' +
' int flightNumber\n' +
' datetime departureTime\n' +
' getDepartureTime() datetime\n' +
'}';
parser.parse(str);
});
it('should handle parsing of separators', function () { it('should handle parsing of separators', function () {
const str = const str =
'classDiagram\n' + 'classDiagram\n' +

View File

@@ -288,23 +288,14 @@ const drawClass = function(elem, classDef) {
} }
const addTspan = function(textEl, txt, isFirst) { const addTspan = function(textEl, txt, isFirst) {
let isMethod = txt.indexOf(')') > 1;
let displayText = txt; let displayText = txt;
let cssStyle = ''; let cssStyle = '';
let methodEnd = txt.indexOf(')') + 1;
if (methodEnd > 1 && methodEnd <= txt.length) { if (isMethod) {
let classifier = txt.substring(methodEnd); let method = buildDisplayTextForMethod(txt);
displayText = method.displayText;
switch (classifier) { cssStyle = method.cssStyle;
case '*':
cssStyle = 'font-style:italic;';
break;
case '$':
cssStyle = 'text-decoration:underline;';
break;
}
displayText = txt.substring(0, methodEnd);
} }
const tSpan = textEl const tSpan = textEl
@@ -321,6 +312,50 @@ const drawClass = function(elem, classDef) {
} }
}; };
const buildDisplayTextForMethod = function(txt) {
let regEx = /(\+|-|~|#)?(\w+)\s?\((\w+(<\w+>|\[\])?\s?(\w+)?)?\)\s?([*|$])?\s?(\w+(<\w+>|\[\])?)?/;
let cssStyle = '';
let displayText = txt;
let methodName = txt;
let classifier = '';
let parsedText = txt.match(regEx);
if (parsedText) {
let visibility = parsedText[1] ? parsedText[1].trim() : '';
methodName = parsedText[2] ? parsedText[2].trim() : '';
let parameters = parsedText[3] ? parsedText[3].trim() : '';
classifier = parsedText[6] ? parsedText[6].trim() : '';
let returnType = parsedText[7] ? ' : ' + parsedText[7].trim() : '';
displayText = visibility + methodName + '(' + parameters + ')' + returnType;
} else {
let methodEnd = displayText.indexOf(')') + 1;
classifier = displayText.substring(methodEnd, methodEnd + 1);
if (classifier !== '' && classifier !== ' ') {
displayText = displayText.replace(classifier, '');
}
}
switch (classifier) {
case '*':
cssStyle = 'font-style:italic;';
break;
case '$':
cssStyle = 'text-decoration:underline;';
break;
}
let method = {
methodname: methodName,
displayText: displayText,
cssStyle: cssStyle
};
return method;
};
const id = classDef.id; const id = classDef.id;
const classInfo = { const classInfo = {
id: id, id: id,