# Nested TikZ nodes

This isn’t the first time this question was asked but the other solutions don’t work in my case.

Consider the following image:

It was created using this code:

\begin{tikzpicture}[
node distance=7mm,
title/.style={font=\fontsize{6}{6}\color{black!50}\ttfamily},
typetag/.style={rectangle, draw=black!50, font=\scriptsize\ttfamily}
]
\node (decomp) [title] { Decomposition };
\draw [draw=black!50] (decomp.north west) rectangle +(2.8cm, -2.7cm);

\node (di) [typetag, below=of decomp.west, anchor=west, xshift=2mm] { Independent };
\node (dr) [typetag, below=of di.west, anchor=west] { Reduction };
\node (dnc) [typetag, below=of dr.west, anchor=west] { DivideAndConquer };

\node (dep) at (3cm, 0) [title] { Dependency };
\draw [draw=black!50] (dep.north west) rectangle ($(dep.north east) - (0, 2cm)$);

\node (da) [typetag, below=of dep.west, anchor=west, xshift=2mm] { Atomic };
\node (dr) [typetag, below=of da.west, anchor=west] { Range };
\end{tikzpicture}


Needless to say, this code is horribly complicated and has no automation (for example, the width of the borders isn’t auto-computed to fit all elements, but rather put in by hand via painstaking trial and error).

There must be an easier way to achieve this.

In particular, I have two questions:

