迷失在森林里了?

迷失在森林里了?

我一直在修改著名的 Forest 示例:

如何在 tikz 中绘制层次图?

并学到了很多东西——我的 OverLeaf 项目位于:

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

我被几件事难住了——(a)最烦人的是,我连接第 2 级和第 1 级的线走在单个第 1 级节点的前面,而不是后面。(b)不那么烦人的是,我想让所有第 2 级和第 4 级框的宽度和高度相同。这似乎应该很简单,但我还没有找到方法。

欢迎提出任何建议。我还希望发布我的 Overleaf 文件的链接是可以接受的,而不是将所有代码粘贴到这里。但是,如果我错了,请告诉我,我会将其粘贴到这里。

谢谢,

韦恩

答案1

为了努力使森林法规从使用的起点变得更短,然而,可以为森林树编写更先进、更简洁的代码,正如你在回答中看到的那样成本加运费,比我的好多了

  • 部分基于第一版的优秀土拨鼠的回答(我太懒了,没有从背面复制操作码)
  • 对于节点使用预定义样式(其中定义矩形节点的最小宽度),现在从其他答案已知更好的解决方案......
  • 对于边缘我使用由定义的样式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}
    

在此处输入图片描述

答案2

如果你想要简洁的代码...请谨慎对待你的愿望...

这是改编自marmot 的回答它删除了不必要的代码并使用当前的 Forest 使代码更加简洁、高效。

\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}

层次化输出

答案3

更新:@cfr 提出了几条改进代码的重要建议,我尝试实施它们。非常感谢!

至于历史:有一些拼写错误,\makebo我刚刚把它改掉了,我对你提到的两个问题有建议。首先,我添加了(假设这些是相关级别,森林从 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}{},

使第 1 层和第 3 层的节点宽度相同。这样也可以避免你一遍又一遍地写同样的东西,比如Zarko 的回答

我的答案的一个关键部分是使最上面的连接复杂化(我不知道为什么拼写检查器会抱怨“复杂化”,这是物理学中的标准术语;-)为了解决第一个问题,请参阅代码。我基本上区分了 3 种情况而不是 2 种情况。而且,感谢 @cfr,我改用了一种让你晚上睡得更好的语法:没有\noexpand黑客,只有简单的森林代码,就像在森林库边缘中一样,我将其用作基础(但这里不需要加载)。对于左边的两个连接,我从东边开始,中间的两个从南边开始,剩下的两个从东边开始。

\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}

在此处输入图片描述

相关内容