mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-10-13 02:59:36 +02:00
add support for stereotype annotations for class diagrams
This commit is contained in:
@@ -1028,4 +1028,88 @@ class C13["With Città foreign language"]
|
|||||||
{ logLevel: 1, htmlLabels: true }
|
{ logLevel: 1, htmlLabels: true }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
it('should render a full class diagram using interface annotation', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
classDiagram
|
||||||
|
Class01 <|-- AveryLongClass : Cool
|
||||||
|
<<interface>> Class01
|
||||||
|
Class03 "0" *-- "0..n" Class04
|
||||||
|
Class05 "1" o-- "many" Class06
|
||||||
|
Class07 .. Class08
|
||||||
|
Class09 "many" --> "1" C2 : Where am i?
|
||||||
|
Class09 "0" --* "1..n" C3
|
||||||
|
Class09 --|> Class07
|
||||||
|
Class07 : equals()
|
||||||
|
Class07 : Object[] elementData
|
||||||
|
Class01 : #size()
|
||||||
|
Class01 : -int chimp
|
||||||
|
Class01 : +int gorilla
|
||||||
|
Class08 <--> C2: Cool label
|
||||||
|
class Class10 {
|
||||||
|
<<service>>
|
||||||
|
int id
|
||||||
|
size()
|
||||||
|
}
|
||||||
|
|
||||||
|
`,
|
||||||
|
{ logLevel: 1, htmlLabels: true }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('should render a full class diagram using abstract annotation', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
classDiagram
|
||||||
|
Class01 <|-- AveryLongClass : Cool
|
||||||
|
<<abstract>> Class01
|
||||||
|
Class03 "0" *-- "0..n" Class04
|
||||||
|
Class05 "1" o-- "many" Class06
|
||||||
|
Class07 .. Class08
|
||||||
|
Class09 "many" --> "1" C2 : Where am i?
|
||||||
|
Class09 "0" --* "1..n" C3
|
||||||
|
Class09 --|> Class07
|
||||||
|
Class07 : equals()
|
||||||
|
Class07 : Object[] elementData
|
||||||
|
Class01 : #size()
|
||||||
|
Class01 : -int chimp
|
||||||
|
Class01 : +int gorilla
|
||||||
|
Class08 <--> C2: Cool label
|
||||||
|
class Class10 {
|
||||||
|
<<service>>
|
||||||
|
int id
|
||||||
|
size()
|
||||||
|
}
|
||||||
|
|
||||||
|
`,
|
||||||
|
{ logLevel: 1, htmlLabels: true }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('should render a full class diagram using enumeration annotation', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
classDiagram
|
||||||
|
Class01 <|-- AveryLongClass : Cool
|
||||||
|
<<enumeration>> Class01
|
||||||
|
Class03 "0" *-- "0..n" Class04
|
||||||
|
Class05 "1" o-- "many" Class06
|
||||||
|
Class07 .. Class08
|
||||||
|
Class09 "many" --> "1" C2 : Where am i?
|
||||||
|
Class09 "0" --* "1..n" C3
|
||||||
|
Class09 --|> Class07
|
||||||
|
Class07 : equals()
|
||||||
|
Class07 : Object[] elementData
|
||||||
|
Class01 : #size()
|
||||||
|
Class01 : -int chimp
|
||||||
|
Class01 : +int gorilla
|
||||||
|
Class08 <--> C2: Cool label
|
||||||
|
class Class10 {
|
||||||
|
<<service>>
|
||||||
|
int id
|
||||||
|
size()
|
||||||
|
}
|
||||||
|
|
||||||
|
`,
|
||||||
|
{ logLevel: 1, htmlLabels: true }
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@@ -45,6 +45,36 @@ export async function textHelper<T extends SVGGraphicsElement>(
|
|||||||
|
|
||||||
labelGroup = shapeSvg.insert('g').attr('class', 'label-group text');
|
labelGroup = shapeSvg.insert('g').attr('class', 'label-group text');
|
||||||
await addText(labelGroup, node, 0, ['font-weight: bolder']);
|
await addText(labelGroup, node, 0, ['font-weight: bolder']);
|
||||||
|
// Determine styling based on annotations
|
||||||
|
let labelStyles = ['font-weight: bolder']; // Default bold style
|
||||||
|
let labelClass = 'classTitle';
|
||||||
|
|
||||||
|
if (node.annotations && node.annotations.length > 0) {
|
||||||
|
const annotation = node.annotations[0].toLowerCase();
|
||||||
|
switch (annotation) {
|
||||||
|
case 'abstract':
|
||||||
|
labelClass = 'classTitle abstract';
|
||||||
|
labelStyles = [];
|
||||||
|
break;
|
||||||
|
case 'enumeration':
|
||||||
|
labelClass = 'classTitle enumeration';
|
||||||
|
labelStyles = [];
|
||||||
|
break;
|
||||||
|
case 'interface':
|
||||||
|
labelClass = 'classTitle interface';
|
||||||
|
labelStyles = [];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
labelClass = 'classTitle';
|
||||||
|
labelStyles = ['font-weight: bolder'];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the CSS class to the label group
|
||||||
|
labelGroup.attr('class', `label-group text ${labelClass}`);
|
||||||
|
|
||||||
|
await addText(labelGroup, node, 0, labelStyles);
|
||||||
const labelGroupBBox = labelGroup.node()!.getBBox();
|
const labelGroupBBox = labelGroup.node()!.getBBox();
|
||||||
labelGroupHeight = labelGroupBBox.height;
|
labelGroupHeight = labelGroupBBox.height;
|
||||||
|
|
||||||
|
@@ -148,6 +148,18 @@ g.classGroup line {
|
|||||||
stroke: ${options.lineColor} !important;
|
stroke: ${options.lineColor} !important;
|
||||||
stroke-width: 1;
|
stroke-width: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.classTitle.abstract {
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
.classTitle.enumeration {
|
||||||
|
text-decoration: underline;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
.classTitle.interface {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
.edgeTerminals {
|
.edgeTerminals {
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
|
Reference in New Issue
Block a user