TikZ tree with a line crossing the edges
To fill the background of a leaf, use \node [fill=<colour>] ..
. I made a style with that, so if you want to change the colour, just modify the style.
Zarko's suggestion for the arrows work fine, but you need to specify the anchor as well, so use e.g. \draw [->] ([yshift=3mm]p1.north) -- ([yshift=3mm]p2.north);
. I used a \foreach
loop to draw the arrows, which makes the code a bit shorter.
For the do-nothing, you can add a label
to the node, i.e. \node [label={below:do-nothing(p1a,p1b)}] (p6){move-stack(p1a,p1b)};
.
\documentclass[border=10pt]{standalone}
\usepackage{tikz-qtree}
\begin{document}
\begin{tikzpicture}[
nodes={draw,rectangle,rounded corners=.8ex}, ->,
level distance=2cm, growth parent anchor=south,
endleaf/.style={fill=blue!30}
]
\Tree
[.\node(p0){move-stack(p1a,q)};
\edge node[draw=none,auto=right]{recursive-move(p1a,p1b,c11,c12)};
[.\node(p1){move-topmost-container(p1a,p1b)};
\edge node[draw=none,auto=right]{take-and-put(...)};
\node [endleaf] (p3){take(crane1,l1a,c11,c12,p1a)};
\node [endleaf] (p4){put(crane1,l1b,c11,pallet,p1b)};
]
[.\node(p2){move-stack(p1a,p1b)};
\edge node[draw=none,auto=right]{recursive-move(p1a,p1b,c12,pallet)};
[.\node(p5){move-topmost-container(p1a,p1b)};
\edge node[draw=none,auto=right]{take-and-put(...)};
\node [endleaf] (p7){take(crane1,l1a,c11,c12,p1a)};
\node [endleaf] (p8){put(crane1,l1b,c11,pallet,p1b)};
]
[.\node [label={below:do-nothing(p1a,p1b)}] (p6){move-stack(p1a,p1b)}; ]
]
]
\foreach [evaluate={\y=int(\x-1)}] \x in {2,4,6,8}
\draw [-latex] ([yshift=3mm]p\y.north) -- ([yshift=3mm]p\x.north);
\end{tikzpicture}
\end{document}
This is shamelessly based on Zarko's answer and is, basically, a more automated form of that solution, with slightly more flexible and streamlined code.
parent anchor=children,
child anchor=parent,
Where possible, my code uses anchors which are sensitive to the direction of the tree's growth. This is especially useful when specifying the code for the horizontal arrows, but good practice generally as it makes for greater flexibility.
where n children=0{fill=blue!50!gray!25}{fill=white},
This saves having to apply the colour manually to each node which needs it. Since all those nodes are leaves and no leaves aren't coloured, it makes sense to use this feature to have Forest determine which ones to fill with blue and which with white.
where={>O_={n}{1}}{tikz+={\draw [thick, shorten >=-10pt, shorten <=-10pt, -{Triangle[width=6pt,length=6pt]}] ([yshift=10pt].-children) -- ([yshift=10pt]!s.-children); }}{}
This code draws the horizontal arrows, without relying on the manual addition of name
to each node. Every first child has a sibling and every such pair has an arrow above, but no other cases need arrows, so we use a node's being the first to decide whether or not to draw the arrow.
([yshift=10pt].-children) -- ([yshift=10pt]!s.-children)
This specifies the path from 10pt above the anchor .-children
of the current node to 10pt above the anchor .-children
of its sibling (!s
). Again, .-children
depends on the direction of growth of three tree.
I've also used arrows from arrows.meta
as arrows such as -stealth
are considered deprecated and do not support the new, more flexible and consistent syntax.
Complete code;
% addaswyd o ateb Zarko: https://tex.stackexchange.com/a/443859/
\documentclass[border=10pt]{standalone}
\usepackage{forest}
\usetikzlibrary{shadows,arrows.meta}
\begin{document}
\begin{forest}
for tree={draw,
rounded corners=.8ex,
drop shadow,
parent anchor=children,
child anchor=parent,
font=\sffamily,
edge+={draw, semithick, -{Triangle[width=4pt,length=4pt]}},
EL/.style={edge label={node[midway, font=\small\sffamily, anchor=south east, inner sep=1pt]{#1}},},
FB/.style={fill=blue!30},
l sep*=3,
},
where n children=0{fill=blue!50!gray!25}{fill=white},
where={>O_={n}{1}}{tikz+={\draw [thick, shorten >=-10pt, shorten <=-10pt, -{Triangle[width=6pt,length=6pt]}] ([yshift=10pt].-children) -- ([yshift=10pt]!s.-children); }}{}
[{move-stack(p1a,q)}
[{move-topmost-container(p1a,p1b)}, EL={recursive-move(p1a,p1b,c11,c12)}
[{take(crane1,l1a,c11,c12,p1a)}, EL={take-and-put(...)}
]
[{put(crane1,l1b,c11,pallet,p1b)},
]
]
[{move-stack(p1a,p1b)},
[{move-topmost-container(p1a,p1b)}, EL={recursive-move(p1a,p1b,c12,pallet)}
[{take(crane1,l1a,c11,c12,p1a)}, EL={take-and-put(...)}
]
[{put(crane1,l1b,c11,pallet,p1b)},
]
]
[{move-stack(p1a,p1b)}, label={[font=\small\sffamily]below:{do-nothing(p1a,p1b)}}
]
]
]
\end{forest}
\end{document}
@cfr: Please feel free to remove the following. I just verified that your code works fine and could not resist to cast some shadows (as the groundhog day was too long ago ;-). -marmot
\documentclass[border=10pt]{standalone}
\usepackage{forest}
\usetikzlibrary{shadows.blur,arrows.meta}
\tikzset{
shadowed/.style={%
preaction={transform canvas={shift={(0,-2pt)}},draw=gray,very thick,draw opacity=.2},
preaction={transform canvas={shift={(0,-3pt)}},draw=gray,very thick,draw opacity=.1},
preaction={transform canvas={shift={(0,-4pt)}},draw=gray,very thick,draw opacity=.05},
},
}
\begin{document}
\begin{forest}
for tree={draw,
rounded corners=.8ex,
blur shadow,
parent anchor=children,
child anchor=parent,
font=\sffamily,
edge={shadowed, semithick, -{Triangle[width=4pt,length=4pt]}},
EL/.style={edge label={node[midway, font=\small\sffamily, anchor=south east, inner sep=1pt]{#1}},},
FB/.style={fill=blue!30},
l sep*=3,
},
where n children=0{fill=blue!50!gray!25}{fill=white},
where={>O_={n}{1}}{tikz+={\draw [shadowed,thick, shorten >=-10pt, shorten <=-10pt, -{Triangle[width=6pt,length=6pt]}] ([yshift=10pt].-children) -- ([yshift=10pt]!s.-children); }}{}
[{move-stack(p1a,q)}
[{move-topmost-container(p1a,p1b)}, EL={recursive-move(p1a,p1b,c11,c12)}
[{take(crane1,l1a,c11,c12,p1a)}, EL={take-and-put(...)}
]
[{put(crane1,l1b,c11,pallet,p1b)},
]
]
[{move-stack(p1a,p1b)},
[{move-topmost-container(p1a,p1b)}, EL={recursive-move(p1a,p1b,c12,pallet)}
[{take(crane1,l1a,c11,c12,p1a)}, EL={take-and-put(...)}
]
[{put(crane1,l1b,c11,pallet,p1b)},
]
]
[{move-stack(p1a,p1b)},fill=white,label={[font=\small\sffamily]below:{do-nothing(p1a,p1b)}}
]
]
]
\end{forest}
\end{document}
solution with forest
:
\documentclass[border=10pt]{standalone}
\usepackage[edges]{forest}
\usetikzlibrary{shadows}
\begin{document}
\begin{forest}
for tree={draw, rounded corners,
fill = white,
inner xsep = 1mm,
inner ysep = 2mm,
drop shadow,
% style of tree (edges, distances, direction)
grow = south,
parent anchor = south,
child anchor = north,
edge = {draw, semithick, -stealth},
EL/.style = {edge label={node[midway, font=\small, inner sep=1pt, anchor=south east]{#1}},},
FB/.style = {fill=blue!30},
s sep = 3mm, % sibling distance
l sep = 12mm, % level distance
}
[{move-stack(p1a,q)}
[{move-topmost-container(p1a,p1b)}, name=p1,
EL={recursive-move(p1a,p1b,c11,c12)}
[{take(crane1,l1a,c11,c12,p1a)}, FB, name=p3,
EL={take-and-put(...)}
]
[{put(crane1,l1b,c11,pallet,p1b)}, FB, name=p4
]
]
[{move-stack(p1a,p1b)}, name=p2,
[{move-topmost-container(p1a,p1b)}, name=p5,
EL={recursive-move(p1a,p1b,c12,pallet)}
[{take(crane1,l1a,c11,c12,p1a)}, FB, name=p7,
EL={take-and-put(...)}
]
[{put(crane1,l1b,c11,pallet,p1b)}, FB, name=p8,
]
]
[{move-stack(p1a,p1b)}, name=p6,
label=below:{do-nothing(p1a,p1b)}
]
]
]
\foreach \x [evaluate=\x as \y using int(\x-1)] in {2,4,6,8}
{
\draw[gray, very thick, -stealth]
([shift={(-3mm,3mm)}] p\y.north) -- ([shift={(3mm,3mm)}] p\x.north);
}
\end{forest}
\end{document}