# Styles in TikZ trees not working as expected

I want to draw a "cut-out" region of a tree, and visually underline this by having dashed edges on top and on the bottom of my diagram (to symbolize the levels further up and further down).

I am attempting to use styles defined in the options of the \tikzpicture environment, but failing to achieve the desired result, which would look something like this:

For me, the "outermost" edges (which I want to be dashed) are just normal lines.

\documentclass{beamer}

\usepackage{tikz}

\begin{document}
\begin{tikzpicture}[
every node/.style={minimum size=4mm, inner sep=0.5mm},
normal/.style={circle,draw},
invis/.style={draw=none},
border/.style={ edge from parent/.style={dashed,draw} },
acc/.style={circle,thick,draw=green!50,fill=green!2},
rej/.style={circle,thick,draw=red!50,fill=red!20},
semithick]

node[invis] (root) {}
child[level distance=11mm] { node[border,normal] {x}
child {node[acc] {x1}
child {node[border,invis] {} }
child {node[border,invis] {} }
child {node[border,invis] {} }
}
child {node[rej] {x2} }
child {node[normal] {x3}
child {node[invis,border] {} }
child {node[invis,border] {} }
child {node[invis,border] {} }
}
};
\end{tikzpicture}
\end{document}


My first hunch was maybe a node could only have one style defined in its options, but even after swapping the two styles for the last tree nodes, it makes no difference. I also tried applying a style and setting an option in the same []-block, and it worked, so this doesn't seem to be the problem.

I am aware that the author of TikZ notes in the manual that "placing node options at the right place is an arcane art", but (after carefully reading) I thought basically it worked like this:

• Options defined in a node are local in effect.
• Options defined in a child command are inherited to all of its child nodes.

When trying to pass the border style to the child command as an alternative , I do get dashed edges which work for the bottom, but if I pass it to the first visible child node (x), all the lines in the tree are dashed (even the node outlines!) because of the inheritance mechanism.

What am I doing wrong/ should I change to achieve the desired result?

-
Hi MHaaZ, could you provide a picture to clarify exactly what you're aiming for? Hand-drawn and scanned in would be fine. You don't have sufficient reputation yet to include pictures in your posts, but if you upload it to imgur.com and then post the link here in the comments, then somebody will insert the picture on your behalf. – John Wickerson Jun 2 '13 at 7:44
Also, it's better to post a complete .tex document, rather than just a snippet. Otherwise, I have to type out the \begin{document} stuff myself, which isn't much fun! :-) – John Wickerson Jun 2 '13 at 7:46
I am currently on the road, will do as soon as I get to campus :) – MHaaZ Jun 2 '13 at 7:49
@John Wickerson Here it is: imgur.com/NgKxzUm Thanks for the remark on the whole .tex, will edit question and remember for the future! :) – MHaaZ Jun 2 '13 at 8:39

The main problem is that your styles for the edges should be applied to the child commands not the node ones. This is what I show in the second solution. Probably better is styling the levels. I'll give this first.

# Styling the levels

\documentclass{article}

\usepackage{tikz}

\begin{document}

\begin{tikzpicture}[
every node/.style={minimum size=4mm, inner sep=0.5mm},
level 1/.style={every child/.style={edge from parent/.style={draw,dashed}}},
level 2/.style={every child/.style={edge from parent/.style={draw,solid}}},
level 4/.style={every child/.style={edge from
parent/.style={draw,dashed}},sibling distance=5mm},
normal/.style={circle,draw,solid},
acc/.style={circle,thick,solid,draw=green!50,fill=green!2},
rej/.style={circle,thick,solid,draw=red!50,fill=red!20},
semithick]

\node (root) {}
child[level distance=11mm] { node[normal] {x}
child {node[acc] {x1}
child { node[normal] {} child child}
child { node[normal] {} child child}
}
child {node[rej] {x2} }
child {node[normal] {x3}
child {node[normal] {} child }
child {node[acc] {} child child }
child {node[normal] {} child child child}
}
};
\end{tikzpicture}

\end{document}


This assumes cut off at uniform depth. The style for level 2 is inherited by lower levels, so you specify styles for the first, second and last levels. If the cut off is not at uniform depth, you can instead write children on the last level as

child { edge from parent[dashed] }


producing a descending dashed line.

# Style on child

\documentclass{article}

\usepackage{tikz}

\begin{document}

\begin{tikzpicture}[
every node/.style={minimum size=4mm, inner sep=0.5mm},
normal/.style={circle,draw},
invis/.style={draw=none},
border/.style={ edge from parent/.style={dashed,draw} },
normaledge/.style={ edge from parent/.style={solid,draw}},
acc/.style={circle,thick,draw=green!50,fill=green!2},
rej/.style={circle,thick,draw=red!50,fill=red!20},
semithick]

\node[invis] (root) {}
child[level distance=11mm,border] { node[normal] {x}
child[normaledge] {node[acc] {x1}
child[border] {node {} }
child[border] {node {} }
child[border] {node {} }
}
child[normaledge] {node[rej] {x2} }
child[normaledge] {node[normal] {x3}
child[border] {node[invis] {} }
child[border] {node[invis] {} }
child[border] {node[invis] {} }
}
};
\end{tikzpicture}

\end{document}


I have introduced a normaledge style for edges that are not borders.

-
This looks pretty good, although I was precisely trying to avoid setting the border style on the topmost child, since that propagates down the tree, requiring the "extra work" of writing normaledge everywhere. Still, I can live with this. One last request, would it be possible to make the outlines of nodes x1 and x3 not dashed? I guess I could change the styles used in node and "override" the dashed style (but how?) – MHaaZ Jun 2 '13 at 8:43
Nevermind, I already inferred how to do that from your example. Thanks a lot :) One last thing I would like to know: since my code compiled, it must be syntactically correct to pass the style to the node - what was its effect, if not the one I was looking for? – MHaaZ Jun 2 '13 at 8:48
I have updated my answer with another solution which may well be simpler to use. In your original syntax tikz recognized the style command but had nothing to apply it to (no edges of this type inside the node). – Andrew Swann Jun 2 '13 at 9:00
I understand know, edges are inherent to child since the nodes could very well used to define a general graph... thanks for further insight into this. And kudos for a (imho) very elegant and flexible solution! – MHaaZ Jun 2 '13 at 9:04
What is executed is essentially the same as \path[dashed,draw] (0,0) -- (1,1) node[circle,draw] {x}; and the dashed gets inherited by the node. Of course, you could the solid to your every node style. – Andrew Swann Jun 2 '13 at 12:16