Chapter 4
State-transitions diagrams

Here is an example of state-transition diagram you can draw:


Now, we will see how to define parts of these diagrams, namely the ten sorts of state and the transitions.

4.1 To define a state

A "standard" state can be defined with the umlstate environment:

 \begin{tikzpicture}  \begin{umlstate}[x=0, y=0, name=state]{state}    \end{umlstate}  \end{tikzpicture}


Both options x and y allows to place the state in the figure, or in another state. The default value is 0. The argument to give is the label of the state. The node representing the state has a default name, based on a global counter. For practical reasons, when you define a transition for instance, you can rename it with the name option.

You can also define the width of an empty state with the width option (8ex by default).

You can define a state in another state. Then, the coordinates of the sub-states are relative to the parent state:

 \begin{tikzpicture}  \begin{umlstate}[name=state]{I am a state}  \begin{umlstate}[name=substate1]{I am a substate 1}    \end{umlstate}  \begin{umlstate}[x=3, y=-3, name=substate2]{I am a substate 2}    \end{umlstate}  \end{umlstate}  \end{tikzpicture}


If you want to define a state without detailing it, you can use the umlbasicstate command, that is an alias of the umlstate environment.

Let’s talk about the pseudo-states:

 \begin{tikzpicture}  \umlstateinitial[name=initial]  \umlstatefinal[x=1, name=final]  \umlstatejoin[x=2, name=join]  \umlstatedecision[x=3, name=decision]  \umlstateenter[y=-2, name=enter]  \umlstateexit[x=1, y=-2, name=exit]  \umlstateend[x=2, y=-2, name=end]  \umlstatehistory[x=3, y=-2, name=hist]  \umlstatedeephistory[x=4, y=-2, name=deephist]  \end{tikzpicture}


From left to right and top to bottom:

These commands take several options: name, to rename the node, and width to set their size. You can use these commands in a umlstate environment:

 \begin{tikzpicture}  \begin{umlstate}[name=state]{state}  \begin{umlstate}[name=substate]{substate}  \umlstateinitial[name=initial]  \umlstatefinal[x=1, name=final]  \umlstatejoin[x=2, name=join]  \end{umlstate}  \umlstatedecision[x=4, name=decision]  \umlstateenter[y=-2, name=enter]  \umlstateexit[x=1, y=-2, name=exit]  \umlstateend[x=2, y=-2, name=end]  \umlstatehistory[x=3, y=-2, name=hist]  \umlstatedeephistory[x=4, y=-2, name=deephist]  \end{umlstate}  \end{tikzpicture}


You can also give actions on a state, through the entry, do and exit options:

 \begin{tikzpicture}  \begin{umlstate}[name=state, do=b, exit=c]{state}  \begin{umlstate}[name=substate, entry=d, exit=f]{substate}  \end{umlstate}  \end{umlstate}  \end{tikzpicture}


4.2 To define a transition

Transitions are relations between states in a state-transition diagram. You can define them with the umltrans command, that is an alias of the umlrelation command. There are unidirectional transitions and recursive transitions.

4.2.1 To define a unidirectional transition

Thanks to the geometry option, usual aliases are available: umlHVtrans, umlVHtrans, umlVHVtrans and umlHVHtrans. Graphically, the use of these aliases are the most interesting, because corners are rounded.

 \begin{tikzpicture}  \umlstateinitial[name=initial]  \umlstatefinal[x=4, y=-2, name=final]  \umlHVtrans[arg=transition1, pos=0.5]{initial}{final}  \umlHVHtrans[arm1=-2cm, arg=transition2, pos=1.5]{initial}{final}  \end{tikzpicture}


Every option of the umlrelation command can be used with the umltrans command and its aliases.

4.2.2 To define a recursive transition

Recursive transitions are graphically the most difficult to manage, because their shape is a rounded rectangle, contrary to recursive relations in a class diagram. Conceptually, it is as if the geometry option has the value -|- or |-|, that is to say arrows composed of several segments.

 \begin{tikzpicture}  \umlbasicstate[name=state]{I am a state}  \umltrans[recursive=-10|10|2cm, arg=a, pos=1.5, recursive direction=right to right]{state}{state}  \umltrans[recursive=-170|-110|2cm, arg=b, pos=2, recursive direction=left to bottom]{state}{state}  \end{tikzpicture}


The recursive direction option is fundamental. Indeed, giving values of start angle and end angle is not enough to determine the start direction and the end direction of the recursive arrow, because it does not define the normal direction. Then, we have to precise it. There are 2 cases:

4.2.3 To define a transition between sub states

When you want to define transitions between sub-states, transitions are drawn inside the parent state.Then, you have to define them inside the umlstate environment. Let’s compare the two following examples:

 \begin{tikzpicture}  \begin{umlstate}[name=state]{state}  \umlbasicstate[name=state1]{sub state1}  \umlbasicstate[x=4, name=state2]{sub state2}  \end{umlstate}    \umlVHVtrans[arm1=-2cm]{state1}{state2}  \end{tikzpicture}


 \begin{tikzpicture}  \begin{umlstate}[name=state]{state}  \umlbasicstate[name=state1]{sub state1}  \umlbasicstate[x=4, name=state2]{sub state2}    \umlVHVtrans[arm1=-2cm]{state1}{state2}  \end{umlstate}  \end{tikzpicture}


4.3 Advanced features for positioning

umlstate and the 9 pseudo-state commands can accept every option key defined for nodes in TikZ . In this section, you will see how some of them can be used for advanced features.

4.3.1 Horizontal and vertical alignment

In a state-transition diagram, states have different width and height. For a graphical purpose, you may want to align them horizontally or vertically. Let’s take the following example:

 \begin{tikzpicture}  \umlbasicstate{A}  \umlbasicstate[x=-2, y=-3]{B}  \umlbasicstate[x=2, y=-3]{C}  \end{tikzpicture}


