Merge branch 'develop' into feature/4661_gantt_customize_days_of_weekend

This commit is contained in:
Sidharth Vinod
2024-03-22 15:28:50 +05:30
committed by GitHub
30 changed files with 1027 additions and 1102 deletions

2
.github/lychee.toml vendored
View File

@@ -40,7 +40,7 @@ exclude = [
# BundlePhobia has frequent downtime
"https://bundlephobia.com",
# Chrome webstore redirect issue
# Chrome webstore migration issue. Temporary
"https://chromewebstore.google.com"
]

View File

@@ -12,7 +12,7 @@ jobs:
draft-release:
runs-on: ubuntu-latest
permissions:
contents: write # write permission is required to create a github release
contents: write # write permission is required to create a GitHub release
pull-requests: read # required to read PR titles/labels
steps:
- name: Draft Release

View File

@@ -0,0 +1,222 @@
> **Warning**
>
> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
>
> ## Please edit the corresponding file in [/packages/mermaid/src/docs/community/new-diagram-jison.md](../../packages/mermaid/src/docs/community/new-diagram-jison.md).
# Adding a New Diagram/Chart (Deprecated) 📊
> **Warning**
> JISON grammars are deprecated in mermaid. Please use Langium instead. See [New Diagram](./new-diagram.md) for more information.
>
> **New diagrams with JISON grammars will not be accepted.**
### Step 1: Grammar & Parsing
#### Grammar
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.
For instance:
- the flowchart starts with the keyword _graph_
- the sequence diagram starts with the keyword _sequenceDiagram_
#### Store data found during parsing
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.
```jison
statement
: 'participant' actor { $$='actor'; }
| signal { $$='signal'; }
| note_statement { $$='note'; }
| 'title' message { yy.setTitle($2); }
;
```
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.
> **Note**
> 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.
For more info look at the example diagram type:
The `yy` object has the following function:
```javascript
exports.parseError = function (err, hash) {
mermaid.parseError(err, hash);
};
```
when parsing the `yy` object is initialized as per below:
```javascript
const parser = exampleParser.parser;
parser.yy = db;
```
### Step 2: Rendering
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.
Place the renderer in the diagram folder.
### Step 3: Detection of the new diagram type
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.
[This key will be used to as the aria roledescription](#aria-roledescription), so it should be a word that clearly describes the diagram type.
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
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.
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.
### Step 4: The final piece - triggering the rendering
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.
## Usage of the parser as a separate module
### Setup
```javascript
const graph = require('./graphDb');
const flow = require('./parser/flow');
flow.parser.yy = graph;
```
### Parsing
```javascript
flow.parser.parse(text);
```
### Data extraction
```javascript
graph.getDirection();
graph.getVertices();
graph.getEdges();
```
The parser is also exposed in the mermaid api by calling:
```javascript
const parser = mermaid.getParser();
```
Note that the parse needs a graph object to store the data as per:
```javascript
flow.parser.yy = graph;
```
Look at `graphDb.js` for more details on that object.
## Layout
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.
### Common parts of a diagram
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:
- Directives, a way of modifying the diagram configuration from within the diagram code.
- 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.
- Themes, there is a common way to modify the styling of diagrams in Mermaid.
- Comments should follow mermaid standards
Here are some pointers on how to handle these different areas.
## Accessibility
Mermaid automatically adds the following accessibility information for the diagram SVG HTML element:
- aria-roledescription
- accessible title
- accessible description
### aria-roledescription
The aria-roledescription is automatically set to [the diagram type](#step-3--detection-of-the-new-diagram-type) and inserted into the SVG element.
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/)
### accessible title and description
The syntax for accessible titles and descriptions is described in [the Accessibility documentation section.](../config/accessibility.md)
As a design goal, the jison syntax should be similar between the diagrams.
```jison
* lexical grammar */
%lex
%x acc_title
%x acc_descr
%x acc_descr_multiline
%%
accTitle\s*":"\s* { this.begin("acc_title");return 'acc_title'; }
<acc_title>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_title_value"; }
accDescr\s*":"\s* { this.begin("acc_descr");return 'acc_descr'; }
<acc_descr>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_descr_value"; }
accDescr\s*"{"\s* { this.begin("acc_descr_multiline");}
<acc_descr_multiline>[\}] { this.popState(); }
<acc_descr_multiline>[^\}]* return "acc_descr_multiline_value";
statement
: acc_title acc_title_value { $$=$2.trim();yy.setTitle($$); }
| acc_descr acc_descr_value { $$=$2.trim();yy.setAccDescription($$); }
| acc_descr_multiline_value { $$=$1.trim();yy.setAccDescription($$); }
```
The functions for setting title and description are provided by a common module. This is the import from flowDb.js:
import {
setAccTitle,
getAccTitle,
getAccDescription,
setAccDescription,
clear as commonClear,
} from '../../commonDb';
The accessibility title and description are inserted into the SVG element in the `render` function in mermaidAPI.
## Theming
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).
When adding themes to a diagram it comes down to a few important locations in the code.
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.
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:
```js
const getStyles = (options) =>
`
.line {
stroke-width: 1;
stroke: ${options.lineColor};
stroke-dasharray: 2;
}
// ...
`;
```
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:
```js
const themes = {
flowchart,
'flowchart-v2': flowchart,
sequence,
xyzDiagram,
//...
};
```
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.

