plantuml

Documenting Layered Architecture with PlantUML


I want to document layered software architecture with plantUML that at the end will look like this:

enter image description here

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) enter image description here

@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

Solution

  • 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:

    PlantUML diagram with aligned layers

    The changes I made were:

    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.