The y coordinate defines the center of the state node. It will be better in this example to have states B and C top-aligned. A solution is to define manually the y value for C, but it is not very convenient. You may prefer use the anchor option. If you specify anchor=north, the y coordinate will define the top center anchor of the node, instead of the center. You may take a look at the differences between both codes.

 \begin{tikzpicture}  \umlbasicstate{A}  \umlbasicstate[x=-2, y=-2, anchor=north]{B}  \umlbasicstate[x=2, y=-2, anchor=north]{C}  \end{tikzpicture}


In a similar way, you may use anchor=east to right align states, anchor=west to left align states or anchor=south to bottom align states.

4.3.2 Relative positioning

Using the x-y coordinate system may be very hard in big diagrams, when you have to change position of elements in order to fit the diagram to the page. Relative positioning may be useful in this case, namely advanced syntax of options above, left, below, right, above left, below left, below right and above right provided by the TikZ library positioning.

Let’s take the previous example, you can define B by its cordinates (-2,-2) or by saying that B is 2cm below and 2cm left of A. You can also define C by saying it is 4cm right of B. Notice that because of the top alignment of B and C, the latter is defined 4cm right of B.north.

 \begin{tikzpicture}  \umlbasicstate{A}  \umlbasicstate[below left=2cm and 2cm of A, anchor=north]{B}  \umlbasicstate[right=4cm of B.north, anchor=north]{C}  \end{tikzpicture}


The behavior is not the one expected. It is because definition of a state node is complex. Instead of B, you may use here B-body.

 \begin{tikzpicture}  \umlbasicstate{A}  \umlbasicstate[below left=2cm and 2cm of A, anchor=north]{B}  \umlbasicstate[right=4cm of B-body.north, anchor=north]{C}  \end{tikzpicture}


4.4 To change preferences

With the tikzumlset command, you can change default colors for states and transitions:

allows to set default text color (=black by default),
allows to set the default edge color and the default color of initial, final and join states (=black by default),
fill state:
allows to set the default background color of a state (=yellow!20 by default),
allows to set the default font style (=\small by default).
state join width
allows to set the default with of a state join (=3ex by default),
state decision width:
allows to set the default width of a state decision (=3ex by default),
state initial width:
allows to set the default width of a state initial (=5ex by default),
state final width:
allows to set the default width of a state final (=5.5ex by default),
state enter width:
allows to set the default width of a state enter (=5ex by default),
state exit width:
allows to set the default width of a state exit (=5ex by default),
state end width:
allows to set the default wdith of a state end (=5ex by default),
state history width:
allows to set the default width of a state history (=5ex by default),
state deep history width:
allows to set the default width of a state deep-history (=5ex by default),
state width:
allows to set the default width of a state (=8ex by default)

You can also use the text, draw and fill options on a particular element, in order to change its colors, as shown in the introduction example.

4.5 Examples

4.5.1 Example from introduction, step by step

Definition of basic states


 \begin{umlstate}[name=Amain]{Etat global de lobjet A}  \begin{umlstate}[name=Bgraph, fill=red!20]{graphe B}
 \umlbasicstate[y=-4, name=test1, fill=white]{test1}
 \umlbasicstate[y=-8, name=test2, fill=white]{test2}
 \umlbasicstate[x=6, y=-6, name=visu, fill=green!20]{Visualisation}

Definition of specific states


 \begin{umlstate}[name=Amain]{Etat global de lobjet A}  \begin{umlstate}[name=Bgraph, fill=red!20]{graphe B}
 \umlbasicstate[y=-4, name=test1, fill=white]{test1}
 \umlbasicstate[y=-8, name=test2, fill=white]{test2}
 \umlstatefinal[x=3, y=-7.75, name=Bfinal]
 \umlstateinitial[x=6, y=1, name=Ainit]
 \umlstatefinal[x=6, y=-3.5, name=Afinal]
 \umlbasicstate[x=6, y=-6, name=visu, fill=green!20]{Visualisation}

Definition of transitions
 \begin{umlstate}[name=Amain]{Etat global de lobjet A}  \begin{umlstate}[name=Bgraph, fill=red!20]{graphe B}  \umlstateinitial[name=Binit]  \umlbasicstate[y=-4, name=test1, fill=white]{test1}
 \umltrans{Binit}{test1}  \umltrans[recursive=20|60|2.5cm, recursive direction=right to top, arg={op1}, pos=1.5]{test1}{test1}  \umltrans[recursive=160|120|2.5cm, recursive direction=left to top, arg={op2}, pos=1.5]{test1}{test1}  \umltrans[recursive=-160|-120|2.5cm, recursive direction=left to bottom, arg={op3}, pos=1.5]{test1}{test1}  \umltrans[recursive=-20|-60|2.5cm, recursive direction=right to bottom, arg={op4}, pos=1.5]{test1}{test1}
 \umlbasicstate[y=-8, name=test2, fill=white]{test2}
 \umltrans[recursive=-160|-120|2.5cm, recursive direction=left to bottom, arg={op5}, pos=1.5]{test2}{test2}  \umltrans{test1}{test2}
 \umlstatefinal[x=3, y=-7.75, name=Bfinal]
 \end{umlstate}  \umlstateinitial[x=6, y=1, name=Ainit]
 \umlstatefinal[x=6, y=-3.5, name=Afinal]
 \umlbasicstate[x=6, y=-6, name=visu, fill=green!20]{Visualisation}
 \umlHVtrans{Bfinal}{visu}  \umltrans{visu}{Afinal}  \umltrans[recursive=-20|-60|2.5cm, recursive direction=right to bottom, arg=a, pos=1.5]{visu}{visu}