5

I have been modifying the famous Forest example at:

How to draw a hierarchical diagram in tikz?

and learning a lot -- my OverLeaf project is at:

https://www.overleaf.com/17438108ktrzgqwkpgtz#/66278887/

I am stuck on several things -- (a) most annoying, my lines connecting level 2 to level 1 go IN-FRONT-OF and not behind of the single level 1 node. (b) less annoying, I would like to make all level 2 and level 4 boxes the same width and height. Seems like it should be very simple to do but I haven't found the path yet.

Any and all suggestions are welcomed. I am also hoping that posting the link to my Overleaf files will be acceptable as opposed to pasting all of that code into here. However, if I am wrong about that, let me know and I will paste it here.

Thanks,

Wayne

7

as exercise with effort to make forest code more shorter from used starting point, however it is possible to write even more advance and concise code for forest tree, as you can see in answer of cfr, which is far better from mine:

  • partially based on the first version of the excellent marmot's answer (i was to lazy to copy op code from overleaf)
  • for nodes are used predefined styles (where is defined minimum width of rectangle nodes), now from from other answer is known better solution ...
  • for edges i use style defined by edge={...}

    \documentclass[border=5pt]{standalone}
    
    \title{The Forest Project}
    
    \usepackage{forest}
    \usetikzlibrary{arrows.meta, calc, shadows, shapes.geometric}
    
    \colorlet{mygreen}{green!75!black}
    \colorlet{col1in}{red!30}
    \colorlet{col1out}{red!40}
    \colorlet{col2in}{mygreen!40}
    \colorlet{col2out}{mygreen!50}
    %\colorlet{col3in}{blue!30}  % not used
    %\colorlet{col3out}{blue!40}
    %\colorlet{col4in}{mygreen!20}
    %\colorlet{col4out}{mygreen!30}
    \colorlet{col5in}{blue!10}
    \colorlet{col5out}{blue!20}
    %\colorlet{col6in}{blue!20}
    %\colorlet{col6out}{blue!30}
    %\colorlet{col7out}{orange}
    %\colorlet{col7in}{orange!50}
    \colorlet{col8out}{orange!40}
    \colorlet{col8in}{orange!20}
    \colorlet{linecol}{blue!60}
    
    \begin{document}
    \begin{forest}
      ellip/.append style={ellipse, inner color=col1in, outer color=col1out},
       rect/.append style={rectangle, rounded corners=2pt, inner color=col2in, outer color=col2out, minimum width=2.7cm},
       circ/.append style={circle, inner color=col8in, outer color=col8out},
       diam/.append style={diamond, inner color=col5in, outer color=col5out},
      for tree={
          font=\sffamily\bfseries,
          line width=2pt,
          draw=linecol, % adds the border to all nodes
          align=center,
          child anchor=north,
          parent anchor=south,
          drop shadow,
          l sep+=12.5pt,
          s sep=0.1cm,
          edge={color=linecol, rounded corners=5pt, -{Stealth[length=10pt]}, line width=1pt},
          edge path={
            \noexpand\path[\forestoption{edge}]
              (!u.parent anchor) -- +(0,-10pt) -|
              (.child anchor)\forestoption{edge label};
            },
          where level={1}{
            if n<={2}{
              edge path={
                \noexpand\path[\forestoption{edge}]
                  (!u.west) -| (.child anchor)\forestoption{edge label};
                }
            }{if n<={4}{
              edge path={
                \noexpand\path[\forestoption{edge}]
                  (!u.south) -| (.child anchor)\forestoption{edge label};
                }
            }{
              edge path={
                \noexpand\path[\forestoption{edge}]
                  (!u.east) -| (.child anchor)\forestoption{edge label};
                },
            }}
          }{},
      }
     [Full Data Set, ellip
        [Middle, rect
            [CFA, circ
                [Middle, rect
                    [LR, diam]
                ]
            ]
         ]
        [Bottom Support, rect
            [CFA, circ
                [Bottom Support, rect
                    [LR, diam]
                ]
            ]
         ]
         [Bottom Carry, rect
            [CFA, circ
                [Bottom Carry, rect
                    [LR, diam]
                ]
            ]
         ]
         [Bottom Other, rect
            [CFA, circ
                [Bottom Other, rect
                    [LR, diam]
                ]
            ]
         ]
          [Top, rect
            [CFA, circ
                [Top, rect
                    [LR, diam]
                ]
            ]
         ]
         [Jungle, rect
            [CFA, circ
                [Jungle, rect
                    [LR, diam]
                ]
            ]
         ]
      ]
    \end{forest}
    \end{document}
    

