5

Is it possible to avoid hardcoding the \node position in the below MWE and apply horisontal offset of the Forest node to the TikZ node it links to?

The goal is to put the green nodes as close as possible to right above the linked Forest node, but at the same time try not to overlap other Forest nodes. The vertical position will have to be hardcoded.

\documentclass{standalone}
\usepackage{forest}

\begin{document}
\begin{forest} 
for tree={
    draw=black, align=center, l sep=4ex, parent anchor=south, child anchor=north,
    node options={font=\footnotesize, minimum width=14em, minimum height=10ex},
    edge path={
        \noexpand\path[\forestoption{edge}]
        (!u.parent anchor) -- +(0,-2ex) -| (.child anchor)\forestoption{edge label};
    }
}
[Parent
    [SubParent
        [Child1
            [Child11]
            [Child12,name=Child12]
        ]
        [Child2
            [Child21]
            [Child22]
            [Child23,name=Child23]
        ]
        [Child3
            [Child31]
            [Child32]
        ]
    ]
]
%
\tikzset{every node/.style={font=\footnotesize, draw=green, minimum width=14em, minimum height=10ex}}
%
\node[anchor=south,draw=green](Second1)  at (-30em, -15ex) {Second Parent 1}[];
\node[anchor=south,draw=green](Second2) at (15em, -15ex) {Second Parent 2}[];
%
\draw[->,dotted] (Child12) to[out=north east,in=south] (Second1);
\draw[->,dotted] (Child23) to[out=north east,in=south] (Second2);
\end{forest}
\end{document}
ajeh
  • 2,572
  • Yes, \usetikzlibrary{positioning}, and instead of at (...) add the key above=3cm of Child12 to the node options. – JLDiaz Jun 11 '14 at 21:26

2 Answers2

5

You don't actually need the positioning library for this although that is one option. At least, if I've understood what you want to do correctly:

\documentclass{standalone}
\usepackage{forest}

\begin{document}
  \begin{forest}
    for tree={
      draw=black, align=center, l sep=4ex, parent anchor=south, child anchor=north,
      node options={font=\footnotesize, minimum width=14em, minimum height=10ex},
      edge path={
        \noexpand\path[\forestoption{edge}]
        (!u.parent anchor) -- +(0,-2ex) -| (.child anchor)\forestoption{edge label};
      }
    }
    [Parent
    [SubParent
    [Child1
    [Child11]
    [Child12,name=Child12]
    ]
    [Child2
    [Child21]
    [Child22]
    [Child23,name=Child23]
    ]
    [Child3
    [Child31]
    [Child32]
    ]
    ]
    ]
    %
    \tikzset{every node/.style={font=\footnotesize, draw=green, minimum width=14em, minimum height=10ex}}
    %
    \node[anchor=south,draw=green](Second1)  at (Child12 |- 0,-15ex) {Second Parent 1}[];
    \node[anchor=south,draw=green](Second2) at (Child23 |- 0,-15ex) {Second Parent 2}[];
    %
    \draw[->,dotted] (Child12) to[out=north east,in=south] (Second1);
    \draw[->,dotted] (Child23) to[out=north east,in=south] (Second2);
  \end{forest}
\end{document}

Non-hardcoded second parents

cfr
  • 198,882
  • Would you explain the (Child12 |- 0,-15ex) syntax please? It's something I don't have a good grasp on. – Herr K. Jun 11 '14 at 23:19
  • 2
    @KevinC As I understand it, it is just taking the x-coordinate from (Child12) and the y-coordinate from (0,-15ex). This is like drawing a vertical line through (Child12) and a horizontal line through (0,-15ex) and placing the node at the intersection of the two lines. (| for vertical; - for horizontal.) – cfr Jun 12 '14 at 00:08
  • I see. Thanks for the explanation :) – Herr K. Jun 12 '14 at 01:42
  • @cfr I accepted and upped this answer as it is excellent, but is there a possibility to avoid overlapping the forest nodes? – ajeh Jun 12 '14 at 13:11
  • @ajeh I'm confused. Which nodes overlap? – cfr Jun 12 '14 at 22:48
  • @cfr They would overlap SubParent if drawn for Child22. Can there be a conditional that if node overlaps a forest node, than shift? – ajeh Jun 13 '14 at 12:59
  • @ajeh Oh, I see. I'm sorry but I have no idea how to do that (or if it is possible). I think the best thing would be to prepare a MWE in which that happens and to post a new question asking specifically about that, linking back to this one. That way, it should get some attention. Also, maybe think about how it should be shifted if you want the structure of the main tree to be unaffected. – cfr Jun 13 '14 at 22:46
1

Another way is to use the yshift key in setting coordinates. Since your green box Second1 is directly above the Child12 node, you can use

\draw(Child12) to ([yshift=25ex]Child12) node{Second Parent 1};

to draw a line from Child12 to a coordinate 25ex units above it. Including the node operation in the same path allows you to place a node at the latter coordinate. Setting the appropriate styles for draw and node is easy from here on.

Code

\documentclass{standalone}
\usepackage{forest}

\begin{document}
\begin{forest} 
for tree={
    draw=black, align=center, l sep=4ex, parent anchor=south, child anchor=north,
    node options={font=\footnotesize, minimum width=14em, minimum height=10ex},
    edge path={
        \noexpand\path[\forestoption{edge}]
        (!u.parent anchor) -- +(0,-2ex) -| (.child anchor)\forestoption{edge label};
    }
}
[Parent
    [SubParent
        [Child1
            [Child11]
            [Child12,name=Child12]
        ]
        [Child2
            [Child21]
            [Child22]
            [Child23,name=Child23]
        ]
        [Child3
            [Child31]
            [Child32]
        ]
    ]
]
%
\tikzset{every node/.style={font=\footnotesize, draw=green, solid, minimum width=14em, minimum height=10ex}}
\draw[->,dotted] (Child12) to[out=north east,in=south] ([yshift=25ex]Child12) 
  node[anchor=south]{Second Parent 1};
\draw[->,dotted] (Child23) to[out=north east,in=south] ([yshift=25ex]Child23) 
  node[anchor=south]{Second Parent 2};
\end{forest}
\end{document}

Output

enter image description here

Herr K.
  • 17,946
  • 4
  • 61
  • 118