mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-10-23 07:59:39 +02:00
Compare commits
22 Commits
feature/66
...
fix-markdo
Author | SHA1 | Date | |
---|---|---|---|
![]() |
70c9e6e57a | ||
![]() |
1f8ba5591d | ||
![]() |
cd6f7a3019 | ||
![]() |
1f0cb96d16 | ||
![]() |
db4a837e9b | ||
![]() |
047b7fccc7 | ||
![]() |
a53c0d4305 | ||
![]() |
13f2040b37 | ||
![]() |
e351a7a488 | ||
![]() |
fe8597d0c8 | ||
![]() |
178ea182c3 | ||
![]() |
3a23372af4 | ||
![]() |
cd6f7192bf | ||
![]() |
ebb77578e8 | ||
![]() |
4d76af679b | ||
![]() |
b7b05f4a55 | ||
![]() |
44a6434e59 | ||
![]() |
37269b47b5 | ||
![]() |
560abf4218 | ||
![]() |
0943edc114 | ||
![]() |
40402a2bd9 | ||
![]() |
dc51c027d6 |
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'mermaid': patch
|
||||
---
|
||||
|
||||
fix: Correct viewBox casing and make SVGs responsive
|
5
.changeset/gold-ducks-sort.md
Normal file
5
.changeset/gold-ducks-sort.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'mermaid': patch
|
||||
---
|
||||
|
||||
fix: Proper separation between strings and markdown strings
|
@@ -1 +1 @@
|
||||
./packages/mermaid/CHANGELOG.md
|
||||
./packages/mermaid/CHANGELOG.md
|
@@ -1 +1 @@
|
||||
./packages/mermaid/src/docs/community/contributing.md
|
||||
./packages/mermaid/src/docs/community/contributing.md
|
@@ -99,7 +99,6 @@ export const openURLAndVerifyRendering = (
|
||||
cy.visit(url);
|
||||
cy.window().should('have.property', 'rendered', true);
|
||||
cy.get('svg').should('be.visible');
|
||||
cy.get('svg').should('not.have.attr', 'viewbox');
|
||||
|
||||
if (validation) {
|
||||
cy.get('svg').should(validation);
|
||||
|
@@ -661,19 +661,6 @@ class Class10
|
||||
{ logLevel: 1, htmlLabels: true, layout: 'elk' }
|
||||
);
|
||||
});
|
||||
|
||||
it('ELK: should render a class with a text label, members and multiple annotations', () => {
|
||||
imgSnapshotTest(
|
||||
`classDiagram
|
||||
class C1["Class 1 with text label"] {
|
||||
<<interface>> <<injected>>
|
||||
+member1
|
||||
}
|
||||
C1 --> C2`,
|
||||
{ logLevel: 1, htmlLabels: true, layout: 'elk' }
|
||||
);
|
||||
});
|
||||
|
||||
it('ELK: should render multiple classes with same text labels', () => {
|
||||
imgSnapshotTest(
|
||||
`classDiagram
|
||||
|
@@ -661,19 +661,6 @@ class Class10
|
||||
{ logLevel: 1, htmlLabels: true, look: 'handDrawn' }
|
||||
);
|
||||
});
|
||||
|
||||
it('HD: should render a class with a text label, membersand multiple annotations', () => {
|
||||
imgSnapshotTest(
|
||||
`classDiagram
|
||||
class C1["Class 1 with text label"] {
|
||||
<<interface>> <<injected>>
|
||||
+member1
|
||||
}
|
||||
C1 --> C2`,
|
||||
{ logLevel: 1, htmlLabels: true, look: 'handDrawn' }
|
||||
);
|
||||
});
|
||||
|
||||
it('HD: should render multiple classes with same text labels', () => {
|
||||
imgSnapshotTest(
|
||||
`classDiagram
|
||||
|
@@ -510,16 +510,6 @@ class Class10
|
||||
C1 --> C2`
|
||||
);
|
||||
});
|
||||
it('should render a class with a text label, members and multiple annotations', () => {
|
||||
imgSnapshotTest(
|
||||
`classDiagram
|
||||
class C1["Class 1 with text label"] {
|
||||
<<interface>> <<injected>>
|
||||
+member1
|
||||
}
|
||||
C1 --> C2`
|
||||
);
|
||||
});
|
||||
it('should render multiple classes with same text labels', () => {
|
||||
imgSnapshotTest(
|
||||
`classDiagram
|
||||
|
@@ -657,17 +657,6 @@ class Class10
|
||||
C1 --> C2`
|
||||
);
|
||||
});
|
||||
it('should render a class with a text label, members and multiple annotations', () => {
|
||||
imgSnapshotTest(
|
||||
`classDiagram
|
||||
class C1["Class 1 with text label"] {
|
||||
<<interface>> <<injected>>
|
||||
+member1
|
||||
}
|
||||
C1 --> C2`
|
||||
);
|
||||
});
|
||||
|
||||
it('should render multiple classes with same text labels', () => {
|
||||
imgSnapshotTest(
|
||||
`classDiagram
|
||||
|
@@ -452,20 +452,6 @@ describe('Class diagram', () => {
|
||||
<<Interface>> \`This\nTitle\nHas\nMany\nNewlines\`
|
||||
`);
|
||||
});
|
||||
it('should render with newlines in title and multiple annotations', () => {
|
||||
imgSnapshotTest(`
|
||||
classDiagram
|
||||
class \`This\nTitle\nHas\nMany\nNewlines\` {
|
||||
+String Also
|
||||
-String Many
|
||||
#int Members
|
||||
+And()
|
||||
-Many()
|
||||
#Methods()
|
||||
}
|
||||
<<Interface>> <<Service>> \`This\nTitle\nHas\nMany\nNewlines\`
|
||||
`);
|
||||
});
|
||||
|
||||
it('should handle newline title in namespace', () => {
|
||||
imgSnapshotTest(`
|
||||
|
@@ -1174,8 +1174,8 @@ end
|
||||
end
|
||||
githost["Github, Gitlab, BitBucket, etc."]
|
||||
githost2["\`Github, Gitlab, BitBucket, etc.\`"]
|
||||
a["1."]
|
||||
b["- x"]
|
||||
a["\`1.\`"]
|
||||
b["\`- x\`"]
|
||||
`;
|
||||
|
||||
it('should render raw strings', () => {
|
||||
|
@@ -1003,4 +1003,49 @@ graph TD
|
||||
}
|
||||
);
|
||||
});
|
||||
it('#5824: should be able to render string and markdown labels', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
flowchart TB
|
||||
mermaid{"What is\nyourmermaid version?"} --> v10["<11"] --"\`<**1**1\`"--> fine["No bug"]
|
||||
mermaid --> v11[">= v11"] -- ">= v11" --> broken["Affected by https://github.com/mermaid-js/mermaid/issues/5824"]
|
||||
subgraph subgraph1["\`How to fix **fix**\`"]
|
||||
broken --> B["B"]
|
||||
end
|
||||
githost["Github, Gitlab, BitBucket, etc."]
|
||||
githost2["\`Github, Gitlab, BitBucket, etc.\`"]
|
||||
a["1."]
|
||||
b["- x"]
|
||||
`,
|
||||
{
|
||||
flowchart: { htmlLabels: true },
|
||||
securityLevel: 'loose',
|
||||
}
|
||||
);
|
||||
});
|
||||
it('69: should render subgraphs with adhoc list headings', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
graph TB
|
||||
subgraph "1. first"
|
||||
a1-->a2
|
||||
end
|
||||
subgraph 2. second
|
||||
b1-->b2
|
||||
end
|
||||
`,
|
||||
{ fontFamily: 'courier' }
|
||||
);
|
||||
});
|
||||
it('70: should render subgraphs with markdown headings', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
graph TB
|
||||
subgraph "\`**strong**\`"
|
||||
a1-->a2
|
||||
end
|
||||
`,
|
||||
{ fontFamily: 'courier' }
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@@ -1,93 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<title>Class Diagram - Multiple Stereotypes Test</title>
|
||||
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=" />
|
||||
<style>
|
||||
div.mermaid {
|
||||
font-family: 'Courier New', Courier, monospace !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Multiple Stereotypes Test</h1>
|
||||
|
||||
<h2>Test 1: Inline with class definition (single)</h2>
|
||||
<pre class="mermaid">
|
||||
classDiagram
|
||||
class Shape <<interface>>
|
||||
</pre>
|
||||
|
||||
<h2>Test 2: Inline with class definition (multiple)</h2>
|
||||
<pre class="mermaid">
|
||||
classDiagram
|
||||
class Shape <<interface>> <<injected>>
|
||||
</pre>
|
||||
|
||||
<h2>Test 3: Separate line (single)</h2>
|
||||
<pre class="mermaid">
|
||||
classDiagram
|
||||
class Shape
|
||||
<<interface>> Shape
|
||||
</pre>
|
||||
|
||||
<h2>Test 4: Separate line (multiple)</h2>
|
||||
<pre class="mermaid">
|
||||
classDiagram
|
||||
class Shape
|
||||
<<interface>> <<injected>> Shape
|
||||
</pre>
|
||||
|
||||
<h2>Test 5: Inside class body (single)</h2>
|
||||
<pre class="mermaid">
|
||||
classDiagram
|
||||
class Shape{
|
||||
<<interface>>
|
||||
noOfVertices
|
||||
draw()
|
||||
}
|
||||
</pre>
|
||||
|
||||
<h2>Test 6: Inside class body (multiple on same line)</h2>
|
||||
<pre class="mermaid">
|
||||
classDiagram
|
||||
class Shape{
|
||||
<<interface>> <<injected>>
|
||||
noOfVertices
|
||||
draw()
|
||||
}
|
||||
</pre>
|
||||
|
||||
<h2>Test 7: Combined example</h2>
|
||||
<pre class="mermaid">
|
||||
classDiagram
|
||||
class Shape{
|
||||
<<interface>> <<injected>>
|
||||
noOfVertices
|
||||
draw()
|
||||
}
|
||||
class Color{
|
||||
<<enumeration>>
|
||||
RED
|
||||
BLUE
|
||||
GREEN
|
||||
WHITE
|
||||
BLACK
|
||||
}
|
||||
Shape <|-- Color
|
||||
</pre>
|
||||
|
||||
<hr />
|
||||
<script type="module">
|
||||
import mermaid from './mermaid.esm.mjs';
|
||||
mermaid.initialize({
|
||||
theme: 'default',
|
||||
logLevel: 3,
|
||||
securityLevel: 'loose',
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@@ -38,7 +38,7 @@
|
||||
+quack()
|
||||
}
|
||||
class Fish{
|
||||
-int sizeInFeet
|
||||
-Listint sizeInFeet
|
||||
-canEat()
|
||||
}
|
||||
class Zebra{
|
||||
@@ -143,7 +143,21 @@
|
||||
Pineapple : -int leafCount()
|
||||
Pineapple : -int spikeCount()
|
||||
</pre>
|
||||
<hr />
|
||||
|
||||
<pre class="mermaid">
|
||||
classDiagram
|
||||
class Person {
|
||||
+ID : Guid
|
||||
+FirstName : string
|
||||
+LastName : string
|
||||
-privateProperty : string
|
||||
#ProtectedProperty : string
|
||||
~InternalProperty : string
|
||||
~AnotherInternalProperty : List~List~string~~
|
||||
}
|
||||
class People List~List~Person~~
|
||||
</pre>
|
||||
<hr />
|
||||
<pre class="mermaid">
|
||||
classDiagram
|
||||
|
@@ -10,7 +10,7 @@
|
||||
|
||||
# Interface: ParseOptions
|
||||
|
||||
Defined in: [packages/mermaid/src/types.ts:88](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L88)
|
||||
Defined in: [packages/mermaid/src/types.ts:89](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L89)
|
||||
|
||||
## Properties
|
||||
|
||||
@@ -18,7 +18,7 @@ Defined in: [packages/mermaid/src/types.ts:88](https://github.com/mermaid-js/mer
|
||||
|
||||
> `optional` **suppressErrors**: `boolean`
|
||||
|
||||
Defined in: [packages/mermaid/src/types.ts:93](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L93)
|
||||
Defined in: [packages/mermaid/src/types.ts:94](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L94)
|
||||
|
||||
If `true`, parse will return `false` instead of throwing error when the diagram is invalid.
|
||||
The `parseError` function will not be called.
|
||||
|
@@ -10,7 +10,7 @@
|
||||
|
||||
# Interface: ParseResult
|
||||
|
||||
Defined in: [packages/mermaid/src/types.ts:96](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L96)
|
||||
Defined in: [packages/mermaid/src/types.ts:97](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L97)
|
||||
|
||||
## Properties
|
||||
|
||||
@@ -18,7 +18,7 @@ Defined in: [packages/mermaid/src/types.ts:96](https://github.com/mermaid-js/mer
|
||||
|
||||
> **config**: [`MermaidConfig`](MermaidConfig.md)
|
||||
|
||||
Defined in: [packages/mermaid/src/types.ts:104](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L104)
|
||||
Defined in: [packages/mermaid/src/types.ts:105](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L105)
|
||||
|
||||
The config passed as YAML frontmatter or directives
|
||||
|
||||
@@ -28,6 +28,6 @@ The config passed as YAML frontmatter or directives
|
||||
|
||||
> **diagramType**: `string`
|
||||
|
||||
Defined in: [packages/mermaid/src/types.ts:100](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L100)
|
||||
Defined in: [packages/mermaid/src/types.ts:101](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L101)
|
||||
|
||||
The diagram type, e.g. 'flowchart', 'sequence', etc.
|
||||
|
@@ -10,7 +10,7 @@
|
||||
|
||||
# Interface: RenderResult
|
||||
|
||||
Defined in: [packages/mermaid/src/types.ts:114](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L114)
|
||||
Defined in: [packages/mermaid/src/types.ts:115](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L115)
|
||||
|
||||
## Properties
|
||||
|
||||
@@ -18,7 +18,7 @@ Defined in: [packages/mermaid/src/types.ts:114](https://github.com/mermaid-js/me
|
||||
|
||||
> `optional` **bindFunctions**: (`element`) => `void`
|
||||
|
||||
Defined in: [packages/mermaid/src/types.ts:132](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L132)
|
||||
Defined in: [packages/mermaid/src/types.ts:133](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L133)
|
||||
|
||||
Bind function to be called after the svg has been inserted into the DOM.
|
||||
This is necessary for adding event listeners to the elements in the svg.
|
||||
@@ -45,7 +45,7 @@ bindFunctions?.(div); // To call bindFunctions only if it's present.
|
||||
|
||||
> **diagramType**: `string`
|
||||
|
||||
Defined in: [packages/mermaid/src/types.ts:122](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L122)
|
||||
Defined in: [packages/mermaid/src/types.ts:123](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L123)
|
||||
|
||||
The diagram type, e.g. 'flowchart', 'sequence', etc.
|
||||
|
||||
@@ -55,6 +55,6 @@ The diagram type, e.g. 'flowchart', 'sequence', etc.
|
||||
|
||||
> **svg**: `string`
|
||||
|
||||
Defined in: [packages/mermaid/src/types.ts:118](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L118)
|
||||
Defined in: [packages/mermaid/src/types.ts:119](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L119)
|
||||
|
||||
The svg code for the rendered graph.
|
||||
|
@@ -21,7 +21,7 @@ title: Animal example
|
||||
classDiagram
|
||||
note "From Duck till Zebra"
|
||||
Animal <|-- Duck
|
||||
note for Duck "can fly<br>can swim<br>can dive<br>can help in debugging"
|
||||
note for Duck "can fly\ncan swim\ncan dive\ncan help in debugging"
|
||||
Animal <|-- Fish
|
||||
Animal <|-- Zebra
|
||||
Animal : +int age
|
||||
@@ -50,7 +50,7 @@ title: Animal example
|
||||
classDiagram
|
||||
note "From Duck till Zebra"
|
||||
Animal <|-- Duck
|
||||
note for Duck "can fly<br>can swim<br>can dive<br>can help in debugging"
|
||||
note for Duck "can fly\ncan swim\ncan dive\ncan help in debugging"
|
||||
Animal <|-- Fish
|
||||
Animal <|-- Zebra
|
||||
Animal : +int age
|
||||
|
@@ -18,7 +18,6 @@
|
||||
%x acc_descr_multiline
|
||||
%x class
|
||||
%x class-body
|
||||
%x class-body-annotation
|
||||
%x namespace
|
||||
%x namespace-body
|
||||
%%
|
||||
@@ -83,16 +82,9 @@ Function arguments are optional: 'call <callback_name>()' simply executes 'callb
|
||||
<class-body><<EOF>> return "EOF_IN_STRUCT";
|
||||
<class-body>"[*]" { return 'EDGE_STATE';}
|
||||
<class-body>[{] return "OPEN_IN_STRUCT";
|
||||
<class-body>"<<" { this.begin("class-body-annotation"); return 'ANNOTATION_START';}
|
||||
<class-body>[\n] /* nothing */
|
||||
<class-body>[ \t]+ /* skip whitespace in class body */
|
||||
<class-body>[^{}\n]* { return "MEMBER";}
|
||||
|
||||
<class-body-annotation>">>" { this.popState(); return 'ANNOTATION_END';}
|
||||
<class-body-annotation>[0-9]+ return 'NUM';
|
||||
<class-body-annotation>\w+ return 'ALPHA';
|
||||
<class-body-annotation>[\s]+ /* ignore whitespace */
|
||||
|
||||
<*>"cssClass" return 'CSSCLASS';
|
||||
<*>"callback" return 'CALLBACK';
|
||||
<*>"link" return 'LINK';
|
||||
@@ -302,26 +294,12 @@ classStatement
|
||||
| classIdentifier STYLE_SEPARATOR alphaNumToken {yy.setCssClass($1, $3);}
|
||||
| classIdentifier STRUCT_START members STRUCT_STOP {yy.addMembers($1,$3);}
|
||||
| classIdentifier STRUCT_START STRUCT_STOP {}
|
||||
| classIdentifier STRUCT_START NEWLINE members STRUCT_STOP {yy.addMembers($1,$4);}
|
||||
| classIdentifier STRUCT_START annotationList members STRUCT_STOP {for(const annotation of $3) { yy.addAnnotation($1, annotation); } yy.addMembers($1,$4);}
|
||||
| classIdentifier STRUCT_START annotationList STRUCT_STOP {for(const annotation of $3) { yy.addAnnotation($1, annotation); }}
|
||||
| classIdentifier STRUCT_START NEWLINE annotationList members STRUCT_STOP {for(const annotation of $4) { yy.addAnnotation($1, annotation); } yy.addMembers($1,$5);}
|
||||
| classIdentifier STRUCT_START NEWLINE annotationList STRUCT_STOP {for(const annotation of $4) { yy.addAnnotation($1, annotation); }}
|
||||
| classIdentifier STYLE_SEPARATOR alphaNumToken STRUCT_START members STRUCT_STOP {yy.setCssClass($1, $3);yy.addMembers($1,$5);}
|
||||
| classIdentifier STYLE_SEPARATOR alphaNumToken STRUCT_START NEWLINE members STRUCT_STOP {yy.setCssClass($1, $3);yy.addMembers($1,$6);}
|
||||
| classIdentifier STYLE_SEPARATOR alphaNumToken STRUCT_START annotationList members STRUCT_STOP {yy.setCssClass($1, $3); for(const annotation of $5) { yy.addAnnotation($1, annotation); } yy.addMembers($1,$6);}
|
||||
| classIdentifier STYLE_SEPARATOR alphaNumToken STRUCT_START annotationList STRUCT_STOP {yy.setCssClass($1, $3); for(const annotation of $5) { yy.addAnnotation($1, annotation); }}
|
||||
| classIdentifier STYLE_SEPARATOR alphaNumToken STRUCT_START NEWLINE annotationList members STRUCT_STOP {yy.setCssClass($1, $3); for(const annotation of $6) { yy.addAnnotation($1, annotation); } yy.addMembers($1,$7);}
|
||||
| classIdentifier STYLE_SEPARATOR alphaNumToken STRUCT_START NEWLINE annotationList STRUCT_STOP {yy.setCssClass($1, $3); for(const annotation of $6) { yy.addAnnotation($1, annotation); }}
|
||||
;
|
||||
|
||||
classIdentifier
|
||||
: CLASS className {$$=$2; yy.addClass($2);}
|
||||
| CLASS className ANNOTATION_START alphaNumToken ANNOTATION_END {$$=$2; yy.addClass($2); yy.addAnnotation($2,$4);}
|
||||
| CLASS className annotationList {$$=$2; yy.addClass($2); for(const annotation of $3) { yy.addAnnotation($2, annotation); }}
|
||||
| CLASS className classLabel {$$=$2; yy.addClass($2);yy.setClassLabel($2, $3);}
|
||||
| CLASS className classLabel ANNOTATION_START alphaNumToken ANNOTATION_END {$$=$2; yy.addClass($2);yy.setClassLabel($2, $3); yy.addAnnotation($2,$5);}
|
||||
| CLASS className classLabel annotationList {$$=$2; yy.addClass($2);yy.setClassLabel($2, $3); for(const annotation of $4) { yy.addAnnotation($2, annotation); }}
|
||||
;
|
||||
|
||||
|
||||
@@ -333,12 +311,6 @@ emptyBody
|
||||
|
||||
annotationStatement
|
||||
: ANNOTATION_START alphaNumToken ANNOTATION_END className { yy.addAnnotation($4,$2); }
|
||||
| annotationList className { for(const annotation of $1) { yy.addAnnotation($2, annotation); } }
|
||||
;
|
||||
|
||||
annotationList
|
||||
: ANNOTATION_START alphaNumToken ANNOTATION_END { $$ = [$2]; }
|
||||
| annotationList ANNOTATION_START alphaNumToken ANNOTATION_END { $1.push($3); $$ = $1; }
|
||||
;
|
||||
|
||||
members
|
||||
|
@@ -36,8 +36,8 @@ export async function textHelper<T extends SVGGraphicsElement>(
|
||||
|
||||
annotationGroup = shapeSvg.insert('g').attr('class', 'annotation-group text');
|
||||
if (node.annotations.length > 0) {
|
||||
const annotationText = node.annotations.map((a: string) => `«${a}»`).join('\n');
|
||||
await addText(annotationGroup, { text: annotationText } as unknown as ClassMember, 0);
|
||||
const annotation = node.annotations[0];
|
||||
await addText(annotationGroup, { text: `«${annotation}»` } as unknown as ClassMember, 0);
|
||||
|
||||
const annotationGroupBBox = annotationGroup.node()!.getBBox();
|
||||
annotationGroupHeight = annotationGroupBBox.height;
|
||||
|
@@ -85,6 +85,17 @@ export class FlowDB implements DiagramDB {
|
||||
return common.sanitizeText(txt, this.config);
|
||||
}
|
||||
|
||||
private sanitizeNodeLabelType(labelType?: string) {
|
||||
switch (labelType) {
|
||||
case 'markdown':
|
||||
case 'string':
|
||||
case 'text':
|
||||
return labelType;
|
||||
default:
|
||||
return 'markdown';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to lookup domId from id in the graph definition.
|
||||
*
|
||||
@@ -208,6 +219,7 @@ export class FlowDB implements DiagramDB {
|
||||
|
||||
if (doc?.label) {
|
||||
vertex.text = doc?.label;
|
||||
vertex.labelType = this.sanitizeNodeLabelType(doc?.labelType);
|
||||
}
|
||||
if (doc?.icon) {
|
||||
vertex.icon = doc?.icon;
|
||||
@@ -267,7 +279,7 @@ export class FlowDB implements DiagramDB {
|
||||
if (edge.text.startsWith('"') && edge.text.endsWith('"')) {
|
||||
edge.text = edge.text.substring(1, edge.text.length - 1);
|
||||
}
|
||||
edge.labelType = linkTextObj.type;
|
||||
edge.labelType = this.sanitizeNodeLabelType(linkTextObj.type);
|
||||
}
|
||||
|
||||
if (type !== undefined) {
|
||||
@@ -702,7 +714,7 @@ You have to call mermaid.initialize.`
|
||||
title: title.trim(),
|
||||
classes: [],
|
||||
dir,
|
||||
labelType: _title.type,
|
||||
labelType: this.sanitizeNodeLabelType(_title?.type),
|
||||
};
|
||||
|
||||
log.info('Adding', subGraph.id, subGraph.nodes, subGraph.dir);
|
||||
@@ -1012,6 +1024,7 @@ You have to call mermaid.initialize.`
|
||||
const baseNode = {
|
||||
id: vertex.id,
|
||||
label: vertex.text,
|
||||
labelType: vertex.labelType,
|
||||
labelStyle: '',
|
||||
parentId,
|
||||
padding: config.flowchart?.padding || 8,
|
||||
@@ -1088,6 +1101,7 @@ You have to call mermaid.initialize.`
|
||||
id: subGraph.id,
|
||||
label: subGraph.title,
|
||||
labelStyle: '',
|
||||
labelType: subGraph.labelType,
|
||||
parentId: parentDB.get(subGraph.id),
|
||||
padding: 8,
|
||||
cssCompiledStyles: this.getCompiledStyles(subGraph.classes),
|
||||
@@ -1119,6 +1133,7 @@ You have to call mermaid.initialize.`
|
||||
end: rawEdge.end,
|
||||
type: rawEdge.type ?? 'normal',
|
||||
label: rawEdge.text,
|
||||
labelType: rawEdge.labelType,
|
||||
labelpos: 'c',
|
||||
thickness: rawEdge.stroke,
|
||||
minlen: rawEdge.length,
|
||||
|
@@ -29,7 +29,7 @@ export interface FlowVertex {
|
||||
domId: string;
|
||||
haveCallback?: boolean;
|
||||
id: string;
|
||||
labelType: 'text';
|
||||
labelType: 'markdown' | 'string' | 'text';
|
||||
link?: string;
|
||||
linkTarget?: string;
|
||||
props?: any;
|
||||
@@ -62,7 +62,7 @@ export interface FlowEdge {
|
||||
style?: string[];
|
||||
length?: number;
|
||||
text: string;
|
||||
labelType: 'text';
|
||||
labelType: 'markdown' | 'string' | 'text';
|
||||
classes: string[];
|
||||
id?: string;
|
||||
animation?: 'fast' | 'slow';
|
||||
|
@@ -62,6 +62,7 @@ const getData = function () {
|
||||
const node = {
|
||||
id: section.id,
|
||||
label: sanitizeText(section.label ?? '', conf),
|
||||
labelType: 'markdown',
|
||||
isGroup: true,
|
||||
ticket: section.ticket,
|
||||
shape: 'kanbanSection',
|
||||
@@ -76,6 +77,7 @@ const getData = function () {
|
||||
id: item.id,
|
||||
parentId: section.id,
|
||||
label: sanitizeText(item.label ?? '', conf),
|
||||
labelType: 'markdown',
|
||||
isGroup: false,
|
||||
ticket: item?.ticket,
|
||||
priority: item?.priority,
|
||||
|
@@ -260,6 +260,7 @@ export class MindmapDB {
|
||||
id: node.id.toString(),
|
||||
domId: 'node_' + node.id.toString(),
|
||||
label: node.descr,
|
||||
labelType: 'markdown',
|
||||
isGroup: false,
|
||||
shape: getShapeFromType(node.type),
|
||||
width: node.width,
|
||||
|
@@ -16,6 +16,7 @@ export interface MindmapNode {
|
||||
x?: number;
|
||||
y?: number;
|
||||
isRoot?: boolean;
|
||||
labelType?: string;
|
||||
}
|
||||
|
||||
export type FilledMindMapNode = RequiredDeep<MindmapNode>;
|
||||
|
@@ -16,7 +16,7 @@ const draw: DrawDefinition = (_text, id, _version, diagram: Diagram) => {
|
||||
const svgWidth = bitWidth * bitsPerRow + 2;
|
||||
const svg: SVG = selectSvgElement(id);
|
||||
|
||||
svg.attr('viewBox', `0 0 ${svgWidth} ${svgHeight}`);
|
||||
svg.attr('viewbox', `0 0 ${svgWidth} ${svgHeight}`);
|
||||
configureSvgSize(svg, svgHeight, svgWidth, config.useMaxWidth);
|
||||
|
||||
for (const [word, packet] of words.entries()) {
|
||||
|
@@ -2,7 +2,6 @@ import type { Diagram } from '../../Diagram.js';
|
||||
import type { RadarDiagramConfig } from '../../config.type.js';
|
||||
import type { DiagramRenderer, DrawDefinition, SVG, SVGGroup } from '../../diagram-api/types.js';
|
||||
import { selectSvgElement } from '../../rendering-util/selectSvgElement.js';
|
||||
import { configureSvgSize } from '../../setupGraphViewbox.js';
|
||||
import type { RadarDB, RadarAxis, RadarCurve } from './types.js';
|
||||
|
||||
const draw: DrawDefinition = (_text, id, _version, diagram: Diagram) => {
|
||||
@@ -54,9 +53,11 @@ const drawFrame = (svg: SVG, config: Required<RadarDiagramConfig>): SVGGroup =>
|
||||
x: config.marginLeft + config.width / 2,
|
||||
y: config.marginTop + config.height / 2,
|
||||
};
|
||||
configureSvgSize(svg, totalHeight, totalWidth, config.useMaxWidth ?? true);
|
||||
|
||||
svg.attr('viewBox', `0 0 ${totalWidth} ${totalHeight}`);
|
||||
// Initialize the SVG
|
||||
svg
|
||||
.attr('viewbox', `0 0 ${totalWidth} ${totalHeight}`)
|
||||
.attr('width', totalWidth)
|
||||
.attr('height', totalHeight);
|
||||
// g element to center the radar chart
|
||||
return svg.append('g').attr('transform', `translate(${center.x}, ${center.y})`);
|
||||
};
|
||||
|
@@ -15,7 +15,7 @@ title: Animal example
|
||||
classDiagram
|
||||
note "From Duck till Zebra"
|
||||
Animal <|-- Duck
|
||||
note for Duck "can fly<br>can swim<br>can dive<br>can help in debugging"
|
||||
note for Duck "can fly\ncan swim\ncan dive\ncan help in debugging"
|
||||
Animal <|-- Fish
|
||||
Animal <|-- Zebra
|
||||
Animal : +int age
|
||||
@@ -358,19 +358,17 @@ It is possible to annotate classes with markers to provide additional metadata a
|
||||
- `<<Service>>` To represent a service class
|
||||
- `<<Enumeration>>` To represent an enum
|
||||
|
||||
Annotations are defined within the opening `<<` and closing `>>`. There are multiple ways to add an annotation to a class, which all result in the same output, and you can add multiple annotations by adding others on the same line:
|
||||
Annotations are defined within the opening `<<` and closing `>>`. There are two ways to add an annotation to a class, and either way the output will be same:
|
||||
|
||||
> **Tip:**
|
||||
> In Mermaid class diagrams, annotations like `<<interface>>` can be attached in two ways:
|
||||
>
|
||||
> - **Inline with the class definition** (Recommended for consistency):
|
||||
>
|
||||
> ```mermaid-example
|
||||
> classDiagram
|
||||
> class Shape <<interface>>
|
||||
> ```
|
||||
|
||||
> ```mermaid-example
|
||||
> classDiagram
|
||||
> class Shape <<interface>> <<injected>>
|
||||
> ```
|
||||
>
|
||||
> - **Separate line after the class definition**:
|
||||
>
|
||||
@@ -380,18 +378,25 @@ Annotations are defined within the opening `<<` and closing `>>`. There are mult
|
||||
> <<interface>> Shape
|
||||
> ```
|
||||
>
|
||||
> ```mermaid-example
|
||||
> classDiagram
|
||||
> class Shape
|
||||
> <<interface>> <<injected>> Shape
|
||||
> ```
|
||||
> Both methods are fully supported and produce identical diagrams.
|
||||
> However, it is recommended to use the **inline style** for better readability and consistent formatting across diagrams.
|
||||
|
||||
> In a **_nested structure_** along with the class definition:
|
||||
- In a **_separate line_** after a class is defined:
|
||||
|
||||
```mermaid-example
|
||||
classDiagram
|
||||
class Shape
|
||||
<<interface>> Shape
|
||||
Shape : noOfVertices
|
||||
Shape : draw()
|
||||
```
|
||||
|
||||
- In a **_nested structure_** along with the class definition:
|
||||
|
||||
```mermaid-example
|
||||
classDiagram
|
||||
class Shape{
|
||||
<<interface>> <<injected>>
|
||||
<<interface>>
|
||||
noOfVertices
|
||||
draw()
|
||||
}
|
||||
|
@@ -30,11 +30,17 @@ const rect = async (parent, node) => {
|
||||
// Create the label and insert it after the rect
|
||||
const labelEl = shapeSvg.insert('g').attr('class', 'cluster-label ');
|
||||
|
||||
const text = await createText(labelEl, node.label, {
|
||||
style: node.labelStyle,
|
||||
useHtmlLabels,
|
||||
isNode: true,
|
||||
});
|
||||
let text;
|
||||
if (node.labelType === 'markdown') {
|
||||
text = await createText(labelEl, node.label, {
|
||||
style: node.labelStyle,
|
||||
useHtmlLabels,
|
||||
isNode: true,
|
||||
});
|
||||
} else {
|
||||
const labelElement = await createLabel(node.label, node.labelStyle, false, true);
|
||||
text = labelEl.node()?.appendChild(labelElement);
|
||||
}
|
||||
|
||||
// Get the size of the label
|
||||
let bbox = text.getBBox();
|
||||
|
@@ -29,7 +29,7 @@ import {
|
||||
import rough from 'roughjs';
|
||||
import createLabel from './createLabel.js';
|
||||
import { addEdgeMarkers } from './edgeMarker.ts';
|
||||
import { isLabelStyle, styles2String } from './shapes/handDrawnShapeStyles.js';
|
||||
import { isLabelStyle } from './shapes/handDrawnShapeStyles.js';
|
||||
|
||||
export const edgeLabels = new Map();
|
||||
export const terminalLabels = new Map();
|
||||
@@ -47,14 +47,16 @@ export const getLabelStyles = (styleArray) => {
|
||||
export const insertEdgeLabel = async (elem, edge) => {
|
||||
let useHtmlLabels = evaluate(getConfig().flowchart.htmlLabels);
|
||||
|
||||
const { labelStyles } = styles2String(edge);
|
||||
edge.labelStyle = labelStyles;
|
||||
const labelElement = await createText(elem, edge.label, {
|
||||
style: edge.labelStyle,
|
||||
useHtmlLabels,
|
||||
addSvgBackground: true,
|
||||
isNode: false,
|
||||
});
|
||||
const labelElement =
|
||||
edge.labelType === 'markdown'
|
||||
? await createText(elem, edge.label, {
|
||||
style: getLabelStyles(edge.labelStyle),
|
||||
useHtmlLabels,
|
||||
addSvgBackground: true,
|
||||
isNode: false,
|
||||
})
|
||||
: await createLabel(edge.label, getLabelStyles(edge.labelStyle), undefined, false);
|
||||
|
||||
log.info('abc82', edge, edge.labelType);
|
||||
|
||||
// Create outer g, edgeLabel, this will be positioned after graph layout
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import createLabel from '../createLabel.js';
|
||||
import { createText } from '../../createText.js';
|
||||
import type { Node } from '../../types.js';
|
||||
import { getConfig } from '../../../diagram-api/diagramAPI.js';
|
||||
@@ -13,7 +14,7 @@ export const labelHelper = async <T extends SVGGraphicsElement>(
|
||||
_classes?: string
|
||||
) => {
|
||||
let cssClasses;
|
||||
const useHtmlLabels = node.useHtmlLabels || evaluate(getConfig()?.htmlLabels);
|
||||
const useHtmlLabels = node.useHtmlLabels || evaluate(getConfig()?.flowchart?.htmlLabels);
|
||||
if (!_classes) {
|
||||
cssClasses = 'node default';
|
||||
} else {
|
||||
@@ -40,14 +41,26 @@ export const labelHelper = async <T extends SVGGraphicsElement>(
|
||||
label = typeof node.label === 'string' ? node.label : node.label[0];
|
||||
}
|
||||
|
||||
const text = await createText(labelEl, sanitizeText(decodeEntities(label), getConfig()), {
|
||||
useHtmlLabels,
|
||||
width: node.width || getConfig().flowchart?.wrappingWidth,
|
||||
// @ts-expect-error -- This is currently not used. Should this be `classes` instead?
|
||||
cssClasses: 'markdown-node-label',
|
||||
style: node.labelStyle,
|
||||
addSvgBackground: !!node.icon || !!node.img,
|
||||
});
|
||||
let text;
|
||||
if (node.labelType === 'markdown') {
|
||||
text = await createText(labelEl, sanitizeText(decodeEntities(label), getConfig()), {
|
||||
useHtmlLabels,
|
||||
width: node.width || getConfig().flowchart?.wrappingWidth,
|
||||
// @ts-expect-error -- This is currently not used. Should this be `classes` instead?
|
||||
cssClasses: 'markdown-node-label',
|
||||
style: node.labelStyle,
|
||||
addSvgBackground: !!node.icon || !!node.img,
|
||||
});
|
||||
} else {
|
||||
const labelElement = await createLabel(
|
||||
sanitizeText(decodeEntities(label), getConfig()),
|
||||
node.labelStyle,
|
||||
false,
|
||||
true
|
||||
);
|
||||
text = labelEl.node()?.appendChild(labelElement);
|
||||
}
|
||||
|
||||
// Get the size of the label
|
||||
let bbox = text.getBBox();
|
||||
const halfPadding = (node?.padding ?? 0) / 2;
|
||||
|
@@ -1,6 +1,7 @@
|
||||
export interface NodeMetaData {
|
||||
shape?: string;
|
||||
label?: string;
|
||||
labelType?: string;
|
||||
icon?: string;
|
||||
form?: string;
|
||||
pos?: 't' | 'b';
|
||||
|
Reference in New Issue
Block a user