View File

@@ -6,52 +6,18 @@
# Adding a New Diagram/Chart 📊
### Examples
Please refer to the following PRs on how to use Langium to add a new diagram grammar.
- <https://github.com/mermaid-js/mermaid/pull/4839>
- <https://github.com/mermaid-js/mermaid/pull/4751>
> **Warning**
> The below steps are a work in progress and will be updated soon.
### Step 1: Grammar & Parsing
#### Grammar
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.
For instance:
- the flowchart starts with the keyword _graph_
- the sequence diagram starts with the keyword _sequenceDiagram_
#### Store data found during parsing
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.
```jison
statement
: 'participant' actor { $$='actor'; }
| signal { $$='signal'; }
| note_statement { $$='note'; }
| 'title' message { yy.setTitle($2); }
;
```
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.
> **Note**
> 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.
For more info look at the example diagram type:
The `yy` object has the following function:
```javascript
exports.parseError = function (err, hash) {
mermaid.parseError(err, hash);
};
```
when parsing the `yy` object is initialized as per below:
```javascript
const parser = exampleParser.parser;
parser.yy = db;
```
### Step 2: Rendering
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.
@@ -67,52 +33,6 @@ would voice that as "U-M-L Deployment diagram." Another good key would be "deplo
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.
### Step 4: The final piece - triggering the rendering
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.
## Usage of the parser as a separate module
### Setup
```javascript
const graph = require('./graphDb');
const flow = require('./parser/flow');
flow.parser.yy = graph;
```
### Parsing
```javascript
flow.parser.parse(text);
```
### Data extraction
```javascript
graph.getDirection();
graph.getVertices();
graph.getEdges();
```
The parser is also exposed in the mermaid api by calling:
```javascript
const parser = mermaid.getParser();
```
Note that the parse needs a graph object to store the data as per:
```javascript
flow.parser.yy = graph;
```
Look at `graphDb.js` for more details on that object.
## Layout
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.
### Common parts of a diagram
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/
The syntax for accessible titles and descriptions is described in [the Accessibility documentation section.](../config/accessibility.md)
As a design goal, the jison syntax should be similar between the diagrams.
```jison
* lexical grammar */
%lex
%x acc_title
%x acc_descr
%x acc_descr_multiline
%%
accTitle\s*":"\s* { this.begin("acc_title");return 'acc_title'; }
<acc_title>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_title_value"; }
accDescr\s*":"\s* { this.begin("acc_descr");return 'acc_descr'; }
<acc_descr>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_descr_value"; }
accDescr\s*"{"\s* { this.begin("acc_descr_multiline");}
<acc_descr_multiline>[\}] { this.popState(); }
<acc_descr_multiline>[^\}]* return "acc_descr_multiline_value";
statement
: acc_title acc_title_value { $$=$2.trim();yy.setTitle($$); }
| acc_descr acc_descr_value { $$=$2.trim();yy.setAccDescription($$); }
| acc_descr_multiline_value { $$=$1.trim();yy.setAccDescription($$); }
```
The functions for setting title and description are provided by a common module. This is the import from flowDb.js:
The functions for setting title and description are provided by a common module. This is the import in flowDb.js:
import {
setAccTitle,

View File

@@ -4,7 +4,7 @@
>
> ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/math.md](../../packages/mermaid/src/docs/config/math.md).
# Math Configuration (v\<MERMAID_RELEASE_VERSION>+)
# Math Configuration (v10.9.0+)
Mermaid supports rendering mathematical expressions through the [KaTeX](https://katex.org/) typesetter.

View File

@@ -250,7 +250,7 @@ The theming engine will only recognize hex colors and not color names. So, the v
| actorBkg | mainBkg | Actor Background Color |
| actorBorder | primaryBorderColor | Actor Border Color |
| actorTextColor | primaryTextColor | Actor Text Color |
| actorLineColor | grey | Actor Line Color |
| actorLineColor | actorBorder | Actor Line Color |
| signalColor | textColor | Signal Color |
| signalTextColor | textColor | Signal Text Color |
| labelBoxBkgColor | actorBkg | Label Box Background Color |

View File

@@ -71,6 +71,12 @@ To add an integration to this list, see the [Integrations - create page](./integ
- [redmine-mermaid](https://github.com/styz/redmine_mermaid)
- Visual Studio Code [Polyglot Interactive Notebooks](https://github.com/dotnet/interactive#net-interactive)
### LLM integrations
LLM integrations to create mermaid diagrams using AI from text descriptions.
- [HueHive - Create mermaid diagrams with text](https://huehive.co/tools/diagrams)
### CRM/ERP
Customer Relationship Management/Enterprise Resource Planning
@@ -118,7 +124,7 @@ Communication tools and platforms
- [phpBB](https://phpbb.com)
- [phpbb-ext-mermaid](https://github.com/AlfredoRamos/phpbb-ext-mermaid)
- [Slack](https://slack.com)
- [Mermaid Preview](https://github.com/JackuB/mermaid-for-slack)
- [Mermaid Preview](https://mermaid-preview.com)
### Wikis
@@ -252,4 +258,4 @@ Communication tools and platforms
- [mermaid-isomorphic](https://github.com/remcohaszing/mermaid-isomorphic)
- [mermaid-server: Generate diagrams using a HTTP request](https://github.com/TomWright/mermaid-server)
<!--- cspell:ignore Blazorade --->
<!--- cspell:ignore Blazorade HueHive --->

View File

@@ -6,6 +6,18 @@
# Blog
## [Mermaid Chart GPT Is Now Available In the GPT Store!](https://www.mermaidchart.com/blog/posts/mermaid-chart-gpt-is-now-available-in-the-gpt-store/)
7 March 2024 · 3 mins
Mermaid Chart GPT is Now Available In the GPT Store!
## [How to Make a Flowchart with Mermaid Chart](https://www.mermaidchart.com/blog/posts/how-to-make-flowcharts-with-mermaid-chart/)
30 January 2024 · 6 mins
Learn how to make a flowchart with Mermaid Chart, the leading text-to-diagram platform for both developers and non-developers.
## [How one data scientist uses Mermaid Chart to quickly and easily build flowcharts](https://www.mermaidchart.com/blog/posts/customer-spotlight-ari-tal/)
23 January 2024 · 4 mins

View File

@@ -143,7 +143,7 @@ After processing the tags, the remaining metadata items are interpreted as follo
| `until <otherTaskId>` | End date of preceding task | Start date of previously specified task `otherTaskID` | n/a |
> **Note**
> Support for keyword `until` was added in (v\<MERMAID_RELEASE_VERSION>+). This can be used to define a task which is running until some other specific task or milestone starts.
> Support for keyword `until` was added in (v10.9.0+). This can be used to define a task which is running until some other specific task or milestone starts.
For simplicity, the table does not show the use of multiple tasks listed with the `after` keyword. Here is an example of how to use it and how it's interpreted:

View File

@@ -32,7 +32,7 @@
"d3": "^7.4.0",
"dagre-d3-es": "7.0.10",
"khroma": "^2.0.0",
"elkjs": "^0.8.2"
"elkjs": "^0.9.0"
},
"devDependencies": {
"concurrently": "^8.0.0",

View File

@@ -1,6 +1,6 @@
{
"name": "@mermaid-js/mermaid-zenuml",
"version": "0.1.2",
"version": "0.2.0",
"description": "MermaidJS plugin for ZenUML integration",
"module": "dist/mermaid-zenuml.core.mjs",
"types": "dist/detector.d.ts",

View File

@@ -1,7 +1,7 @@
{
"name": "mermaid",
"version": "11.0.0-alpha.6",
"description": "Markdown-ish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
"description": "Markdown-ish syntax for generating flowcharts, mindmaps, sequence diagrams, class diagrams, gantt charts, git graphs and more.",
"type": "module",
"module": "./dist/mermaid.core.mjs",
"types": "./dist/mermaid.d.ts",
@@ -20,7 +20,16 @@
"sequence diagram",
"gantt",
"class diagram",
"git graph"
"git graph",
"mindmap",
"packet diagram",
"c4 diagram",
"er diagram",
"pie chart",
"pie diagram",
"quadrant chart",
"requirement diagram",
"graph"
],
"scripts": {
"clean": "rimraf dist",

View File

@@ -252,11 +252,12 @@ export function transformMarkdownAst({
node.lang = MERMAID_KEYWORD;
return [node];
} else if (MERMAID_EXAMPLE_KEYWORDS.includes(node.lang)) {
// Return 2 nodes:
// If Vitepress, return only the original node with the language now set to 'mermaid-example' (will be rendered using custom renderer)
// Else Return 2 nodes:
// 1. the original node with the language now set to 'mermaid-example' (will be rendered as code), and
// 2. a copy of the original node with the language set to 'mermaid' (will be rendered as a diagram)
node.lang = MERMAID_CODE_ONLY_KEYWORD;
return [node, Object.assign({}, node, { lang: MERMAID_KEYWORD })];
return vitepress ? [node] : [node, Object.assign({}, node, { lang: MERMAID_KEYWORD })];
}
// Transform these blocks into block quotes.

View File

@@ -343,10 +343,10 @@ const drawActorTypeParticipant = async function (elem, actor, conf, isFooter) {
.attr('y1', centerY)
.attr('x2', center)
.attr('y2', 2000)
.attr('class', 'actor-line')
.attr('class', '200')
.attr('class', 'actor-line 200')
.attr('stroke-width', '0.5px')
.attr('stroke', '#999');
.attr('stroke', '#999')
.attr('name', actor.name);
g = boxplusLineGroup.append('g');
actor.actorCnt = actorCnt;
@@ -425,10 +425,10 @@ const drawActorTypeActor = async function (elem, actor, conf, isFooter) {
.attr('y1', centerY)
.attr('x2', center)
.attr('y2', 2000)
.attr('class', 'actor-line')
.attr('class', '200')
.attr('class', 'actor-line 200')
.attr('stroke-width', '0.5px')
.attr('stroke', '#999');
.attr('stroke', '#999')
.attr('name', actor.name);
actor.actorCnt = actorCnt;
}

View File

@@ -9,35 +9,15 @@ const MermaidExample = async (md: MarkdownRenderer) => {
md.renderer.rules.fence = (tokens, index, options, env, slf) => {
const token = tokens[index];
if (token.info.trim() === 'mermaid-example') {
if (!md.options.highlight) {
// this function is always created by vitepress, but we need to check it
// anyway to make TypeScript happy
throw new Error(
'Missing MarkdownIt highlight function (should be automatically created by vitepress'
);
}
// doing ```mermaid-example {line-numbers=5 highlight=14-17} is not supported
const langAttrs = '';
return `
<h5>Code:</h5>
<div class="language-mermaid">
<button class="copy"></button>
<span class="lang">mermaid</span>
${
// html is pre-escaped by the highlight function
// (it also adds `v-pre` to ignore Vue template syntax)
md.options.highlight(token.content, 'mermaid', langAttrs)
}
</div>`;
} else if (token.info.trim() === 'mermaid') {
const language = token.info.trim();
if (language.startsWith('mermaid')) {
const key = index;
return `
<Suspense>
<template #default>
<Mermaid id="mermaid-${key}" graph="${encodeURIComponent(token.content)}"></Mermaid>
<Mermaid id="mermaid-${key}" :showCode="${
language === 'mermaid-example'
}" graph="${encodeURIComponent(token.content)}"></Mermaid>
</template>
<!-- loading state via #fallback slot -->
<template #fallback>
@@ -45,25 +25,18 @@ const MermaidExample = async (md: MarkdownRenderer) => {
</template>
</Suspense>
`;
}
if (token.info.trim() === 'warning') {
} else if (language === 'warning') {
return `<div class="warning custom-block"><p class="custom-block-title">WARNING</p><p>${token.content}}</p></div>`;
}
if (token.info.trim() === 'note') {
} else if (language === 'note') {
return `<div class="tip custom-block"><p class="custom-block-title">NOTE</p><p>${token.content}}</p></div>`;
}
if (token.info.trim() === 'regexp') {
} else if (language === 'regexp') {
// shiki doesn't yet support regexp code blocks, but the javascript
// one still makes RegExes look good
token.info = 'javascript';
// use trimEnd to move trailing `\n` outside if the JavaScript regex `/` block
token.content = `/${token.content.trimEnd()}/\n`;
return defaultRenderer(tokens, index, options, env, slf);
}
if (token.info.trim() === 'jison') {
} else if (language === 'jison') {
return `<div class="language-">
<button class="copy"></button>
<span class="lang">jison</span>

View File

@@ -1,4 +1,16 @@
<template>
<div v-if="props.showCode">
<h5>Code:</h5>
<div class="language-mermaid">
<button class="copy"></button>
<span class="lang">mermaid</span>
<pre><code :contenteditable="contentEditable" @input="updateCode" @keydown.meta.enter="renderChart" @keydown.ctrl.enter="renderChart" ref="editableContent" class="editable-code"></code></pre>
<div class="buttons-container">
<span>{{ ctrlSymbol }} + Enter</span><span>|</span>
<button @click="renderChart">Run </button>
</div>
</div>
</div>
<div v-html="svg"></div>
</template>
@@ -15,18 +27,40 @@ const props = defineProps({
type: String,
required: true,
},
showCode: {
type: Boolean,
default: true,
},
});
const svg = ref('');
const code = ref(decodeURIComponent(props.graph));
const ctrlSymbol = ref(navigator.platform.includes('Mac') ? '⌘' : 'Ctrl');
const editableContent = ref(null);
const isFirefox = navigator.userAgent.toLowerCase().includes('firefox');
const contentEditable = ref(isFirefox ? 'true' : 'plaintext-only');
let mut = null;
const updateCode = (event) => {
code.value = event.target.innerText;
};
onMounted(async () => {
mut = new MutationObserver(() => renderChart());
mut.observe(document.documentElement, { attributes: true });
if (editableContent.value) {
// Set the initial value of the contenteditable element
// We cannot bind using `{{ code }}` because it will rerender the whole component
// when the value changes, shifting the cursor when enter is used
editableContent.value.textContent = code.value;
}
await renderChart();
//refresh images on first render
const hasImages = /<img([\w\W]+?)>/.exec(decodeURIComponent(props.graph))?.length > 0;
const hasImages = /<img([\w\W]+?)>/.exec(code.value)?.length > 0;
if (hasImages)
setTimeout(() => {
let imgElements = document.getElementsByTagName('img');
@@ -51,16 +85,14 @@ onMounted(async () => {
onUnmounted(() => mut.disconnect());
const renderChart = async () => {
console.log('rendering chart' + props.id + props.graph);
console.log('rendering chart' + props.id + code.value);
const hasDarkClass = document.documentElement.classList.contains('dark');
const mermaidConfig = {
securityLevel: 'loose',
startOnLoad: false,
theme: hasDarkClass ? 'dark' : 'default',
};
console.log({ mermaidConfig });
let svgCode = await render(props.id, decodeURIComponent(props.graph), mermaidConfig);
let svgCode = await render(props.id, code.value, mermaidConfig);
// This is a hack to force v-html to re-render, otherwise the diagram disappears
// when **switching themes** or **reloading the page**.
// The cause is that the diagram is deleted during rendering (out of Vue's knowledge).
@@ -70,3 +102,35 @@ const renderChart = async () => {
svg.value = `${svgCode} <span style="display: none">${salt}</span>`;
};
</script>
<style>
.editable-code:focus {
outline: none; /* Removes the default focus indicator */
}
.buttons-container {
position: absolute;
bottom: 0;
right: 0;
z-index: 1;
padding: 0.5rem;
display: flex;
gap: 0.5rem;
}
.buttons-container > span {
cursor: default;
opacity: 0.5;
font-size: 0.8rem;
}
.buttons-container > button {
color: #007bffbf;
font-weight: bold;
cursor: pointer;
}
.buttons-container > button:hover {
color: #007bff;
}
</style>

View File

@@ -0,0 +1,220 @@
# Adding a New Diagram/Chart (Deprecated) 📊
```warning
JISON grammars are deprecated in mermaid. Please use Langium instead. See [New Diagram](./new-diagram.md) for more information.
**New diagrams with JISON grammars will not be accepted.**
```
### Step 1: Grammar & Parsing
#### Grammar
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.
For instance:
- the flowchart starts with the keyword _graph_
- the sequence diagram starts with the keyword _sequenceDiagram_
#### Store data found during parsing
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.
```jison
statement
: 'participant' actor { $$='actor'; }
| signal { $$='signal'; }
| note_statement { $$='note'; }
| 'title' message { yy.setTitle($2); }
;
```
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.
```note
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.
```
For more info look at the example diagram type:
The `yy` object has the following function:
```javascript
exports.parseError = function (err, hash) {
mermaid.parseError(err, hash);
};
```
when parsing the `yy` object is initialized as per below:
```javascript
const parser = exampleParser.parser;
parser.yy = db;
```
### Step 2: Rendering
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.
Place the renderer in the diagram folder.
### Step 3: Detection of the new diagram type
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.
[This key will be used to as the aria roledescription](#aria-roledescription), so it should be a word that clearly describes the diagram type.
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
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.
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.
### Step 4: The final piece - triggering the rendering
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.
## Usage of the parser as a separate module
### Setup
```javascript
const graph = require('./graphDb');
const flow = require('./parser/flow');
flow.parser.yy = graph;
```
### Parsing
```javascript
flow.parser.parse(text);
```
### Data extraction
```javascript
graph.getDirection();
graph.getVertices();
graph.getEdges();
```
The parser is also exposed in the mermaid api by calling:
```javascript
const parser = mermaid.getParser();
```
Note that the parse needs a graph object to store the data as per:
```javascript
flow.parser.yy = graph;
```
Look at `graphDb.js` for more details on that object.
## Layout
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.
### Common parts of a diagram
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:
- Directives, a way of modifying the diagram configuration from within the diagram code.
- 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.
- Themes, there is a common way to modify the styling of diagrams in Mermaid.
- Comments should follow mermaid standards
Here are some pointers on how to handle these different areas.
## Accessibility
Mermaid automatically adds the following accessibility information for the diagram SVG HTML element:
- aria-roledescription
- accessible title
- accessible description
### aria-roledescription
The aria-roledescription is automatically set to [the diagram type](#step-3--detection-of-the-new-diagram-type) and inserted into the SVG element.
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/)
### accessible title and description
The syntax for accessible titles and descriptions is described in [the Accessibility documentation section.](../config/accessibility.md)
As a design goal, the jison syntax should be similar between the diagrams.
```jison
* lexical grammar */
%lex
%x acc_title
%x acc_descr
%x acc_descr_multiline
%%
accTitle\s*":"\s* { this.begin("acc_title");return 'acc_title'; }
<acc_title>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_title_value"; }
accDescr\s*":"\s* { this.begin("acc_descr");return 'acc_descr'; }
<acc_descr>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_descr_value"; }
accDescr\s*"{"\s* { this.begin("acc_descr_multiline");}
<acc_descr_multiline>[\}] { this.popState(); }
<acc_descr_multiline>[^\}]* return "acc_descr_multiline_value";
statement
: acc_title acc_title_value { $$=$2.trim();yy.setTitle($$); }
| acc_descr acc_descr_value { $$=$2.trim();yy.setAccDescription($$); }
| acc_descr_multiline_value { $$=$1.trim();yy.setAccDescription($$); }
```
The functions for setting title and description are provided by a common module. This is the import from flowDb.js:
```
import {
setAccTitle,
getAccTitle,
getAccDescription,
setAccDescription,
clear as commonClear,
} from '../../commonDb';
```
The accessibility title and description are inserted into the SVG element in the `render` function in mermaidAPI.
## Theming
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).
When adding themes to a diagram it comes down to a few important locations in the code.
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.
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:
```js
const getStyles = (options) =>
`
.line {
stroke-width: 1;
stroke: ${options.lineColor};
stroke-dasharray: 2;
}
// ...
`;
```
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:
```js
const themes = {
flowchart,
'flowchart-v2': flowchart,
sequence,
xyzDiagram,
//...
};
```
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.

View File

@@ -1,52 +1,18 @@
# Adding a New Diagram/Chart 📊
### Examples
Please refer to the following PRs on how to use Langium to add a new diagram grammar.
- https://github.com/mermaid-js/mermaid/pull/4839
- https://github.com/mermaid-js/mermaid/pull/4751
```warning
The below steps are a work in progress and will be updated soon.
```
### Step 1: Grammar & Parsing
#### Grammar
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.
For instance:
- the flowchart starts with the keyword _graph_
- the sequence diagram starts with the keyword _sequenceDiagram_
#### Store data found during parsing
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.
```jison
statement
: 'participant' actor { $$='actor'; }
| signal { $$='signal'; }
| note_statement { $$='note'; }
| 'title' message { yy.setTitle($2); }
;
```
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.
```note
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.
```
For more info look at the example diagram type:
The `yy` object has the following function:
```javascript
exports.parseError = function (err, hash) {
mermaid.parseError(err, hash);
};
```
when parsing the `yy` object is initialized as per below:
```javascript
const parser = exampleParser.parser;
parser.yy = db;
```
### Step 2: Rendering
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.
@@ -62,52 +28,6 @@ would voice that as "U-M-L Deployment diagram." Another good key would be "deplo
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.
### Step 4: The final piece - triggering the rendering
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.
## Usage of the parser as a separate module
### Setup
```javascript
const graph = require('./graphDb');
const flow = require('./parser/flow');
flow.parser.yy = graph;
```
### Parsing
```javascript
flow.parser.parse(text);
```
### Data extraction
```javascript
graph.getDirection();
graph.getVertices();
graph.getEdges();
```
The parser is also exposed in the mermaid api by calling:
```javascript
const parser = mermaid.getParser();
```
Note that the parse needs a graph object to store the data as per:
```javascript
flow.parser.yy = graph;
```
Look at `graphDb.js` for more details on that object.
## Layout
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.
### Common parts of a diagram
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:
@@ -137,33 +57,7 @@ See [the definition of aria-roledescription](https://www.w3.org/TR/wai-aria-1.1/
The syntax for accessible titles and descriptions is described in [the Accessibility documentation section.](../config/accessibility.md)
As a design goal, the jison syntax should be similar between the diagrams.
```jison
* lexical grammar */
%lex
%x acc_title
%x acc_descr
%x acc_descr_multiline
%%
accTitle\s*":"\s* { this.begin("acc_title");return 'acc_title'; }
<acc_title>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_title_value"; }
accDescr\s*":"\s* { this.begin("acc_descr");return 'acc_descr'; }
<acc_descr>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_descr_value"; }
accDescr\s*"{"\s* { this.begin("acc_descr_multiline");}
<acc_descr_multiline>[\}] { this.popState(); }
<acc_descr_multiline>[^\}]* return "acc_descr_multiline_value";
statement
: acc_title acc_title_value { $$=$2.trim();yy.setTitle($$); }
| acc_descr acc_descr_value { $$=$2.trim();yy.setAccDescription($$); }
| acc_descr_multiline_value { $$=$1.trim();yy.setAccDescription($$); }
```
The functions for setting title and description are provided by a common module. This is the import from flowDb.js:
The functions for setting title and description are provided by a common module. This is the import in flowDb.js:
```
import {

View File

@@ -1,4 +1,4 @@
# Math Configuration (v<MERMAID_RELEASE_VERSION>+)
# Math Configuration (v10.9.0+)
Mermaid supports rendering mathematical expressions through the [KaTeX](https://katex.org/) typesetter.

View File

@@ -172,7 +172,7 @@ The theming engine will only recognize hex colors and not color names. So, the v
| actorBkg | mainBkg | Actor Background Color |
| actorBorder | primaryBorderColor | Actor Border Color |
| actorTextColor | primaryTextColor | Actor Text Color |
| actorLineColor | grey | Actor Line Color |
| actorLineColor | actorBorder | Actor Line Color |
| signalColor | textColor | Signal Color |
| signalTextColor | textColor | Signal Text Color |
| labelBoxBkgColor | actorBkg | Label Box Background Color |

View File

@@ -66,6 +66,12 @@ To add an integration to this list, see the [Integrations - create page](./integ
- [redmine-mermaid](https://github.com/styz/redmine_mermaid)
- Visual Studio Code [Polyglot Interactive Notebooks](https://github.com/dotnet/interactive#net-interactive)
### LLM integrations
LLM integrations to create mermaid diagrams using AI from text descriptions.
- [HueHive - Create mermaid diagrams with text](https://huehive.co/tools/diagrams)
### CRM/ERP
Customer Relationship Management/Enterprise Resource Planning
@@ -113,7 +119,7 @@ Communication tools and platforms
- [phpBB](https://phpbb.com)
- [phpbb-ext-mermaid](https://github.com/AlfredoRamos/phpbb-ext-mermaid)
- [Slack](https://slack.com)
- [Mermaid Preview](https://github.com/JackuB/mermaid-for-slack)
- [Mermaid Preview](https://mermaid-preview.com)
### Wikis
@@ -247,4 +253,4 @@ Communication tools and platforms
- [mermaid-isomorphic](https://github.com/remcohaszing/mermaid-isomorphic)
- [mermaid-server: Generate diagrams using a HTTP request](https://github.com/TomWright/mermaid-server)
<!--- cspell:ignore Blazorade --->
<!--- cspell:ignore Blazorade HueHive --->

View File

@@ -1,5 +1,17 @@
# Blog
## [Mermaid Chart GPT Is Now Available In the GPT Store!](https://www.mermaidchart.com/blog/posts/mermaid-chart-gpt-is-now-available-in-the-gpt-store/)
7 March 2024 · 3 mins
Mermaid Chart GPT is Now Available In the GPT Store!
## [How to Make a Flowchart with Mermaid Chart](https://www.mermaidchart.com/blog/posts/how-to-make-flowcharts-with-mermaid-chart/)
30 January 2024 · 6 mins
Learn how to make a flowchart with Mermaid Chart, the leading text-to-diagram platform for both developers and non-developers.
## [How one data scientist uses Mermaid Chart to quickly and easily build flowcharts](https://www.mermaidchart.com/blog/posts/customer-spotlight-ari-tal/)
23 January 2024 · 4 mins

View File

@@ -34,7 +34,7 @@
"unplugin-vue-components": "^0.26.0",
"vite": "^4.5.2",
"vite-plugin-pwa": "^0.19.0",
"vitepress": "1.0.0-rc.44",
"vitepress": "1.0.0-rc.45",
"workbox-window": "^7.0.0"
}
}

View File

@@ -92,7 +92,7 @@ After processing the tags, the remaining metadata items are interpreted as follo
| `until <otherTaskId>` | End date of preceding task | Start date of previously specified task `otherTaskID` | n/a |
```note
Support for keyword `until` was added in (v<MERMAID_RELEASE_VERSION>+). This can be used to define a task which is running until some other specific task or milestone starts.
Support for keyword `until` was added in (v10.9.0+). This can be used to define a task which is running until some other specific task or milestone starts.
```
For simplicity, the table does not show the use of multiple tasks listed with the `after` keyword. Here is an example of how to use it and how it's interpreted:

View File

@@ -70,7 +70,7 @@ class Theme {
this.actorBorder = this.actorBorder || this.primaryBorderColor;
this.actorBkg = this.actorBkg || this.mainBkg;
this.actorTextColor = this.actorTextColor || this.primaryTextColor;
this.actorLineColor = this.actorLineColor || 'grey';
this.actorLineColor = this.actorLineColor || this.actorBorder;
this.labelBoxBkgColor = this.labelBoxBkgColor || this.actorBkg;
this.signalColor = this.signalColor || this.textColor;
this.signalTextColor = this.signalTextColor || this.textColor;

View File

@@ -109,7 +109,7 @@ class Theme {
this.actorBorder = this.border1;
this.actorBkg = this.mainBkg;
this.actorTextColor = this.mainContrastColor;
this.actorLineColor = this.mainContrastColor;
this.actorLineColor = this.actorBorder;
this.signalColor = this.mainContrastColor;
this.signalTextColor = this.mainContrastColor;
this.labelBoxBkgColor = this.actorBkg;

View File

@@ -53,7 +53,7 @@ class Theme {
this.actorBorder = 'calculated';
this.actorBkg = 'calculated';
this.actorTextColor = 'black';
this.actorLineColor = 'grey';
this.actorLineColor = 'calculated';
this.signalColor = 'calculated';
this.signalTextColor = 'calculated';
this.labelBoxBkgColor = 'calculated';
@@ -187,6 +187,7 @@ class Theme {
this.loopTextColor = this.actorTextColor;
this.noteBorderColor = this.border2;
this.noteTextColor = this.actorTextColor;
this.actorLineColor = this.actorBorder;
/* Gantt chart variables */

View File

@@ -46,7 +46,7 @@ class Theme {
this.actorBorder = 'calculated';
this.actorBkg = 'calculated';
this.actorTextColor = 'black';
this.actorLineColor = 'grey';
this.actorLineColor = 'calculated';
this.signalColor = '#333';
this.signalTextColor = '#333';
this.labelBoxBkgColor = 'calculated';
@@ -101,6 +101,7 @@ class Theme {
this.loopTextColor = this.actorTextColor;
this.noteBorderColor = this.border2;
this.noteTextColor = this.actorTextColor;
this.actorLineColor = this.actorBorder;
/* Each color-set will have a background, a foreground and a border color */
this.cScale0 = this.cScale0 || this.primaryColor;

View File

@@ -58,7 +58,7 @@ class Theme {
this.actorBorder = 'calculated';
this.actorBkg = 'calculated';
this.actorTextColor = 'calculated';
this.actorLineColor = 'calculated';
this.actorLineColor = this.actorBorder;
this.signalColor = 'calculated';
this.signalTextColor = 'calculated';
this.labelBoxBkgColor = 'calculated';
@@ -113,7 +113,7 @@ class Theme {
this.actorBorder = lighten(this.border1, 23);
this.actorBkg = this.mainBkg;
this.actorTextColor = this.text;
this.actorLineColor = this.lineColor;
this.actorLineColor = this.actorBorder;
this.signalColor = this.text;
this.signalTextColor = this.text;
this.labelBoxBkgColor = this.actorBkg;

1200
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff