mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-08-15 14:29:25 +02:00
Merge branch 'develop' of https://github.com/mermaid-js/mermaid into saurabh/refactor/convert-flowDb-to-class
This commit is contained in:
5
.changeset/bright-ads-exist.md
Normal file
5
.changeset/bright-ads-exist.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'mermaid': patch
|
||||
---
|
||||
|
||||
Fixes for consistent edge id creation & handling edge cases for animate edge feature
|
5
.changeset/chatty-elephants-warn.md
Normal file
5
.changeset/chatty-elephants-warn.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'mermaid': patch
|
||||
---
|
||||
|
||||
Fix for issue #6195 - allowing @ signs inside node labels
|
5
.changeset/stupid-dots-do.md
Normal file
5
.changeset/stupid-dots-do.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'mermaid': patch
|
||||
---
|
||||
|
||||
fix: Gantt, Sankey and User Journey diagram are now able to pick font-family from mermaid config.
|
@@ -78,9 +78,11 @@
|
||||
font-family: monospace;
|
||||
font-size: 72px;
|
||||
}
|
||||
|
||||
pre {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* tspan {
|
||||
font-size: 6px !important;
|
||||
} */
|
||||
@@ -103,16 +105,20 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<pre id="diagram4" class="mermaid2">
|
||||
<pre id="diagram4" class="mermaid">
|
||||
flowchart LR
|
||||
A --> B
|
||||
AB["apa@apa@"] --> B(("`apa@apa`"))
|
||||
</pre>
|
||||
<pre id="diagram4" class="mermaid">
|
||||
flowchart
|
||||
D(("for D"))
|
||||
</pre>
|
||||
<pre id="diagram4" class="mermaid">
|
||||
flowchart LR
|
||||
A e1@==> B
|
||||
e1@{ animate: true}
|
||||
</pre>
|
||||
<pre id="diagram4" class="mermaid2">
|
||||
<pre id="diagram4" class="mermaid">
|
||||
flowchart LR
|
||||
A e1@--> B
|
||||
classDef animate stroke-width:2,stroke-dasharray:10\,8,stroke-dashoffset:-180,animation: edge-animation-frame 6s linear infinite, stroke-linecap: round
|
||||
@@ -126,7 +132,7 @@ flowchart LR
|
||||
class e1 animate
|
||||
</pre>
|
||||
<h2>Mermaid - edge-animation-slow</h2>
|
||||
<pre id="diagram4" class="mermaid">
|
||||
<pre id="diagram4" class="mermaid2">
|
||||
flowchart LR
|
||||
A e1@--> B
|
||||
e1@{ animation: fast}
|
||||
@@ -428,7 +434,10 @@ kanban
|
||||
window.callback = function () {
|
||||
alert('A callback was triggered');
|
||||
};
|
||||
mermaid.initialize({
|
||||
function callback() {
|
||||
alert('It worked');
|
||||
}
|
||||
await mermaid.initialize({
|
||||
// theme: 'base',
|
||||
// theme: 'default',
|
||||
// theme: 'forest',
|
||||
@@ -440,9 +449,11 @@ kanban
|
||||
// layout: 'fixed',
|
||||
// htmlLabels: false,
|
||||
flowchart: { titleTopMargin: 10 },
|
||||
|
||||
// fontFamily: 'Caveat',
|
||||
// fontFamily: 'Kalam',
|
||||
// fontFamily: 'courier',
|
||||
fontFamily: 'arial',
|
||||
sequence: {
|
||||
actorFontFamily: 'courier',
|
||||
noteFontFamily: 'courier',
|
||||
@@ -454,10 +465,9 @@ kanban
|
||||
fontSize: 12,
|
||||
logLevel: 0,
|
||||
securityLevel: 'loose',
|
||||
callback,
|
||||
});
|
||||
function callback() {
|
||||
alert('It worked');
|
||||
}
|
||||
|
||||
mermaid.parseError = function (err, hash) {
|
||||
console.error('In parse error:');
|
||||
console.error(err);
|
||||
|
@@ -20,7 +20,7 @@
|
||||
|
||||
#### Defined in
|
||||
|
||||
[packages/mermaid/src/rendering-util/types.ts:147](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/types.ts#L147)
|
||||
[packages/mermaid/src/rendering-util/types.ts:148](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/types.ts#L148)
|
||||
|
||||
---
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
#### Defined in
|
||||
|
||||
[packages/mermaid/src/rendering-util/types.ts:146](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/types.ts#L146)
|
||||
[packages/mermaid/src/rendering-util/types.ts:147](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/types.ts#L147)
|
||||
|
||||
---
|
||||
|
||||
@@ -40,4 +40,4 @@
|
||||
|
||||
#### Defined in
|
||||
|
||||
[packages/mermaid/src/rendering-util/types.ts:145](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/types.ts#L145)
|
||||
[packages/mermaid/src/rendering-util/types.ts:146](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/types.ts#L146)
|
||||
|
@@ -133,10 +133,10 @@ export class FlowDB implements DiagramDB {
|
||||
const edge = this.edges.find((e) => e.id === id);
|
||||
if (edge) {
|
||||
const edgeDoc = doc as EdgeMetaData;
|
||||
if (edgeDoc?.animate) {
|
||||
if (edgeDoc?.animate !== undefined) {
|
||||
edge.animate = edgeDoc.animate;
|
||||
}
|
||||
if (edgeDoc?.animation) {
|
||||
if (edgeDoc?.animation !== undefined) {
|
||||
edge.animation = edgeDoc.animation;
|
||||
}
|
||||
return;
|
||||
@@ -251,6 +251,7 @@ export class FlowDB implements DiagramDB {
|
||||
text: '',
|
||||
labelType: 'text',
|
||||
classes: [],
|
||||
isUserDefinedId: false,
|
||||
};
|
||||
log.info('abc78 Got edge...', edge);
|
||||
const linkTextObj = type.text;
|
||||
@@ -270,8 +271,19 @@ export class FlowDB implements DiagramDB {
|
||||
edge.stroke = type.stroke;
|
||||
edge.length = type.length > 10 ? 10 : type.length;
|
||||
}
|
||||
if (id) {
|
||||
if (id && !this.edges.some((e) => e.id === id)) {
|
||||
edge.id = id;
|
||||
edge.isUserDefinedId = true;
|
||||
} else {
|
||||
const existingLinks = this.edges.filter((e) => e.start === edge.start && e.end === edge.end);
|
||||
if (existingLinks.length === 0) {
|
||||
edge.id = getEdgeId(edge.start, edge.end, { counter: 0, prefix: 'L' });
|
||||
} else {
|
||||
edge.id = getEdgeId(edge.start, edge.end, {
|
||||
counter: existingLinks.length + 1,
|
||||
prefix: 'L',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (this.edges.length < (this.config.maxEdges ?? 500)) {
|
||||
@@ -302,9 +314,18 @@ You have to call mermaid.initialize.`
|
||||
|
||||
log.info('addLink', _start, _end, id);
|
||||
|
||||
// for a group syntax like A e1@--> B & C, only the first edge should have an the userDefined id
|
||||
// the rest of the edges should have auto generated ids
|
||||
for (const start of _start) {
|
||||
for (const end of _end) {
|
||||
this.addSingleLink(start, end, linkData, id);
|
||||
//use the id only for last node in _start and and first node in _end
|
||||
const isLastStart = start === _start[_start.length - 1];
|
||||
const isFirstEnd = end === _end[0];
|
||||
if (isLastStart && isFirstEnd) {
|
||||
this.addSingleLink(start, end, linkData, id);
|
||||
} else {
|
||||
this.addSingleLink(start, end, linkData, undefined);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1077,6 +1098,7 @@ You have to call mermaid.initialize.`
|
||||
}
|
||||
const edge: Edge = {
|
||||
id: getEdgeId(rawEdge.start, rawEdge.end, { counter: index, prefix: 'L' }, rawEdge.id),
|
||||
isUserDefinedId: rawEdge.isUserDefinedId,
|
||||
start: rawEdge.start,
|
||||
end: rawEdge.end,
|
||||
type: rawEdge.type ?? 'normal',
|
||||
|
@@ -251,7 +251,7 @@ describe('when parsing directions', function () {
|
||||
expect(data4Layout.nodes[0].shape).toEqual('squareRect');
|
||||
expect(data4Layout.nodes[0].label).toEqual('This is a<br/>multiline string');
|
||||
});
|
||||
it(' should be possible to use } in strings', function () {
|
||||
it('should be possible to use } in strings', function () {
|
||||
const res = flow.parser.parse(`flowchart TB
|
||||
A@{
|
||||
label: "This is a string with }"
|
||||
@@ -264,7 +264,7 @@ describe('when parsing directions', function () {
|
||||
expect(data4Layout.nodes[0].shape).toEqual('squareRect');
|
||||
expect(data4Layout.nodes[0].label).toEqual('This is a string with }');
|
||||
});
|
||||
it(' should be possible to use @ in strings', function () {
|
||||
it('should be possible to use @ in strings', function () {
|
||||
const res = flow.parser.parse(`flowchart TB
|
||||
A@{
|
||||
label: "This is a string with @"
|
||||
@@ -277,7 +277,7 @@ describe('when parsing directions', function () {
|
||||
expect(data4Layout.nodes[0].shape).toEqual('squareRect');
|
||||
expect(data4Layout.nodes[0].label).toEqual('This is a string with @');
|
||||
});
|
||||
it(' should be possible to use @ in strings', function () {
|
||||
it('should be possible to use @ in strings', function () {
|
||||
const res = flow.parser.parse(`flowchart TB
|
||||
A@{
|
||||
label: "This is a string with}"
|
||||
@@ -291,7 +291,7 @@ describe('when parsing directions', function () {
|
||||
expect(data4Layout.nodes[0].label).toEqual('This is a string with}');
|
||||
});
|
||||
|
||||
it(' should be possible to use @ syntax to add labels on multi nodes', function () {
|
||||
it('should be possible to use @ syntax to add labels on multi nodes', function () {
|
||||
const res = flow.parser.parse(`flowchart TB
|
||||
n2["label for n2"] & n4@{ label: "labe for n4"} & n5@{ label: "labe for n5"}
|
||||
`);
|
||||
@@ -317,7 +317,90 @@ describe('when parsing directions', function () {
|
||||
expect(data4Layout.nodes[3].label).toEqual('for E');
|
||||
expect(data4Layout.nodes[4].label).toEqual('for D');
|
||||
});
|
||||
it.skip(' should be possible to use @ syntax to add labels with trail spaces', function () {
|
||||
|
||||
it('should be possible to use @ syntax in labels', function () {
|
||||
const res = flow.parser.parse(`flowchart TD
|
||||
A["@A@"] --> B["@for@ B@"] & C@{ label: "@for@ c@"} & E{"\`@for@ E@\`"} & D(("@for@ D@"))
|
||||
H1{{"@for@ H@"}}
|
||||
H2{{"\`@for@ H@\`"}}
|
||||
Q1{"@for@ Q@"}
|
||||
Q2{"\`@for@ Q@\`"}
|
||||
AS1>"@for@ AS@"]
|
||||
AS2>"\`@for@ AS@\`"]
|
||||
`);
|
||||
|
||||
const data4Layout = flow.parser.yy.getData();
|
||||
expect(data4Layout.nodes.length).toBe(11);
|
||||
expect(data4Layout.nodes[0].label).toEqual('@A@');
|
||||
expect(data4Layout.nodes[1].label).toEqual('@for@ B@');
|
||||
expect(data4Layout.nodes[2].label).toEqual('@for@ c@');
|
||||
expect(data4Layout.nodes[3].label).toEqual('@for@ E@');
|
||||
expect(data4Layout.nodes[4].label).toEqual('@for@ D@');
|
||||
expect(data4Layout.nodes[5].label).toEqual('@for@ H@');
|
||||
expect(data4Layout.nodes[6].label).toEqual('@for@ H@');
|
||||
expect(data4Layout.nodes[7].label).toEqual('@for@ Q@');
|
||||
expect(data4Layout.nodes[8].label).toEqual('@for@ Q@');
|
||||
expect(data4Layout.nodes[9].label).toEqual('@for@ AS@');
|
||||
expect(data4Layout.nodes[10].label).toEqual('@for@ AS@');
|
||||
});
|
||||
|
||||
it('should handle unique edge creation with using @ and &', function () {
|
||||
const res = flow.parser.parse(`flowchart TD
|
||||
A & B e1@--> C & D
|
||||
A1 e2@--> C1 & D1
|
||||
`);
|
||||
|
||||
const data4Layout = flow.parser.yy.getData();
|
||||
expect(data4Layout.nodes.length).toBe(7);
|
||||
expect(data4Layout.edges.length).toBe(6);
|
||||
expect(data4Layout.edges[0].id).toEqual('L_A_C_0');
|
||||
expect(data4Layout.edges[1].id).toEqual('L_A_D_0');
|
||||
expect(data4Layout.edges[2].id).toEqual('e1');
|
||||
expect(data4Layout.edges[3].id).toEqual('L_B_D_0');
|
||||
expect(data4Layout.edges[4].id).toEqual('e2');
|
||||
expect(data4Layout.edges[5].id).toEqual('L_A1_D1_0');
|
||||
});
|
||||
|
||||
it('should handle redefine same edge ids again', function () {
|
||||
const res = flow.parser.parse(`flowchart TD
|
||||
A & B e1@--> C & D
|
||||
A1 e1@--> C1 & D1
|
||||
`);
|
||||
|
||||
const data4Layout = flow.parser.yy.getData();
|
||||
expect(data4Layout.nodes.length).toBe(7);
|
||||
expect(data4Layout.edges.length).toBe(6);
|
||||
expect(data4Layout.edges[0].id).toEqual('L_A_C_0');
|
||||
expect(data4Layout.edges[1].id).toEqual('L_A_D_0');
|
||||
expect(data4Layout.edges[2].id).toEqual('e1');
|
||||
expect(data4Layout.edges[3].id).toEqual('L_B_D_0');
|
||||
expect(data4Layout.edges[4].id).toEqual('L_A1_C1_0');
|
||||
expect(data4Layout.edges[5].id).toEqual('L_A1_D1_0');
|
||||
});
|
||||
|
||||
it('should handle overriding edge animate again', function () {
|
||||
const res = flow.parser.parse(`flowchart TD
|
||||
A e1@--> B
|
||||
C e2@--> D
|
||||
E e3@--> F
|
||||
e1@{ animate: true }
|
||||
e2@{ animate: false }
|
||||
e3@{ animate: true }
|
||||
e3@{ animate: false }
|
||||
`);
|
||||
|
||||
const data4Layout = flow.parser.yy.getData();
|
||||
expect(data4Layout.nodes.length).toBe(6);
|
||||
expect(data4Layout.edges.length).toBe(3);
|
||||
expect(data4Layout.edges[0].id).toEqual('e1');
|
||||
expect(data4Layout.edges[0].animate).toEqual(true);
|
||||
expect(data4Layout.edges[1].id).toEqual('e2');
|
||||
expect(data4Layout.edges[1].animate).toEqual(false);
|
||||
expect(data4Layout.edges[2].id).toEqual('e3');
|
||||
expect(data4Layout.edges[2].animate).toEqual(false);
|
||||
});
|
||||
|
||||
it.skip('should be possible to use @ syntax to add labels with trail spaces', function () {
|
||||
const res = flow.parser.parse(
|
||||
`flowchart TB
|
||||
n2["label for n2"] & n4@{ label: "labe for n4"} & n5@{ label: "labe for n5"} `
|
||||
|
@@ -141,7 +141,7 @@ that id.
|
||||
.*direction\s+RL[^\n]* return 'direction_rl';
|
||||
.*direction\s+LR[^\n]* return 'direction_lr';
|
||||
|
||||
[^\s]+\@(?=[^\{]) { return 'LINK_ID'; }
|
||||
[^\s\"]+\@(?=[^\{\"]) { return 'LINK_ID'; }
|
||||
[0-9]+ return 'NUM';
|
||||
\# return 'BRKT';
|
||||
":::" return 'STYLE_SEPARATOR';
|
||||
|
@@ -53,6 +53,7 @@ export interface FlowText {
|
||||
}
|
||||
|
||||
export interface FlowEdge {
|
||||
isUserDefinedId: boolean;
|
||||
start: string;
|
||||
end: string;
|
||||
interpolate?: string;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
const getStyles = (options) =>
|
||||
`
|
||||
.mermaid-main-font {
|
||||
font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif);
|
||||
font-family: ${options.fontFamily};
|
||||
}
|
||||
|
||||
.exclude-range {
|
||||
@@ -45,7 +45,7 @@ const getStyles = (options) =>
|
||||
|
||||
.sectionTitle {
|
||||
text-anchor: start;
|
||||
font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif);
|
||||
font-family: ${options.fontFamily};
|
||||
}
|
||||
|
||||
|
||||
@@ -86,13 +86,13 @@ const getStyles = (options) =>
|
||||
|
||||
.taskText {
|
||||
text-anchor: middle;
|
||||
font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif);
|
||||
font-family: ${options.fontFamily};
|
||||
}
|
||||
|
||||
.taskTextOutsideRight {
|
||||
fill: ${options.taskTextDarkColor};
|
||||
text-anchor: start;
|
||||
font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif);
|
||||
font-family: ${options.fontFamily};
|
||||
}
|
||||
|
||||
.taskTextOutsideLeft {
|
||||
@@ -248,7 +248,7 @@ const getStyles = (options) =>
|
||||
text-anchor: middle;
|
||||
font-size: 18px;
|
||||
fill: ${options.titleColor || options.textColor};
|
||||
font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif);
|
||||
font-family: ${options.fontFamily};
|
||||
}
|
||||
`;
|
||||
|
||||
|
@@ -4,11 +4,13 @@ import parser from './parser/sankey.jison';
|
||||
import db from './sankeyDB.js';
|
||||
import renderer from './sankeyRenderer.js';
|
||||
import { prepareTextForParsing } from './sankeyUtils.js';
|
||||
import sankeyStyles from './styles.js';
|
||||
|
||||
const originalParse = parser.parse.bind(parser);
|
||||
parser.parse = (text: string) => originalParse(prepareTextForParsing(text));
|
||||
|
||||
export const diagram: DiagramDefinition = {
|
||||
styles: sankeyStyles,
|
||||
parser,
|
||||
db,
|
||||
renderer,
|
||||
|
@@ -136,7 +136,6 @@ export const draw = function (text: string, id: string, _version: string, diagOb
|
||||
svg
|
||||
.append('g')
|
||||
.attr('class', 'node-labels')
|
||||
.attr('font-family', 'sans-serif')
|
||||
.attr('font-size', 14)
|
||||
.selectAll('text')
|
||||
.data(graph.nodes)
|
||||
|
6
packages/mermaid/src/diagrams/sankey/styles.js
Normal file
6
packages/mermaid/src/diagrams/sankey/styles.js
Normal file
@@ -0,0 +1,6 @@
|
||||
const getStyles = (options) =>
|
||||
`.label {
|
||||
font-family: ${options.fontFamily};
|
||||
}`;
|
||||
|
||||
export default getStyles;
|
@@ -1,7 +1,6 @@
|
||||
const getStyles = (options) =>
|
||||
`.label {
|
||||
font-family: 'trebuchet ms', verdana, arial, sans-serif;
|
||||
font-family: var(--mermaid-font-family);
|
||||
font-family: ${options.fontFamily};
|
||||
color: ${options.textColor};
|
||||
}
|
||||
.mouth {
|
||||
@@ -79,8 +78,7 @@ const getStyles = (options) =>
|
||||
text-align: center;
|
||||
max-width: 200px;
|
||||
padding: 2px;
|
||||
font-family: 'trebuchet ms', verdana, arial, sans-serif;
|
||||
font-family: var(--mermaid-font-family);
|
||||
font-family: ${options.fontFamily};
|
||||
font-size: 12px;
|
||||
background: ${options.tertiaryColor};
|
||||
border: 1px solid ${options.border2};
|
||||
|
@@ -125,6 +125,7 @@ export interface Edge {
|
||||
pattern?: string;
|
||||
thickness?: 'normal' | 'thick' | 'invisible' | 'dotted';
|
||||
look?: string;
|
||||
isUserDefinedId?: boolean;
|
||||
}
|
||||
|
||||
export interface RectOptions {
|
||||
|
Reference in New Issue
Block a user