There is a free Java tool called PlantUML that offers to create UML diagrams through programming in a domain-specific-language, instead of graphically drawing boxes and lines.
I used PlantUML for some months, and had ups and downs with it. The ups took place when drawing sequence diagrams. Downs I had with all other kinds of diagrams when trying to give them good layout.
Simple Example
This is a small class-diagram example, suitable to quickly show how things are done using PlantUML.
@startuml legend An airport can have several terminals. A terminal can have several gates. endlegend Airport *-{ Terminal Terminal *-{ Gate @enduml
Store this text into a file named airport.puml
.
Then download
plantuml.jar
, place it into the folder where the file is,
and launch following commandline:
java -jar plantuml.jar airport.puml
An image file named airport.png
will be generated,
and you can view it through any image viewer.
A more convenient way to work with plantuml.jar
is following command:
java -jar plantuml.jar -gui
This starts a graphical user interface that will list all .puml
files in directory.
Moreover it will immediately generate an image for every newly created file.
Double-clicking onto an list item will open a built-in image viewer that displays the diagram in a new window.
This is how the class-diagram above looks like:
Try it out by yourself at the online-server.
Vertical Variant
If you want the boxes to be vertically arranged, you must increase the edge lengths (!) by adding a "-":
@startuml Airport *--{ Terminal Terminal *--{ Gate @enduml
Result:
Styling
Of course you can customize colors and lines using PlantUML skinparams. Names of skinparams can be listed using following command:
java -jar plantuml.jar -language
Comments
Commenting out lines can be done via quotes:
@startuml ' single line comment /' multiline comment '/ @enduml
More Complex Example
Following is a component-diagram that describes how to use an airport for departure.
@startuml legend Check-in starts about 3 hours before take-off. Mind that automated check-in will not accept your non-cabin baggage, and you may want to get rid of that because it contains your camping knife! Airports differ in where and when they check passports, boarding card and cabin baggage. Boarding (at the gate) starts about 60 - 30 minutes before and normally includes an accurate cabin baggage check (knives will be confiscated). Boarding closes 20 minutes before flight. State officials that check passports will **not** help you find your gate! **Unchecked (cabin) baggage**: what you take into the aircraft and put into the rack, 7 kg, must not contain a knife or liquids, can contain a laptop. **Checked (hold) baggage**: what you give to the airline on check-in, 23 kg, may contain a knife, don't put laptop into it. Baggage must not exceed 55 x 38 x 20 cm. Damaged baggage must be reported (written) within 7 days, delayed baggage within 21 days. endlegend skinparam rectangle { roundCorner 30 borderColor gray } package "Airport A" { package "Terminal 1" { rectangle "Public Access / Departure" as publiczone { "**Check-in**:\nShow passport and ticket,\nassign seat,\nleave hold baggage,\nget boarding card" as check_in check_in -> [Airline C] [Airline B] [Airline A] } rectangle "Transit Zone (passengers only)" as transitzone { stack "Duty-free shopping" package "Gate A1" as gate { "Cabin baggage check,\nshow boarding card\nand passport" as board } } publiczone ==|> transitzone: Say Goodbye, you're leaving the country.\nShow boarding card and passport. queue "Aircraft for Flight ABC-123" as flight board ==|> flight: Show boarding card, passport. } } @enduml
Here is how the departure diagram looks like:
You see that I used some tricks like inline text formatting (bold font, newlines) and skin-parameters (to style the inner boxes).
Now this is quite acceptable I think, although the red edges are much too long, and they touch the text. And - why is the legend on bottom when I wrote it on top?
Anyway, let's create another diagram for arrival:
@startuml legend In case an immigration form is required, make sure you filled one before standing in long lines at arrival passport checks, because you may be sent back to fill one and then again stand in line! endlegend skinparam rectangle { roundCorner 30 borderColor gray } package "Airport B" { package "Terminal 2" { queue "Aircraft for Flight ABC-123" as flight rectangle "Transit Zone" as transitzone { "With cabin baggage" as unboard } flight -> unboard rectangle "Arrival" as arrival { "Get hold baggage" as passenger passenger <- [Hold luggage conveyor for Flight ABC-123] } transitzone ==|> arrival: Show boarding card, passport,\nmaybe immigration form.\nYou are entering the country. rectangle "Public Access / Arrival" as publiczone { "City Train" "Taxi" } arrival ==|> publiczone: Customs, then say Hello! } } @enduml
Here is how the arrival looks like:
This is not acceptable. Look at the edges. Why do they bend so ugly? Why don't they go straight down?
Here the PlantUML weakness shows up. It is the automatic layout done by GraphViz, which is a native library, not Java. The way how PlantUML and GraphViz work together is not the best one.
Now you may say "It is the edges that are too long!". So let's make them shorter by taking away a "=":
@startuml .... transitzone =|> arrival: Show boarding card, passport,\nmaybe immigration form.\nYou are entering the country. .... arrival =|> publiczone: Customs, then say Hello! .... @enduml
I don't want to show the result. The diagram now expands horizontally, the edges are cluttered, obscuring the text. You can try it out by yourself. It is not acceptable.
The only way I could improve this is by adding following instruction:
@startuml skinparam linetype ortho .... @enduml
Then it looked like this:
Still the red edges are much too long and unnecessarily crooked. The first one looks like it is not related at all to its text, the second one obscures it.
Layout with PlantUML is really time-consuming. You have to find out the techniques that PlantUML built in to manipulate GraphViz. Moreover I uncovered platform differences, the diagram looked differently when rendered on WINDOWS, LINUX or at the online-server, or when rendered with different versions of GraphViz and PlantUML.
Conclusion
Use PlantUML for sequence diagrams, here it shines. This is because PlantUML doesn't use GraphViz for it. Don't use PlantUML for anything complex unless you want your readers shake their heads and skip your diagram.
Keine Kommentare:
Kommentar veröffentlichen