Ziel: Einrichtung und Anwendung der textbasierten Diagrammgenerierung mit AsciiDoc
Praktikumsaufgaben Teil 5 - Diagramme 1
In diesem Aufgabenteil betrachten wir die Möglichkeit der textbasierten Diagrammgenerierung mit Asciidoctor und der textuellen Notation PlantUML.
|
Aufgrund der nicht gespeicherten Nutzer-Profile in den Windows-Laboren, sind zu jedem Praktikumsbeginn folgende Schritte durchzuführen:
Schritte zur Vorbereitung des Praktikums
-
Git-Konfiguration
C:\Users\<username>\.gitconfig
wiederherstellen oder anpassen:per Editor in der .gitconfig[user] name = Vorname Nachname email = s00000@htw-dresden.de [safe] directory = * [http] proxy = http://www-cache.htw-dresden.de:3128
oder per PowerShell und Git-Kommandos> git config --global user.name "Vorname Nachname" > git config --global user.email s00000@informatik.htw-dresden.de > git config --global --add safe.directory * > git config --global http.proxy http://www-cache.htw-dresden.de:3128
-
Visual Studio Code: Anpassen der AsciiDoc-Einstellungen:
-
Asciidoc > Preview: Use Editor Style: (deaktiviert)
-
Asciidoc > Extensions: Enable Kroki: (aktiviert)
-
-
GitHub Login mit gespeichertem oder neuem Personal Access Token über die PowerShell bekanntgeben:
Repository vorhanden> U: > cd path/to/repository/<repo-name>/ > git pull Authentifizierung ...
Repository nicht vorhanden (Home-/SAMBA-Laufwerk)> U: > cd path/to/repository/ > git clone https://github.com/.../<repo-name> Authentifizierung ...
Repository nicht vorhanden (TEMP-Laufwerk)> T: > git clone https://github.com/.../<repo-name> Authentifizierung ...
Vorbereitung
Für die Unterstützung der PlantUML Syntax und der Generierung von Diagrammen sind Anpassungen in Visual Studio Code, Asciidoctor und Git notwendig.
Visual Studio Code
Für die Verwendung der Diagramme mit der asciidoctor-diagram Erweiterung (bspw. per PlantUML Notation), muss für die Vorschau und Generierung folgende Einstellung angepasst werden:
-
Einstellungen:
in Visual Studio Code setzen:-
AsciiDoc > Extensions: Enable Kroki: (aktiviert)
-
Git Konfiguration
Es empfiehlt sich, die generierten Grafiken nicht ins Repository aufnehmen, da diese jederzeit neu generiert werden können.
Nutzt man die lokal installierte Asciidoctor-Version, wird für die generierten Grafiken ein zugehöriger Bilder-Cache angelegt. Dieser befindet sich im Verzeichnis der jeweiligen adoc-Datei(en) unter .asciidoctor/diagram/ und sollte auch vom Repository ausgeschlossen werden.
*.html *.pdf images/diagrams/ (1) .asciidoctor/ (2)
1 | Ausschluss des Ordners images/diagrams/ (Siehe Asciidoctor und PlantUML) vom Repository |
2 | Ausschluss des Bilder-Caches .asciidoctor/ vom Repository (Nur für lokal installiertes Asciidoctor notwendig) |
Asciidoctor und PlantUML
Der folgende Abschnitt erklärt, wie im Asciidoctor-Dokument die PlantUML Notation angewendet wird, was es für nützliche Attribute gibt und wie das fertige Dokument inkl. der Diagramme generiert wird.
Attribute
Das Asciidoctor-Dokument benötigt folgende zusätzliche Attribute, wobei die Werte beispielhaft gewählt sind:
:imagesdir: images (1)
:diagramsdir: diagrams (2)
:plantumlsdir: plantuml (3)
1 | In der Regel schon vorhanden. Verzeichnis bzw. Standardpfad, in welchem die Bilder des Dokumentes liegen. (Siehe Set the Images Directory) |
2 | Verzeichnis, in welchem die generierten Diagramme gespeichert werden. Es wird später dem Dateinamen der Diagramme mitgegeben, so dass sich die generierten Diagramme unterhalb des {imagesdir} -Verzeichnisses in ihrem eigenen Verzeichnis befinden. |
3 | Verzeichnis, in welchem die PlantUML Quelldateien liegen. Für die Variante, wenn die PlantUML Diagramme in extra Dateien ausgelagert werden. |
Standardmäßig werden die generierten Grafiken im vorgegebenen Bildverzeichnis {imagesdir}
gespeichert. Möchte man die Diagramme getrennt halten und unbeabsichtigtes Überschreiben anderer Bilder verhindern, empfiehlt es sich für die generierten Diagramme im Namen ein extra Verzeichnis {diagramsdir}/diagram-name
anzugeben. Dadurch werden die Diagramme in ihrem eigenen Verzeichnis unterhalb des {imagesdir}
-Verzeichnisses gespeichert.
documentation-x ├── images (1) │ ├── diagrams (2) │ │ ├── diagram1.jpg │ │ └── ... │ ├── image1.jpg │ └── ... ├── ... ├── plantuml (3) │ ├── class-diagram.puml │ └── ... ├── ... ├── document1.adoc ├── document2.adoc └── ...
1 | {imagesdir} |
2 | {diagramsdir} |
3 | {plantumlsdir} |
Praktikumsbeispiel
Praktikumsbeispiel für die Demonstration der Verwendung von Diagrammen mit PlantUML in Asciidoctor.
-
Vorführungsprojekt: htw-se-practical-asciidoc-diagram-demo
PlantUML Notation
@startuml (1) (2)
Bob -> Alice : Guten Tag! (3)
@enduml (1)
1 | Ein PlantUML Diagramm beginnt mit dem Schlüsselwort @startuml und endet mit dem Schlüsselwort @enduml . (Kann in Asciidoctor bzw. bei nur einem Diagrammabschnitt auch weggelassen werden.) |
2 | Standardmäßig hat das generierte Diagramm den gleichen Namen wie die Quelldatei (example.puml → example.svg). Die Dateiendung ist von der Art der zu generierenden Datei abhängig (bspw. .svg, .png). Gibt man mit @startuml filename einen Namen an, kann ein alternativer Dateiname festgelegt werden (example.puml → filename.svg). |
3 | Bereich für die Diagrammbeschreibung |
Der Dateiname bei @startuml filename wird in Asciidoctor nicht beachtet bzw. über die Einbindungssyntax festgelegt.
|
Diagramm eingebettet
In Asciidoctor werden Diagramme über einen Block eingebunden, welcher die Attribute und die textliche Beschreibung (PlantUML Notation) der zu generierenden Grafik enthält.
.Klassendiagramm mit PlantUML (1)
[plantuml, "{diagramsdir}/syntax-example1", svg] (2) (3)
....
class Graphic (4)
interface Shape <<Interface>> {
draw()
}
class Circle
class Triangle
class Square
Graphic -> Shape
Shape <|.. Circle
Shape <|.. Triangle
Shape <|.. Square
....
1 | Titel der Grafik (Bildunterschrift) |
2 | Attribute für die Generierung mit der Asciidoctor-Diagramm Erweiterung |
3 | Attribute: Diagramm-Type (Textsyntax), generierter Dateiname (inkl. Zielverzeichnis {diagramsdir} ), Bildformat (png, svg) |
4 | textliche Beschreibung (PlantUML Notation) des entsprechenden Diagramm-Types |
Die erfolgreich generierte Grafik Abbildung 3, “Klassendiagramm mit PlantUML” sieht wie folgt aus:
Diagramm in extra Datei
Die textlichen Diagrammbeschreibungen können, für eine bessere Wartbarkeit und Übersichtlichkeit im Asciidoctor-Dokument, mit Hilfe von include::
in extra PlantUML-Dateien *.puml
ausgelagert werden.
syntax-example.puml
@startuml
class Graphic
interface Shape <<Interface>> {
draw()
}
class Circle
class Triangle
class Square
Graphic -> Shape
Shape <|.. Circle
Shape <|.. Triangle
Shape <|.. Square
@enduml
.Klassendiagramm mit PlantUML
[plantuml, "{diagramsdir}/syntax-example2", svg]
....
include::{plantumlsdir}/syntax-example2.puml[]
....
:diagramTitle: Klassendiagramm mit PlantUML
:diagramFile: syntax-example2
plantuml::{plantumlsdir}/{diagramFile}.puml[title="{diagramTitle}", alt="{diagramTitle}", format="svg", target="{diagramsdir}/{diagramFile}"]
Hinweise: Block Macro Variante
Die Variante als Block Macro funktioniert nur mit einer lokal installierten Asciidoctor Version bzw. wenn diese für die Vorschau in Visual Studio Code verwendet wird. |
[#diagram_example] (1)
plantuml::{plantumlsdir}/diagram-example.puml[format=svg, alt="Diagrammbeispiel", title="Diagrammbeispiel", target="{diagramsdir}/diagram-example"] (2)
1 | optionale ID für Verweise (<<#ID>> ) oder als id= Attribute |
2 | Block Macro mit Diagramm-Type (Textsyntax) und Attribute für die Generierung mit der Asciidotor-Diagramm Erweiterung
|
:diagramTitle: Klassendiagramm mit PlantUML
:diagramFile: syntax-example2
plantuml::{plantumlsdir}/{diagramFile}.puml[title="{diagramTitle}", alt="{diagramTitle}", format="svg", target="{diagramsdir}/{diagramFile}"]
Visual Studio Code bietet Erweiterungen für die Unterstützung von PlantUML-Dateien (*.puml) für die Vorschau und Generierung an, bspw. die Erweiterung PlantUML.
|
Generierung PDF/HTML
In Visual Studio Code und der Asciidoc Extensions mit Hilfe der Command Palette über Hauptmenü:
:AsciiDoc: Save HTML Document
AsciiDoc: Export Document as PDF
Für das Generieren im Terminal (CLI) muss zusätzlich die installierte Asciidoctor-Diagram Erweiterung mit -r
bzw. --require
angegeben werden:
% asciidoctor -r asciidoctor-diagram plantuml_test.adoc
% asciidoctor-pdf -r asciidoctor-diagram plantuml_test.adoc
% asciidoctor -r asciidoctor-diagram -r asciidoctor-pdf -b pdf plantuml_test.adoc
PlantUML Notation im Detail
In den folgenden Aufgaben, wollen wir uns an ausgewählten Diagrammtypen die PlantUML Notation näher anschauen und erarbeiten.
Hinweise und Tipps
Neben den in den Aufgaben verlinkten Syntax-Hinweisen findet man auch die entsprechenden Abschnitte im PlantUML – Ein kurzer Überblick. Ebenfalls bereitgestellt sind jeweils die PlantUML-Quelltexte der verwendeten Beispieldiagramme.
Hilfreich für das Layout bzw. zur Positionierung von Elementen ist auch ein Blick in den entsprechenden Guide zu The Hitchhiker’s Guide to PlantUML - Layout.
Hinweise und Tipps zur Anwendung der PlantUML Notation
-
In der Regel definiert man erste die Elemente (Type, Bezeichnung) und nachfolgend die Beziehungen zwischen ihnen. Elemente in Kontainern/Paketen, werden am Anfang des entsprechenden Kontainers definiert.
-
Lange Bezeichnungen mit Leerzeichen werden in Anführungszeichen bzw. den Eingrenzungszeichen des jeweiligen Elementes gesetzt und können mit
\n
Zeilenumbrüche enthalten. -
Den Elementen kann über das Schlüsselwort
as
Alias-Namen vergeben werden, welche anstelle der Bezeichnung beim Definieren der Beziehungen verwendet werden. -
Pro Zeile wird immer ein Elemente definiert.
-
Beziehungen können immer nur für zwei beteiligte Elemente pro Zeile angegeben werden. (Bspw.
A — B
undB — C
stattA — B — C
) -
Die Hintergrundfarbe von Elemente kann durch Angabe eine Hexadezimalwertes festgelegt werden:
class MyClass #f00
(Siehe auch Colors)-
Weitere Möglichkeiten bieten Skinparam Befehl und Style (or CSS like style)
-
Mit
skinparam shadowing false
können bspw. Schatten deaktiviert werden.
-
-
Stereotypen werden nach der Elementbezeichnung angegeben. Bsp.:
class MyClass <<MyStereotype>>
-
Kommentare werden einzeilig mit
'
eingeleitet und mehrzeilig in/' … '/
eingeschlossen. -
Standardmäßig werden Diagramme von oben nach unten aufgebaut. Je nach Diagramm kann auch ein Aufbau von links nach rechts besser aussehen.
-
top to bottom direction
(Standard) -
left to right direction
-
-
Diagramme können über die Webseite https://www.plantuml.com/plantuml/ direkt generiert und getestet werden.
-
Mit
together {…}
werden Elemente gruppiert bzw. zusammengehalten. (Siehe Hilfe beim Layout) -
Wird das Attribut
subs="attributes+"
bei der Einbindung in Asciidoctor verwendet, können innerhalb des PlantUML-Diagramms Variablen vom Asciidoctor-Dokument verwendet werden.:variable1: Human :variable2: Hallo :variable3: World [plantuml, format="svg", subs="attributes+"] .... actor {variable1} note right of {variable1} : {variable2} usecase {variable3} ....
Aufgabe 1 - Anwendungsfalldiagramm
Schauen Sie sich die Syntax für ein Anwendungsfalldiagramm an und erstellen Sie, angelehnt an das Beispiel, ein Anwendungsfalldiagramm.
Hinweise: Anwendungsfalldiagramm in PlantUML
actor Akteur1 (1) :Akteur 2: actor "Akteur4 mit langem\nNamen" as ac2
1 | Akteure werden über das Schlüsselwort actor oder in Doppelpunkte :…: eingeschlossen. |
usecase Anwendungsfall1 (1) usecase "Anwendungsfall 1" as uc01 (Anwendungsfall 2) as uc02 (UC03\nAnwendungsfall 3) as uc03 usecase uc04 as "Langer Text (2) mit neuer Zeile -- und Trennlinie"
1 | Anwendungsfälle werden über das Schlüsselwort usecase oder in Klammern (…) eingeschlossen. |
2 | Bei Inhalt mit mehreren Zeilen, muss erst der Alias und dann der mehrzeilige Inhalt angegeben werden. |
Akteur1 -- (Anwendungsfall1) (1) ac2 -- uc02 uc02 <. uc03 : include (2) (3)
1 | Beziehungen werden mit -- (senkrecht), - (waagerecht) und gestrichelt mit .. (senkrecht), . (waagerecht) angegeben. |
2 | Für Pfeilrichtungen an den entsprechenden Seiten ein < bzw. > anfügen. |
3 | Mit : wird der Beziehung eine Beschreibung angegeben. |
example_usecase-diagram.puml
@startuml example-usecase-diagram
left to right direction
' skin parameters for usecase with special stereotype
skinparam usecase<<unspezifiziert>> {
BackgroundColor #eee
BorderColor #gray
StereotypeFontColor #gray
StereotypeFontSize 10
}
actor Nutzer
actor Service
rectangle "eRoller App" {
usecase "UC01\nRoller finden" as uc01
usecase "UC02\nRoller freischalten" as uc02
usecase "UC03\nRoller abstellen" as uc03
usecase "UC04\nRoller melden" as uc04
' single line:
'usecase "UC05\nAnmeldedaten erfassen" as uc05
' multiple lines:
usecase uc05 as "UC05
Anmeldedaten erfassen"
usecase "UC06\nRoller verwalten" <<unspezifiziert>> as uc06
}
Nutzer -- uc01
Nutzer -- uc02
Nutzer -- uc03
Nutzer -- uc04
uc02 .down.> uc05 : include
Service -- uc06
@enduml
Aufgabe 2 - Anwendungsfalldiagramm für Cocktailversand
Nehmen Sie das Anwendungsfalldiagramm aus Aufgabe 1 und erstellen Sie ein Anwendungsfalldiagramm für den Cocktailversand. Öffnen Sie dazu parallel Ihr Cocktailversand Repository in Visual Studio Code:
-
Legen Sie im Ordner docs/requirements parallel zum Ordner Images einen neuen Ordner plantuml an.
-
Legen Sie im Ordner plantuml eine neue Datei use-case-diagram.puml an.
-
Binden Sie die Datei use-case-diagram.puml in die Datei use-case_model.adoc an geigneter Stelle per
include
ein.
Weitere Diagrammarten
Wechseln Sie hierzu wieder in Ihr Vorführungsprojekt und ergänzen Sie die folgenden Diagramme.
Aufgabe 3 - Klassendiagramm
Schauen Sie sich die Syntax für ein Klassendiagramm an und erstellen Sie, angelehnt an das Beispiel, ein Klassendiagramm.
Hinweise: Klassendiagramm in PlantUML
class Klasse1 (1) class Klasse2 { (2) String var1 double var2 void methode1() bool methode2(int x) } interface Interface1 (3) interface Interface1 { void methode1() }
1 | Klassen werden mit dem Schlüsselwort class angelegt. |
2 | Klassen können Angaben zu den Typen und Methoden haben. |
3 | Interface Klassen werden mit dem Schlüsselwort interface angelegt. Abstrakte Klassen mit abstract bzw. abstract class . |
class Dummy { (1) -field1 #field2 ~method1() +method2() }
1 | Mit - (private), # (protected), ~ (package private) und + (public) werden Sichtbarkeiten festgelegt. |
class Dummy { (1) {static} String id {abstract} void methods() }
1 | Modifikatoren für {static} (statisch) oder {abstract} abstrakt. |
Klasse1 <-- Klasse2 (1) (2) (3) Klasse3 <|-- Klasse4 Klasse5 *-- Klasse6 Klasse7 o-- Klasse8
1 | Assoziation <-- , Generalisierung <|-- , Realisierung <|.. , Komposition *-- , Aggregation o-- |
2 | -- durchgezogene Linie, .. gestrichelte Linie |
3 | - /. vertikal, -- /.. horizontal, --- /… horizontal lang |
Klasse1 "1" *-- "many" Klasse2 : Beschreibung > (1) (2)
1 | "1" und "many" legen die Kardinalität fest. |
2 | in der Beschreibung : kann mit < text oder text > eine Richtung angegeben werden. |
example_class-diagram.puml
@startuml example-class-diagram
class MyService {
-repository : MyRepository
+MyService(MyRepository)
+getProcessedStudents() : List
+getProcessedMarks() : List
}
interface MyRepository <<interface>> {
+getStudents() : List
+getMarks() : List
}
class DictionaryRepository {
-data : TestData
+getStudents() : List
+getMarks() : List
}
class TestData {
#students : Dictionary
#marks : Dictionary
+generateKey(Student, SubjectMark) : String
}
class MsSqlRepository {
-connection : OdbcConnection
+getStudents() : List
+getMarks() : List
}
MyService --> "1" MyRepository
MyRepository <|.. DictionaryRepository
MyRepository <|.. MsSqlRepository
TestData "1" <- DictionaryRepository
note left of MyRepository: Interface for local test data\nand different databases
@enduml
Aufgabe 4 - Aktivitätsdiagramm
Schauen Sie sich die Syntax für ein Aktivitätsdiagramm (Beta) an und erstellen Sie, angelehnt an das Beispiel, ein Aktivitätsdiagramm.
Hinweise: Aktivitätsdiagramm in PlantUML TODO
Die Hinweise zur Erstellung von Aktivitätsdiagramm entnehmen Sie bitte, auf Grund der Veränderungen durch die Beta und Legacy Variante, direkt der offiziellen Dokumentation:
example_activity-diagram.puml
@startuml example-activity-diagram
start
:Initialization;
note right: The first <del>Avenger</del> Activity
if (Some Test) then (yes)
:Some Activity;
#LightBlue:Object] /'idea: activity as object flow'/
:Another Activity;
else (no)
:Something else;
note right #LightBlue: Object /'idea: note as object'/
endif
:Final Activity;
stop
@enduml
Hinweise: Bisherige Aktivitätsdiagramm (Legacy) Variante
Unter Aktivitätsdiagramm (Legacy) findet man die bisherige Variante.
example_activity-diagram_legacy.puml
@startuml example-activity-diagram
(*) --> "Initialization"
note right: The first <del>Avenger</del> Activity
if "Some Test" then
-->[true] "Some Activity"
--> "Another Activity"
--> "Final Activity"
else
-->[false] "Something else"
--> "Final Activity"
endif
--> (*)
@enduml
Aufgabe 5 - C4 Model Diagramme
PlantUML kann neben UML auch Diagramme basierend auf dem C4 Model erzeugen. Dies wären, sortiert nach zunehmenden Detailgrad, die Kontext-, Kontainer- und Komponentendiagramme. Es gibt noch die Codediagramme, diese können bspw. mit den aus der UML bekannten Klassendiagrammen dargestellt werden.
Schauen Sie sich auf [1] und [2] die Syntax für die C4 Model Diagramme an und erstellen Sie, angelehnt an das Beispiel, ein C4 Model Diagramm.
Hinweise: C4 Model Diagramme in PlantUML
LAYOUT_TOP_DOWN or LAYOUT_LEFT_RIGHT (1)
LAYOUT_WITH_LEGEND (2)
LAYOUT_AS_SKETCH (3)
1 | Diagrammausrichtung |
2 | Legende anzeigen |
3 | Darstellungsstil skizzenhaft |
-
Diagrammtitel werden mit
titel
vergeben:title Dies ist ein Diagrammtitel
-
System Context & System Landscape diagrams
-
Import:
!include <c4/C4_Context.puml>
-
C4-Model Elemente:
-
Person
,Person_Ext
-
System
,System_Ext
-
SystemDb
,SystemDb_Ext
-
-
C4 Model Kontainer:
-
Boundary
,System_Boundary
,Enterprise_Boundary
-
-
-
Container diagram
-
Import:
!include <c4/C4_Container.puml>
-
Zusätzliche C4-Model Elemente (Knoten):
-
Container
,ContainerDb
-
-
Zusätzliche C4-Model Elemente (Kontainer):
-
Container_Boundary
-
-
-
Component diagram
-
Import:
!include <c4/C4_Component.puml>
-
Zusätzliche C4-Model Elemente (Knoten):
-
Component
,ComponentDb
-
-
-
Für jedes Element wird ein Alias, der Name und eine Beschreibung vergeben:
Person(alias, Name, "Beschreibung")
-
Beziehungen werden über
Rel(…)
beschrieben und können zwischen Elementen und Kontainern bestehen:Rel(alias_person1, alias_container1, "Beschreibung") Rel(alias_element1, alias_element2, "Beschreibung", "Text in [...]")
-
Über
Rel_R
,Rel_L
,Rel_D
,Rel_U
,Rel_Back
,Rel_Neighbor
undRel_Back_Neighbor
kann die Pfeilrichtung und Ausrichtung des in Beziehung stehenden Elementes beeinflusst werden.
-
Elemente kann man in Bereiche bündeln:
Boundary(alias, "Name") { ... }
example_c4-model-diagram.puml
@startuml example-c4-modell-diagram
' source: https://github.com/plantuml-stdlib/C4-PlantUML
' C4 Model
!include <c4/C4_Context.puml>
' Images
!include <office/Users/user.puml>
!include <office/Users/mobile_user.puml>
' Diagram title
title \nSystem Context diagram for Internet Banking System\n
' Diagram syntax
Person(customer, Customer, "<$user> <$mobile_user>\n A customer of the bank, with personal bank accounts")
Enterprise_Boundary(c0, "Big Bank plc") {
System(banking_system, "Internet Banking System", "Allows customers to view information about their bank accounts, and make payments.")
System_Ext(mail_system, "E-mail system", "The internal Microsoft Exchange e-mail system.")
System_Ext(mainframe, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transactions, etc.")
Rel(customer, banking_system, "Uses")
Rel_Back(customer, mail_system, "Sends e-mails to")
Rel_Neighbor(banking_system, mail_system, "Sends e-mails", "SMTP")
Rel(banking_system, mainframe, "Uses")
}
@enduml