当前活动图(activity diagram)的语法有诸多限制和缺点,比如代码难以维护。
所以从V7947开始提出一种全新的、更好的语法格式和软件实现供用户使用(beta版)。
就像序列图一样,新的软件实现的另一个优点是它不再依赖于Graphviz。
新的语法将会替换旧的语法。然而考虑到兼容性,旧的语法仍能够被使用以确保向前兼容。
但是我们鼓励用户使用新的语法格式。
活动标签(activity label)以冒号开始,以分号结束。
文本格式支持creole wiki语法。
活动默认按照它们定义的顺序进行自动连接。
🎉 Copied!
|
@startuml
:Hello world;
:This is defined on
several **lines**;
@enduml
|
你可以使用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] 。
你可以使用 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
|
你可以使用 break 关键字跟在循环中的某个行为后面打断循环.
🎉 Copied!
|
@startuml
start
repeat
:测试某事;
if (发生错误?) then (没有)
#palegreen:好的;
break
endif
->not ok;
:弹窗 "文本过长错误";
repeat while (某事发生文本过长错误?) is (是的) not (不是)
->//合并步骤//;
:弹窗 "成功!";
stop
@enduml
|
[参考: QA-6105]
⚠ 目前正在试验中的特性 🚧
如下,可以使用 label 和 goto 关键字来进行进程标记和进程跳转:
label <label_name>
goto <label_name>
🎉 Copied!
|
@startuml
title Point two queries to same activity\nwith `goto`
start
if (Test Question?) then (yes)
'空标签仅起对齐作用
label sp_lab0
label sp_lab1
'真正要用的标签
label lab
:shared;
else (no)
if (Second Test Question?) then (yes)
label sp_lab2
goto lab
else
:nonShared;
endif
endif
:merge;
@enduml
|
[Ref. QA-15026, QA-12526 and initially QA-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
|
你可以使用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
|
文本格式支持creole wiki语法。
一个注释可以是浮动的,使用 floating 关键词。
🎉 Copied!
|
@startuml
start
:foo1;
floating note left: 这是一个注释
:foo2;
note right
这个注释是
//多行的//, 同样可以
包含 <b>HTML</b> 文本.
====
* 调用函数 ""foo()"" 是被禁止的。
end note
stop
@enduml
|
您可以添加返回行为的注释:
🎉 Copied!
|
@startuml
start
repeat :输入数据;
:提交;
backward :警告;
note right: 备注
repeat while (校验通过?) is (否) not (是)
stop
@enduml
|
[参考: QA-11788]
您可以添加分区活动的注释:
🎉 Copied!
|
@startuml
start
partition "**处理** HelloWorld" {
note
这是我的注释
----
//Creole 测试//
end note
:Ready;
:HelloWorld(i)>
:Hello-Sent;
}
@enduml
|
[参考: QA-2398]
你可以为一些活动指定颜色
🎉 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
|
你可以使用括号定义连接器。
🎉 Copied!
|
@startuml
start
:Some activity;
(A)
detach
(A)
:Other activity;
@enduml
|
你可以在连接器上增加 颜色
🎉 Copied!
|
@startuml
start
:下面的连接器
应该是蓝色;
#blue:(B)
:下一个连接器应该
看起来应该是
深绿色;
#green:(G)
stop
@enduml
|
[参考. QA-10077]
通过定义分组(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
|
通过修改活动标签最后的分号分隔符(; ),可以为活动设置不同的形状。
🎉 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
|
🎉 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
|
|
|