Raymond Gauthier
2020/01/23
Développeur: Arnaud Roques
Premier release: 17 April 2009.
L’auteur désirait une façon de créer et mettre à jour ses diagrammes à même Microsoft word.
Inspiration de l’auteur: L’outil en ligne: WebSequenceDiagrams.
Était trop limité pour ses besoin (seulement diagramme de séquence) et puisqu’en ligne demandait tout de même des opérations de “copier / coller”.
Représentation textuelle
Un simple DSL1 / notation bien spécifiée pour déclarer des diagrammes.
Gratuit
Édité avec les mêmes outils que le code source
Plus besoin de se poser des questions ennuyantes telles que:
On édite simplement le diagramme avec notre éditeur préféré
Plus de diagrammes “pas à jour”
Vit au même endroit que votre code source
Versionnée
Un refactor du code impliquera un refactor des diagrammes
Un reviewer du code source verra également les changements au diagrammes
Bref, on a les choses bien en main!
Plus besoin d’opérations manuelles désagréables puisqu’on a une application en ligne de commande
L’outil devient le compilateur pour votre documentation
À ce titre, on peut même l’enrober dans un Makefile
ou tout autre build system au choix
Nous en parlerons plus en détails dans quelques “slides”
Puisqu’en java, fonctionne donc sur toutes les plateformes supportant Java et Graphviz.
Pour les plateformes unix-like: nix/nixpkgs offre un packet qui s’occupe de tout installer pour vous tout en exposant un petit executable plantuml
:
Voir installer nix pour l’installation de nix.
Il est possible que votre distribution linux ou package manager osx offre également un packet du même genre.
Je vous laisse cependant l’exercice de le découvrir vous même.
Pour tout autres plateformes, il s’agit d’installation les dépendances, télécharger plantuml.jar
et de le rouler via la JVM.
$ export GRAPHVIZ_DOT=/path/to/graphviz/dot
$ java -jar /path/to/my/downloaded/plantuml.jar -help
# ..
À noter GRAPHVIZ_DOT
permettant de spécifier l’emplacement d’installation de l’exécutable dot
.
Il pourrait être également utile (dépendamment des outils utilisés) d’exposer l’emplacement d’installation de plantuml.jar
via PLANTUML_JAR_PATH
.
Assumant le fichier: my.puml
suivant:
Rouler:
Produira l’image my.png
suivante:
Comme le montre l’aide en ligne de commande, png n’est pas le seul format de sortie:
$ plantuml -help
# ...
-tpng To generate images using PNG format (default)
-tsvg To generate images using SVG format
-teps To generate images using EPS format
-tpdf To generate images using PDF format
-tvdx To generate images using VDX format
-txmi To generate XMI file for class diagram
-tscxml To generate SCXML file for state diagram
-thtml To generate HTML file for class diagram
-ttxt To generate images with ASCII art
-tutxt To generate images with ASCII art using Unicode characters
-tlatex To generate images using LaTeX/Tikz format
-tlatex:nopreamble To generate images using LaTeX/Tikz format without preamble
# ..
Ma recommandation en générale est de générer une image svg:
Voici pouquoi:
Format vectoriel sans perte / non discrétisé. Vous ne serez pas limité à un affichage à un dpi spécifique.
Textuel, donc mieux supporté par git
et autres système de gestions de code source.
S’ouvre à l’aide de n’importe que navigateur moderne (e.g: firefox ./my.svg
).
Voici le résultat:
Bien remarquer également la transparent du fond de l’image contrairement au png.
On peut en quelques lignes se faire un petit makefile (gnu dans ce cas-ci) permettant de produire des images (*.svg
dans ce cas) pour l’ensemble des fichier de code *.puml
dans une arborescence de répertoires:
MKF_CWD := $(shell pwd)
OUTPUT_REL_DIR := .
SRC_PUML := $(shell \
find . -mindepth 1 -type f -name '*.puml' -printf '%P\n')
OUT_SVG_FROM_PUML := $(patsubst \
%.puml,$(OUTPUT_REL_DIR)/%.svg,$(SRC_PUML))
.PHONY: all clean svg-from-puml clean-svg-from-puml
all: svg-from-puml
clean: clean-svg-from-puml
svg-from-puml: $(OUT_SVG_FROM_PUML)
clean-svg-from-puml:
rm -f $(OUT_SVG_FROM_PUML)
.SECONDEXPANSION:
$(OUTPUT_REL_DIR)/%.svg : %.puml | $$(@D)/.
plantuml -tsvg -o "$(MKF_CWD)/$(@D)/" "$<"
$ make
plantuml -tsvg -o "/my/cwd/./" "AtRoot.puml"
plantuml -tsvg -o "/my/cwd/SubDir/" "SubDir/InSubDir.puml"
$ tree
.
├── AtRoot.puml
├── AtRoot.svg
├── Makefile
└── SubDir
├── InSubDir.puml
└── InSubDir.svg
1 directory, 5 files
plantuml -r
(mode récursif de PlantUML) c’est qu’on a un bien meilleur contrôle sur les images en sortie (où on les envoi, etc).
Une extension permettant d’obtenir un preview pane du code plantuml.
Amène également un support de syntax highlighting pour le code source plantuml.
*.puml
, *.iuml
ou *.wsd
.@start
/ @end
.Alt + D
.Une excellent façon d’itérer sur un diagramme.
À noter: le panneau se rafraîchit automatiquement lorsque vous éditez le code.
Pour tous nos amis qui ont la tête dans les nuages, plusieurs solutions s’offrent à vous:
Un simple editeur en ligne, split view code / output.
PlantUML for Confluence Cloud - Atlassian Marketplace
Le plugin est même gratuit, ce qui est plutôt rare chez Atlassian!
Il semblerait que ce système de diagram libre supporte également PlantUML.
On voit ici à gauche la démonstration d’une macro pour l’intégration PlanUML dans Microsoft Word.
Rappelez vous, c’était l’une des motivation principales de l’auteur.
Je ne suis pas certain que tout fonctionne encore bien avec Office 365 (puisqu’en ligne), du moins sans avoir à payer une souscription! À essayer avec la version installé.
Il existe également une intégration Libre/Open office:
Une extension vscode et atom supportant le rendu de blocs de code PlantUML se trouvant directement dans un fichier markdown (*.md
).
*.puml
externe via la directive @import
.Il est également assez simple d’automatiser workflow en combinant pandoc, PlantUML et un build system au choix (e.g.: gnumake).
Voir pandoc-md-wiki pour un example d’intégration. Cette présentation en est d’ailleur un example.
On trouve des intégration PlantUML avec pratiquement tout les outils de développement ayant un minimum de sérieux.
Un peu au même titre que Graphviz - Dot
PlantUML - Intégration Doxygen
Possible d’intégrer à Doxygen avec quelques efforts.
Même chose pour Sphinx. Il s’agit d’un package contribué.
Tools using the PlantUML language
Pour tout le reste.
@startuml
hide footbox
actor user
participant webfrontend
participant webserver
participant hwdevice
participant os
user -> hwdevice ++ : power on
hwdevice -> hwdevice ++: boot process
hwdevice -> os ++: boot loader
os -> webserver **: launch
activate webserver
return success
os -> webfrontend **: launch
activate webfrontend
webfrontend -> webserver ++: request html ui
return html ui
webfrontend --> os : success
deactivate webfrontend
@enduml
@startuml
hide footbox
actor user
participant webfrontend
participant webserver
participant hwdevice
participant os
user ->> webfrontend ++: click on process button
webfrontend -> webserver ++: request processing result
webserver -> hwdevice ++: request sensor state\nsample (camera, etc)
return sensors states
webserver -> webserver ++: process sensor states
return result
webfrontend -> webfrontend ++: render into images
return images
webfrontend ->> user: images as light
@enduml
@startuml
interface Animal {
+get_name(): str
+get_legs(): Leg[]
}
class Leg
class Fin
class Dog {
+barks()
}
class Master {
+run()
}
Animal <|-- Dog: inherits
Animal <|-- Dolphin: inherits
Lion -|> Animal: inherits
Lion o--> "0-1" Dog: hold in its mouth
Lion o--> "0-1" Master: hold in its mouth
Dog *--> "4" Leg: has
Dolphin *--> "0" Leg
Dolphin *--> "1" Fin
Dog ..> Master: depends on its
@enduml
@startuml
start
-> <u>**Systemd supports parallel boot!**</u>;
partition "System Boot" {
fork
partition "Update System" {
if (requires updates?) then
repeat :Download <u>*app*</u> update package;
repeat while (not ok and retry count\nnot exhausted)
if (download package?) then
-[#green]->
:Installing new <u>*app*</u> package;
else
-[#red]-> Cannot proceed, this is not safe!
**shuting down** the system...;
end
endif
endif
}
fork again
:Launching postgres db;
:Launching application backend;
end fork
}
:Lauching application;
stop
@enduml
@startuml
scale 1 as 100 pixels
Title Power of a street light as a function of time
legend
february 18 2017
end legend
header: Test MY-MODEL
robust "Street light power 80000 (kWh) as P" as P
robust "Requested (%)" as R
P has 0.07,0.06,0.05,0.04,0.03,0.02,0.01,0.00
R has 100,90,80,70,60,50,40,30,20,10,0
@0
P is 0.00: 15:00
R is 0
@1
P is 0.00
R is 0
@2
P is 0.02 : 17:00
R is 30
@3
P is 0.08 : Sun set
R is 80
@4
P is 0.04
R is 80
@enduml
@startuml
state "Awaiting input" as State1
state "Looking for matches" as State2
state "Processing selection" as State4
[*] -> State1
State1 --> State2 : Input received
State1 --> [*] : Timeout
State2 --> State1 : No matches / To many matches
State2 --> State4 : Single match
State2 --> State3 : Multiple maches found
state State3 {
[*] --> State3A
state "CursorOnMatch1" as State3A
state "CursorOnMatch2" as State3B
State3A --> State3B: Arrow down
State3A --> [*]: Enter / Esc / Ctrl+c
State3B --> State3A: Arrow up
State3B --> [*]: Enter / Esc / Ctrl+c
}
State3 --> [*] : Selection rejected / Aborted
State3 --> State4 : Single match selected
State4 --> [*]: Done
@enduml
@startuml
package "Some Group" {
HTTP - [First Component]
[Another Component]
}
node "Other Groups" {
FTP - [Second Component]
[First Component] --> FTP
}
cloud {
[Example 1]
}
database "MySql" {
folder "This is my folder" {
[Folder 3]
}
frame "Foo" {
[Frame 4]
}
}
[Another Component] --> [Example 1]
[Example 1] --> [Folder 3]
[Folder 3] --> [Frame 4]
@enduml
Voici d’autres diagrammes que je n’ai pas encore eu l’occasion ou trouvé le besoin d’utiliser:
Une extension des diagrammes de classes permettant de faire de la schématisation DB.
@startuml
skinparam linetype ortho
entity "Class" as e_class {
*class_id : number <<generated>>
--
*name : text
}
entity "Student" as e_student {
*student_id : number <<generated>>
--
class_id : number <<FK>>
phone_number : text
}
entity "Teacher" as e_teacher {
*teacher_id : number <<generated>>
--
*class_id : number <<FK>>
other_details : text
}
e_class }|..o{ e_student: includes / goes to
e_class ||..o{ e_teacher: is taught / teaches
e_student }|..|{ e_teacher: has
@enduml
Pour Cédric et autre gestionnaires:
@startgantt
[Prototype design] lasts 13 days and is colored in Lavender/LightBlue
[Test prototype] lasts 9 days and is colored in Coral/Green and starts 3 days after [Prototype design]'s end
[Write tests] lasts 5 days and ends at [Prototype design]'s end
[Hire tests writers] lasts 6 days and ends at [Write tests]'s start
[Init and write tests report] is colored in Coral/Green
[Init and write tests report] starts 1 day before [Test prototype]'s start and ends at [Test prototype]'s end
@endgantt
@startwbs
+ New Job
++ Decide on Job Requirements
+++ Identity gaps
+++ Review JDs
++++ Sign-Up for courses
++++ Volunteer
++++ Reading
++- Checklist
+++- Responsibilities
+++- Location
++ CV Upload Done
+++ CV Updated
++++ Spelling & Grammar
++++ Check dates
---- Skills
+++ Recruitment sites chosen
@endwbs
Via Salt, on peut même faire du design d’interfaces graphique!
Un autre example vraiment très intéressant permettant d’inclure Salt à même un diagramme d’état. Je ne montrerai pas le code puisque trop long, mais voici tout de même le résultat:
Puisque PlantUML dépend déjà de Graphviz, un support du language dot est offert.
Le diagram parfait pour les artistes ASCII. Via outil ditaa
installable et utilisable séparément.
Inclusion par path relatif:
./my-shared.iuml
:
./my-diagram.puml
:
Configuration par défaut: ./my-config.iuml
:
Include search path:
Permet d’inclure certaines libraries réutilisable à travers les projets.
En particulier pratique pour les styles mais sans y être limité.
Par example:
PlantUML vient avec un préprocesseur simple.
Permet un certain niveau de réutilisation de diagrammes / parties de diagrammes et configuration.
On peut par example penser à un diagramme paramétrable.
./my-parameterizable.iuml
:
!function $var_exists_or_default($varname, $default_value)
!if (%not(%variable_exists($varname)))
%set_variable_value($varname, $default_value)
!endif
!endfunction
$var_exists_or_default("$my_param_a", 5)
$var_exists_or_default("$my_param_b", 10)
robust "MyEntity" as myEntity
@$my_param_a
myEntity is StateA
@$my_param_b
myEntity is StateB
!$my_computed_c = $my_param_a + $my_param_b
@$my_computed_c
myEntity is StateC
Donne:
On remarque StateC
commence à 30
plutôt que 15
que l’on aurait obtenu par défaut.
Il arrive parfois que l’on se trouve à répéter un certain patron (timing diagram, etc).
Le préprocesseur à la rescousse!
Il est en effet possible de répéter un bout de diagramme plusieurs fois via une fonction récursive:
Un example concret:
@startuml
skinparam backgroundColor LightYellow
skinparam state {
StartColor MediumBlue
EndColor Red
BackgroundColor Peru
BackgroundColor<<Warning>> Olive
BorderColor Gray
FontName Impact
}
[*] --> NotShooting
state "Not Shooting State" as NotShooting {
state "Idle mode" as Idle <<Warning>>
state "Configuring mode" as Configuring
[*] --> Idle
Idle --> Configuring : EvConfig
Configuring --> Idle : EvConfig
}
NotShooting --> [*]
@enduml
@startuml
skinparam backgroundColor #AAFFFF
skinparam activity {
StartColor red
BarColor SaddleBrown
EndColor Silver
BackgroundColor Peru
BackgroundColor<< Begin >> Olive
BorderColor Peru
FontName Impact
}
(*) --> "Climbs on Platform" << Begin >>
--> === S1 ===
--> Bows
--> === S2 ===
--> WavesArmes
--> (*)
@enduml
Il existe des dépôts pour Amazon AWS, Kubernetes, la suite Office, etc. Petit example (AWS):
Ce n’est pas quelque chose que j’ai eu l’opportunité de faire mais il semble exister plusieurs outils basé sur PlantUML pour faire ceci dans certain contextes:
Maintenant, est-ce que ceux-ci fonctionnent bien, à vous de voir!
Également, pour une expérience plus interactive (non lié à PlantUML):
Référence de Jérôme.
Un outil permettant d’explorer visuellement une base de code supportant C, C++, Java, Python.
Celui qui aura inspiré l’auteur.
Permet de faire des diagrammes de séquence.
Permet de faire des diagrammes d’activité / diagrammes blocs.
Permet de faire des diagrammes de séquence.
Permet de faire: activité, séquence, Gantt, class, state, etc.
Celui qui se rapproche le plus de PlanUML au niveau de la largeur de couverture.
Permet de faire des timing diagrams.
Le site officiel. Vous y trouverez un documentation généralement assez complète sur chacun des types de diagrammes (beaucoup d’examples).
Lorsque vous avez des questions plus pointues, une petite recherche / poser une question sur le forum officiel est un des meilleur moyen d’obtenir une réponse avant d’aller fouiller le code source.
Je vous conseille de vous abonner au flux RSS de ce forum pour les nouveautés.
Grosse librairie comportant des example des différents types de diagrammes.
Une excellente documentation de la grosse majorité des paramètres permettant de changer l’aspect visuel. À noter, tout n’est malheureusement pas là.
Plusieurs références vers des outils utilisant ou liés à PlantUML.
À noter qu’une grande partie des examples proviennent ou ont été adapté à partir de ceux fournis sur https://plantuml.com.
Merci donc à l’auteur original.
Powered by pandoc, plantuml and nix.
Cette présentation est écrite en Pandoc’s Markdown, les diagrammes plantuml sont tout générés on the fly via plantuml lors du build de cette documentation. Il ont donc été testés avec la version de plantuml fournie par l’environement nix shell.nix
à la racine de ses sources.
Plusieurs morceaux ont été empruntés à pandoc-md-wiki, en particulier:
Pour les intéressés, le code source permettant de compiler cette présentation ainsi que le résultat de cette compilation ont été rendu publics aux emplacements respectif suivants: