User Tools

Site Tools


v060:layout

Diagram Language Guide for version 0.6.0

Currently txtUML supports diagram definitions for class- and flat state machine diagrams. The language is universal, but only supports flat (one level) diagrams. For simplicity in this description, whenever a box is referenced, it stands for either a class, state or composition role name. Also if a line is present, it stands for association or transition.

General structure

A diagram definition is a Java class inheriting from the appropriate type:

  • Class diagram: ClassDiagram.
  • State machine diagram: StateMachineDiagram<C>, where C is a ModelClass which states we want to display in this diagram.

This class must contain an inner class definition, inheriting from Layout. The actual layout constraints can be written as annotations on this inner class.

class MyDiagram extends ClassDiagram {
  // layout constraints as annotations
  @North(val = A.class, from = B.class)
  class MyLayout extends Layout {}
}

Please note that diagrams are not considered as part of the referenced model, therefore diagram definitions must be placed in a separate package from the model.

Simple layout constraints for nodes

In this section A and B are boxes (classes, states, compositions) already defined in a txtUML model. Relative layout for these boxes can be given as presented:

  • @North(val = A.class, from = B.class) : The diagram can be cut horizontally such that A is in the upper half and B is in the lower half.
  • @East(val = A.class, from = B.class) : The diagram can be cut vertically such that A is in the right half and B is in the left half.
  • @South(val = A.class, from = B.class) : The diagram can be cut horizontally such that A is in the lower half and B is in the upper half.
  • @West(val = A.class, from = B.class) : The diagram can be cut vertically such that A is in the left half and B is in the right half.
  • @Above(val = A.class, from = B.class) : Box A is north from B and is right next to it.
  • @Right(val = A.class, from = B.class) : Box A is east from B and is right next to it.
  • @Below(val = A.class, from = B.class) : Box A is south from B and is right next to it.
  • @Left(val = A.class, from = B.class) : Box A is west from B and is right next to it.

Example: Model contains these classes: A, B and C.

class MyClassDiagram extends ClassDiagram {
  @North(val = A.class, from = B.class)
  @Below(val = A.class, from = C.class)
  @West(val = C.class, from = B.class)
  class MyLayout extends Layout {}
}

Example: The class A contains these states: Init, Disabled and Active.

class MyStateDiagram extends StateMachineDiagram<A> {
  @Left(val = Init.class, from = Disabled.class)
  @Left(val = Disabled.class, from = Active.class)
  class MyLayout extends Layout {}
}

Compound layout constraints for nodes

In this section A, B, C and D are boxes already defined in a txtUML model. Complex layout for these boxes can be given as presented:

  • @Column({A.class, B.class, C.class}) : The boxes A, B and C are arranged in a column, with the top being A and preserving the order. Any number of boxes can be given here.
  • @Row({A.class, B.class, C.class, D.class}) : The boxes A, B, C and D are arranged in a row, with the left most being A and preserving the order. Any number of boxes can be given here.
  • @Diamond(top = A.class, right = B.class, bottom = C.class, left = D.class) : The boxes A, B, C and D are arranged in a diamond shape where the four boxes are in the corners and an empty spot remains between them.
  • @TopMost(A.class) : Box A is north from every other box.
  • @RightMost(A.class) : Box A is east from every other box.
  • @BottomMost(A.class) : Box A is south from every other box.
  • @LeftMost(A.class) : Box A is west from every other box.

Example: Model contains these classes: C, E, D, O, R, S1 and S2.

class MyDiagram extends ClassDiagram {
  @Row({R.class, E.class, D.class})
  @Column({C.class, R.class, O.class, S1.class, S2.class})
  class MyLayout extends Layout {}
}

In this section A is a box already defined in a txtUML model and L is a line with an endpoint at box A. Relative layout for the line and box can be given as presented. For reflexive lines a third parameter must be added which is a value of LinkEnd enum.

  • @North(val = L.class, from = A.class) : Line L will connect to box A on A's northern side.
  • @North(val = L.class, from = A.class, end = LinkEnd.Start) : Reflexive line L's starting point will connect to box A on A's northern side.
  • @North(val = L.class, from = A.class, end = LinkEnd.End) : Reflexive line L's ending point will connect to box A on A's northern side.
  • Can be used similarly with @East, @South and @West.
  • @Priority(val = L.class, prior = 50) : Gives line L a priority value of 50. Higher priority means shorter route and less turns.

