官网:https://mermaid.js.org/syntax/classDiagram.html
参考文档
版本号:9.3.0
本文由 大侠(AhcaoZhu)翻译整理。
在软件工程中,统一建模语言(UML)中的类图是一种静态结构图,它通过显示系统的类、它们的属性、操作(或方法)以及对象之间的关系来描述系统的结构。
——摘自维基百科
类图是面向对象建模的主要构建块。它用于应用程序结构的一般概念建模,以及用于将模型转换为编程代码的详细建模。类图也可以用于数据建模。类图中的类既表示主要元素、应用程序中的交互,也表示要编程的类。
Mermaid可以渲染类图。
代码:
classDiagram
note "From Duck till Zebra"
Animal <|-- Duck
note for Duck "can fly\ncan swim\ncan dive\ncan help in debugging"
Animal <|-- Fish
Animal <|-- Zebra
Animal : +int age
Animal : +String gender
Animal: +isMammal()
Animal: +mate()
class Duck{
+String beakColor
+swim()
+quack()
}
class Fish{
-int sizeInFeet
-canEat()
}
class Zebra{
+bool is_wild
+run()
}
译者注:
- CSDN目前暂不支持
title
、note
UML提供了表示类成员的机制,例如属性和方法,以及关于它们的附加信息。图中一个类的单个实例包含三个部分:
**顶部的隔层包含类的名称。**它以粗体居中印刷,第一个字母是大写的。它还可以包含描述类性质的可选注释文本。
**中间的隔区包含类的属性。**它们左对齐,第一个字母是小写。
**底部隔间包含类可以执行的操作。**它们也是左对齐的,并且第一个字母是小写的。
代码:
classDiagram
class BankAccount
BankAccount : +String owner
BankAccount : +Bigdecimal balance
BankAccount : +deposit(amount)
BankAccount : +withdrawal(amount)
定义类有两种方式: 显式地使用关键字class,如class Animal,它将定义Animal类。
通过一次定义两个类及其关系的关系。例如, Vehicle <|-- Car.
代码:
classDiagram
class Animal
Vehicle <|-- Car
命名约定:类名应该只由字母数字字符(包括unicode)和下划线组成。
UML提供了一些机制来表示类成员,如属性和方法,以及关于它们的附加信息。
Mermaid根据括号()是否存在来区分属性和函数/方法。带有()的被视为函数/方法,而所有其他的被视为属性。
定义类的成员有两种方法,无论使用哪种语法定义成员,输出都是相同的。这两种不同的方法是:
使用:(冒号)后跟成员名来关联类的成员,这对于一次定义一个成员很有用。例如:
代码:
classDiagram
class BankAccount
BankAccount : +String owner
BankAccount : +BigDecimal balance
BankAccount : +deposit(amount)
BankAccount : +withdrawal(amount)
类的关联成员使用{}括号,其中成员用花括号分组。适合同时定义多个成员。例如:
代码:
classDiagram
class BankAccount{
+String owner
+BigDecimal balance
+deposit(amount)
+withdrawal(amount)
}
您还可以选择使用将要返回的数据类型(注意:右括号和返回类型之间必须有空格)来结束方法/函数定义。一个例子:
代码:
classDiagram
class BankAccount{
+String owner
+BigDecimal balance
+deposit(amount) bool
+withdrawal(amount) int
}
成员可以使用泛型类型定义,例如List,用于字段、参数和返回类型,方法是将类型包含在~(波浪号)中。注意:嵌套类型声明,如List,目前不支持。
泛型可以表示为类定义的一部分,也可以表示为方法/函数的参数或返回值:
代码:
classDiagram
class Square~Shape~{
int id
List~int~ position
setPoints(List~int~ points)
getPoints() List~int~
}
Square : -List~string~ messages
Square : +setMessages(List~string~ messages)
Square : +getMessages() List~string~
您还可以选择使用将返回的数据类型结束方法/函数定义。
为了描述作为类(即类成员)一部分的属性或方法/函数的可见性(或封装性),可以在成员名之前加上可选的符号:
+ Public
- Private
# Protected
~ Package/Internal
注意,你也可以在方法定义中添加额外的分类器,方法是在方法的末尾添加以下符号,即:在()之后:
* Abstract e.g.:
someAbstractMethod()*
$ Static e.g.:someStaticMethod()$
请注意,您还可以通过在字段名称的末尾添加以下符号,在字段定义中包含其他分类符:
$ Static e.g.:String someField$
关系是一个通用术语,涵盖了在类图和对象图中发现的特定类型的逻辑连接。
[classA][Arrow][ClassB]
目前支持的UML下为类定义了八种不同类型的关系:
Type | Description |
---|---|
<|– | Inheritance继承 |
*– | Composition构成 |
o– | Aggregation聚合 |
–> | Association关联 |
– | Link (Solid)链接(实线) |
…> | Dependency依赖 |
…|> | Realization实现 |
… | Link (Dashed)链接(虚线) |
代码: |
classDiagram
classA <|-- classB
classC *-- classD
classE o-- classF
classG <-- classH
classI -- classJ
classK <.. classL
classM <|.. classN
classO .. classP
我们可以用标签来描述两个类之间关系的本质。同样,箭头也可以用在相反的方向:
代码:
classDiagram
classA --|> classB : Inheritance
classC --* classD : Composition
classE --o classF : Aggregation
classG --> classH : Association
classI -- classJ : Link(Solid)
classK ..> classL : Dependency
classM ..|> classN : Realization
classO .. classP : Link(Dashed)
可以为关系加上一个标签:
[classA][Arrow][ClassB]:LabelText
代码:
关系可以在逻辑上表示N:M关联:
代码:
classDiagram
Animal <|--|> Zebra
下面是语法:
[Relation Type][Link][Relation Type]
关系类型可以是以下的其中一种:
Type | Description |
---|---|
<| | Inheritance |
* | Composition |
o | Aggregation |
> | Association |
< | Association |
|> | Realization |
链接可以是以下::
Type | Description |
---|---|
– | Solid实线 |
… | Dashed虚线 |
类图中的多重性或基数表示可以链接到另一个类的实例的一个类的实例的数量。例如,每个公司将有一个或多个员工(不是零),每个员工目前为零家或一家公司工作。
多重符号放置在关联的末尾。
不同的基数选项有:
[classA] "cardinality1" [Arrow] "cardinality2" [ClassB]:LabelText
代码:
classDiagram
Customer "1" --> "*" Ticket
Student "1" --> "1..*" Course
Galaxy --> "many" Star : Contains
可以用标记对类进行注释,以提供关于类的额外元数据。这可以更清楚地说明它的性质。一些常见的注释包括:
<
> 接口类
<> 摘要类
<> 服务类
<> 枚举类
注释定义在开头<<和结束>>中。向类中添加注释有两种方式,任何一种方式的输出都是相同的:
在定义类之后的单独一行中:
代码:
classDiagram
class Shape
<<interface>> Shape
Shape : noOfVertices
Shape : draw()
代码:
在与类定义一起嵌套的结构中:
代码:
classDiagram
class Shape{
<<interface>>
noOfVertices
draw()
}
class Color{
<<enumeration>>
RED
BLUE
GREEN
WHITE
BLACK
}
注释可以在类图中输入,解析器将忽略注释。注释需要在它们自己的行上,并且必须以%%(双百分号)作为前缀。在下一个换行符之前的任何文本都将被视为注释,包括任何类图语法。
代码:
classDiagram
%% This whole line is a comment classDiagram class Shape <<interface>>
class Shape{
<<interface>>
noOfVertices
draw()
}
对于类图,你可以使用direction语句来设置图将呈现的方向:
代码:
classDiagram
direction RL
class Student {
-idCard : IdCard
}
class IdCard{
-id : int
-name : string
}
class Bike{
-id : int
-name : string
}
Student "1" --o "1" IdCard : carries
Student "1" --o "1" Bike : rides
可以将单击事件绑定到节点。点击可以导致一个 javascript 回调或一个链接,将在一个新的浏览器选项卡中打开。注意:当使用securityLevel='strict'
时该功能被禁用,当使用securityLevel='loose'
时该功能被启用。
在声明了所有类之后,可以在单独的一行上定义这些操作。
action className "reference" "tooltip"
click className call callback() "tooltip"
click className href "url" "tooltip"
Action可以是link
,也可以是callback
,这取决于您想调用的交互类型
className
是动作将关联到的节点的idReference
要么是url链接,要么是回调函数名。 (optional)
tooltip 是鼠标悬停在元素上时显示的字符串(注意: 工具提示的样式由. mermaidtooltip 类设置)。可以使用注释“line1\nline2”在图表上添加注释,或者使用注释类“line1\nline2”为类添加注释
URL Link:
代码:
classDiagram
class Shape
link Shape "https://www.github.com" "This is a tooltip for a link"
class Shape2
click Shape2 href "https://www.github.com" "This is a tooltip for a link"
代码:
classDiagram
class Shape
callback Shape "callbackFunction" "This is a tooltip for a callback"
class Shape2
click Shape2 call callbackFunction() "This is a tooltip for a callback"
代码:
classDiagram
class Class01
class Class02
callback Class01 "callbackFunction" "Callback tooltip"
link Class02 "https://www.github.com" "This is a link"
class Class03
class Class04
click Class03 call callbackFunction() "Callback tooltip"
click Class04 href "https://www.github.com" "This is a link"
工具提示功能和链接到url的能力从0.5.2版本可用。
初学者提示——一个在HTML页面中使用交互式链接的完整示例:
html
<body>
<pre class="mermaid">
classDiagram
Animal <|-- Duck
Animal <|-- Fish
Animal <|-- Zebra
Animal : +int age
Animal : +String gender
Animal: +isMammal()
Animal: +mate()
class Duck{
+String beakColor
+swim()
+quack()
}
class Fish{
-int sizeInFeet
-canEat()
}
class Zebra{
+bool is_wild
+run()
}
callback Duck callback "Tooltip"
link Zebra "https://www.github.com" "This is a link"
</pre>
<script>
const callback = function () {
alert('A callback was triggered');
};
const config = {
startOnLoad: true,
securityLevel: 'loose',
};
mermaid.initialize(config);
</script>
</body>
可以对单个节点应用特定的样式,如较粗的边框或不同的背景色。这是通过在css样式中预定义类来实现的,这些类可以从图形定义中应用:
html
<style>
.cssClass > rect {
fill: #ff0000;
stroke: #ffff00;
stroke-width: 4px;
}
</style>
然后将该类附加到特定的节点:
cssClass "nodeId1" cssClass;
也可以在一条语句中将一个类附加到一个节点列表:
cssClass "nodeId1,nodeId2" cssClass;
添加类的一种简短形式是使用:::操作符将类名附加到节点:
代码:
classDiagram
class Animal:::cssClass
或者:
代码:
classDiagram
class Animal:::cssClass {
-int sizeInFeet
-canEat()
}
cssClasses不能作为关系语句同时使用此简写方法添加。
由于类图的现有标记的限制,目前不可能在图本身中定义css类。快了!
类图的主要样式是用预设数量的css类完成的。在呈现过程中,这些类从src/themes/class.scss文件中提取。这里使用的类描述如下:
Class | Description |
---|---|
g.classGroup text | Styles for general class text |
classGroup .title | Styles for general class title |
g.classGroup rect | Styles for class diagram rectangle |
g.classGroup line | Styles for class diagram line |
.classLabel .box | Styles for class label box |
.classLabel .label | Styles for class label text |
composition | Styles for composition arrow head and arrow line |
aggregation | Styles for aggregation arrow head and arrow line(dashed or solid) |
dependency | Styles for dependency arrow head and arrow line |
body {
background: white;
}
g.classGroup text {
fill: $nodeBorder;
stroke: none;
font-family: 'trebuchet ms', verdana, arial;
font-family: var(--mermaid-font-family);
font-size: 10px;
.title {
font-weight: bolder;
}
}
g.classGroup rect {
fill: $nodeBkg;
stroke: $nodeBorder;
}
g.classGroup line {
stroke: $nodeBorder;
stroke-width: 1;
}
.classLabel .box {
stroke: none;
stroke-width: 0;
fill: $nodeBkg;
opacity: 0.5;
}
.classLabel .label {
fill: $nodeBorder;
font-size: 10px;
}
.relation {
stroke: $nodeBorder;
stroke-width: 1;
fill: none;
}
@mixin composition {
fill: $nodeBorder;
stroke: $nodeBorder;
stroke-width: 1;
}
# compositionStart {
@include composition;
}
# compositionEnd {
@include composition;
}
@mixin aggregation {
fill: $nodeBkg;
stroke: $nodeBorder;
stroke-width: 1;
}
# aggregationStart {
@include aggregation;
}
# aggregationEnd {
@include aggregation;
}
# dependencyStart {
@include composition;
}
# dependencyEnd {
@include composition;
}
# extensionStart {
@include composition;
}
# extensionEnd {
@include composition;
}