enter image description here

  • Just to point out that I don't think "i was to lazy to copy op code from overleaf" is appropriate. My answer already solved both of the issues by the OP and the only thing you did was adding styles (which however IMHO made the code less flexible). – user121799 Jun 30 '18 at 17:48
7

If you desire concise code ... be careful what you wish for ...

This is an adaption of marmot's answer which removes unnecessary code and uses current Forest to make the code both more concise and more efficient.

\documentclass[border=12pt]{standalone}
\usepackage{forest}
\usetikzlibrary{arrows.meta, shadows.blur}
\colorlet{mygreen}{green!75!black}
\colorlet{col1in}{red!30}
\colorlet{col1out}{red!40}
\colorlet{col2in}{mygreen!40}
\colorlet{col2out}{mygreen!50}
\colorlet{col5in}{blue!10}
\colorlet{col5out}{blue!20}
\colorlet{col8out}{orange!40}
\colorlet{col8in}{orange!20}
\colorlet{linecol}{blue!60}
\tikzset{% no point in making this a forest style
  rect/.append style={rounded corners=2pt, minimum width=2.7cm, inner color=col2in, outer color=col2out},
} 
\forestset{
  declare toks={branch from}{parent anchor}
}
\begin{document}
\begin{forest}
  for tree={
    font=\sffamily\bfseries,
    line width=2pt,
    draw=linecol,
    align=center,
    child anchor=parent,
    parent anchor=children,
    blur shadow,
    l sep'+=12.5pt,
    s sep'=0.1cm,
    edge+={linecol, rounded corners=5pt, -{Stealth[length=10pt]}, line width=1pt},
    if={ > Ow+P {level}{isodd(#1)}}{rect}{
      if level=2{circle, inner color=col8in, outer color=col8out}{
        if level=4{diamond, inner color=col5in, outer color=col5out}{},
      },
    },
  },
  for nodewalk={1,n}{branch from=west},
  for nodewalk={l,p}{branch from=east},
  for children={edge path'/.process={Ow{branch from}{(!u.#1) -| (.child anchor)}}}
  [Full Data Set, ellipse, inner color=col1in, outer color=col1out, 
    [Middle, 
    [CFA
            [Middle
                [LR]
            ]
        ]
     ]
    [Bottom Support
        [CFA
            [Bottom Support
                [LR]
            ]
        ]
     ]
     [Bottom Carry
        [CFA
            [Bottom Carry
                [LR]
            ]
        ]
     ]
     [Bottom Other
        [CFA
            [Bottom Other
                [LR]
            ]
        ]
     ]
      [Top
        [CFA
            [Top
                [LR]
            ]
        ]
     ]
     [Jungle
        [CFA
            [Jungle
                [LR]
            ]
        ]
     ]
  ]
\end{forest}
\end{document}

hierarchical output

5

UPDATE: @cfr made several crucial suggestions to improve the code, and I tried to implement them. Big thanks!

As for the history: there was some typo, \makebo, I just got rid of it, and I have proposals for the two issues you mention. First, I added (assuming that these were the relevant levels, forest starts counting at 0)

 if level={1}{minimum width=2.7cm,rect, inner color=col2in, outer color=col2out}{},
 if level={2}{circle, inner color=col8in, outer color=col8out}{},
 if level={3}{minimum width=2.7cm,rect, inner color=col2in, outer color=col2out}{},
 if level={4}{diamond, inner color=col5in, outer color=col5out}{},

to make the nodes at levels 1 and 3 the same width. This also spares you from writing the same thing over and over, as in Zarko's answer.

One crucial part of my answer was and is to complexify (I don't know why the spell-checker complains about "complexify", this is a standard term in physics;-) the uppermost connections in order to cure the first issue, please see the code. I essentially discriminate between 3 rather than 2 cases. And, thanks to @cfr, I switched to a syntax that let's you sleep better at night: no \noexpand hackery, just plain forest code, just like in the forest library edges, which I used as a basis (but is not necessary to load here). For the left two connections I start east, the middle two south and the remaining two east.

\documentclass[border=5pt]{standalone}

\title{The Forest Project}

\usepackage{forest}
\usetikzlibrary{arrows.meta, shapes.geometric, calc, shadows.blur}

\forestset{
  declare dimen={crazy sep}{-10pt},
  crazy edge'/.style={
    edge path'={[color=linecol, rounded corners=5pt, -{Stealth[length=10pt]}, line width=1pt]
    (!u.parent anchor) -- +(0,\forestoption{crazy sep}) -|  (.child anchor)},
  },
  crazy edge/.style={
    on invalid={fake}{!parent.parent anchor=children},
    child anchor=parent,
    crazy edge',
  },
  crazy edges/.style={for nodewalk={#1}{crazy edge}},
  crazy edges/.default=tree,
}

\colorlet{mygreen}{green!75!black}
\colorlet{col1in}{red!30}
\colorlet{col1out}{red!40}
\colorlet{col2in}{mygreen!40}
\colorlet{col2out}{mygreen!50}
\colorlet{col3in}{blue!30}
\colorlet{col3out}{blue!40}
\colorlet{col4in}{mygreen!20}
\colorlet{col4out}{mygreen!30}
\colorlet{col5in}{blue!10}
\colorlet{col5out}{blue!20}
\colorlet{col6in}{blue!20}
\colorlet{col6out}{blue!30}
\colorlet{col7out}{orange}
\colorlet{col7in}{orange!50}
\colorlet{col8out}{orange!40}
\colorlet{col8in}{orange!20}
\colorlet{linecol}{blue!60}

\begin{document}
\pgfkeys{/forest,
 rect/.append style={rectangle, rounded corners=2pt, inner color=col6in, outer color=col6out},
 ellip/.append style={ellipse, inner color=col5in, outer color=col5out},
 orect/.append style={rect, font=\sffamily\bfseries\LARGE, text width=325pt, text centered, minimum height=10pt, outer color=col7out, inner color=col7in},
 oellip/.append style={ellip, inner color=col8in, outer color=col8out, font=\sffamily\bfseries\large, text centered},
} 

\begin{forest}
  for tree={
      font=\sffamily\bfseries,
      line width=2pt,
      draw=linecol, % adds the border to all boxes
      align=center,
      child anchor=north,
      parent anchor=south,
      blur shadow,
      l sep+=12.5pt,
      s sep=0.1cm,
      crazy edges,
      if level={1}{minimum width=2.7cm,rect, inner color=col2in, outer color=col2out}{},
      if level={2}{circle, inner color=col8in, outer color=col8out}{},
      if level={3}{minimum width=2.7cm,rect, inner color=col2in, outer color=col2out}{},
      if level={4}{diamond, inner color=col5in, outer color=col5out}{},
      if level={1}{
        if n<={2}{
          edge path'={
            [color=linecol, rounded corners=5pt, -{Stealth[length=10pt]}, line width=1pt]
              (!u.west) -| (.child anchor)
            }
        }{if n<={4}{
          edge path'={
            [color=linecol, rounded corners=5pt, -{Stealth[length=10pt]}, line width=1pt]
              (!u.south) -| (.child anchor)
            }
        }{
          edge path'={
            [color=linecol, rounded corners=5pt, -{Stealth[length=10pt]}, line width=1pt]
              (!u.east) -| (.child anchor)
            },
        }}
      }{},
  }
 [Full Data Set, ellipse, inner color=col1in, outer color=col1out
    [Middle, 
        [CFA
            [Middle
                [LR]
            ]
        ]
     ]
    [Bottom Support
        [CFA
            [Bottom Support
                [LR]
            ]
        ]
     ]
     [Bottom Carry
        [CFA
            [Bottom Carry
                [LR]
            ]
        ]
     ]
     [Bottom Other
        [CFA
            [Bottom Other
                [LR]
            ]
        ]
     ]
      [Top
        [CFA
            [Top
                [LR]
            ]
        ]
     ]
     [Jungle
        [CFA
            [Jungle
                [LR]
            ]
        ]
     ]
  ]
\end{forest}
\end{document}

enter image description here

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.