Skip to content

Commit cd3d560

Browse files
authored
Merge pull request #5372 from mermaid-js/sidv/updateNewDiagramDoc
Update new diagram doc to reflect focus on Langium
2 parents e6d80c6 + c0497d3 commit cd3d560

File tree

4 files changed

+458
-228
lines changed

4 files changed

+458
-228
lines changed

docs/community/new-diagram-jison.md

+222
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
> **Warning**
2+
>
3+
> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
4+
>
5+
> ## Please edit the corresponding file in [/packages/mermaid/src/docs/community/new-diagram-jison.md](../../packages/mermaid/src/docs/community/new-diagram-jison.md).
6+
7+
# Adding a New Diagram/Chart (Deprecated) 📊
8+
9+
> **Warning**
10+
> JISON grammars are deprecated in mermaid. Please use Langium instead. See [New Diagram](./new-diagram.md) for more information.
11+
>
12+
> **New diagrams with JISON grammars will not be accepted.**
13+
14+
### Step 1: Grammar & Parsing
15+
16+
#### Grammar
17+
18+
This would be to define a JISON grammar for the new diagram type. That should start with a way to identify that the text in the mermaid tag is a diagram of that type. Create a new folder under diagrams for your new diagram type and a parser folder in it. This leads us to step 2.
19+
20+
For instance:
21+
22+
- the flowchart starts with the keyword _graph_
23+
- the sequence diagram starts with the keyword _sequenceDiagram_
24+
25+
#### Store data found during parsing
26+
27+
There are some jison specific sub steps here where the parser stores the data encountered when parsing the diagram, this data is later used by the renderer. You can during the parsing call an object provided to the parser by the user of the parser. This object can be called during parsing for storing data.
28+
29+
```jison
30+
statement
31+
: 'participant' actor { $$='actor'; }
32+
| signal { $$='signal'; }
33+
| note_statement { $$='note'; }
34+
| 'title' message { yy.setTitle($2); }
35+
;
36+
```
37+
38+
In the extract of the grammar above, it is defined that a call to the setTitle method in the data object will be done when parsing and the title keyword is encountered.
39+
40+
> **Note**
41+
> Make sure that the `parseError` function for the parser is defined and calling `mermaid.parseError`. This way a common way of detecting parse errors is provided for the end-user.
42+
43+
For more info look at the example diagram type:
44+
45+
The `yy` object has the following function:
46+
47+
```javascript
48+
exports.parseError = function (err, hash) {
49+
mermaid.parseError(err, hash);
50+
};
51+
```
52+
53+
when parsing the `yy` object is initialized as per below:
54+
55+
```javascript
56+
const parser = exampleParser.parser;
57+
parser.yy = db;
58+
```
59+
60+
### Step 2: Rendering
61+
62+
Write a renderer that given the data found during parsing renders the diagram. To look at an example look at sequenceRenderer.js rather than the flowchart renderer as this is a more generic example.
63+
64+
Place the renderer in the diagram folder.
65+
66+
### Step 3: Detection of the new diagram type
67+
68+
The second thing to do is to add the capability to detect the new diagram to type to the detectType in `diagram-api/detectType.ts`. The detection should return a key for the new diagram type.
69+
[This key will be used to as the aria roledescription](#aria-roledescription), so it should be a word that clearly describes the diagram type.
70+
For example, if your new diagram uses a UML deployment diagram, a good key would be "UMLDeploymentDiagram" because assistive technologies such as a screen reader
71+
would voice that as "U-M-L Deployment diagram." Another good key would be "deploymentDiagram" because that would be voiced as "Deployment Diagram." A bad key would be "deployment" because that would not sufficiently describe the diagram.
72+
73+
Note that the diagram type key does not have to be the same as the diagram keyword chosen for the [grammar](#grammar), but it is helpful if they are the same.
74+
75+
### Step 4: The final piece - triggering the rendering
76+
77+
At this point when mermaid is trying to render the diagram, it will detect it as being of the new type but there will be no match when trying to render the diagram. To fix this add a new case in the switch statement in main.js:init this should match the diagram type returned from step #2. The code in this new case statement should call the renderer for the diagram type with the data found by the parser as an argument.
78+
79+
## Usage of the parser as a separate module
80+
81+
### Setup
82+
83+
```javascript
84+
const graph = require('./graphDb');
85+
const flow = require('./parser/flow');
86+
flow.parser.yy = graph;
87+
```
88+
89+
### Parsing
90+
91+
```javascript
92+
flow.parser.parse(text);
93+
```
94+
95+
### Data extraction
96+
97+
```javascript
98+
graph.getDirection();
99+
graph.getVertices();
100+
graph.getEdges();
101+
```
102+
103+
The parser is also exposed in the mermaid api by calling:
104+
105+
```javascript
106+
const parser = mermaid.getParser();
107+
```
108+
109+
Note that the parse needs a graph object to store the data as per:
110+
111+
```javascript
112+
flow.parser.yy = graph;
113+
```
114+
115+
Look at `graphDb.js` for more details on that object.
116+
117+
## Layout
118+
119+
If you are using a dagre based layout, please use flowchart-v2 as a template and by doing that you will be using dagre-wrapper instead of dagreD3 which we are migrating away from.
120+
121+
### Common parts of a diagram
122+
123+
There are a few features that are common between the different types of diagrams. We try to standardize the diagrams that work as similar as possible for the end user. The commonalities are:
124+
125+
- Directives, a way of modifying the diagram configuration from within the diagram code.
126+
- Accessibility, a way for an author to provide additional information like titles and descriptions to people accessing a text with diagrams using a screen reader.
127+
- Themes, there is a common way to modify the styling of diagrams in Mermaid.
128+
- Comments should follow mermaid standards
129+
130+
Here are some pointers on how to handle these different areas.
131+
132+
## Accessibility
133+
134+
Mermaid automatically adds the following accessibility information for the diagram SVG HTML element:
135+
136+
- aria-roledescription
137+
- accessible title
138+
- accessible description
139+
140+
### aria-roledescription
141+
142+
The aria-roledescription is automatically set to [the diagram type](#step-3--detection-of-the-new-diagram-type) and inserted into the SVG element.
143+
144+
See [the definition of aria-roledescription](https://www.w3.org/TR/wai-aria-1.1/#aria-roledescription) in [the Accessible Rich Internet Applications W3 standard.](https://www.w3.org/WAI/standards-guidelines/aria/)
145+
146+
### accessible title and description
147+
148+
The syntax for accessible titles and descriptions is described in [the Accessibility documentation section.](../config/accessibility.md)
149+
150+
As a design goal, the jison syntax should be similar between the diagrams.
151+
152+
```jison
153+
154+
* lexical grammar */
155+
%lex
156+
%x acc_title
157+
%x acc_descr
158+
%x acc_descr_multiline
159+
160+
%%
161+
accTitle\s*":"\s* { this.begin("acc_title");return 'acc_title'; }
162+
<acc_title>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_title_value"; }
163+
accDescr\s*":"\s* { this.begin("acc_descr");return 'acc_descr'; }
164+
<acc_descr>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_descr_value"; }
165+
accDescr\s*"{"\s* { this.begin("acc_descr_multiline");}
166+
<acc_descr_multiline>[\}] { this.popState(); }
167+
<acc_descr_multiline>[^\}]* return "acc_descr_multiline_value";
168+
169+
statement
170+
: acc_title acc_title_value { $$=$2.trim();yy.setTitle($$); }
171+
| acc_descr acc_descr_value { $$=$2.trim();yy.setAccDescription($$); }
172+
| acc_descr_multiline_value { $$=$1.trim();yy.setAccDescription($$); }
173+
174+
```
175+
176+
The functions for setting title and description are provided by a common module. This is the import from flowDb.js:
177+
178+
import {
179+
setAccTitle,
180+
getAccTitle,
181+
getAccDescription,
182+
setAccDescription,
183+
clear as commonClear,
184+
} from '../../commonDb';
185+
186+
The accessibility title and description are inserted into the SVG element in the `render` function in mermaidAPI.
187+
188+
## Theming
189+
190+
Mermaid supports themes and has an integrated theming engine. You can read more about how the themes can be used [in the docs](../config/theming.md).
191+
192+
When adding themes to a diagram it comes down to a few important locations in the code.
193+
194+
The entry point for the styling engine is in **src/styles.js**. The getStyles function will be called by Mermaid when the styles are being applied to the diagram.
195+
196+
This function will in turn call a function _your diagram should provide_ returning the css for the new diagram. The diagram specific, also which is commonly also called getStyles and located in the folder for your diagram under src/diagrams and should be named styles.js. The getStyles function will be called with the theme options as an argument like in the following example:
197+
198+
```js
199+
const getStyles = (options) =>
200+
`
201+
.line {
202+
stroke-width: 1;
203+
stroke: ${options.lineColor};
204+
stroke-dasharray: 2;
205+
}
206+
// ...
207+
`;
208+
```
209+
210+
Note that you need to provide your function to the main getStyles by adding it into the themes object in **src/styles.js** like in the xyzDiagram in the provided example:
211+
212+
```js
213+
const themes = {
214+
flowchart,
215+
'flowchart-v2': flowchart,
216+
sequence,
217+
xyzDiagram,
218+
//...
219+
};
220+
```
221+
222+
The actual options and values for the colors are defined in **src/theme/theme-\[xyz].js**. If you provide the options your diagram needs in the existing theme files then the theming will work smoothly without hiccups.

docs/community/new-diagram.md

+8-114
Original file line numberDiff line numberDiff line change
@@ -6,51 +6,17 @@
66
77
# Adding a New Diagram/Chart 📊
88

9-
### Step 1: Grammar & Parsing
10-
11-
#### Grammar
12-
13-
This would be to define a JISON grammar for the new diagram type. That should start with a way to identify that the text in the mermaid tag is a diagram of that type. Create a new folder under diagrams for your new diagram type and a parser folder in it. This leads us to step 2.
14-
15-
For instance:
16-
17-
- the flowchart starts with the keyword _graph_
18-
- the sequence diagram starts with the keyword _sequenceDiagram_
19-
20-
#### Store data found during parsing
9+
### Examples
2110

22-
There are some jison specific sub steps here where the parser stores the data encountered when parsing the diagram, this data is later used by the renderer. You can during the parsing call an object provided to the parser by the user of the parser. This object can be called during parsing for storing data.
11+
Please refer to the following PRs on how to use Langium to add a new diagram grammar.
2312

24-
```jison
25-
statement
26-
: 'participant' actor { $$='actor'; }
27-
| signal { $$='signal'; }
28-
| note_statement { $$='note'; }
29-
| 'title' message { yy.setTitle($2); }
30-
;
31-
```
32-
33-
In the extract of the grammar above, it is defined that a call to the setTitle method in the data object will be done when parsing and the title keyword is encountered.
34-
35-
> **Note**
36-
> Make sure that the `parseError` function for the parser is defined and calling `mermaid.parseError`. This way a common way of detecting parse errors is provided for the end-user.
13+
- <https://github.com/mermaid-js/mermaid/pull/4839>
14+
- <https://github.com/mermaid-js/mermaid/pull/4751>
3715

38-
For more info look at the example diagram type:
39-
40-
The `yy` object has the following function:
41-
42-
```javascript
43-
exports.parseError = function (err, hash) {
44-
mermaid.parseError(err, hash);
45-
};
46-
```
47-
48-
when parsing the `yy` object is initialized as per below:
16+
> **Warning**
17+
> The below steps are a work in progress and will be updated soon.
4918
50-
```javascript
51-
const parser = exampleParser.parser;
52-
parser.yy = db;
53-
```
19+
### Step 1: Grammar & Parsing
5420

5521
### Step 2: Rendering
5622

@@ -67,52 +33,6 @@ would voice that as "U-M-L Deployment diagram." Another good key would be "deplo
6733

6834
Note that the diagram type key does not have to be the same as the diagram keyword chosen for the [grammar](#grammar), but it is helpful if they are the same.
6935

70-
### Step 4: The final piece - triggering the rendering
71-
72-
At this point when mermaid is trying to render the diagram, it will detect it as being of the new type but there will be no match when trying to render the diagram. To fix this add a new case in the switch statement in main.js:init this should match the diagram type returned from step #2. The code in this new case statement should call the renderer for the diagram type with the data found by the parser as an argument.
73-
74-
## Usage of the parser as a separate module
75-
76-
### Setup
77-
78-
```javascript
79-
const graph = require('./graphDb');
80-
const flow = require('./parser/flow');
81-
flow.parser.yy = graph;
82-
```
83-
84-
### Parsing
85-
86-
```javascript
87-
flow.parser.parse(text);
88-
```
89-
90-
### Data extraction
91-
92-
```javascript
93-
graph.getDirection();
94-
graph.getVertices();
95-
graph.getEdges();
96-
```
97-
98-
The parser is also exposed in the mermaid api by calling:
99-
100-
```javascript
101-
const parser = mermaid.getParser();
102-
```
103-
104-
Note that the parse needs a graph object to store the data as per:
105-
106-
```javascript
107-
flow.parser.yy = graph;
108-
```
109-
110-
Look at `graphDb.js` for more details on that object.
111-
112-
## Layout
113-
114-
If you are using a dagre based layout, please use flowchart-v2 as a template and by doing that you will be using dagre-wrapper instead of dagreD3 which we are migrating away from.
115-
11636
### Common parts of a diagram
11737

11838
There are a few features that are common between the different types of diagrams. We try to standardize the diagrams that work as similar as possible for the end user. The commonalities are:
@@ -142,33 +62,7 @@ See [the definition of aria-roledescription](https://www.w3.org/TR/wai-aria-1.1/
14262

14363
The syntax for accessible titles and descriptions is described in [the Accessibility documentation section.](../config/accessibility.md)
14464

145-
As a design goal, the jison syntax should be similar between the diagrams.
146-
147-
```jison
148-
149-
* lexical grammar */
150-
%lex
151-
%x acc_title
152-
%x acc_descr
153-
%x acc_descr_multiline
154-
155-
%%
156-
accTitle\s*":"\s* { this.begin("acc_title");return 'acc_title'; }
157-
<acc_title>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_title_value"; }
158-
accDescr\s*":"\s* { this.begin("acc_descr");return 'acc_descr'; }
159-
<acc_descr>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_descr_value"; }
160-
accDescr\s*"{"\s* { this.begin("acc_descr_multiline");}
161-
<acc_descr_multiline>[\}] { this.popState(); }
162-
<acc_descr_multiline>[^\}]* return "acc_descr_multiline_value";
163-
164-
statement
165-
: acc_title acc_title_value { $$=$2.trim();yy.setTitle($$); }
166-
| acc_descr acc_descr_value { $$=$2.trim();yy.setAccDescription($$); }
167-
| acc_descr_multiline_value { $$=$1.trim();yy.setAccDescription($$); }
168-
169-
```
170-
171-
The functions for setting title and description are provided by a common module. This is the import from flowDb.js:
65+
The functions for setting title and description are provided by a common module. This is the import in flowDb.js:
17266

17367
import {
17468
setAccTitle,

0 commit comments

Comments
 (0)