Example: Model contains these classes: A and B. Model contains these links: L (A - B) and R (A - A).

class MyDiagram extends ClassDiagram {
  @North(val = L.class, from = A.class)
  @East(val = L.class, from = B.class)
  @Above(val = A.class, from = B.class)
  @West(val = R.class, from = A.class, end = LinkEnd.Start)
  @South(val = R.class, from = A.class, end = LinkEnd.End)
  class MyLayout extends Layout {}
}

Groups

In this section A, B, C are boxes already defined in a txtUML model and L and J are lines with an endpoint at box A.

A group can be specified by defining a class inheriting either from NodeGroup or from LinkGroup. The elements of the group can be specified with the @Contains annotation. A group can contain model elements of the corresponding type or other groups containing elements of the corresponding type.

  @Contains({A.class, B.class})
  class NG1 extends NodeGroup {}
  @Contains({L.class, J.class})
  class LG1 extends LinkGroup {}

If the given group is a NodeGroup, the annotation @Alignment can be used to set the alignment of its elements, using items of enum hu.elte.txtuml.layout.lang.AlignmentType, i.e. TopToBottom, BottomToTop, RightToLeft or LeftToRight.

  @Contains({NG1.class, C.class})
  @Alignment(AlignmentType.TopToBottom)
  class NG2 extends NodeGroup {} 

This notation of groups is equivalent to using {…} symbols and enumerate the contents within. This is called an unnamed group, while the previously shown is a named group. Both can be used in the same way. The previously mentioned statements can be used with these groups as parameters as well.

  • @North(val = {A.class, B.class}, from = C.class) : Both boxes A and B are north from C. The layout between A and B is not defined.
  • @North(val = A.class, from = {B.class, C.class}) : Box A is north from box B and from box C as well. The layout between B and C is not defined.
  • @North(val = LG1.class, from = A.class) : Every element of group LG1 is north from box A. The layout between the elements of LG1 is not defined.
  • Can be used similarly with @East, @South and @West.
  • @TopMost({A. class, B.class}) : Boxes A and B are north from every other boxes in the model.
  • @TopMost(NG1.class) : Boxes which are elements of LG1 are north from every other boxes in the model.
  • Can be used similarly with @RightMost, @BottomMost and @LeftMost.

Example: Model contains these classes: A, B, C and D.

class MyDiagram extends ClassDiagram {
  @Contains({C.class, D.class})
  @Alignment(AlignmentType.TopToBottom)
  class MyGroup extends NodeGroup{}
  
  @Row({A.class, MyGroup.class, B.class})
  class MyLayout extends Layout {}
}

Phantom nodes

In this section A and B are boxes already defined in a txtUML model. Phantoms are defined by extending class Phantom and can be used as nodes in layout statements.

Example:

  class MyPhantom extends Phantom {}
  //...
  @Above(val = A.class, from = MyPhantom.class)
  @Above(val = MyPhantom.class, from = B.class)
  //...

Other

If we do not include a box into any statements (annotations) then the box won't appear on the diagram by itself. We can explicitly make it appear - without restricting it's position with other statements - using @Show.

@Show(A.class) : Box A is present in the diagram.

Example: Model contains these classes: A and B.

class MyDiagram extends ClassDiagram {
  @Show(A.class)
  class MyLayout extends Layout {}
}

We can reduce/increase the space between boxes in the generated diagram by using @Spacing statement (annotation), with a percentage given.

@Spacing(0.8) : The empty space between diagrams will be 80% of the default. Note: the space between boxes has a lower limit, so depending on a specific diagram using the @Spacing statement with “too low” values will not affect the generated diagram.

Example: Model contains these classes: A and B.

class MyDiagram extends ClassDiagram {
  @Spacing(0.6)
  @Row({A.class, B.class})
  class MyLayout extends Layout {}
}

Contradictions and other errors

There may be certain errors that blocks the running of the diagram layout generation process. This may occur because of:

  • Contradiction in user given statements
    • @North(val = A.class, from = B.class) and @South(val = A.class, from = B.class)
  • Lack of statements, so two boxes are arranged into the same place. The algorithm might try to solve this, but it is not guaranteed that it will succeed.
v060/layout.txt · Last modified: 2017/04/24 14:09 by ndj94