# UML Statediagram

I am trying to draw a UML statediagram with TikZ. I tried tikz-uml, but I was not satisfied with the way it handles the state nodes. While I love TikZ for its versatile placement options of nodes (relative placement with above, selecting anchor points), I have no clue how to do this with tikz-uml. Furthermore, it gives me text extending outside the node.

Looking briefly at tikz-uml's implementation (I am still a TeX noob), I learned that actually a rounded rectangle is drawn around a title node and a content node with the fitting library, and subsequently a line separating the statename is added. Thus I tried to have an implementation of my own, drawing the title and the contents in one TikZ picture, which I then put inside a node. That way I hope to preserve the easy placement that I have grown accustomed to from normal TikZ nodes. Here is the code and the problem, the line I draw for separation is misplaced above the nodes (note: render twice to get the same line placement I got):

\documentclass{article}
\usepackage{tikz}
\usepackage{tikz-uml}
\usepackage[active,tightpage]{preview}
\usetikzlibrary{calc}
\usetikzlibrary{positioning}
\PreviewEnvironment{tikzpicture}
\begin{document}
\begin{tikzpicture}
\node[draw, rounded corners](box){
\begin{tikzpicture}[remember picture]
\node[draw=red](caption) {titel};
\node[below=0 of caption] {\begin{tabular} ccontent\\more content\end{tabular}};
\end{tikzpicture}
};
\draw (caption.south -| box.west) -- (caption.south -| box.east);
\end{tikzpicture}
\end{document}


To show where the line should be, the title box is drawn in red, the line should be on its lower edge, similar to the tikz-uml output. The line actually is the black bar above the outer black node, drawn above it near the top edge of the image.

For comparison here is what I tried with tikz-uml and the result (simply replace everyting inside the outer tikzpicture above with this to test):

\begin{umlstate}[x=-3, y=-4, name=discard, do=clear all valid bits]{discard}
\end{umlstate}


-
Could you edit your question to include a complete LaTeX document, that I can paste into my editor? –  John Wickerson May 8 '13 at 10:23
@JohnWickerson: done. I skipped it for the lower part, since it uses the same preamble on one hand, and I am not satisfied with the placement option tikz-uml gives me anyway on the other hand. Thansk for the grammar corrections, I hope I learned a thing or two. –  ted May 8 '13 at 10:49
No prob. By the way, if you write do=clear all\\valid bits then you can avoid the problem of the text extending outside the node. –  John Wickerson May 8 '13 at 10:55
My guess is that you should stick with the tikz-uml package, as it's probably the best tool for the job of writing UML diagrams. Can you give a specific example of the placement options that you're not satisfied with? –  John Wickerson May 8 '13 at 10:56
@JohnWickerson: I am not satisfied with the lack of relative placement (e.g. below=1cm of myOtherUmlState), at least I don't know how to apply it to tikz-uml. Furthermore I consider the forced linebreak a hack, wich should not be necessary since tikz can handle this nicly. I have to read up on it again, but I don't recall any prerequisites for nodes fitting the text placed inside. Furthermore I would appreciate placement at different anchors (I hava a decision with 5 outcomes and would like to place them in equal distance to the decision marker at 0, -45, -90, -135 and 180°) –  ted May 8 '13 at 11:05

You could make your state node into a 'multipart' node. For that, you need to load the shapes.multipart TikZ library. You should then be able to use all the placement options that you're used to.

Result:

Code:

\documentclass[border=1cm]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart}
\begin{document}
\begin{tikzpicture}
\node[rectangle split, rectangle split parts=2, draw, rounded corners]{%
\tikz\node[draw=red, rectangle, rounded corners]{titel};
\nodepart{two}
\begin{tabular}{c}
content \\ more content
\end{tabular}
};
\end{tikzpicture}
\end{document}


PS. You might alternatively make your state node into a matrix, but then it's quite hard to get the horizontal line that you want (see this discussion, for instance).

-
Looks awesome, this can be simplified, since I only had the redf rame to show were the lines was supposed to be. Thank you very much (I think the implementor of tikz-uml could improve his library with his approach(correct look, handling like a standard tikz node, and if simplified no more hassle than the tikz-uml state representation)). –  ted May 8 '13 at 12:24
btw. for people drawing statediagrams defining a style helps. Just put [stateNode/.style={rectangle split, rectangle split parts=2, draw, rounded corners, fill=yellow!10}] behind tikzpicture and use it with \node[statenode]{...}, I wonder if there is a shortcut for the \nodepart{two}\tabular-part since this gets tedious –  ted May 8 '13 at 12:51
You could probably factor that into a macro, say \statenode, such that the diagram in my answer could be obtained by writing \statenode{titel}{content \\ more content}. –  John Wickerson May 8 '13 at 13:32
the problem with a macro is not loosing tikz power... (adding positioning, nameing the nodes are most important and possible, but what about special cases like different fills, fancy decorations,...) (sort of forwarding), I am rather leaving this untouched (I am clueless as to how do proper forwarding, best would be a command that mimics a node (in alll ways), but has two textparameters. –  ted May 8 '13 at 13:56
Fair enough. Then maybe just factor out the contents of the state node into a macro: \node[statenode]{\statenode{titel}{content \\ more content}}. –  John Wickerson May 8 '13 at 14:19