Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Suppose I want to show the expression

a IF b OR c
b IF d AND e
c IF f OR g

as a tree, using tikz-qtree. I'd want to do something like this:

\documentclass{article}

\usepackage{tikz-qtree}

\begin{document}

\begin{tikzpicture}[grow'=right]
\tikzset{level distance=2cm}
\tikzset{sibling distance=1cm}
\tikzset{every tree node/.style={anchor=base west}}
\Tree[.a
         [.b
             [.d ]
             [.e ] ]
         [.c
             [.f ]
             [.g ] ] ]
\end{tikzpicture}

\end{document}

The above code generates the following tree:

The resulting tree

However, I'd like to include some decoration in the branches, showing that the first one (from a to b and c) is an "OR" branch, and that the others are one AND branch (from b) and one OR branch (from c). Something like a arc with a label, for example. I didn't find a way to do this in the tikz-qtree documentation.

share|improve this question

1 Answer 1

up vote 6 down vote accepted

How about this:

\documentclass{article}
\usepackage{tikz-qtree}
\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}

\begin{tikzpicture}[grow'=right]
\tikzset{level distance=2cm}
\tikzset{sibling distance=1cm}
\tikzset{every tree node/.style={anchor=base west}}
\Tree[.\node (a) {a};
         [.\node (b) {b};
             [.\node (d) {d}; ]
             [.\node (e) {e}; ] ]
         [.\node (c) {c};
             [.\node (f) {f}; ]
             [.\node (g) {g}; ] ] ]
\node[red] at ($0.33*(a)+0.33*(b)+0.33*(c)$) {\textbf{OR}};
\node[red] at ($0.33*(b)+0.33*(d)+0.33*(e)$) {\textbf{AND}};
\node[red] at ($0.33*(c)+0.33*(f)+0.33*(g)$) {\textbf{OR}};
\end{tikzpicture}

\end{document}

enter image description here

I used the possibility to add named nodes in a qtree (see the manual, section 4). Then I used the calc library provided by TikZ to compute a coordiante "in the middle", which is basically the weighted average of the coordinates around it (with equal weights, thus 0.33).


Edit 1: Here's a variant drawing an arc, it uses Jasper Loy's answer to this question:

\documentclass{article}
\usepackage{tikz-qtree}
\usepackage{tikz}
\usetikzlibrary{calc}

\usepackage{tkz-euclide}
\usetkzobj{all} 

\newcommand{\sparc}[8]% vertex, first child, last child, relative radius, text, text options, draw options, shift
{   \coordinate (firstarm) at ($(#1)!#4!(#2)$);
    \coordinate (lastarm) at ($(#1)!#4!(#3)$);
    \tkzDrawArc[#7](#1,lastarm)(firstarm)
    \node[#6] at ($(#1)+(#8)$) {#5};
}

\begin{document}

\begin{tikzpicture}[grow'=right]
\tikzset{level distance=2cm}
\tikzset{sibling distance=1cm}
\tikzset{every tree node/.style={anchor=base west}}
\Tree[.\node (a) {a};
         [.\node (b) {b};
             [.\node (d) {d}; ]
             [.\node (e) {e}; ]
             [.\node (e2) {e$_2$}; ]
             [.\node (e3) {e$_3$}; ] ]
         [.\node (c) {c};
             [.\node (f) {f}; ]
             [.\node (g) {g}; ]
             [.\node (h) {h}; ] ] ]
\sparc{a}{b}{c}{0.7}{OR}{red}{ultra thick,color=blue!50!cyan}{1.5,0}
\sparc{b}{d}{e3}{0.6}{AND}{yellow,circle,fill=green!50!gray}{ultra thick,color=red!50!orange}{1,0}
\sparc{c}{f}{h}{0.6}{OR}{blue,circle,fill=blue!50!gray,fill opacity=0.3,text opacity=1}{ultra thick,color=green!30!gray}{1,0}
\end{tikzpicture}

\end{document}

enter image description here


Edit 2: the small gaps in the arcs are due to the fact that always the .center of the nodes is used for computation. For a left-to right graph, this would be better:

\newcommand{\sparc}[8]% vertex, first child, last child, relative radius, text, text options, draw options, shift
{   \coordinate (firstarm) at ($(#1.east)!#4!(#2.west)$);
    \coordinate (lastarm) at ($(#1.east)!#4!(#3.west)$);
    \coordinate (vertex) at (#1.east);
    \tkzDrawArc[#7](vertex,lastarm)(firstarm)
    \node[#6] at ($(#1)+(#8)$) {#5};
}

enter image description here

share|improve this answer
    
Thanks! But I'd like something that would go across all branches from a node (if a node has three or five children, then putting a label as you showed may not look nice -- an arc going through the branches would be great) –  Jay Aug 15 '12 at 16:27
    
this is great -- exactly what I needed, thank you! –  Jay Aug 15 '12 at 23:48
    
One last observation: that code works when the size of the nodes above and below the arc are the same. If they're different, then their center will be at different places, and the arc will be longer at one of its sides. (I've made the nodes the same size, so I'm OK with it) –  Jay Aug 16 '12 at 18:45

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.