The real trick here is how to put the outer boxes around the inner nodes.
As you may have already discovered, it's not possible to embed a \node
inside another \node
. It is also a really bad idea to embed one tikzpicture
inside another (which might appear to be another solution to this problem. Here's a solution that is based on Mark Everitt's answer to this question tikz: a big box with fixed width containing smaller boxes.
It uses the shapes.multipart
library to split the tree nodes, and the fit
library to put outer boxes around the tree nodes. The positioning
and calc
libraries are used to calculate the placement of the outer node text, and the edge from parent
path, so that although the tree is built on the inner nodes, the branches actually connect at a point that appears to be the edge of the outer nodes.
Update: Based on this question: How to make tikz multipart node parts have uniform size? I've added some code to make all the inner nodes (both split and single) uniform size.
\documentclass{article}
\usepackage{tikz-qtree}
\usetikzlibrary{fit,backgrounds,shapes.multipart,calc,positioning}
\begin{document}
\tikzset{
sibling distance=2cm,
level distance=2.5cm,
split/.style={draw,
rectangle split, rectangle split parts=2,draw,inner
sep=0pt,rectangle split horizontal,minimum size=3ex,text width=3ex,align=center,rectangle split part align=base},
boxed/.style={draw,minimum size=3ex,inner sep=0pt,align=center},
edge from parent/.style={draw,
edge from parent path={[->,thick]
(\tikzparentnode) -- ($(\tikzchildnode.north) + 25*(0pt,1pt)$) }}
}
\begin{tikzpicture}
\Tree [.\node[split] (M1) {g\nodepart{two}t};
[.\node[split] (M2) {h\nodepart{two}r};
[.\node[boxed] (M3) {o};
[.\node[boxed] (M4) {s};
[.\node[boxed] (M5) {t};
[.\node[boxed] (E1) {};]
]
]
]
[.\node[boxed] (M6) {e};
[.\node[boxed] (M7) {e};
[.\node[boxed] (M8) {n};
[.\node[boxed] (E2) {};]
]
]
]
]
[.\node[split] (M9) {a\nodepart{two}r};
[.\node[boxed] (M10) {n};
[.\node[boxed] (E3) {};]
]
[.\node[split] (M11) {e\nodepart{two}i};
[.\node[boxed] (M12) {e};
[.\node[boxed] (E4) {};]
]
[.\node[boxed] (M13) {e};
[.\node[boxed] (E5) {};]
]
]
]
]
\begin{pgfonlayer}{background}
\foreach \x in {1,...,13}{
\node (A\x) [above =5pt of M\x] {Middle};
\node[draw,red,] [fit=(M\x) (A\x) ] {};}
\foreach \x in {1,...,5}{
\node (B\x) [above =5pt of E\x] {End};
\node[draw,red,] [fit=(E\x) (B\x) ] {};}
\end{pgfonlayer}
\end{tikzpicture}
\end{document}
Here you have a starting point:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{trees}
\begin{document}
\begin{tikzpicture}[
tlabel/.style={pos=0.4,right=-1pt,font=\footnotesize\color{red!70!black}},
]
\node{S}
child {node {a}}
child {node {S}
child {node {a}}
child {node {S}
child {node {$\varepsilon$}
edge from parent node[tlabel,pos=0.2] {2}
}
edge from parent node[tlabel] {1}
}
child {node {B}
child {node {B}
child {node {b}
edge from parent node[tlabel,pos=0.2] {5}
}
edge from parent node[tlabel] {4}
}
child {node {b}}
}
edge from parent node[tlabel] {1}
}
child {node {B}
child[missing] {}
child[missing] {}
child {node {b}
edge from parent node[tlabel,pos=0.15,right=2pt] {5}
}
};
\end{tikzpicture}
\end{document}
Best Answer
One problem is all the
(left node)
and(right node)
notations. That syntax gives a name to the nodes. Usually node names are unique, but you've named half of them one thing and half of them another thing! So just take those out.The sibling distance is by default 15mm at each level of the tree. There's no computation about the number of descendants to make the tree space out automatically. So you just have to make sure that the first level stretches out a bit.
Here is a complete example document: