47

I am using PlantUML to make simple class diagrams and the tool is awesome, but I couldn't find any way to align classes with each other except putting them into packages or using relationships like Alice -left-* Bob. What I need is something like:

@startuml  
class Bob  
class Alice  
class Dan  
**Dan aligned Alice: horizontally**  
'or using a grid?  
**Bob at grid (2, 3)**  
@enduml

Is there a way?

Zong
  • 6,160
  • 5
  • 32
  • 46
Yuriy Kulikov
  • 2,059
  • 1
  • 16
  • 29

6 Answers6

23

UPDATES Aug.08.2019

From Rotsiser's comment, by combining changing the length of lines with together keyword, it can align elements

@startuml
class A
A ..> B
C ---> B
D ...> B
together {
    class E
    class F
    class G
}
E ----> B
@enduml

enter image description here


OUTDATED

You are able to align elements by changing the number of line's character, such as '-', '.', and so on.

@startuml
class A
A ..> B
C ---> B
D ...> B
E ----> B
F ----> B
G ----> B
@enduml

enter image description here

Yu Huang
  • 3,085
  • 2
  • 24
  • 22
  • 3
    This will not align items, it will increase the length of the connector. Still helpful, but not exactly what I was looking for. – Yuriy Kulikov Apr 22 '19 at 10:10
  • 2
    I had good results combining this with the other answer suggesting to use the `together` keyword. – Rotsiser Mho Aug 08 '19 at 19:50
  • Rotsiser's answer is correct, classes can be aligned with together keyword – Yu Huang Aug 08 '19 at 20:36
  • Changing the line lenght also works when you need to add several arrows between the same two componnents in the same direction and need that each connection produce an arrow. Plantuml will create only one arrow by default. In my case I needed several arrows each with a different label – CaribeGirl Jun 08 '20 at 14:15
  • This approach won't work as soon as the classes are populated with different number of items – albert Dec 09 '20 at 10:05
22

Using a -[hidden] relation can do the job :

@startuml  
class Bob  
class Alice  
class Dan  
class Foo
class Bar
class Foobar

Bob -[hidden] Alice
Bar -[hidden] Foobar
@enduml

http://www.plantuml.com/plantuml/png/Iyv9B2vMSCfFKb3WIWQp7NCoarFXF9V4F3ZRBJyVod9AB4A89G4vN20JTACpCbDIKlDY8MPm0LKXYK5K0W00

freezed
  • 1,269
  • 1
  • 17
  • 34
14

Here is a solution.

The documentation: "It is also possible to change arrow direction by adding left, right, up or down keywords inside the arrow:"

@startuml
foo -left-> dummyLeft 
foo -right-> dummyRight 
foo -up-> dummyUp 
foo -down-> dummyDown
@enduml

enter image description here

To your question:

@startuml
class Bob
class Alice
class Dan
Alice -left[hidden]-> Bob
Alice -right[hidden]-> Dan 
@enduml

enter image description here

It may also be useful:

@startuml
class Bob
class Alice
class Dan
Bob -right-|> Alice
Alice -right-> Dan
interface Friend
Dan -up..> Friend
interface Person
Friend -left-> Person
interface Object
Person -down-> Object
interface Native
Object -right-> Native
@enduml

enter image description here

Dmytro Sokolyuk
  • 966
  • 13
  • 13
13

No, there's no way to do that, sorry :( The idea behind PlantUML is that you should not care too much about the layout rendering.

Actually, early versions of PlantUML use to align classes, but it was an issue: When there were many unrelated classes, diagrams tended to be very large and very thin. So a patch was added to organize classes in a square.

How many classes do you want to have in your diagram? Sure it would be possible to disable the organizing patch for e.g. 3 to 5 classes. You could post a suggestion to the forum to see what other users think about it.

zb226
  • 9,586
  • 6
  • 49
  • 79
PlantUML
  • 921
  • 7
  • 6
  • 2
    I thought about an alternative, that shouldn't be very hard to implement: add "group", which allows to group several objects in a same way "package" or "namespace" does (but there is no frame). This can have additional options like "horizontal" or "vertical", but it is not that important. Important is, that we should be able to group classes after the whole diagram is finished by simply adding 'group { Bob Alice Animals.Cat }' which will force classes to stay close to each other. – Yuriy Kulikov Jul 24 '12 at 09:39
7

You don't need a hidden package, use the together keyword:

together {
class A
class B
}
Jayesh Babu
  • 1,389
  • 2
  • 20
  • 34
user11863067
  • 71
  • 1
  • 1
  • I had good results combining this with the other answer suggesting to change the number of lines in the arrow link. – Rotsiser Mho Aug 08 '19 at 19:50
6

A cleaner approach is to put them in a hidden package, which is more logical.

@startuml

skinparam shadowing false
skinparam package<<Layout>> {
  borderColor Transparent
  backgroundColor Transparent
  fontColor Transparent
  stereotypeFontColor Transparent
}

package x <<Layout>>{ 
    class A
    class B
} 
A .. D
B .. C
C .. D

A1 .. D1
B1 .. C1
C1 .. D1

@end

enter image description here

Ajeet Ganga
  • 8,353
  • 10
  • 56
  • 79
  • This is not a response to @Yuriy Kulikov question : **align more than two classes horizontaly**. Nice theming anyway. – freezed Jul 11 '19 at 08:30
  • : I thought this is what he wanted. Yuriy Kulikov . Settle this for us. :) @freezed : Can you draw a diagram/sketch of expected output according to you? – Ajeet Ganga Jul 17 '19 at 08:03
  • This approach won't work as soon as the classes are populated with different number of items. – albert Dec 09 '20 at 10:00