Proposed way to define fixed layout in class diagrams

0 votes
asked Feb 14, 2019 in Wanted features by Riccardo (120 points)


First of all, thanks for this great tool.

I'm planning to substitute Astah use with PlantUML. For sequence diagrams, PlantUML is great, easy, fast to write, perfect. For Class diagrams the resulting layout is confused to present to not I.T. people.

I see that, for this diagram, PlantUML uses Graphviz that has it owns way to organize things. I tried to use [hidden] relations to setup a fixed layout, but It was without success.

Basically, I can use relations on objects (or better in  'together' groups) to make my specific layout, but then when I define relation between objects the previous good layout changes to a confused one.

This is an example (using groups and hidden relations to define the layout), with the problematic relations commented:


hide circle
skinparam linetype ortho

together cln {
  class Client
together mls {
  interface MemberListener
together mrl {
  interface MemberRole
together msg {
  class Message

' my defined layout
mls -u[hidden]- mrl
cln -r[hidden]- mrl
mrl -d[hidden]- msg

' object real relations
Client -> MemberRole
''''''Client -|> MemberListener
''''''Client -|> MemberListener


However, according with there is a way to Graphviz to ignore the relations (edge [constraint=false]; ) when it make the diagram layout. The behavior can be shown in the difference between


So, my suggestion is to make a new 'tag', like the -left- one or the -[hidden] one to enable this behavior on specific relations, so that the others relations can be the only used by Graphviz to define the layout.

Do you think that it can be possible?

Thanks again,


1 Answer

0 votes
answered Feb 14, 2019 by plantuml (294,660 points)

It's not that simple.

If I understand correctly, the "edge [constraint=false];" stuff applies globally on a whole subgraph.
The equivalent in PlantUML of a subgraph is a package/folder.
So we could add an option per package/folder so that this package/folder turns globally to "edge [constraint=false];"
I am note sure that it's exactly what you want.

Note that there is a "norank" option available today that may help you:

class B extends A
class C extends A
B -[norank]- C

I am wondering if it's not what you are looking for.

commented Feb 15, 2019 by Riccardo (120 points)
commented Feb 16, 2019 by zimchaa (1,040 points)
Hi - it's possible to get a bit closer with something like this that makes it easier to maintain:

''hide circle
skinparam linetype ortho
skinparam shadowing false
'skinparam MinClassWidth 70
skinparam nodesep 80
skinparam ranksep 80

interface MemberListener
interface MemberRole
interface HallService
interface Member

'' relations ''

Client                  -->              HallService
MemberListener          <|-            Client
Client          "1"     ->      "0..*"  MemberRole

HallService             <|-            Hall
MemberListener  "0..*"  -       "1"     Hall
Hall                    ---       "0..*"  Room
Hall            "1"     -      "0..*"  ControlledMember

MemberListener  "1"     <---             ControlledMember
MemberRole              <|---            ControlledMember
Member                  <|-            ControlledMember
Room            "1"     <-             ControlledMember
Room                    ->             Member

Member                  <|--            BotMember

commented Feb 16, 2019 by Riccardo (120 points)
edited Feb 17, 2019 by Riccardo
Hi @zimchaa, and thanks

It is good enough.  However, let me just define 2 packages to organize such classes, and you will see that the default resulting layout is unusable

little better

little better

seq diagram:

I really would be like to define the position of the objects