6

This is a followup to the question at Is it possible to change the edges for some tree level using forest package? for lack of a followup question option.

The modified MWE below does almost 100% of what I was looking for, but there is still minor tweaking to do in the anchoring of the last level's parent and corresponding edge path.

Why does the edge path work fine in the first forest which grows east, but not in the last level of the second forest which grows east as well? Should the edge path of the last level in the second forest work exactly the same?

Also, I tried to push the child nodes down (after creating the screen shot!), but the s option seemed to only work for the bottom child node N1C2 but not for the top node N1C1.

\documentclass{article}
\usepackage{forest}

\begin{document}
\begin{forest} 
for tree={
    draw=black,align=center,l sep=4em,grow=east,parent anchor=east,child anchor=west,
    where n children=0{draw=red,for parent={calign=last}}{},
    edge path={
        \noexpand\path[\forestoption{edge}]
      (!u.parent anchor) -- +(15pt,0) |-        % used with east-west growth
      (.child anchor)\forestoption{edge label};
    }   
}
[P\\1\\2
  [N1\\1\\2,name=_N1
    [N1C1\\1\\2]
    [N1C2,name=_N2]
  ]
  [N2
    [N2C1]
    [N2C2]
  ]
]
\end{forest}

\begin{forest} 
for tree={
    draw=black,align=center,l sep=4ex,
    where n children=0{
        child anchor=west,
        edge path={
            \noexpand\path[\forestoption{edge}]
            (!u.parent anchor) -- +(15pt,0) |-      % used with east-west growth
            (.child anchor)\forestoption{edge label};
        },
        draw=red,for parent={
            parent anchor=east,
            grow'=east,calign=first,}}{},
  edge path={
    \noexpand\path[\forestoption{edge}]
      (!u.parent anchor) -- +(0,-25pt) -|       % used with normal north-south growth
      (.child anchor)\forestoption{edge label};
  }
}
[P\\1\\2
  [N1\\1\\2,name=_N1
    [N1C1\\1\\2,s=-8ex]
    [N1C2,name=_N2,s=-16ex]
  ]
  [N2
    [N2C1]
    [N2C2]
  ]
]\end{forest}

\end{document}

enter image description here

UPDATE:

After more tweaking the code below gets within hair width of the ideal solution. Just a note: the top 2 levels cannot be hardcoded, there can be any number of them, and the issues in this question apply to the last level in red only.

The only 2 remaining issues are how to push the red nodes down to start below their parents?

\documentclass{article}
\usepackage{forest}

\begin{document}
\begin{forest} 
for tree={
    draw=black,align=center,l sep=4ex,parent anchor=south,child anchor=north,
    edge path={
        \noexpand\path[\forestoption{edge}]
        (!u.parent anchor) -- +(0,-2ex) -|      % used with normal north-south growth
        (.child anchor)\forestoption{edge label};
    },
    where n children=0{
        child anchor=west,node options={minimum width=22em}, % to make nodes same width
        edge path={
            \noexpand\path[\forestoption{edge}]
            (!u.parent anchor) -- +(-1em,0) |-      % used with east-west growth
            (.child anchor)\forestoption{edge label};
        },
        draw=red,for parent={
            parent anchor=south,l sep=1em,
            grow'=east,calign=child edge%first
        }
    }{}
}
[P0\\1\\2
  [N111111111111111111111\\1\\2,name=N1
    [N1C1\\1\\2,name=N1C1]
    [N1C2\\1\\2,name=N1C2]
  ]
  [N2222222222\\1\\2,name=N2
    [N2C1\\1\\2,name=N2C1]
    [N2C2\\1\\2,name=N2C2]
  ]
  [N3333333333333\\1\\2,name=N3
    [N3C1.............\\1\\2,name=N3C1]
    [N3C2....\\1\\2,name=N3C2]
    [N3C3........\\1\\2,name=N3C3]
  ]
]
\end{forest}
\end{document}

enter image description here

1 Answer 1

7

You could use the text width (or minimum width) keys at any particular level to guarantee that the nodes at that level will have constant width; to push the children down, the simplest is to use phantom nodes.

\documentclass[border=3pt]{standalone}
\usepackage{forest}

\begin{document}
\begin{forest} 
for tree={
    draw=black,align=center,l sep=4ex,parent anchor=south,child anchor=north,
    edge path={
        \noexpand\path[\forestoption{edge}]
        (!u.parent anchor) -- +(0,-2ex) -|      % used with normal north-south growth
        (.child anchor)\forestoption{edge label};
    },
    where n children=0{
        child anchor=west,
        text width=1.5cm,
        edge path={
            \noexpand\path[\forestoption{edge}]
            (!u.parent anchor)  |-      % used with east-west growth
            (.child anchor)\forestoption{edge label};
        },
        draw=red,for parent={
            parent anchor=south,l sep=1em,
            grow'=east,calign=child edge%first
        }
    }{}
}
[P0\\1\\2
  [N111111111111111111111\\1\\2,name=N1
    [,phantom]
    [N1C1\\1\\2,name=N1C1]
    [N1C2\\1\\2,name=N1C2]
    [N1C3\\1\\2,name=N1C3]
  ]
  [N2222222222\\1\\2,name=N2
    [,phantom]
    [N2C1\\1\\2,name=N2C1]
    [N2C2\\1\\2,name=N2C2]
  ]
  [N3333333333333\\1\\2,name=N3
    [,phantom]
    [N3C1.............\\1\\2,name=N3C1]
    [N3C2....\\1\\2,name=N3C2]
    [N3C3........\\1\\2,name=N3C3]
  ]
]
\end{forest}
\end{document}

enter image description here

Or, using the for children (respectively, for descendants) key for just a node to affect only its children ((respectively, its descendants) and not a whole level:

\documentclass[border=3pt]{standalone}
\usepackage{forest}

\begin{document}
\begin{forest} 
for tree={
    draw=black,align=center,l sep=4ex,parent anchor=south,child anchor=north,
    edge path={
        \noexpand\path[\forestoption{edge}]
        (!u.parent anchor) -- +(0,-2ex) -|      % used with normal north-south growth
        (.child anchor)\forestoption{edge label};
    },
    where n children=0{
        child anchor=west,
        edge path={
            \noexpand\path[\forestoption{edge}]
            (!u.parent anchor)  |-      % used with east-west growth
            (.child anchor)\forestoption{edge label};
        },
        draw=red,for parent={
            parent anchor=south,l sep=1em,
            grow'=east,calign=child edge%first
        }
    }{}
}
[P0\\1\\2
  [N111111111111111111111\\1\\2,name=N1
    [,phantom]
    [N1C1\\1\\2,name=N1C1]
    [N1C2\\1\\2,name=N1C2]
    [N1C3\\1\\2,name=N1C3]
  ]
  [N2222222222\\1\\2,name=N2
    [,phantom]
    [N2C1\\1\\2,name=N2C1]
    [N2C2\\1\\2,name=N2C2]
  ]
  [N3333333333333\\1\\2,name=N3,for children={text width=2.5cm}
    [,phantom]
    [N3C1.............\\1\\2,name=N3C1]
    [N3C2....\\1\\2,name=N3C2]
    [N3C3........\\1\\2,name=N3C3]
  ]
]
\end{forest}
\end{document}

enter image description here

3
  • Thank you! This almost what I need, and I was going to modify the question moments ago as I found a similar solution. The edited question is almost 100%, very close, with only one issure remaining: need to push the red nodes down to start below their parents!
    – ajeh
    Jun 6, 2014 at 18:48
  • 1
    @ajeh please see my updated answer. Jun 6, 2014 at 19:19
  • You've added phantom nodes! This is exactly what was needed, plus it is going to solve another problem I did not mention: if the level 2 had a node with no children, it would have been considered same as the red nodes and messed the whole rendering. I was looking for what to add to it and phantom is exactly that!
    – ajeh
    Jun 6, 2014 at 19:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .