[Tex/LaTex] How to make TikZ draw right child before left

colortikz-treestrees

I'm trying to make a tree with two different colors of edges, black and gray. This is my code:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning,automata}
\definecolor{light-gray}{gray}{0.6}
\begin{document}
\begin{tikzpicture}[line width=.1cm,shorten >=0pt,auto,on grid=false, every state/.style={minimum size=0pt}, level distance=2.0cm, level 1/.style={sibling distance=2cm}, level 2/.style={sibling distance=1cm}, level 3/.style={sibling distance=.5cm}]
\tikzstyle{every node}=[font=\tiny , circle, outer sep=0pt, inner sep=0pt]
\node[] (S) {}
  child {node[state] (S1) {}
     child {node[state] (S11) {} edge from parent[light-gray] }
     child {node[state] (S12) {}}}
  child {node[state] (S2) {}
     child {node[state] (S21) {}}
     child {node[state] (S22) {} edge from parent[light-gray] }};
\end{tikzpicture}
\end{document}

You can see the output below:

TikZ Tree with overlapping edges

The problem is, I want the black lines to be on top of the gray lines. This is happening in the left subtree, because the left edge is drawn before the right one. However, this is not happening in the right subtree. I want the right subtree to be a mirror image of the left subtree. This is what it should look like:

Desired TikZ Tree

I tried changing the order of the gray and black nodes and trying to specify the direction of the children, like this:

     child[right] {node[state] (S22) {} edge from parent[light-gray] }
     child[left] {node[state] (S21) {}}};

and this:

     child {node[state, right] (S22) {} edge from parent[light-gray] }
     child {node[state, left] (S21) {}}};

but it doesn't work!

Any help would be appreciated!

Best Answer

Here are two quick fixes:

Code A introduces a fix for the edge to parent path operator that uses background edge as a switch to enclose the path in a pgfonlayer environment.

Code B uses \tikz@swap@growth which is used by grow' to swap the directions. As in your idea, you need to switch the children, too (this won’t work if you have alternating black/gray lines in a row, they are still drawn after each other).

Code A

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning,automata,backgrounds}
\definecolor{light-gray}{gray}{0.6}
\makeatletter
\def\tikz@@edgetoparent[#1]{%
  \let\tikz@edge@to@parent@needed=\pgfutil@empty%
  \tikz@node@is@a@labeltrue%
  \begingroup
    \tikzset{edge from parent,#1}%
    \ifpgf@edge@background
      \edef\pgf@next{\noexpand\edef\noexpand\pgf@linewidth{\the\pgflinewidth}\noexpand\pgfutil@firstoftwo}
    \else
      \def\pgf@next{\pgfutil@secondoftwo}
    \fi
    \pgfmath@smuggleone\pgf@next
  \endgroup
  \pgf@next{\pgfonlayer{background}\path[style=edge from parent,line width/.expanded=\pgf@linewidth,#1] \tikz@edge@to@parent@path;\endpgfonlayer\tikz@scan@next@command}%
  {\tikz@scan@next@command [style=edge from parent,#1] \tikz@edge@to@parent@path}%
}
\newif\ifpgf@edge@background
\tikzset{background edge/.is if=pgf@edge@background}
\makeatother

\begin{document}
\begin{tikzpicture}[line width=.1cm,shorten >=0pt,auto,on grid=false, every state/.style={minimum size=0pt}, level distance=2.0cm, level 1/.style={sibling distance=2cm}, level 2/.style={sibling distance=1cm}, level 3/.style={sibling distance=.5cm}]
\tikzstyle{every node}=[font=\tiny , circle, outer sep=0pt, inner sep=0pt]
\node[] (S) {} 
  child {node[state] (S1) {}
     child {node[state] (S11) {} edge from parent[background edge,light-gray] }
     child {node[state] (S12) {}}
  }
  child {node[state] (S2) {}
     child {node[state] (S21) {}}
     child {node[state] (S22) {} edge from parent[background edge,light-gray] }
  };
\end{tikzpicture}
\end{document}

Code B

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning,automata}
\definecolor{light-gray}{gray}{0.6}
\makeatletter
\tikzset{swap grow direction/.style={every child/.append code=\tikz@swap@growth}}
\makeatother
\begin{document}
\begin{tikzpicture}[line width=.1cm,shorten >=0pt,auto,on grid=false, every state/.style={minimum size=0pt}, level distance=2.0cm, level 1/.style={sibling distance=2cm}, level 2/.style={sibling distance=1cm}, level 3/.style={sibling distance=.5cm}]
\tikzstyle{every node}=[font=\tiny , circle, outer sep=0pt, inner sep=0pt]
\node[] (S) {}
  child {node[state] (S1) {}
     child {node[state] (S11) {} edge from parent[light-gray] }
     child {node[state] (S12) {}}}
  child[swap grow direction] {node[state] (S2) {}
     child {node[state] (S22) {} edge from parent[light-gray] }
     child {node[state] (S21) {}}};
\end{tikzpicture}
\end{document}

Output

enter image description here

Related Question