Search

Dark theme | Light theme
Showing posts with label PlantUML. Show all posts
Showing posts with label PlantUML. Show all posts

September 8, 2021

PlantUML Pleasantness: Change Look-and-feel With Themes

When we convert our PlantUML diagrams we get a default look-and-feel for our diagrams that is mostly red and yellow based. We can alter the style and color of individual elements using the skinparam command. But we can also apply so-called themes to our diagram that will alter the look-and-feel of our diagram with a simple theme reference.

We can define the name of the theme in our diagram markup using the !theme directive. Or we can use the command-line option -theme when we generate a diagram from our markup. We can even combine both methods where the end result is also a combination of both themes.

Let's start with simple PlantUML markup to test some themes:

@startuml

' Elements
actor "Application User" as User
[Mail server] as Mail <<Mail>>

package "Sample Application" {
    [Controller] <<Spring REST controllers>>
    [Service] <<Spring service>>
}

' Connections
User --> Controller
Controller --> Service
Service --> Mail

@enduml

Without themes we get the following diagram with the default look-and-feel:

First we use the !theme directive and apply the cerulean theme. Later we will how we can check which themes are part of your PlantUML version.

@startuml

' Set theme
!theme cerulean

' Elements
actor "Application User" as User
[Mail server] as Mail <<Mail>>

package "Sample Application" {
    [Controller] <<Spring REST controllers>>
    [Service] <<Spring service>>
}

' Connections
User --> Controller
Controller --> Service
Service --> Mail

@enduml

The resulting diagram now has a different look-and-feel:

Instead of adding the !theme directive we can also the command-line tool for PlantUML and specify a theme with the option -theme. For our example we could run $ plantuml diagram.puml -theme crt-green and we get the following result:

If the PlantUML markup contains the !theme directive and we use the command-line -theme option the end result will be a combination. For example if we set the cerulean with the !theme directive and specify sketchy-outline with the -theme option we get:

If we want to know which themes are included with our PlantUML version we can use the command help themes in our PlantUML markup and the resulting diagram shows all themes available.

@startuml
help themes
@enduml

For an overview of themes we can check out the theme gallery.
More information is also available in the PlantUML documentation.

Written with PlantUML 1.2021.10.

June 6, 2018

PlantUML Pleasantness: Using AWS, Font Awesome, Devicons and Google Material Icons

In a previous post we learned how to use the built-in icons from the OpenIconic set. In the newer PlantUML versions several icon sets have been added as standard library. These sets include AWS icons, Font Awesome icons, Devicons and Google Material icons.

To use an icon from the icon set we must include the icon using the !include statement. In our PlantUML definition we reference the icon with the syntax <$iconName>. In the following example PlantUML definition we include 2 icons from the Font Awesome and Devicons icon sets:

@startuml
' We only include the icon files.
!include <devicons/github>
!include <font-awesome/gitlab>

rectangle github [
    ' Reference github icon with <$icon>.
    <$github>
]

rectangle gitlab [
    ' Reference gitlab icon with <$icon>.
    <$gitlab>
]

github -> gitlab : ~#movingtogitlab
@enduml

When we render this definition to a diagram we get the following result:

Each icon set also comes with a common file that defines macros for creating elements with an icon. Instead of referencing an icon with the syntax <$iconName> we can use a macro. For each icon there is a corresponding macro and the macro is overloaded to accept different arguments. The icon sets for AWS, Font Awesome and Devicons use the same macro arguments. The arguments for using the Google Material icons is different. So we need to keep this in mind when we use the macros in our PlantUML definition.

We use the macros from the different icon sets n the following examples:

@startuml

' Include common to use icon macros.
!include <devicons/common>
' Include icon from Devicons.
!include <devicons/github>
' Include icon from Font Awesome icons.
!include <font-awesome/gitlab>

' Use macros from common library and icon file.
' First argument is alias, second label.
DEV_GITHUB(github, 'Github')
FA_GITLAB(gitlab, 'Gitlab')

' Use ~ to escape #
github -> gitlab : ~#movingtogitlab

@enduml

Let's render the diagram for the PlantUML definition:

In the next example we use the extra arguments to style the element. Also we use the stereotype set by the macro to change the foreground and background colors of the element:

@startuml

!include <devicons/common>
!include <devicons/github>
!include <font-awesome/gitlab>

' Change styling via stereotypes, set by
' macro from devicons/github library.
skinparam cloud<<DEV GITHUB>> {
    BackgroundColor #66ffcc
    ForegroundColor #ccff66
}

