4

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[margin=0cm,nohead]{geometry}
\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.

line misplaced above box


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}

overset text with tikz uml

6
  • Could you edit your question to include a complete LaTeX document, that I can paste into my editor? May 8, 2013 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, 2013 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. May 8, 2013 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? May 8, 2013 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, 2013 at 11:05

1 Answer 1

2

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:

enter image description here

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).

5
  • 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, 2013 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, 2013 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}. May 8, 2013 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, 2013 at 13:56
  • 1
    Fair enough. Then maybe just factor out the contents of the state node into a macro: \node[statenode]{\statenode{titel}{content \\ more content}}. May 8, 2013 at 14:19

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .