以前用于活动图的语法存在一些局限性和可维护性问题。认识到这些弊端后,我们推出了全新的语法和实现方式,不仅用户友好,而且更加稳定。
新语法的优势
- 无需依赖 Graphviz:与序列图一样,新语法无需安装 Graphviz,从而简化了设置过程。
- 维护的便利性:新语法的直观特性意味着更容易管理和维护您的图表。
过渡到新 语法
虽然我们将继续支持旧语法以保持兼容性,但我们强烈建议用户迁移到新语法,以充分利用它所提供的增强功能和优势。
现在就进行迁移,使用新的活动图语法体验更简化、更高效的图表制作流程。
活动标签以
: 开始,以
; 结束。
文本格式可以使用
克里奥尔语的维基语法。
它们的定义顺序是隐性链接的。
|
🎉 Copied!
|
@startuml
:Hello world;
:This is defined on
several **lines**;
@enduml
|
Simple action list separated by -
|
🎉 Copied!
|
@startuml
- Action 1
- Action 2
- Action 3
@enduml
|
Simple action list separated by *
With one level
|
🎉 Copied!
|
@startuml
* Action 1
* Action 2
* Action 3
@enduml
|
With several levels
|
🎉 Copied!
|
@startuml
<style>
element {MinimumWidth 150}
</style>
* Action 1
** Sub-Action 1.1
** Sub-Action 1.2
*** Sub-Action 1.2.1
*** Sub-Action 1.2.2
* Action 2
@enduml
|
[Ref. GH-2376]
你可以使用
start 和
stop 关键字来表示一个图的开始和结束
。
|
🎉 Copied!
|
@startuml
start
:Hello world;
:This is defined on
several **lines**;
stop
@enduml
|
你也可以使用
end 关键字。
|
🎉 Copied!
|
@startuml
start
:Hello world;
:This is defined on
several **lines**;
end
@enduml
|
你可以使用
if,
then,
break和
else 关键词来在你的图表中放入测试。
标签可以用圆括号提供。
有3种语法可供选择。
|
🎉 Copied!
|
@startuml
start
if (Graphviz installed?) then (yes)
:process all\ndiagrams;
else (no)
:process only
__sequence__ and __activity__ diagrams;
endif
stop
@enduml
|
|
🎉 Copied!
|
@startuml
if (color?) is (<color:red>red) then
:print red;
else
:print not red;
@enduml
|
if (...) equals (...) then
|
🎉 Copied!
|
@startuml
if (counter?) equals (5) then
:print 5;
else
:print not 5;
@enduml
|
[Ref.QA-301]
几个测试(水平模式)
你可以使用
elseif 关键字来拥有几个测试
(默认是水平模式)。
|
🎉 Copied!
|
@startuml
start
if (condition A) then (yes)
:Text 1;
elseif (condition B) then (yes)
:Text 2;
stop
(no) elseif (condition C) then (yes)
:Text 3;
(no) elseif (condition D) then (yes)
:Text 4;
else (nothing)
:Text else;
endif
stop
@enduml
|
几个测试(垂直模式)
你可以使用
!pragma useVerticalIf on 命令,让测试处于垂直模式。
|
🎉 Copied!
|
@startuml
!pragma useVerticalIf on
start
if (condition A) then (yes)
:Text 1;
elseif (condition B) then (yes)
:Text 2;
stop
elseif (condition C) then (yes)
:Text 3;
elseif (condition D) then (yes)
:Text 4;
else (nothing)
:Text else;
endif
stop
@enduml
|
你可以使用
-P command-line[命令行]选项来指定pragma。
java -jar plantuml.jar -PuseVerticalIf=on
[参考文献:QA-3931,issue-582] 。
*[Refs. [QA-3931](https:
forum.plantuml.net/3931/please-provide-elseif-structure-vertically-activity-diagrams), [GH-582](https:github.com/plantuml/plantuml/issues/582)]*
WARNING
This translation need to be updated. WARNING
你可以使用
switch,
case 和
endswitch 关键词在图表中绘制Switch判断.
使用括号表示标注.
|
🎉 Copied!
|
@startuml
start
switch (测试?)
case ( 条件 A )
:Text 1;
case ( 条件 B )
:Text 2;
case ( 条件 C )
:Text 3;
case ( 条件 D )
:Text 4;
case ( 条件 E )
:Text 5;
endswitch
stop
@enduml
|
你可以在if判断中终止一个行为.
|
🎉 Copied!
|
@startuml
if (条件?) then
:错误;
stop
endif
#palegreen:行为;
@enduml
|
但如果你想在特定行为上停止,你可以使用
kill 或
detach关键字:
|
🎉 Copied!
|
@startuml
if (条件?) then
#pink:错误;
kill
endif
#palegreen:行为;
@enduml
|
[参考. QA-265]
|
🎉 Copied!
|
@startuml
if (条件?) then
#pink:错误;
detach
endif
#palegreen:行为;
@enduml
|
你可以使用关键字
repeat和
repeatwhile进行重复循环。
|
🎉 Copied!
|
@startuml
start
repeat
:读取数据;
:生成图片;
repeat while (更多数据?)
stop
@enduml
|
你同样可以使用一个全局行为作为
repeat目标, 在返回循环开始时使用
backward关键字插入一个全局行为。
|
🎉 Copied!
|
@startuml
start
repeat :foo作为开始标注;
:读取数据;
:生成图片;
backward:这是一个后撤行为;
repeat while (更多数据?)
stop
@enduml
|
[Ref. QA-5826]
WARNING
This translation need to be updated. WARNING
你可以使用
break 关键字跟在循环中的某个行为后面打断循环.
|
🎉 Copied!
|
@startuml
start
repeat
:测试某事;
if (发生错误?) then (没有)
#palegreen:好的;
break
endif
->not ok;
:弹窗 "文本过长错误";
repeat while (某事发生文本过长错误?) is (是的) not (不是)
->//合并步骤//;
:弹窗 "成功!";
stop
@enduml
|
[参考: QA-6105]
⚠ 目前只是实验性的 🚧
你可以使用
label 和
goto 关键词来表示Goto处理,其中:
label <label_name>
goto <label_name>
|
🎉 Copied!
|
@startuml
title Point two queries to same activity\nwith `goto`
start
if (Test Question?) then (yes)
'space label only for alignment
label sp_lab0
label sp_lab1
'real label
label lab
:shared;
else (no)
if (Second Test Question?) then (yes)
label sp_lab2
goto sp_lab1
else
:nonShared;
endif
endif
:merge;
@enduml
|
[Ref.QA-15026,QA-12526and initiallyQA-1626] 。
可以使用关键字
while和
end while进行while循环。
|
🎉 Copied!
|
@startuml
start
while (data available?)
:read data;
:generate diagrams;
endwhile
stop
@enduml
|
还可以在关键字
endwhile后添加标注,还有一种方式是使用关键字
is。
|
🎉 Copied!
|
@startuml
while (check filesize ?) is (not empty)
:read file;
endwhile (empty)
:close file;
@enduml
|
如果你使用
+detach+ 来形成一个无限循环, 那么你可能需要使用
+-[hidden]->+ 来隐藏一些不完整的箭头。
|
🎉 Copied!
|
@startuml
:Step 1;
if (condition1) then
while (loop forever)
:Step 2;
endwhile
-[hidden]->
detach
else
:end normally;
stop
endif
@enduml
|
WARNING
This translation need to be updated. WARNING
你可以使用
fork,
fork again和
end fork 或者
end merge 等关键字表示并行处理。
fork 示例
|
🎉 Copied!
|
@startuml
start
fork
:行为 1;
fork again
:行为 2;
end fork
stop
@enduml
|
fork 和合并示例
|
🎉 Copied!
|
@startuml
start
fork
:行为 1;
fork again
:行为 2;
end merge
stop
@enduml
|
[参考: QA-5320]
|
🎉 Copied!
|
@startuml
start
fork
:行为 1;
fork again
:行为 2;
fork again
:行为 3;
fork again
:行为 4;
end merge
stop
@enduml
|
|
🎉 Copied!
|
@startuml
start
fork
:行为 1;
fork again
:行为 2;
end
end merge
stop
@enduml
|
[参考: QA-13731]
end fork 标注 (或 UML 连接规范):
|
🎉 Copied!
|
@startuml
start
fork
:行为 A;
fork again
:行为 B;
end fork {或}
stop
@enduml
|
|
🎉 Copied!
|
@startuml
start
fork
:行为 A;
fork again
:行为 B;
end fork {和}
stop
@enduml
|
[参考: QA-5346]
其他示例
|
🎉 Copied!
|
@startuml
start
if (多进程处理?) then (是)
fork
:进程 1;
fork again
:进程 2;
end fork
else (否)
:逻辑 1;
:逻辑 2;
endif
@enduml
|
分割
你可以使用
split,
split again 和
end split 关键字去表达分割处理
|
🎉 Copied!
|
@startuml
start
split
:A;
split again
:B;
split again
:C;
split again
:a;
:b;
end split
:D;
end
@enduml
|
输入分割 (多个入口)
你可以使用包含
hidden 指令的箭头去制造一个输入分割 (多入口):
|
🎉 Copied!
|
@startuml
split
-[hidden]->
:A;
split again
-[hidden]->
:B;
split again
-[hidden]->
:C;
end split
:D;
@enduml
|
|
🎉 Copied!
|
@startuml
split
-[hidden]->
:A;
split again
-[hidden]->
:a;
:b;
split again
-[hidden]->
(Z)
end split
:D;
@enduml
|
[参考: QA-8662]
输出分割 (多个结束点)
你可以使用
kill 或
detach 去制造一个输出分割 (多个结束点):
|
🎉 Copied!
|
@startuml
start
split
:A;
kill
split again
:B;
detach
split again
:C;
kill
end split
@enduml
|
|
🎉 Copied!
|
@startuml
start
split
:A;
kill
split again
:b;
:c;
detach
split again
(Z)
detach
split again
end
split again
stop
end split
@enduml
|
文本格式可以使用
克里奥尔维基语法。
可以使用
floating 关键字浮动注释。
|
🎉 Copied!
|
@startuml
start
:foo1;
floating note left: This is a note
:foo2;
note right
This note is on several
//lines// and can
contain <b>HTML</b>
====
* Calling the method ""foo()"" is prohibited
end note
stop
@enduml
|
您可以为后向活动添加注释:
|
🎉 Copied!
|
@startuml
start
repeat :Enter data;
:Submit;
backward :Warning;
note right: Note
repeat while (Valid?) is (No) not (Yes)
stop
@enduml
|
[Ref.QA-11788]
可以添加分区活动注释:
|
🎉 Copied!
|
@startuml
start
partition "**process** HelloWorld" {
note
This is my note
----
//Creole test//
end note
:Ready;
:HelloWorld(i)>
:Hello-Sent;
}
@enduml
|
[参考QA-2398]
WARNING
This translation need to be updated. WARNING
你可以为一些活动指定
颜色
|
🎉 Copied!
|
@startuml
start
:开始处理;
#HotPink:读取配置文件
这些文件应该在此处编辑;
#AAAAAA:结束处理;
@enduml
|
你通用可以使用
渐变色.
|
🎉 Copied!
|
@startuml
start
partition #red/white test分片 {
#blue\green:test活动;
}
@enduml
|
[参考: QA-4906]
您可以使用
skinparam ArrowHeadColor none 参数来表示仅使用线条连接活动,而不带箭头。
|
🎉 Copied!
|
@startuml
skinparam ArrowHeadColor none
start
:Hello world;
:This is on defined on
several **lines**;
stop
@enduml
|
|
🎉 Copied!
|
@startuml
skinparam ArrowHeadColor none
start
repeat :Enter data;
:Submit;
backward :Warning;
repeat while (Valid?) is (No) not (Yes)
stop
@enduml
|
使用
->标记,你可以给箭头添加文字或者修改箭头
颜色。
同时,你也可以选择点状 (dotted),条状(dashed),加粗或者是隐式箭头
|
🎉 Copied!
|
@startuml
:foo1;
-> You can put text on arrows;
if (test) then
-[#blue]->
:foo2;
-[#green,dashed]-> The text can
also be on several lines
and **very** long...;
:foo3;
else
-[#black,dotted]->
:foo4;
endif
-[#gray,bold]->
:foo5;
@enduml
|
You can use multiple colored arrow.
|
🎉 Copied!
|
@startuml
skinparam colorArrowSeparationSpace 1
start
-[#red;#green;#orange;#blue]->
if(a?)then(yes)
-[#red]->
:activity;
-[#red]->
if(c?)then(yes)
-[#maroon,dashed]->
else(no)
-[#red]->
if(b?)then(yes)
-[#maroon,dashed]->
else(no)
-[#blue,dashed;dotted]->
:do a;
-[#red]->
:do b;
-[#red]->
endif
-[#red;#maroon,dashed]->
endif
-[#red;#maroon,dashed]->
elseif(e?)then(yes)
-[#green]->
if(c?)then(yes)
-[#maroon,dashed]->
else(no)
-[#green]->
if(d?)then(yes)
-[#maroon,dashed]->
else(no)
-[#green]->
:do something; <<continuous>>
-[#green]->
endif
-[#green;#maroon,dashed]->
partition dummy {
:some function;
}
-[#green;#maroon,dashed]->
endif
-[#green;#maroon,dashed]->
elseif(f?)then(yes)
-[#orange]->
:activity; <<continuous>>
-[#orange]->
else(no)
-[#blue,dashed;dotted]->
endif
stop
@enduml
|
[Ref. QA-4411]
你可以使用括号定义连接器。
|
🎉 Copied!
|
@startuml
start
:Some activity;
(A)
detach
(A)
:Other activity;
@enduml
|
WARNING
This translation need to be updated. WARNING
你可以在连接器上增加
颜色
|
🎉 Copied!
|
@startuml
start
:下面的连接器
应该是蓝色;
#blue:(B)
:下一个连接器应该
看起来应该是
深绿色;
#green:(G)
stop
@enduml
|
[参考. QA-10077]
[Ref. QA-19975]
WARNING
This translation need to be updated. WARNING
通过定义分组(group),你可以把多个活动分组。
|
🎉 Copied!
|
@startuml
start
group 初始化分组
:read config file;
:init internal variable;
end group
group 运行分组
:wait for user interaction;
:print information;
end group
stop
@enduml
|
分区
通过定义分区(partition),你可以把多个活动组合(group)在一起:
|
🎉 Copied!
|
@startuml
start
partition 初始化分区 {
:read config file;
:init internal variable;
}
partition 运行分区 {
:wait for user interaction;
:print information;
}
stop
@enduml
|
这里同样可以改变分区颜色
color:
|
🎉 Copied!
|
@startuml
start
partition #lightGreen "Input Interface" {
:read config file;
:init internal variable;
}
partition Running {
:wait for user interaction;
:print information;
}
stop
@enduml
|
[参考: QA-2793]
同样可以添加一个
链接 到分区:
|
🎉 Copied!
|
@startuml
start
partition "[[http://plantuml.com partition_name]]" {
:read doc. on [[http://plantuml.com plantuml_website]];
:test diagram;
}
end
@enduml
|
[参考: QA-542]
分组, 分区, 包, 矩形 或 卡片式
你可以分组活动通过定义:
- group;
- partition;
- package;
- rectangle;
- card.
|
🎉 Copied!
|
@startuml
start
group 分组
:Activity;
end group
floating note: 分组备注
partition 分区 {
:Activity;
}
floating note: 分区备注
package 包 {
:Activity;
}
floating note: 包备注
rectangle 矩形 {
:Activity;
}
floating note: 矩形备注
card 卡片式 {
:Activity;
}
floating note: 卡片式备注
end
@enduml
|
你可以使用管道符
|来定义泳道。
还可以改变泳道的
颜色。
|
🎉 Copied!
|
@startuml
|Swimlane1|
start
:foo1;
|#AntiqueWhite|Swimlane2|
:foo2;
:foo3;
|Swimlane1|
:foo4;
|Swimlane2|
:foo5;
stop
@enduml
|
你可以在泳道中增加
if 判断或
repeat 或
while 循环.
|
🎉 Copied!
|
@startuml
|#pink|Actor_For_red|
start
if (color?) is (red) then
#pink:**action red**;
:foo1;
else (not red)
|#lightgray|Actor_For_no_red|
#lightgray:**action not red**;
:foo2;
endif
|Next_Actor|
#lightblue:foo3;
:foo4;
|Final_Actor|
#palegreen:foo5;
stop
@enduml
|
你同样可以在泳道中增加别名,使用
alias 语法:
|[#<color>|]<swimlane_alias>| <swimlane_title>
|
🎉 Copied!
|
@startuml
|#palegreen|f| fisherman
|c| cook
|#gold|e| eater
|f|
start
:go fish;
|c|
:fry fish;
|e|
:eat fish;
stop
@enduml
|
[参考: QA-2681]
可以使用关键字
detach 或
kill移除箭头。
|
🎉 Copied!
|
@startuml
:start;
fork
:foo1;
:foo2;
fork again
:foo3;
detach
endfork
if (foo4) then
:foo5;
detach
endif
:foo6;
detach
:foo7;
stop
@enduml
|
|
🎉 Copied!
|
@startuml
:start;
fork
:foo1;
:foo2;
fork again
:foo3;
kill
endfork
if (foo4) then
:foo5;
kill
endif
:foo6;
kill
:foo7;
stop
@enduml
|
SDL 形状名称表
|
名称
|
旧语法
|
定型语法
|
|
输入
|
<
|
<<input>>
|
|
输出
|
>
|
<<output>>
|
|
程序
|
|
|
<<procedure>>
|
|
加载
|
\
|
<<load>>
|
|
保存
|
/
|
<<save>>
|
|
连续
|
}
|
<<continuous>>
|
|
任务
|
]
|
<<task>>
|
[Ref.QA-11518,GH-1270]
SDL using final separator (Deprecated form)
通过更改最终
; separator,可以为活动设置不同的渲染:
|
🎉 Copied!
|
@startuml
:Ready;
:next(o)|
:Receiving;
split
:nak(i)<
:ack(o)>
split again
:ack(i)<
:next(o)
on several lines|
:i := i + 1]
:ack(o)>
split again
:err(i)<
:nak(o)>
split again
:foo/
split again
:bar\\
split again
:i > 5}
stop
end split
:finish;
@enduml
|
使用正态分隔符和立体原型的 SDL(当前正式形式)
|
🎉 Copied!
|
@startuml
start
:SDL Shape;
:input; <<input>>
:output; <<output>>
:procedure; <<procedure>>
:load; <<load>>
:save; <<save>>
:continuous; <<continuous>>
:task; <<task>>
end
@enduml
|
|
🎉 Copied!
|
@startuml
:Ready;
:next(o); <<procedure>>
:Receiving;
split
:nak(i); <<input>>
:ack(o); <<output>>
split again
:ack(i); <<input>>
:next(o)
on several lines; <<procedure>>
:i := i + 1; <<task>>
:ack(o); <<output>>
split again
:err(i); <<input>>
:nak(o); <<output>>
split again
:foo; <<save>>
split again
:bar; <<load>>
split again
:i > 5; <<continuous>>
stop
end split
:finish;
@enduml
|
WARNING
This translation need to be updated. WARNING
Table of UML Shape Name
|
Name
|
Stereotype syntax
|
|
ObjectNode
|
<<object>>
|
ObjectNode typed by signal
|
<<objectSignal>> or <<object-signal>>
|
AcceptEventAction without TimeEvent trigger
|
<<acceptEvent>> or <<accept-event>>
|
AcceptEventAction with TimeEvent trigger
|
<<timeEvent>> or <<time-event>>
|
SendSignalAction
SendObjectAction with signal type
|
<<sendSignal>> or <<send-signal>>
|
|
Trigger
|
<<trigger>>
|
[Ref. GH-2185]
UML Shape Example using Stereotype
|
🎉 Copied!
|
@startuml
:action;
:object; <<object>>
:ObjectNode
typed by signal; <<objectSignal>>
:AcceptEventAction
without TimeEvent trigger; <<acceptEvent>>
:SendSignalAction; <<sendSignal>>
:SendObjectAction
with signal type; <<sendSignal>>
:Trigger; <<trigger>>
:\t\t\t\t\t\tAcceptEventAction
\t\t\t\t\t\twith TimeEvent trigger; <<timeEvent>>
:an action;
@enduml
|
[Ref. GH-2185, QA-16558, GH-1659]
|
🎉 Copied!
|
@startuml
start
:ClickServlet.handleRequest();
:new page;
if (Page.onSecurityCheck) then (true)
:Page.onInit();
if (isForward?) then (no)
:Process controls;
if (continue processing?) then (no)
stop
endif
if (isPost?) then (yes)
:Page.onPost();
else (no)
:Page.onGet();
endif
:Page.onRender();
endif
else (false)
endif
if (do redirect?) then (yes)
:redirect process;
else
if (do forward?) then (yes)
:Forward request;
else (no)
:Render page template;
endif
endif
stop
@enduml
|
inside 样式 (默认)
|
🎉 Copied!
|
@startuml
skinparam conditionStyle inside
start
repeat
:act1;
:act2;
repeatwhile (<b>end)
:act3;
@enduml
|
|
🎉 Copied!
|
@startuml
start
repeat
:act1;
:act2;
repeatwhile (<b>end)
:act3;
@enduml
|
Diamond 样式
|
🎉 Copied!
|
@startuml
skinparam conditionStyle diamond
start
repeat
:act1;
:act2;
repeatwhile (<b>end)
:act3;
@enduml
|
InsideDiamond (或 Foo1) 样式
|
🎉 Copied!
|
@startuml
skinparam conditionStyle InsideDiamond
start
repeat
:act1;
:act2;
repeatwhile (<b>end)
:act3;
@enduml
|
|
🎉 Copied!
|
@startuml
skinparam conditionStyle foo1
start
repeat
:act1;
:act2;
repeatwhile (<b>end)
:act3;
@enduml
|
[参考: QA-1290 and #400]
Diamond 样式 (默认)
|
🎉 Copied!
|
@startuml
skinparam ConditionEndStyle diamond
:A;
if (decision) then (yes)
:B1;
else (no)
endif
:C;
@enduml
|
|
🎉 Copied!
|
@startuml
skinparam ConditionEndStyle diamond
:A;
if (decision) then (yes)
:B1;
else (no)
:B2;
endif
:C;
@enduml
@enduml
|
水平线 (hline) 样式
|
🎉 Copied!
|
@startuml
skinparam ConditionEndStyle hline
:A;
if (decision) then (yes)
:B1;
else (no)
endif
:C;
@enduml
|
|
🎉 Copied!
|
@startuml
skinparam ConditionEndStyle hline
:A;
if (decision) then (yes)
:B1;
else (no)
:B2;
endif
:C;
@enduml
@enduml
|
[Ref. QA-4015]
无样式 (默认)
|
🎉 Copied!
|
@startuml
start
:init;
-> test of color;
if (color?) is (<color:red>red) then
:print red;
else
:print not red;
note right: no color
endif
partition End {
:end;
}
-> this is the end;
end
@enduml
|
有样式
你可以使用
style 节点去定义样式然后改变渲染。
|
🎉 Copied!
|
@startuml
<style>
activityDiagram {
BackgroundColor #33668E
BorderColor #33668E
FontColor #888
FontName arial
diamond {
BackgroundColor #ccf
LineColor #00FF00
FontColor green
FontName arial
FontSize 15
}
arrow {
FontColor gold
FontName arial
FontSize 15
}
partition {
LineColor red
FontColor green
RoundCorner 10
BackgroundColor PeachPuff
}
note {
FontColor Blue
LineColor Navy
BackgroundColor #ccf
}
}
document {
BackgroundColor transparent
}
</style>
start
:init;
-> test of color;
if (color?) is (<color:red>red) then
:print red;
else
:print not red;
note right: no color
endif
partition End {
:end;
}
-> this is the end;
end
@enduml
|