' Third argument is element type.
DEV_GITHUB(github, 'Github', cloud)
' Fourth argument is foreground color.
' After macro definition we can set the background color.
FA_GITLAB(gitlab, 'Gitlab', cloud, #ff9e27) #ccff66

github -> gitlab : ~#movingtogitlab

@enduml

We get the following diagram:

Now we use the AWS icons:

@startuml

' Include common to use icon macros.
!include <aws/common>
' Include three icons.
!include <aws/Compute/AmazonECR/AmazonECR>
!include <aws/Compute/AmazonECS/AmazonECS>
!include <aws/Compute/AmazonECS/ECScontainer/ECScontainer>

' Macro signature is the same as for font-awesome and devicons.
AMAZONECR(ecr)
AMAZONECS(ecs) {
    ECSCONTAINER(containers, 'Containers', collections)
} 

ecr .> containers

@enduml

This results in the following diagram:

And with the Google Material icon set we must keep in mind that the arguments for the macros are different:

@startuml

' Include common to use material icon macros.
!include <material/common>
' Include console icon.
!include <material/console>
' Include clipboard_text icon.
!include <material/clipboard_text>

' Do not show stereotype in diagram.
hide stereotype

' Use icon macro where first argument is
' the foreground color, the second is the
' scale of the icon, third argument is alias.
MA_CONSOLE(#ff9e27, 1, console)
' Fourth argument is the type
MA_CONSOLE(#ff9e27, 2, consoleLarge, rectangle)
' And the fifth argument is a label.
MA_CONSOLE(#ff9e27, 4, consoleBig, file, 'A big console')

file clipboard [
    ' Instead of using the macro we can reference
    ' the icon by name directory. We must use the ma_
    ' prefix before the icon name.
    <$ma_clipboard_text>
]

@enduml

The definition gives the following diagram:

Written with PlantUML 1.2018.6.

June 5, 2018

PlantUML Pleasantness: Setting Arrow Directions

PlantUML mostly does a good job organizing elements and arrows in the resulting diagram. But we can help PlantUML by defining the arrow direction in our PlantUML definition. We can use the keywords up, down, left and right inside the arrow definition.

In the following example we have five rectangles connected with arrows. We define the arrow direction for each arrow.

@startuml
rectangle Export 
rectangle PDF
rectangle HTML
rectangle ePub
rectangle Word

Export -left-> PDF
Export -right-> HTML
Export -down-> ePub
Export -up-> Word
@enduml

We can even only use the first letters of the direction. The following definition will render the same diagram:

@startuml
rectangle Export 
rectangle PDF
rectangle HTML
rectangle ePub
rectangle Word

Export -l-> PDF
Export -r-> HTML
Export -d-> ePub
Export -u-> Word
@enduml

The resulting diagram looks like this:

Written with PlantUML 1.2018.6.

October 23, 2017

PlantUML Pleasantness: Using The Built-in Icons

PlantUML has a built-in icon set we can use in our diagram definitions. The icon set is open source icon set OpenIconic. We refer to an icon using the syntax <&iconName>.We can use an icon everywhere where we can use text in our diagrams.

In the following example we use different icons in different places:

@startuml

skinparam DefaultFontSize 24
skinparam DefaultTextAlignment center

title <&caret-right> Using icons in PlantUML <&caret-left>

package "Charts <&menu>" as charts {

    file bar [
        Bar

        <size:120><&bar-chart></size>
    ]

    file pie [
        Pie

        <size:42><&pie-chart></size>
    ]

}   

@enduml

When we generate a diagram we see the following output:

To get a list of available icons we can use the statement listopeniconic. This will create a diagram with all the icons and their names we can use:

@startuml
listopeniconic
@enduml

The following image shows all icons that we can use:

Written with PlantUML 1.2017.18.

October 19, 2017

PlantUML Pleasantness: Creating Our Own Sprites

PlantUML supports sprites to be used in diagrams. A sprite is text encoded monochrome graphic we can reference using the syntax <$spriteName>. The sprite is defined using hexadecimal values. We can define a set of hexadecimal values to create our sprite, but we can also generate the correct values from for example a PNG image.

We start with a simple example where we create a small triangle using hexadecimal values:

@startuml
title Triangle sprite

skinparam defaultTextAlignment center

sprite $triangle {
    00000000000
    00000F00000
    0000FBF0000
    0000FBF0000
    000F999F000
    000F999F000
    00F66666F00
    00F66666F00
    0F3333333F0
    0F3333333F0
    0FFFFFFFFF0
    00000000000
}

rectangle Sample [
    Triangle
    ' Reference sprite with name triangle
    <$triangle>
]

@enduml

Let's generate a PNG image from this PlantUML definition and we get the following result:

If we have already an image we want to turn into a sprite we can use the command-line option -encodesprite when we run PlantUML. As option we must specify the gray level for our sprite. We can choose for level 4, 8 or 16. If we place the letter z after the number the sprite definition is compressed. PlantUML will output to the console the sprite definition that we can use in our PlantUML definition file. We get the best result if the original image is grayscale.

We start with the following image:

Next we run PlantUML to encode the image to a sprite definition:

$ plantuml -encodesprite 16 JDrivenIcon.png
sprite $JDrivenIcon [64x64/16] {
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0010000000000000000000000000000000000000000000000000000000000000
0016510000000000000000000000000000000000000000000000000000000000
25007FA520000000000000000000000000000000000000000000000000000000
0C4004FFFB620000000000000000000000000000000000000000000000000000
06F3002CFFFFC731000000000000000000000000000000000000000000000000
03FF30019FCEFFFF841000000000000000000000000000000000000000000000
01FFF30006FEEEDFFFF942000000000000000000000000000000000000000000
00AFEF20004FFDFFEDFFFF952000000000000000000000000000000000000000
007FDFF20002FFDFFFFEDEFFFA62000000000000000000000000000000000000
004FDEFF100019FDFFFFFFEDEFFFC73100000000000000000000000000000000
002FEFEFE100006FEEFFFFFFFEDEFFFF84100000000000000000000000000000
000BFEFEFD100004FFDFFFFFFFFFEEDFFFF94200000000000000000000000000
0007FEFFDFB100003FFDFFFFFFFFFFFFEDFFFF95200000000000000000000000
0004FDFFFDFA000001AFDFFFFFFFFFFFFFFEDEFFFB6300000000000000000000
0002FEFFFFDF90000007FEEFFFFFFFFFFFFFFFEDEFFFC7310000000000000000
0000BFEFFFFDF90000005FFEFFFFFFFFFFFFFFFFFEDEFFFF8410000000000000
00007FEFFFFFDF80000003FFDFFFFFFFFFFFFFFFFFFFEEDFFFF9410000000000
00004FDFFFFFFDF70000001BFDFFFFFFFFFFFFFFFFFFFFFFEDFFFF9520000000
00002FEFFFFFFFDF700000007FEFFFFFFFFFFFFFFFFFFFFEEEDDCDFFFB631000
00000BFFFFFFFFFDF600000005FFEFFFFEEEEDDDDDEEFFFFFFFFFFFFFFFFA520
000007FEFFFFFFFFDF600000003FFDFFFFFFFFFFFFFFFDBA8766543321100000
000004FDFFFFFFFFFDF500000002BFFECA987654332211000000000000000131
000002FEFFFFFFFFFFDF5000000002110000000000000000000000001357CF40
000000CFEFFFFFFFFFFEF4000000000000000000000000000001247AFFFFC100
0000008FEFFFFFFFFFFFEF4000000000000000000000001247AFFFFFFCF80000
0000004FDFFFFFFFFFFFFEF30000000000000000002469EFFFFFEDEDEF600000
0000002FEFFFFFFFFFFFFEFF10000000000001368CFFFFFEDEEFFFDFF4000000
0000000DFEFFFFFFFFFFFEFB000000001358BFFFFFEDEEFFFFFFFDFD20000000
00000008FEFFFFFFFFFFFDF60000007BFFFFFFEDEFFFFFFFFFFFDF9100000000
00000005FDFFFFFFFFFFFDF3000003FFFDDEEFFFFFFFFFFFFFEEF60000000000
00000002FEFFFFFFFFFFFFE1000009FDFFFFFFFFFFFFFFFFFDFF400000000000
00000001EFFFFFFFFFFFEF8000002FEFFFFFFFFFFFFFFFFFDFF3000000000000
000000008FEFFFFFFFFFDF4000007FEFFFFFFFFFFFFFFFFDFA10000000000000
000000005FDFFFFFFFFFEF200001FFFFFFFFFFFFFFFFFEEF7000000000000000
000000002FEFFFFFFFFEFA000005FDFFFFFFFFFFFFFFEFF50000000000000000
000000001EFFFFFFFFFDF600001CFFFFFFFFFFFFFFFDFF300000000000000000
0000000008FEFFFFFFFEF300004FDFFFFFFFFFFFFFDFB1000000000000000000
0000000005FDFFFFFFFFE10000AFEFFFFFFFFFFFFDF800000000000000000000
0000000003FEFFFFFFEF800003FDFFFFFFFFFFFEFF5000000000000000000000
0000000001EFFFFFFFDF400008FEFFFFFFFFFFDFF30000000000000000000000
00000000009FEFFFFFEF20002FEFFFFFFFFFFDFC200000000000000000000000
00000000005FDFFFFEFA00006FDFFFFFFFFFDF91000000000000000000000000
00000000003FEFFFFDF60001EFFFFFFFFFEEF600000000000000000000000000
00000000001FFFFFFDF30004FDFFFFFFFDFF4000000000000000000000000000
000000000009FEFFFFE1000BFEFFFFFFDFF20000000000000000000000000000
000000000006FDFFEF80003FDFFFFFFDFA100000000000000000000000000000
000000000003FDFFDF40009FEFFFFEEF70000000000000000000000000000000
000000000001FFFFEF1002FEFFFFEFF400000000000000000000000000000000
000000000000AFEEFA0007FDFFFDFF3000000000000000000000000000000000
0000000000006FDEF6001FFFFFDFB10000000000000000000000000000000000
0000000000003FDEF3005FDFFEF8000000000000000000000000000000000000
0000000000001FEFD100CFFEFF50000000000000000000000000000000000000
0000000000000AFF8004FEDFF300000000000000000000000000000000000000
00000000000006FF4009FDFC2000000000000000000000000000000000000000
00000000000003FF203FDF910000000000000000000000000000000000000000
00000000000001FA008FF6000000000000000000000000000000000000000000
00000000000000C602FF40000000000000000000000000000000000000000000
000000000000007307F200000000000000000000000000000000000000000000
0000000000000031191000000000000000000000000000000000000000000000
0000000000000000200000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
}

$

The following PlantUML definition contains the result of encoding the image as sprite for grey levels 4, 8, 16, 4z, 8z and 16z:

@startuml
nsprite $JDrivenIcon4 [64x64/4] {
0000000000000000000000000000000000000000000000000000000000000000
071GKDB732100000000000000000000000000000000000000000000000000000
0G_F300muz___VFFB73210000000000000000000000000000000000000000000
00b___F300Gmy-________lVFB73310000000000000000000000000000000000
000v_____F2000Gqy_______________lVFB7321000000000000000000000000
000G-______lB20000Wqz____________________lVFF7332100000000000000
0000K_________l7100000muz__________________________lVFB732100000
00000b___________V7100000Gmy-____---zzzzyyyyyyuuuqqqqqmmmmmmWG00
000000-_____________V7100000000000000000000000001123377BFFVUymG0
000000G________________E0000000000122337BFFVVl__________yqG00000
0000000a_______________G000002Vl____________________zqW000000000
00000000v_____________a000007___________________zum0000000000000
000000000-___________a00001V________________-ymG0000000000000000
000000000G__________v00002l______________yqW00000000000000000000
0000000000a________v00007____________zum000000000000000000000000
00000000000v______-0000R_________-ymG000000000000000000000000000
000000000000-____-G001l_______yqG0000000000000000000000000000000
000000000000G____G007_____zuW00000000000000000000000000000000000
0000000000000a__a00R__-ym000000000000000000000000000000000000000
00000000000000za01lyqG000000000000000000000000000000000000000000
00000000000000000W0000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
}

sprite $JDrivenIcon8 [64x64/8] {
0000000000000000000000000000000000000000000000000000000000000000
0003200000000000000000000000000000000000000000000000000000000000
8M20OwlNF5310000000000000000000000000000000000000000000000000000
0P_F108my_-_tVF7420000000000000000000000000000000000000000000000
00z__F100Ow__-t__-_dNF421000000000000000000000000000000000000000
00Q_s__F0008uyt-____t__-_lVF631000000000000000000000000000000000
008z_____60000Ow__-_______t___-_dN742100000000000000000000000000
000Q_-__t-l500008uzt-____________t__-_dNF53100000000000000000000
0008z_____t-d400000Ow__________________t__-_tVF74200000000000000
0000Q_-_____t-d3000008uzt-____________________t__-_dN74210000000
00008z________t-V3000000Ow___________-----________tttt___lVF5210
00000Q_-________t-V20000008vzt__-zyyxxwwvvvvumeeWOOOGG8880000010
000008-___________t_N200000008000000000000000000000012357FNVsuG0
000000Y_-_____________N100000000000000000012347FNVl__-_-_txW0000
0000008-_______________z00000000012457FVdt_-____t____-t-vG000000
0000000Y_-___________s_P000001Vl_--____t____________txW000000000
00000008______________y000001d_t________________-t_vG00000000000
00000000Y_-_________t_H00000V__________________txe00000000000000
000000008__________-_h00000M_t_____________-__vG0000000000000000
000000000Y_-_________80000L_t____________-tye0000000000000000000
0000000008________-_Y0000C_t__________-__vG000000000000000000000
0000000000Y_-______z8000B_-_________-tym800000000000000000000000
00000000008______s_P0002_-_______-__wO00000000000000000000000000
00000000000Z_-____y0001l-______-tzu80000000000000000000000000000
000000000008_t__t_G001d________wO0000000000000000000000000000000
000000000000h_-__h000V_t__-tzu8000000000000000000000000000000000
0000000000008_t_-800M_t___wW000000000000000000000000000000000000
0000000000000h__Y00K_-t-v800000000000000000000000000000000000000
00000000000008_z80C_txW00000000000000000000000000000000000000000
00000000000000pP0B_vG0000000000000000000000000000000000000000000
00000000000000801W0000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
}

sprite $JDrivenIcon16 [64x64/16] {
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0010000000000000000000000000000000000000000000000000000000000000
0016510000000000000000000000000000000000000000000000000000000000
25007FA520000000000000000000000000000000000000000000000000000000
0C4004FFFB620000000000000000000000000000000000000000000000000000
06F3002CFFFFC731000000000000000000000000000000000000000000000000
03FF30019FCEFFFF841000000000000000000000000000000000000000000000
01FFF30006FEEEDFFFF942000000000000000000000000000000000000000000
00AFEF20004FFDFFEDFFFF952000000000000000000000000000000000000000
007FDFF20002FFDFFFFEDEFFFA62000000000000000000000000000000000000
004FDEFF100019FDFFFFFFEDEFFFC73100000000000000000000000000000000
002FEFEFE100006FEEFFFFFFFEDEFFFF84100000000000000000000000000000
000BFEFEFD100004FFDFFFFFFFFFEEDFFFF94200000000000000000000000000
0007FEFFDFB100003FFDFFFFFFFFFFFFEDFFFF95200000000000000000000000
0004FDFFFDFA000001AFDFFFFFFFFFFFFFFEDEFFFB6300000000000000000000
0002FEFFFFDF90000007FEEFFFFFFFFFFFFFFFEDEFFFC7310000000000000000
0000BFEFFFFDF90000005FFEFFFFFFFFFFFFFFFFFEDEFFFF8410000000000000
00007FEFFFFFDF80000003FFDFFFFFFFFFFFFFFFFFFFEEDFFFF9410000000000
00004FDFFFFFFDF70000001BFDFFFFFFFFFFFFFFFFFFFFFFEDFFFF9520000000
00002FEFFFFFFFDF700000007FEFFFFFFFFFFFFFFFFFFFFEEEDDCDFFFB631000
00000BFFFFFFFFFDF600000005FFEFFFFEEEEDDDDDEEFFFFFFFFFFFFFFFFA520
000007FEFFFFFFFFDF600000003FFDFFFFFFFFFFFFFFFDBA8766543321100000
000004FDFFFFFFFFFDF500000002BFFECA987654332211000000000000000131
000002FEFFFFFFFFFFDF5000000002110000000000000000000000001357CF40
000000CFEFFFFFFFFFFEF4000000000000000000000000000001247AFFFFC100
0000008FEFFFFFFFFFFFEF4000000000000000000000001247AFFFFFFCF80000
0000004FDFFFFFFFFFFFFEF30000000000000000002469EFFFFFEDEDEF600000
0000002FEFFFFFFFFFFFFEFF10000000000001368CFFFFFEDEEFFFDFF4000000
0000000DFEFFFFFFFFFFFEFB000000001358BFFFFFEDEEFFFFFFFDFD20000000
00000008FEFFFFFFFFFFFDF60000007BFFFFFFEDEFFFFFFFFFFFDF9100000000
00000005FDFFFFFFFFFFFDF3000003FFFDDEEFFFFFFFFFFFFFEEF60000000000
00000002FEFFFFFFFFFFFFE1000009FDFFFFFFFFFFFFFFFFFDFF400000000000
00000001EFFFFFFFFFFFEF8000002FEFFFFFFFFFFFFFFFFFDFF3000000000000
000000008FEFFFFFFFFFDF4000007FEFFFFFFFFFFFFFFFFDFA10000000000000
000000005FDFFFFFFFFFEF200001FFFFFFFFFFFFFFFFFEEF7000000000000000
000000002FEFFFFFFFFEFA000005FDFFFFFFFFFFFFFFEFF50000000000000000
000000001EFFFFFFFFFDF600001CFFFFFFFFFFFFFFFDFF300000000000000000
0000000008FEFFFFFFFEF300004FDFFFFFFFFFFFFFDFB1000000000000000000
0000000005FDFFFFFFFFE10000AFEFFFFFFFFFFFFDF800000000000000000000
0000000003FEFFFFFFEF800003FDFFFFFFFFFFFEFF5000000000000000000000
0000000001EFFFFFFFDF400008FEFFFFFFFFFFDFF30000000000000000000000
00000000009FEFFFFFEF20002FEFFFFFFFFFFDFC200000000000000000000000
00000000005FDFFFFEFA00006FDFFFFFFFFFDF91000000000000000000000000
00000000003FEFFFFDF60001EFFFFFFFFFEEF600000000000000000000000000
00000000001FFFFFFDF30004FDFFFFFFFDFF4000000000000000000000000000
000000000009FEFFFFE1000BFEFFFFFFDFF20000000000000000000000000000
000000000006FDFFEF80003FDFFFFFFDFA100000000000000000000000000000
000000000003FDFFDF40009FEFFFFEEF70000000000000000000000000000000
000000000001FFFFEF1002FEFFFFEFF400000000000000000000000000000000
000000000000AFEEFA0007FDFFFDFF3000000000000000000000000000000000
0000000000006FDEF6001FFFFFDFB10000000000000000000000000000000000
0000000000003FDEF3005FDFFEF8000000000000000000000000000000000000
0000000000001FEFD100CFFEFF50000000000000000000000000000000000000
0000000000000AFF8004FEDFF300000000000000000000000000000000000000
00000000000006FF4009FDFC2000000000000000000000000000000000000000
00000000000003FF203FDF910000000000000000000000000000000000000000
00000000000001FA008FF6000000000000000000000000000000000000000000
00000000000000C602FF40000000000000000000000000000000000000000000
000000000000007307F200000000000000000000000000000000000000000000
0000000000000031191000000000000000000000000000000000000000000000
0000000000000000200000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
}

sprite $JDrivenIcon4z [64x64/4z] {
vPVHbi8m24IPuV__sJLD3JKa1VhaMOwFpWN6O8Z8pmVmIFttKTOHsW1QHa0RfKK9eGt0Wr0eGmy0L6i8Je0Sekbac91577d5cd06eWQS0EXt1ChW5d2Fw1hA
R488SUQak2RS8_GAWAu2MmC20ByCS_HaOy8IWRb2QWRXj0ZLE88LW470DTbJa7Z7sW0Be954HY0tDi3uPdBk08wHoGtkAJM7nJFxHZhbq1i0k9-5wOUoKkym
haReIiTgc6Lx0Zxu-1oxUiR_1jpwVFd-FyHaGAXrpu1rUaH6WClq28qGLkdlRv7jNHIuHTQNuLvkowLRFYIgXvS-Ueswoq10FWpWx1xZUq0llxn7pCjGTAsZ
qJFL-hn795kt3U2IFhCBZd9BydvVMVUogtJFc6zzD30jP7bzUPbdIuf2wny3q6qiFcPw-PIYdYrz-JNrLZwG7u-vPwz9oh-A5m00
}
sprite $JDrivenIcon8z [64x64/8z] {
rPTHiiCW24L5GFQ_uvUg94emnVJh-T5fft831oIOqhzVc7ymXiCOXJEy5IY7G1OHndSIA8STb4D1oXi9a8z08gaIGjimf0bWzQ19RBd1NI0tysq9_9X0YwJ5
K3_3F7FTNxygX2uHumdDeljohJ1FRjkxCwSBOPwTFAiteq148dVkhExC0bzvWkwYT8CW4Pvi1BB8IiBbYM84RX0C31T0_HlJ2i83JnZ-nBI6qFSSo_1aHo0R
4yUVi-kWE08EXC9CY9Wp0BW0ge3Y0QucHDt2IHvO09D0WiV6YTTEusZ-rdEHhoFJ3cvGG4s7Oh40wWBNbCuGZ-teLe0kOujKnYekraMRAHuUIpoQzkSR1ydK
Q7TEWvt3cqBt09GUFzJQknSUhdg02P-SKrJyxCoRQ45LjDVV5ZaLY9uvFpN1EVtUwSNd9ZXcBplHvwVNgCbU2OP-1m3UuvUXtm6OfhGgcXK0Qh_t3dKosQDu
w1O0t5jIWU0SeDd3wRXHV0xesGiLZGUWz66eF9-N1m1JyYBana6gPG-kDo9lJ995iqUReOy0fkHjJQEisKET9FVcOTIslXtw003Ev57QNVsTLlP3Fm6Gpf1l
RXDOdqgnyxAwIq3mlBW0kDOElZHF1Jy-lB_F7JCPokkhN1ruAFsq8FslzGS0
}

sprite $JDrivenIcon16z [64x64/16z] {
rPVPTeKW34MP11dp_tzRvacqUEz3L-bBL-ivafq40q9_lV2tUdvyOK4EX0IeWtngO1X2300q_yo20_MxCDu1ZA3l8w4G3B04uuB7oLvQO8W6VX_EEHii97iL
YG87GU0XU7csUC5J15bud4I3O14YKRiy6OJdGzGUGZGe5diyYT-__y4eGu3UOeUdZWOMemgXMEpn55xjLHhdT3O3sEB9eiA2IlbKeq69H7Fw020QoBeV1okB
EvvwCZW0PeD7dY8_Rk6iDMtXkYfFl08G3KGkQhqqkE59wdQhGTtJPGlEMcCJJzm0G3NWQ8JWeiIl2zHswdGlQmOB25QhKt1-C4e9nWi0qU0eOVbjEQEabqJ5
84cOSWYa3xOPeAkYanx202k7O6_Wwfzlf8G95S-xwduEjEyDgjIBIx7C0AB1ejO9uzALKlJ5o9SLaFM0ns3vQOhKHKRJ5kqKWEuudRgN9iHswkSHG2q2eOVc
gV-MSrwE0O3DyTFm-rnuRWnz3I3voqKNNK9FOOxXdolJ8b-UGpq0cz-mw45_ogrBiWUGlaVnopPtR-tl1m0kdwJ7vI25rXeF07BsiDaCVGQGgtUgwVg5k5dT
RbFsr4ZFzlsod2FSa3qwlFufz0b0pjuvdYbFeQDSRAxBtdGacT-7WGmWPuyFHwB4EuEKQzdhqhdibvj1glPUIzwwNnu0nEpf4dwUZVOcILkoHziNKMtFWr6K
ibUsSjylTm1SE3bpyjnsw7MIJDaJUQBvlMXc035NUATVrW1YxnqDvCjHEes1PgTVrW32IraSKkXxkGSGWCkzVbdV9KWi0_dPZGg7x9smro_BonGFjm3sgHm9
wclduwkS1u2n_Eu-Ij3_MZy0
}

rectangle JDrivenIcon4 [
    Gray level 4

    <$JDrivenIcon4>
]

rectangle JDrivenIcon8 [
    Gray level 8

    <$JDrivenIcon8>
]

rectangle JDrivenIcon16 [
    Gray level 16

    <$JDrivenIcon16>
]

rectangle JDrivenIcon4z [
    Gray level 4
    compressed

    <$JDrivenIcon4z>
]

rectangle JDrivenIcon8z [
    Gray level 8
    compressed

    <$JDrivenIcon8z>
]

rectangle JDrivenIcon16z [
    Gray level 16
    compressed

    <$JDrivenIcon16z>
]
@enduml

The PNG image of the previous PlantUML definition looks like this:

Written with PlantUML 1.2017.16.

October 18, 2017

PlantUML Pleasantness: Layout Elements With Hidden Lines

In a previous post we learned how to use a together block to keep elements together. We can also layout elements in a different way: using hidden lines. We define our elements and by using the keyword [hidden] in our line definition the elements are layout as if there was a line, but we don't see it. This gives us great flexibility on how we layout our elements.

In the following sample we first have a PlantUML definition where we rely on the default layout:

@startuml

package "Core Components" {
    [Backend Client] as BackendClient
    [File Reader] as FileReader
    [Content Transform] as ContentTransform
    [Logging]
}

BackendClient ~~> ContentTransform : uses
FileReader ~~> ContentTransform: uses

@enduml

This definition renders the following diagram:

We want the Logging component at the bottom right corner of the Core Components. Using a visible line we would connect the BackendClient to the Logging component. This would place the Logging component beneath the BackendClient, just like we want. So we add a connecting line and we add the [hidden] attribute on our line definition. The Logging component is placed where we want and we don't see the line supporting this:

@startuml

package "Core Components" {
    [Backend Client] as BackendClient
    [File Reader] as FileReader
    [Content Transform] as ContentTransform
    [Logging]
}

BackendClient ~~> ContentTransform : uses
FileReader ~~> ContentTransform: uses

' Layout Logging under BackendClient
BackendClient -[hidden]- Logging

@enduml

When we regenerate the diagram we get the result we want:

Written with PlantUML 1.2017.16.

October 17, 2017

PlantUML Pleasantness: Use Gradients In Diagrams

We have a lot of ways to customize our PlantUML diagrams. We can change the colors and we can even set gradients as color. A gradient has two colors and a direction. The direction of the gradient is set by the separator between the two colors. We can use the following separators to set the gradient direction:

  • /: direction top left to bottom right
  • \: direction bottom left to top right
  • |: direction left to right
  • -: direction top to bottom

In the following example PlantUML diagram definition we apply different gradient directions and different colors:

@startuml

title Gradient

skinparam defaultTextAlignment center
skinparam RectangleFontSize 20

skinparam TitleFontStyle bold
skinparam TitleFontColor #e723e7

' Define two colors for a gradient
' and use - for left to right.
skinparam BackgroundColor  #e2e2e2-#afafaf

' Define two colors for a gradient
' and use / for top left to bottom right.
skinparam RectangleBackgroundColor #ffd200/#8cfcff

rectangle A [
    From top left
    to bottom right
    <&fullscreen-enter>
]

' Use \ for bottom left to top right
rectangle B #ffd200\8cfcff [
    From bottom left
    to top right
    <&resize-both>
]

' Use | for left to right
rectangle C #ffd200|8cfcff [
    From left
    to right
    <&resize-width>
]

' Use | for top to bottom
rectangle D #ffd200-8cfcff [
    From top
    to bottom
    <&resize-height>
]

@enduml

When we convert this PlantUML syntax to a PNG image we get the following result:

Written with PlantUML 1.2017.16.

October 13, 2017

PlantUML Pleasantness: Align Multi-line Label Text

PlantUML has some features that come from the underlying software to create diagrams. Graphviz is used by PlantUML and we can use Graphviz features in our PlantUML diagrams. For example we can align multi-line text of labels to be either center (default), left or right aligned using a Graphviz feature. When we want to text to be center aligned we simply use the new-line character \n. If we want to have our text left aligned we use \l instead of \n. And to right align the text we use \r.

In the following example we have three labels that are center, left and right aligned:

@startuml

actor "Application User" as User

[Mail server] as Mail <<Mail>> #ffcc66

package "Sample Application" {
    [Controller] <<Spring REST controllers>>
    [Service] <<Spring service>>
}

' Label text is centered
User --> Controller : Types in\ndata to\nsend a message.

' Label text is left aligned
Controller --> Service : User data to\lcreate a\lnew message.

' Label text is right aligned
Service --> Mail : Mail message\robject containing\rall user information.

@enduml

When we run PlantUML with this diagram syntax we get the following diagram:

Written with PlantUML 1.2017.16.

December 16, 2016

PlantUML Pleasantness: Get PlantUML Definition From PNG

When we generate a PNG version of our PlantUML definition the original definition is stored in the PNG image. We can extract the definition using the command line option -metadata. We need to provide the PNG file and in the output we see the original PlantUML definition.

The following PNG image (activity.png) is created with PlantUML:

Next we run PlantUML from the command line using the option -metadata:

$ java -jar plantuml.jar -metadata activity.png
------------------------
activity.png

@startuml

' Make a dashed line, alternative syntax for ..>
(*) -[dashed]-> "Write outline"

' Make line bold and use color code
"Write outline" -[bold,#008000]-> "Find example"

' Only change the color
"Find example" -[#ff00ff]-> "Write blog"

' Order of line style and color can be reversed
"Write blog" -[#6666ff,dashed]-> "Publish"

' Use dotted line style
"Publish" -[dotted]-> (*)

@enduml

PlantUML version 8051(Thu Dec 01 18:52:05 CET 2016)
(GPL source distribution)
Java Runtime: Java(TM) SE Runtime Environment
JVM: Java HotSpot(TM) 64-Bit Server VM
Java Version: 1.8.0_112-b16
Operating System: Mac OS X
OS Version: 10.12.1
Default Encoding: UTF-8
Language: en
Country: US

------------------------
$

At the top we see the section @startuml..@enduml with the PlantUML syntax that was used to generate the PNG image.

Written with PlantUML 8051.

December 14, 2016

PlantUML Pleasantness: Change Line Style And Color

We can change the line style and color when we "draw" the line in our PlantUML definition. We must set the line style and color between square brackets ([]). We can choose the following line styles: bold, plain, dotted and dashed. The color is either a color name or a hexadecimal RGB code prefixed with a hash (#).

In the following example activity diagram we apply different styles and colors to the lines:

@startuml

' Make a dashed line, alternative syntax for ..>
(*) -[dashed]-> "Write outline"

' Make line bold and use color name
"Write outline" -[bold,#green]-> "Find example"

' Only change the color with hexadecimal RGB code
"Find example" -[#ff00ff]-> "Write blog"

' Order of line style and color can be reversed
"Write blog" -[#6666ff,dashed]-> "Publish"

' Use dotted line style
"Publish" -[dotted]-> (*)

@enduml

When we generate the activity diagram we see the different line styles and colors:

Written with PlantUML 8051.

December 12, 2016

PlantUML Pleasantness: Using Current Date

In PlantUML we can use the special variable %date% to get the current date and time. The default format shows day of the week, date, time and timezone. We can change the date format by specifying our format with the Java SimpleDateFromat symbols. For example to only get the hours and minutes we would write %date[HH:mm]%.

In the following example we use the %date% variable as is and with a custom format:

@startuml
' Use %date% to get date diagram is generated.
title Sample with date - %date%

' We can use Java SimpleDateFormat options
' to format the date. In this example we
' only want the day-month-year of the date.
footer Generated on %date[dd-MM-yyyy]%
@enduml

When we generate a graphical representation we get the following result:

Written with PlantUML 8051.

December 9, 2016

PlantUML Pleasantness: Check If PlantUML Is Up To Date

With the command line option -checkversion we can see if we have the latest PlantUML version. The command prints to the console our current PlantUML version and latest version that is available. Inside a PlantUML definition we can use the command checkversion and generate for example a PNG image with information about our PlantUML version and the latest version that can be downloaded.

First we use the command line option -checkversion for an out-of-date version:

$ plantuml -checkversion
PlantUML version 8048 (Thu Sep 29 19:04:02 CEST 2016)

Last available version for download : 8051

A newer version is available for download.
$

We update our PlantUML and run the command again:

$ plantuml -checkversion
PlantUML version 8051 (Thu Dec 01 18:52:05 CET 2016)

Last available version for download : 8051

Your version is up to date.
$

Now we use a PlantUML definition so we can generate a graphical representation of the information.

@startuml
checkversion
@enduml

First we use the older version of PlantUML to generate a PNG image:

Next we use the latest version that is available:

Written with PlantUML 8051.

PlantUML Pleasantness: Generate Graphical Version Information

If we want to know which version of PlantUML we are using we can use the command line option -version. PlantUML will print the version and also some extra information like the machine name, memory and more. But we can also create a PlantUML definition with the command version and we can transform it to a graphical presentation like a PNG image. This can be handy if we use PlantUML in an environment like Asciidoctor with diagram support and we want to know which version of PlantUML is used.

In our first example we run PlantUML from the command line and use the -version option:

$ plantuml -version
PlantUML version 8051 (Thu Dec 01 18:52:05 CET 2016)
(GPL source distribution)
Java Runtime: Java(TM) SE Runtime Environment
JVM: Java HotSpot(TM) 64-Bit Server VM
Java Version: 1.8.0_112-b16
Operating System: Mac OS X
OS Version: 10.12.1
Default Encoding: UTF-8
Language: en
Country: US
Machine: mrhaki-laptop-2015.fritz.box
PLANTUML_LIMIT_SIZE: 4096
Processors: 8
Max Memory: 3,817,865,216
Total Memory: 257,425,408
Free Memory: 249,050,832
Used Memory: 8,374,576
Thread Active Count: 2

The environment variable GRAPHVIZ_DOT has been set to /usr/local/bin/dot
Dot executable is /usr/local/bin/dot
Dot version: dot - graphviz version 2.38.0 (20140413.2041)
Installation seems OK. File generation OK
$

In the second example we create a file with the following PlantUML definition:

@startuml
version
@enduml

When we generate a PNG from this definition we get the following result:

Written with PlantUML 8051.

December 6, 2016

PlantUML Pleasantness: Create A Sudoku :)

PlantUML has a fun command to create a Sudoku puzzle. We must use sudoku in our PlantUML definition and a random puzzle is generated. We can even give a seed value for a given Sudoku so it is generated again.

In the following example PlantUML definition we use the sudoku command:

@startuml
sudoku
@enduml

We create a PNG file with PlantUML and we get the following result:

To regenerate the same Sudoku we must use the seed value cinnld556e0o:

@startuml
sudoku cinnld556e0o
@enduml

Written with PlantUML 8048.

PlantUML Pleasantness: Include Partial Content From Files

With PlantUML we can include external files in our definition with the !include directive. We specify the file name and the content is included in our PlantUML definition. The included file can also have multiple @startuml ... @enduml sections and we can refer to individual sections with the !include directive. We must append to the include file name an exclamation mark (!) followed by either a number or identifier. If we use a number we specify which section we want to include, where section are numbered starting from 0. So to get the second section from a file commons.puml we would write !include commons.puml!1. Alternatively we can use identifiers in the include file. We append to @startuml an identifier as (id=idValue). Then from the definition that is including the file we refer to the identifier after an exclamation mark (!). If our included file commons.puml has a section with id user then we would include it as !include commons.puml!user.

In the following example PlantUML definition we define the file to be included. We have two sections with @startuml ... @enduml which both have an identifier:

' File: commons.puml

' section with id user to define user actor
@startuml(id=user)
actor "Application User" as User
@enduml

' section with id mail to define mail component
@startuml(id=mail)
[Mail server] as Mail <<Mail>> #ffcc66
@enduml

Next we write a definition where we include commons.puml using a section number and section identifier:

' File: sample.puml
@startuml

' Include first section (0-based index) of commons.puml
!include commons.puml!0

' Include section with id mail of commons.puml
!include commons.puml!mail


[Sample Application] <<Software System>> as SampleApp

User --> SampleApp
SampleApp --> Mail

@enduml

Let's generate a diagram and look at the result where we see our user and mail components from the included file:

Written with PlantUML 8086.

PlantUML Pleasantness: Customize Stereotype Styling

To change the styling of our generated diagrams with PlantUML we can use the skinparam command. We can set for example font size, style, color, background colors and much more. We can change the style for a specific element or for the whole diagram. We can even set specific styling options for stereotypes. The settings for the stereotype are then applied to all elements in our diagram with that stereotype. We must append <<stereotype name>> to the skin parameter name.

In the following example PlantUML description we apply custom background colors to each stereotype:

@startuml

/' Set custom background colors for the default
   component elements and the specific stereotypes. '/
skinparam component {
    BackgroundColor #ff6666
    BackgroundColor<<Database>> #ccff66
    BackgroundColor<<Spring service>> #66ccff
    BackgroundColor<<Spring REST controllers>> #66ffcc
    BackgroundColor<<Spring repository>> #66ffff
    BackgroundColor<<Mail server>> #ffcc66
}

actor User
[Third party application] as ThirdPartyApp

together {
    [PostgreSQL database] as PostgresDB <<Database>>
    [Mail server] as Mail <<Mail server>>
}

package "Spring Boot Application" {
    [APIController] <<Spring REST controllers>>
    [AdminController] <<Spring REST controllers>>

    [AdminService] <<Spring service>>
    [DataStoreService] <<Spring service>>

    [Repository] <<Spring repository>>
}

User --> AdminController
ThirdPartyApp --> APIController

APIController --> DataStoreService
AdminController --> DataStoreService
AdminController --> AdminService

DataStoreService --> Repository
AdminService --> Mail

Repository --> PostgresDB

@enduml

When we generate the diagram we see that each stereotype has it's own background color:

Written with PlantUML 8086.

December 5, 2016

PlantUML Pleasantness: Keeping Elements Together

When we write a PlantUML definition the generated graphical diagram is laid out by PlantUML. In a previous post we learned how to move elements using the length of the connection. But we can also use a together block with all elements that should be at the same level. PlantUML will try to keep the elements together when the diagram is drawn.

In the following sample PlantUML definition we want the PostgresDB and Mail elements to be at the same level, so we group them using a together block:

@startuml

actor User
[Third party application] as ThirdPartyApp

/' Try to keep PostgresDB and Mail together,
   so they are at the same level in the diagram. '/
together {
    [PostgreSQL database] as PostgresDB <<Database>>
    [Mail server] as Mail <<Mail server>>
}

package "Spring Boot Application" {
    [Controllers] <<Spring REST controllers>>
    [DataStoreService] <<Spring service>>
    [Repository] <<Spring repository>>
}

User --> Controllers
ThirdPartyApp --> Controllers

Controllers --> DataStoreService

DataStoreService --> Repository
DataStoreService --> Mail

Repository --> PostgresDB

@enduml

Let's create the diagram and we see the elements are aligned nicely:

Written with PlantUML 8086.

PlantUML Pleasantness: No Shadows In Diagrams

By default elements in a PlantUML generated diagram have shadows. To disable shadows we must set the skin parameter shadowing to the value false. PlantUML will then not create shadows on elements.

In the following sample PlantUML definition we use the value false for the skin parameter shadowing:

@startuml

' Remove shadows
skinparam shadowing false

actor User
[Third party application] as ThirdPartyApp

package "Spring Boot Application" {
    rectangle Controllers <<Spring REST controllers>>
    rectangle DataStoreService <<Spring service>>
    rectangle Repository <<Spring repository>>
}

User --> Controllers
ThirdPartyApp --> Controllers

Controllers --> DataStoreService
DataStoreService --> Repository

@enduml

The generated diagram has no shadows:

Written with PlantUML 8086.

PlantUML Pleasantness: Diagrams In Black And White

The default colors of PlantUML use red and yellow to draw the diagram elements. If we want our diagram to be in black, grey and white we can simply set skin parameter monochrome to true. The generated graphical diagram will now have black, grey and white colors.

In the following sample PlantUML definition we set the diagram skin parameter monochrone to true:

@startuml

' Generated diagram will be in black/grey/white.
skinparam monochrome true

actor User
[Third party application] as ThirdPartyApp

package "Spring Boot Application" {
    rectangle Controllers <<Spring REST controllers>>
    rectangle DataStoreService <<Spring service>>
    rectangle Repository <<Spring repository>>
}

User --> Controllers
ThirdPartyApp --> Controllers

Controllers --> DataStoreService
DataStoreService --> Repository

@enduml

The generated diagram looks like this:

Written with PlantUML 8048.

PlantUML Pleasantness: Align Elements With Line Length

Drawing diagrams with PlantUML is fun and easy. We use text to describe the diagram and the we get a graphical representation. Especially in combination with Asciidoctor with PlantUML integration we have a winning combination to write technical documentation. Because our text is transformed into a graphical format like PNG we don't have much influence on the layout. There are options to indicate positions of elements, but we can also use the length of lines to influence the position of elements.

In the following sample we have a PlantUML diagram description with standard lines. We use two hyphens (--) to define a line:

@startuml
actor User
[Third party application] as ThirdPartyApp

[PostgreSQL database] <<Database>> as PostgresDB
[Mail server] <<Mail server>> as Mail

package "Spring Boot Application" {
    [Controllers] <<Spring REST controllers>>
    [DataStoreService] <<Spring service>>
    [Repository] <<Spring repository>>
}

User --> Controllers
ThirdPartyApp --> Controllers

Controllers --> DataStoreService
DataStoreService --> Repository

DataStoreService --> Mail

Repository --> PostgresDB
@enduml

We create a diagram and we get the following graphical diagram:

The diagram looks fine, but we want to have our mail server at the same level as the PostgreSQL database element. We simply add an extra hyphen (-) to the connection line between DataStoreService and Mail:

@startuml
actor User
[Third party application] as ThirdPartyApp

[PostgreSQL database] <<Database>> as PostgresDB
[Mail server] <<Mail server>> as Mail

package "Spring Boot Application" {
    [Controllers] <<Spring REST controllers>>
    [DataStoreService] <<Spring service>>
    [Repository] <<Spring repository>>
}

User --> Controllers
ThirdPartyApp --> Controllers

Controllers --> DataStoreService
DataStoreService --> Repository

/'Add extra hyphen (-) to put Mail
  add the same level as PostgresDB '/
DataStoreService ---> Mail

Repository --> PostgresDB
@enduml

We regenerate our diagram and we get the following result:

Written with PlantUML 8048.