I’ve always had a love of sequence diagrams, for those that don’t know what a sequence diagram is, this may not be the blog for you! Sequence diagrams have always struck me as one of the more useful, and practical design documents to use to describe how a system works.
ArchiMate, of course, works on a slightly larger level, but I think great things can happen when you combine the two, and have used many diagrams to help describe some of the more intricate detail within an architecture.
There are many tools which can be used to create sequence diagrams, but, as I am a nerd, and enjoy over-complicating things, PlantUML floats my boat in many ways, mainly because it still feels like a fun techie tool (and works well with Markdown too!).
PlantUML is a tool which allows you to quickly create UML diagrams based on a (fairly) simple text syntax. It supports many types of diagram, including Sequence Diagrams and basic ArchiMate. As PlantUML supports both of these diagrams, I have written a support library which can be included in any PlantUML diagram to define each of the ArchiMate concepts and include them within a sequence diagram.
Example Diagram Source
@startuml Archi Usage | |
!include archi-seq.puml | |
title Archi Print Usage | |
' Define Elements | |
$businessActor("Architect","architect") | |
$applicationComponent("Archi","archi") | |
$applicationFunction("Update\nModel","update") | |
$applicationFunction("Print\nView","print") | |
$systemSoftware("Windows\nPrint\nService","windowsPrint") | |
$equipment("Printer", "printer") | |
' Define Sequence | |
architect->archi ++ | |
archi->update ++ : Make changes | |
$document("Not exactly correct!\nBut you get the idea.","right","update") | |
return Updated Model | |
archi ->print ++ : Click print | |
print -\windowsPrint ++ | |
print –> archi –: Sent to printer | |
windowsPrint -> printer ++ | |
return Complete | |
archi –> architect — | |
@enduml |
Support Library
@startuml Common | |
' PlantUML ArchiMate Sequence Diagram template v5 | |
' Changelog: | |
' v3 Updated for new PreProcessor | |
' v4 Function to Procedure | |
' v5 Added Motivation, migrated to Styles, added Structure type | |
' Author: Steven Mileham (steven.mileham@gmail.com) | |
skinparam dpi 150 | |
skinparam useBetaStyle true | |
<style> | |
sequenceDiagram { | |
LineColor black | |
shadowing 0 | |
FontName "Roboto" | |
Box { | |
LineColor Gray | |
BackgroundColor #f2f2f2 | |
Padding 10 | |
} | |
Lifeline { | |
LineColor DimGray | |
BackgroundColor LightGray | |
} | |
.Business { | |
LineColor #GoldenRod | |
BackgroundColor #Business | |
} | |
.Application { | |
LineColor #LightSteelBlue | |
BackgroundColor #Application | |
} | |
.Technology { | |
LineColor #LimeGreen | |
BackgroundColor #Technology | |
} | |
.Physical { | |
LineColor #LimeGreen | |
BackgroundColor #Technology | |
} | |
.Motivation { | |
LineColor #Purple | |
BackgroundColor #Motivation | |
} | |
.active { | |
} | |
.behavior { | |
RoundCorner 10 | |
} | |
.passive {} | |
.motive { | |
DiagonalCorner 10 | |
} | |
} | |
</style> | |
' Archimate Components | |
' Generic | |
!procedure $element($layer,$type,$structure,$label,$name="") | |
!if ($name=="") | |
participant "<$archimate/$type>\r $label" as $label << $layer >> << $structure >> | |
!else | |
participant "<$archimate/$type>\r $label" as $name << $layer >> << $structure >> | |
!endif | |
!endprocedure | |
' Motivation | |
!procedure $driver($label,$name="") | |
$element("Motivation", "driver","motive", $label, $name) | |
!endprocedure | |
!procedure $assessment($label,$name="") | |
$element("Motivation", "assessment","motive", $label, $name) | |
!endprocedure | |
!procedure $goal($label,$name="") | |
$element("Motivation", "goal","motive", $label, $name) | |
!endprocedure | |
!procedure $outcome($label,$name="") | |
$element("Motivation", "motivation-outcome","motive", $label, $name) | |
!endprocedure | |
!procedure $principle($label,$name="") | |
$element("Motivation", "principle","motive", $label, $name) | |
!endprocedure | |
!procedure $requirement($label,$name="") | |
$element("Motivation", "requirement","motive", $label, $name) | |
!endprocedure | |
!procedure $constraint($label,$name="") | |
$element("Motivation", "constraint","motive", $label, $name) | |
!endprocedure | |
!procedure $value($label,$name="") | |
$element("Motivation", "value","passive", $label, $name) | |
!endprocedure | |
!procedure $meaning($label,$name="") | |
$element("Motivation", "meaning","passive", $label, $name) | |
!endprocedure | |
!procedure $stakeholder($label,$name="") | |
$element("Motivation", "role","motive", $label, $name) | |
!endprocedure | |
' Business | |
!procedure $businessActor($label,$name="") | |
$element("Business", "actor","active", $label, $name) | |
!endprocedure | |
!procedure $businessCollaboration($label,$name="") | |
$element("Business", "collaboration","active", $label, $name) | |
!endprocedure | |
!procedure $businessEvent($label,$name="") | |
$element("Business", "event","behavior", $label, $name) | |
!endprocedure | |
!procedure $businessInteraction($label,$name="") | |
$element("Business","interaction","behavior", $label, $name) | |
!endprocedure | |
!procedure $businessInterface($label,$name="") | |
$element("Business","interface","active", $label, $name) | |
!endprocedure | |
!procedure $businessObject($label,$name="") | |
$element("Business","object","passive", $label, $name) | |
!endprocedure | |
!procedure $businessProcess($label,$name="") | |
$element("Business","process","behavior", $label, $name) | |
!endprocedure | |
!procedure $businessRole($label,$name="") | |
$element("Business","role","behavior", $label, $name) | |
!endprocedure | |
!procedure $businessService($label,$name="") | |
$element("Business","service","behavior", $label, $name) | |
!endprocedure | |
!procedure $contract($label,$name="") | |
$element("Business","contract","passive", $label, $name) | |
!endprocedure | |
!procedure $product($label,$name="") | |
$element("Business","product","passive", $label, $name) | |
!endprocedure | |
!procedure $representation($label,$name="") | |
$element("Business","representation","passive", $label, $name) | |
!endprocedure | |
' Application | |
!procedure $applicationCollaboration($label,$name="") | |
$element("Application","collaboration","active", $label, $name) | |
!endprocedure | |
!procedure $applicationComponent($label,$name="") | |
$element("Application","component","active", $label, $name) | |
!endprocedure | |
!procedure $applicationEvent($label,$name="") | |
$element("Application","event","behavior", $label, $name) | |
!endprocedure | |
!procedure $applicationFunction($label,$name="") | |
$element("Application","function","behavior", $label, $name) | |
!endprocedure | |
!procedure $applicationInteraction($label,$name="") | |
$element("Application","interaction","behavior", $label, $name) | |
!endprocedure | |
!procedure $applicationInterface($label,$name="") | |
$element("Application","interface","active", $label, $name) | |
!endprocedure | |
!procedure $applicationProcess($label,$name="") | |
$element("Application","process","behavior", $label, $name) | |
!endprocedure | |
!procedure $applicationService($label,$name="") | |
$element("Application","service","behavior", $label, $name) | |
!endprocedure | |
!procedure $dataObject($label,$name="") | |
$element("Application","object","passive", $label, $name) | |
!endprocedure | |
' Technology | |
!procedure $artifact($label,$name="") | |
$element("Technology","technology-artifact","passive", $label, $name) | |
!endprocedure | |
!procedure $communicationNetwork($label,$name="") | |
$element("Technology","network","active", $label, $name) | |
!endprocedure | |
!procedure $device($label,$name="") | |
$element("Technology","device","active", $label, $name) | |
!endprocedure | |
!procedure $node($label,$name="") | |
$element("Technology","node","active", $label, $name) | |
!endprocedure | |
!procedure $path($label,$name="") | |
$element("Technology","technology-communication-path","active", $label, $name) | |
!endprocedure | |
!procedure $systemSoftware($label,$name="") | |
$element("Technology","system-software","active", $label, $name) | |
!endprocedure | |
!procedure $technologyCollaboration($label,$name="") | |
$element("Technology","collaboration","active", $label, $name) | |
!endprocedure | |
!procedure $technologyEvent($label,$name="") | |
$element("Technology","event","behavior", $label, $name) | |
!endprocedure | |
!procedure $technologyFunction($label,$name="") | |
$element("Technology","function","behavior", $label, $name) | |
!endprocedure | |
!procedure $technologyInteraction($label,$name="") | |
$element("Technology","interaction","behavior", $label, $name) | |
!endprocedure | |
!procedure $technologyInterface($label,$name="") | |
$element("Technology","interface","active", $label, $name) | |
!endprocedure | |
!procedure $technologyProcess($label,$name="") | |
$element("Technology","process","behavior", $label, $name) | |
!endprocedure | |
!procedure $technologyService($label,$name="") | |
$element("Technology","service","behavior", $label, $name) | |
!endprocedure | |
' Physical | |
!procedure $distributionNetwork($label,$name="") | |
$element("Physical","physical-distribution-network","active", $label, $name) | |
!endprocedure | |
!procedure $equipment($label,$name="") | |
$element("Physical","physical-equipment","active", $label, $name) | |
!endprocedure | |
!procedure $facility($label,$name="") | |
$element("Physical","physical-facility","active", $label, $name) | |
!endprocedure | |
!procedure $material($label,$name="") | |
$element("Physical","physical-material","passive", $label, $name) | |
!endprocedure | |
' Notes | |
!procedure $assume($text, $placement = "left", $component = "") | |
hnote $placement $component #FFAAAA: <&warning> $text | |
!endprocedure | |
!procedure $document($text, $placement = "left", $component = "") | |
note $placement $component #FFFFA5: <&document> $text | |
!endprocedure | |
!procedure $question($text, $placement = "left", $component = "") | |
rnote $placement $component #FFBF00: <&question-mark> $text | |
!endprocedure | |
!procedure $schedule($text, $placement = "left", $component = "") | |
rnote $placement $component #98FB98: <&timer> $text | |
!endprocedure | |
!procedure $change($text, $placement = "left", $component = "") | |
rnote $placement $component #FFBF00: <&circle-check> $text | |
!endprocedure | |
!procedure $reuse($text, $placement = "left", $component = "") | |
rnote $placement $component #98FB98: <&circle-check> $text | |
!endprocedure | |
!procedure $error($text, $placement = "left", $component = "") | |
rnote $placement $component #FFCCCB: <&bug> $text | |
!endprocedure | |
hide stereotype | |
footer Generated on %date() | |
@enduml |
Next steps… figure out how I can write a jArchi script to write my PlantUML for me!
Hi,
I also often use PlantUML and find it useful to work directly from Archi and don’t rely on a browser. For this purpose, I have a really small script containing only: Browser.open(“https://www.planttext.com/”, “PlantUML”)
This opens a new tab in Archi with PlantText. Once you’ve created your sequence diagram, you can simply drag’n drop it to another tab containing a canvas and the image will be created in it.
LikeLiked by 1 person
Dear JB, i am using Archi 4.8 nevertheless drag’n dropping a PlantUML sequence diagram into a neighboring Archi Canvas Tab does not work i.e. nothing gets created within the Canvas View. Is there any setting that needs to be enabled to allow drag/drop between Archi tabs?
Thank you very much,
Henri
LikeLike
Hi! This looks really amazing and I want to use it!
Two questions:
1) How are the archimate symbols rendered? From an image file or from code?
2) Does this require me to download PlantUML and run it locally? I am currently writing PlantUML straight into a macro in Confluence on web. Is it possible to include the support library in the same “file” as where the actual diagram is defined?
LikeLike
Hey Daniel,
Firstly: thanks for commenting, I’m glad you find this useful!
1) The archimate images are embedded in the version of PlantUML used.
2) There are a few options to include the file when running via a PlantUML server instance, firstly you could host the “archi-seq.puml” file yourself, and include it via that URL, or you could use the “GIST” hosted version, finally you could literally copy and paste the content of the package into the top of your PlantUML diagram file.
To include the externally hosted file, it depends on what version of PlantUML is bundled, in the latest version you can use:
!include https://gist.githubusercontent.com/smileham/82518cef78c48c5417b22fe88771754e/raw/35c76599bf6b23489bc11a82695d635ff92eeb42/archi-seq.puml
or in the older versions it would be:
!includeurl https://gist.githubusercontent.com/smileham/82518cef78c48c5417b22fe88771754e/raw/35c76599bf6b23489bc11a82695d635ff92eeb42/archi-seq.puml
(what I’m not sure about is whether the GIST raw URL ever changes)
LikeLike