1. How do I automate the drawing of the border + title (the grey text) so that the border is just large enough to accomodate all the typetag elements that follow after (and how to specify them?)
2. How can I arrange the typetag elements more smartly? (having to write, every time, below=of Element.west, anchor=west is extremely annoying, but I don’t succeed to put this into the typetag/.style because TikZ “forgets” this information (I have also tried adding ever node/.style={anchor=west} in the tikzpicture options, to no avail).

Question 1 is the important thing here, though. Question 2 is more of a general question that crops up again and again …

-
do you really need nodes? Because it is a simple combination of boxes which can be done easily with default LaTeX commands. –  Herbert Dec 27 '10 at 16:11
@Herbert: It’s part of a larger (TikZ) picture. So yes, TikZ would be much preferred, unless your solution mixes well with TikZ code (i.e. can be used inside TikZ). –  Konrad Rudolph Dec 27 '10 at 16:14

For the first point, you can use the fit library.

For the second: According to the manual, setting below also sets anchor=north. So adding anchor=west to typetag and then setting typetag after below does the trick.

\documentclass{minimal}

\usepackage{tikz}
\usetikzlibrary{positioning,fit,calc}
\begin{document}

\begin{tikzpicture}[
node distance=7mm,
title/.style={font=\fontsize{6}{6}\color{black!50}\ttfamily},
typetag/.style={rectangle, draw=black!50, font=\scriptsize\ttfamily, anchor=west}
]
\node (decomp) [title] { Decomposition };

\node (di) [below=of decomp.west, typetag, xshift=2mm] { Independent };
\node (dr) [below=of di.west, typetag] { Reduction };
\node (dnc) [below=of dr.west, typetag] { DivideAndConquer };

\node [draw=black!50, fit={(decomp) (di) (dr) (dnc)}] {};

\node (dep) at (3cm, 0) [title] { Dependency };

\node (da) [below=of dep.west, typetag, xshift=2mm] { Atomic };
\node (dr) [below=of da.west, typetag] { Range };

\node [draw=black!50, fit={(dep) (dr) (da)}] {};
\end{tikzpicture}
\end{document}


(inner sep, should probably be adjusted a bit)

-

Would a matrix make sense here? ie:

\documentclass{minimal}
\usepackage{tikz}
\usetikzlibrary{matrix, positioning, fit}
\begin{document}
\begin{tikzpicture}[font=\ttfamily,
mymatrix/.style={matrix of nodes, nodes=typetag, row sep=1em},
mycontainer/.style={draw=gray, inner sep=1ex},
typetag/.style={draw=gray, inner sep=1ex, anchor=west},
title/.style={draw=none, color=gray, inner sep=0pt}
]
\matrix[mymatrix] (mx1) {
|[title]|Decomposition \\
Independent \\
Reduction \\
DivideAndConquer \\
};
\matrix[mymatrix, right=of mx1.north east, matrix anchor=north west] (mx2) {
|[title]|Dependency \\
Atomic \\
Range \\
};
\node[mycontainer, fit=(mx1)] {};
\node[mycontainer, fit=(mx2)] {};

\end{tikzpicture}
\end{document}


-
Interesting approach. Perhaps this could work. However, is there a way to make the top and left margins of the title attributes much smaller than the rest? These two entries should effectively be glued to the frame, and be very small. Perhaps using shift? I’ll try it some time. –  Konrad Rudolph Jan 14 '11 at 11:17
@Konrad Rudolph: I always feel dirty for some reason when shifting. Also, it didn't seem to work here. Instead, you could try adding inner sep=-1ex to title's style. If you'd like, I could update those to my answer aswell. –  morbusg Jan 14 '11 at 11:53
May be you can write Decomposition and Dependency with a label of the container nodes instead of being matrix nodes. –  Ignasi Jan 14 '11 at 12:13
@Ignasi: I actually tried that. It would require shifting the label, as well as the container contents (with \\'s for example), which seemed rather icky. Also, I'm not sure how you could left-align the title, then. –  morbusg Jan 14 '11 at 12:41
Look at my answer. I used a \phantom to reserve some place inside the matrix and a new node for the title. –  Ignasi Jan 16 '11 at 21:39

Here it is the same with only \fbox and automatic calculation of the box widths, can also be used inside of tikz. If you need connections, you can set single nodes of the box contents.

\documentclass[12pt]{article}
\usepackage[T1]{fontenc}
\usepackage{tgheros}
\usepackage{varwidth}
\usepackage{setspace}
\usepackage{xcolor}
\usepackage{tikz}

\begin{document}

\fboxsep=10pt\sffamily\setstretch{2}
\fbox{\begin{varwidth}[t]{\linewidth}
\tikzset{node distance=7mm,
title/.style={font=\color{black!50}\ttfamily},
typetag/.style={rectangle, draw=black!50, font=\large\ttfamily}}

\fboxsep=10pt\sffamily\setstretch{2}
\fbox{\begin{varwidth}[t]{\linewidth}
\tikz\node (decomp) [title] { Decomposition };

\tikz\node (di) [typetag]{ Independent };

\tikz\node (dr) [typetag]{ Reduction\vphantom{g} };

\tikz\node (dnc) [typetag]{ DivideAndConquer};

\fbox{\begin{varwidth}[t]{\linewidth}
\tikz\node (dep) [title] { Dependency };

\fbox{\bfseries Atomic}

\fbox{\bfseries Range}
\end{varwidth}}}


\end{document}

-
dang, I oversimplified. I’m so, so sorry. :-( The inner boxes in my code are actually more complex (custom TikZ) shapes, not rectangles. –  Konrad Rudolph Dec 27 '10 at 16:27
@Konrad: I cannot see a problem here, because all inner rectangles can be single nodes with any shape instead of the fbox –  Herbert Dec 27 '10 at 16:31
I edited the code so that you can see what I mean –  Herbert Dec 27 '10 at 16:48
I can’t get this to work … when I replace the inner fboxes by notes, chaos ensues. In particular, the varwidth box doesn’t seem to heed the nodes in its width calculation and the height is only approximately right. –  Konrad Rudolph Dec 27 '10 at 16:49

Here you have another option with matrix. You can 'draw' the matrix node, so don't need to use a fitting node. I could not declare titles with label (may be someone knows how to do it) but with another node anchored to matrix.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix, positioning, fit}

\usepackage[active,tightpage,pdftex]{preview}
\PreviewEnvironment{tikzpicture}

\begin{document}
\begin{tikzpicture}[font=\ttfamily,
mymatrix/.style={matrix of nodes, nodes=typetag, row sep=1em},
mycontainer/.style={draw=gray, inner sep=1ex},
typetag/.style={draw=gray, inner sep=1ex, anchor=west},
title/.style={draw=none, color=gray, inner sep=0pt,font=\ttfamily\footnotesize}
]
\matrix[mymatrix,draw] (mx1) {
|[title]|\phantom{aaaaaaaaaaa} \\
Independent \\
Reduction \\
DivideAndConquer \\
};
\matrix[mymatrix, right=of mx1.north east, matrix anchor=north west,draw] (mx2) {
|[title]|\phantom{aaaaaaaaa} \\
Atomic \\
Range \\
};
\node[title,anchor=north west,outer sep=2pt] () at (mx1.north west) {Decomposition};
\node[title,anchor=north west,outer sep=2pt] () at (mx2.north west) {Dependency};

\end{tikzpicture}
\end{document}


Here you have the result:

-