10

I'm trying to draw a tree with double arrows. To that end, I have combined the file system tree from texample.net with the basic idea of double arrows a la chef:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{trees,decorations.markings}
\begin{document}
\tikzstyle{every node}=[draw=black,thick,anchor=west]
\tikzstyle{selected}=[draw=red,fill=red!30]
\tikzstyle{optional}=[dashed,fill=gray!50]

\newcommand{\arrowcolor}{red}
\newcommand{\arrowfillcolor}{white}

\begin{tikzpicture}[%
  rightarr/.pic={\path[pic actions] (-0.4,0)--(-1,-0.35)--(-1,.35)--cycle;},
  grow via three points={one child at (0.5,-0.7) and
  two children at (0.5,-0.7) and (0.5,-1.4)},
  edge from parent path={(\tikzparentnode.south) |- (\tikzchildnode.west)},
  edge from parent/.style={
    decoration={
      markings,
      mark=at position 1 with{\coordinate (0, 0) pic[\arrowcolor,fill=\arrowfillcolor,scale=0.22]{rightarr};},
    },
    draw = \arrowcolor,
    line width = 3pt,
    shorten >= 5.7pt,
    shorten <= 2pt,
    postaction = {decorate},
    postaction = {draw,line width=1.4pt, white},
  }]
  \node {texmf}
    child { node {doc}}      
    child { node {fonts}}
    child { node {source}}
    child { node [selected] {tex}
      child { node {generic}}
      child { node [optional] {latex}}
      child { node {plain}}
    }
    child [missing] {}                       
    child [missing] {}                       
    child [missing] {}                       
    child { node {texdoc}};
\end{tikzpicture}
\end{document}

This looks like so:

enter image description here

I don't understand why the vertical arrow lines run straight through at the junctions. Shouldn't the "draw" postaction replay the exact path and draw one inner, 1.4pt wide, white connected surface over the existing path?

Jan
  • 221
  • 3
    They probably do, but the first edge from parent from texmf to doc is overwritten by the edge from texmf to fonts and so on. – Ignasi Apr 26 '16 at 15:07

1 Answers1

7

Yo! Ignasi's comment was eye-opening: "The path" is in fact many paths, each of them starting from top to its respective child. Seems obvious if you think about it. Each of them nicely a la chef, but each of them also ruining the one drawn before. Cool, so here's my next take on the problem, throwing \pgfonlayer into the mix, as borrowed from this post on layers:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{trees,decorations.markings}
\begin{document}
\tikzstyle{every node}=[draw=black,thick,anchor=west]
\tikzstyle{selected}=[draw=red,fill=red!30]
\tikzstyle{optional}=[dashed,fill=gray!50]

\newcommand{\arrowcolor}{red}
\newcommand{\arrowfillcolor}{white}

\pgfdeclarelayer{front}
\pgfsetlayers{main,front}

\makeatletter
\pgfkeys{%
  /tikz/path on layer/.code={
    \def\tikz@path@do@at@end{\endpgfonlayer\endgroup\tikz@path@do@at@end}%
    \pgfonlayer{#1}\begingroup%
  }%
}
\makeatother

\begin{tikzpicture}[%
  rightarr/.pic={\path[pic actions] (-0.4,0)--(-1,-0.35)--(-1,.35)--cycle;},
  grow via three points={one child at (0.5,-0.7) and
  two children at (0.5,-0.7) and (0.5,-1.4)},
  edge from parent path={(\tikzparentnode.south) |- (\tikzchildnode.west)},
  edge from parent/.style={
    decoration={
      markings,
      mark=at position 1 with{\coordinate (0, 0) pic[\arrowcolor,fill=\arrowfillcolor,scale=0.22]{rightarr};},
    },
    draw = \arrowcolor,
    line width = 3pt,
    shorten >= 5.7pt,
    shorten <= 2pt,
    postaction = {decorate},
    postaction = {draw,line width=1.4pt,white,path on layer=front},
  }]
  \node {texmf}
    child { node {doc}}     
    child { node {fonts}}
    child { node {source}}
    child { node [selected] {tex}
      child { node {generic}}
      child { node [optional] {latex}}
      child { node {plain}}
    }
    child [missing] {}                      
    child [missing] {}                      
    child [missing] {}                      
    child { node {texdoc}};
\end{tikzpicture}
\end{document}

Which does the trick for me:

enter image description here

Thanks!

Jan
  • 221
  • You could just use the backgrounds library .... – cfr Apr 26 '16 at 21:39
  • @cfr: could you elaborate? I had considered this method of using the backgrounds library, but had no idea of how to put main action and postaction into different scopes. Which (I think) would be necessary. – Jan Apr 27 '16 at 08:31
  • I was mainly thinking about the fact that it defines an extra layer and on layer etc. out-of-the-box. – cfr Apr 28 '16 at 02:31
  • Yes, I know. My problem is that I don't know how those could be possibly applied. According to the pgf manual, on layer only works as a {scope} option. I have no clue how to squeeze a {scope} into the postaction – Jan Apr 28 '16 at 09:00
  • You may be right about that. You might want to rename the on layer style in case you end up wanting to use backgrounds for pictures in the same document, in that case and/or just to avoid confusion. But you may well need the different definition. Sorry for the noise. – cfr Apr 28 '16 at 13:41
  • 1
    You're right, done that. – Jan Apr 28 '16 at 16:16
  • Neat! Sorry I can't upvote again ;). – cfr Apr 28 '16 at 17:43