4

I'm trying to make a tree of a corporate structure starting at some owner, and ending with a single company. This means that all lines start at a single node, and all ends at a single node.

This thread helped me to where I am: LaTeX: how to make a horizontal tree that is closed at the end (forest), but I end up with lines through my nodes. As I will be doing this repetitively (many different corporate structures) I'm looking for a structural solution.

\documentclass{standalone}
\usepackage{forest}
\forestset{
  default preamble={
    for tree={rectangle, draw, text width = 2cm, grow=0 }
  }
}
\begin{document}
\begin{forest} 
    [Company 4, name =E0
        [Company 3
            [Company 2, name = E1]
        ]
        [Company 5, name = E2]
        [Company 8
            [Company 7, name=E3]
            [Company 10, name = E4]
        ]
    ]
    \node[draw] (EndNode) at ($(E3.east) + (2,0)$){Company 1};
    \foreach \num in {0,1,2,3, 4}{
        \draw (E\num.east) -- (EndNode.west);
    }
\end{forest}
\end{document}

Tree at this stage

Minor other issue on the side : how to center the text within these boxes?

  • Welcome! Can you edit your code so we can copy-paste-compile it? That's a lot more helpful than a fragment (albeit a pretty hefty fragment). What you want is not strictly a tree but a generic graph and, out-of-the-box, Forest only does trees. So some hackery is necessary. What do you mean by a 'structural solution? – cfr Aug 23 '17 at 16:10
5

This is a reasonably automatic solution. It changes the style of the edges, but I prefer squared edges here anyway. It is minimally tested, so let me know if it doesn't quite work as is. (I'm bound to have forgotten something.)

The tricky part is to connect the root node to the additional terminus. That takes a bit of trickery.

\documentclass[border=10pt]{standalone}
\usepackage[edges]{forest}
\tikzset{%
  company/.style={draw, text width = 2cm},
}
\forestset{%
  declare keylist register={terminus},
  terminus=,
  terminal/.style={
    tikz+={
      \node (terminal) [company, anchor=west] at ([xshift=2*\foresteoption{l sep}]current bounding box.east) {#1};
    },
    before drawing tree={
      split register={terminus}{,}{terminal connection},
    },
  },
  terminal connection/.style={
    tikz+={
      \draw (terminal.west) -- ++(-\foresteoption{fork sep},0pt) |- (#1.parent anchor)  ;
    },
  },
  default preamble={
    forked edges,
    for tree={
      company,
      grow=0,
      fit=band,
      parent anchor=children,
      child anchor=parent,
    },
    delay={
      if={>On>{!r.n children}{1}}{
        for n/.process={OSw+P?_lw2+n{n children}{isodd(#1)}{1}{0}{(#1+#2)/2}{insert after={[,coordinate, calign with current edge]}}},
      }{
        append={[, coordinate, calign with current]}
      },
    },
    before typesetting nodes={
      where n children=0{
        terminus/.option=name,
      }{},
    },
  },
}
\begin{document}
\begin{forest}
  terminal=Company 1,
  [Company 4
        [Company 3
            [Company 2]
        ]
        [Company 5]
        [Company 8
            [Company 7]
            [Company 10]
        ]
  ]
\end{forest}
\end{document}

closed Forest

The nice thing about separating the TikZ setting from the Forest configuration is that you can easily apply the same style to nodes in the tree and outside it, without needing to specify a special path for the key.

For example, to centre the text in nodes as desired, change the company style definition to

\tikzset{%
  company/.style={draw, text width = 2cm, text centered,
}

centred text

or, for something fancier, try

\usetikzlibrary{shadows.blur}
\tikzset{%
  company/.style={draw, text width = 2cm, text centered, rounded corners, font=\sffamily, top color=gray!5, bottom color=gray!15, blur shadow},
}

fancier style

  • bravo! (+1), i need more practice :-( – Zarko Aug 23 '17 at 17:59
3

enter image description here

do you liked? mwe:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\usepackage{forest}

\begin{document}
\forestset{
  default preamble={
    for tree={rectangle, draw, text width=22mm, inner sep=2mm,
              text centered,
              grow  = 0,
              s sep = 11mm,
              l sep = 7mm }
  }
}
\begin{forest}
    [Company 4, name =E0
        [Company 3
            [Company 2, name = E1]
        ]
        [Company 5, name = E2]
        [Company 8
            [Company 7, name=E3]
            [Company 10, name = E4]
        ]
    ]
    \node[draw, right=of E3.east |- E2] (EndNode) {Company 1};
    \foreach \num in {1,2,3, 4}{
        \draw (E\num.east) -- (EndNode.west);
                                }
    \draw (E0) edge [bend angle=20,bend right] (EndNode.west);
\end{forest}
\end{document}
  • Forest practise is paying off :-). – cfr Aug 23 '17 at 17:30
  • Thanks to the both of you! Looks good and is exactly what I was looking for. – Gijs Aug 24 '17 at 13:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.