I want to document layered software architecture with plantUML that at the end will look like this:
What will be the best approach to create this type of diagram with plantUML?
This is the initial what I came up with, which represents 3 layered architecture with some generic components. (please check the link)
@startuml
LAYER_3 -[hidden]down- LAYER_2
LAYER_2 -[hidden]down- LAYER_1
package LAYER_3 {
component Comp30 {
}
component Comp31 {
}
component Comp32 {
}
component Comp33 {
}
}
package LAYER_2 {
component Comp20 {
}
component Comp21 {
}
component Comp22 {
}
component Comp23 {
}
component Comp24 {
}
component Comp25 {
}
component Comp26 {
}
component Comp27 {
}
}
package LAYER_1 {
component Comp10 {
}
component Comp11 {
}
component Comp12 {
}
component Comp13 {
}
component Comp14 {
}
component Comp15 {
}
component Comp16 {
}
component Comp17 {
}
}
Comp23 -[#6666ff,dotted]> Comp10
Comp21 -[dotted,#red]> Comp10
Comp20 -> Comp10
Comp20 -> Comp16
@enduml
It's not ideal, but with some encouragement from carefully placed hidden
arrows and judicious use of norank
on the visible arrows, this is possible:
The changes I made were:
hidden
right arrows between each component in a layer, e.g. from Comp30
to Comp31
, and Comp31
to Comp32
, etc. This is necessary to encourage the components to remain in order within the layer.hidden
down arrows from the first component in each layer to the first component in the below layer. This encourages each layer to be left-aligned the same amount. Additionally, made this arrows long (e.g. --->
) to create more space between the layers, so that there is more space for the visible arrows to be clearly distinguished.
norank
to all the visible arrows, to prevent them from breaking the layout that was encouraged by the hidden arrows.
Comp20
to Comp10
arrow), the hidden arrow is omitted and the visible arrow is not marked as norank
. Again, this is to avoid a curving arrow caused by having two arrows on the same connection. Essentially the visible arrow is serving the purpose of encouraging the right layout.Here are these modifications applied to your PlantUML example, or view it live here:
@startuml
package LAYER_3 {
component Comp30 {
}
component Comp31 {
}
component Comp32 {
}
component Comp33 {
}
}
package LAYER_2 {
component Comp20 {
}
component Comp21 {
}
component Comp22 {
}
component Comp23 {
}
component Comp24 {
}
component Comp25 {
}
component Comp26 {
}
component Comp27 {
}
}
package LAYER_1 {
component Comp10 {
}
component Comp11 {
}
component Comp12 {
}
component Comp13 {
}
component Comp14 {
}
component Comp15 {
}
component Comp16 {
}
component Comp17 {
}
}
' Hidden connections
' ------------------
' Use hidden right connections to encourage the components
' within each layer to be placed in the desired order.
Comp30 -[hidden]r- Comp31
Comp31 -[hidden]r- Comp32
Comp32 -[hidden]r- Comp33
Comp20 -[hidden]r- Comp21
Comp21 -[hidden]r- Comp22
Comp22 -[hidden]r- Comp23
Comp23 -[hidden]r- Comp24
Comp24 -[hidden]r- Comp25
Comp25 -[hidden]r- Comp26
Comp26 -[hidden]r- Comp27
Comp10 -[hidden]r- Comp11
Comp11 -[hidden]r- Comp12
Comp12 -[hidden]r- Comp13
Comp13 -[hidden]r- Comp14
Comp14 -[hidden]r- Comp15
Comp15 -[hidden]r- Comp16
Comp16 -[hidden]r- Comp17
' Use hidden down connections between the first component in each
' layer to encourage all the layers to be left-aligned.
' NOTE: Use longer arrows to force more space between the layers, so
' that the visible arrows can be more clearly distinguished.
' NOTE: Since we later create a *visible* connection from Comp20 to
' Comp10, we omit create a hidden connection here, otherwise the
' visible connection ends up curving to avoid the hidden one.
Comp30 -[hidden]d-- Comp20
'Comp20 -[hidden]d-- Comp10
' Visible connections
' -------------------
' NOTE: Use norank to prevent these visible connections from taking
' prescedence over the hidden connections and breaking the layout,
' *except* for the visible connections which are equivalent to the
' hidden connections that we have omitted.
Comp23 -[norank,#6666ff,dotted]-> Comp10
Comp21 -[norank,dotted,#red]-> Comp10
Comp20 -d--> Comp10
Comp20 -[norank]-> Comp16
@enduml
For reference, I found this guide helpful in encouraging the right layout. In particular, it introduced me to the norank
property. However, I fear this answer goes against the advice from that same page that these "layout tweak mechanisms [should] be used sparingly". The page also says:
Wrangling diagram elements to an exact position or layout is not what PlantUML is for.
I suspect that the approach I have taken will become increasingly brittle as the diagram grows in size and complexity, to the point of become untenable, but in the absence of a better solution it might be sufficient for simpler use cases.