tikz/forest 中的层次结构图-级别选项

tikz/forest 中的层次结构图-级别选项

基于这个层次图在 tikz 中使用 forest 包,我想要一个修改后的版本。目前我有

\documentclass[tikz,border=10pt]{standalone}
\usepackage{verbatim}
\usepackage{forest}

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

% colors
\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=1pt,
      draw=linecol,
      ellip,
      align=center,
            child anchor=north,
      parent anchor=south,
            drop shadow,
            l sep+=12.5pt,
            edge path={
        \noexpand\path[color=linecol, rounded corners=5pt,
          >={Stealth[length=10pt]}, line width=1pt, ->, \forestoption{edge}]
          (!u.parent anchor) -- +(0,-5pt) -|
          (.child anchor)\forestoption{edge label};
        },
            where level={3}{tier=tier3}{},
            where level={0}{l sep-=15pt}{},
            where level={1}{
        if n={1}{
          edge path={
            \noexpand\path[color=linecol, rounded corners=5pt,
              >={Stealth[length=10pt]}, line width=1pt, ->,
              \forestoption{edge}]
              (!u.west) -| (.child anchor)\forestoption{edge label};
            }
                }{
          edge path={
            \noexpand\path[color=linecol, rounded corners=5pt,
              >={Stealth[length=10pt]}, line width=1pt, ->,
              \forestoption{edge}]
              (!u.east) -| (.child anchor)\forestoption{edge label};
            },
        }
            }{}
    }
    [Light Detection and Ranging\\LiDAR, inner color=col1in, outer color=col1out
    [Scanning, inner color=col2in, outer color=col2out
      [Spinning head\\with single-spot\\sensors, inner color=col4in, outer color=col4out]
      [Moving mirrors/\\prisms, inner color=col4in, outer color=col4out
                [Rotating/oscillating\\macro mirrors/prisms, inner color=col8in, outer color=col8out]
                [Oscillating MEMS\\mirror, inner color=col8in, outer color=col8out]
            ]
      [Optical phased-\\arrays, inner color=col4in, outer color=col4out]
    ]
    [Non-scanning (staring), inner color=col2in, outer color=col2out
      [Fixed (multi-)\\beam, inner color=col4in, outer color=col4out]
      [Diffuse light cone\\ ``FLASH'' LiDAR, inner color=col4in, outer color=col4out]
        ]
    ]
\end{forest}

\end{document}

产生什么 在此处输入图片描述

如您所见,第二级的连接并未针对三个子级进行优化。“移动镜子/棱镜”椭圆与其父级“扫描”的连接非常糟糕。

据我所知,森林文档对这个主题没有什么帮助。我该如何设置级别选项,以便所有内容都相同,但中间的椭圆直接与其父级“南”相连?

答案1

文档中可能很容易忽略这一点,但forest有一个选项calign(“子对齐”)可以解决您的问题。如果我理解正确的话,您希望将子节点定位到“扫描”节点,以便第二个节点居中。

这是通过calign=child, calign child=2向父节点添加选项来实现的。(请参阅森林文档的 §3.7.2“节点位置”)。

如果您想自动设置,您可以使用语法if n children=3

使用校准

\documentclass[tikz,border=10pt]{standalone}
\usepackage{verbatim}
\usepackage{forest}

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

% colors
\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=1pt,
      draw=linecol,
      ellip,
      align=center,
            child anchor=north,
      parent anchor=south,
            drop shadow,
            l sep+=12.5pt,
            edge path={
        \noexpand\path[color=linecol, rounded corners=5pt,
          >={Stealth[length=10pt]}, line width=1pt, ->, \forestoption{edge}]
          (!u.parent anchor) -- +(0,-5pt) -|
          (.child anchor)\forestoption{edge label};
        },
            where level={3}{tier=tier3}{},
            where level={0}{l sep-=15pt}{},
            where level={1}{
        if n={1}{
          edge path={
            \noexpand\path[color=linecol, rounded corners=5pt,
              >={Stealth[length=10pt]}, line width=1pt, ->,
              \forestoption{edge}]
              (!u.west) -| (.child anchor)\forestoption{edge label};
            }
                }{
          edge path={
            \noexpand\path[color=linecol, rounded corners=5pt,
              >={Stealth[length=10pt]}, line width=1pt, ->,
              \forestoption{edge}]
              (!u.east) -| (.child anchor)\forestoption{edge label};
            },
        }
            }{}
    }
    [Light Detection and Ranging\\LiDAR, inner color=col1in, outer color=col1out
    [Scanning, inner color=col2in, outer color=col2out,calign=child, calign child=2
      [Spinning head\\with single-spot\\sensors, inner color=col4in, outer color=col4out]
      [Moving mirrors/\\prisms, inner color=col4in, outer color=col4out
                [Rotating/oscillating\\macro mirrors/prisms, inner color=col8in, outer color=col8out]
                [Oscillating MEMS\\mirror, inner color=col8in, outer color=col8out]
            ]
      [Optical phased-\\arrays, inner color=col4in, outer color=col4out]
    ]
    [Non-scanning (staring), inner color=col2in, outer color=col2out
      [Fixed (multi-)\\beam, inner color=col4in, outer color=col4out]
      [Diffuse light cone\\ ``FLASH'' LiDAR, inner color=col4in, outer color=col4out]
        ]
    ]
\end{forest}

\end{document}

答案2

另一种选择是before computing xy={s/.average={s}{siblings}}在节点“移动镜子/\棱镜”处使用。通过一些努力使你的 MWE 更短(对我来说更美观),MWE 是:

\documentclass[tikz,border=10pt]{standalone}
\usepackage[edges]{forest}
\usetikzlibrary{arrows.meta, calc, shadows, shapes.geometric}
% colors
\colorlet{linecol}{blue!60}

\begin{document}

\begin{forest}
    for tree={
E/.style = {ellipse, draw=linecol, line width=1pt,
            inner color=#1!15, outer color=#1!45, % nodes color
            inner xsep=-1pt, font=\sffamily\bfseries,
            align=center, drop shadow}, % nodes style with parameter for color
 child anchor = north,
parent anchor = south,
        s sep = 4mm,    % "sibling distance"
        l sep = 8mm,    % "level distance"
         edge = {draw=linecol, line width=1pt, -{Stealth[length=7pt]}, % common style for all edges
                 rounded corners},
    edge path = {\noexpand\path[\forestoption{edge}]
          (!u.parent anchor) -- + (0,-4mm) -| (.child anchor);},
            where level={2}{tier=tier2}{},% nodes on the level 2
                                          % (from top) are vertically aligned
                                          % on the top is level 0
            where level={1}{
        if n={1}{edge path={\noexpand\path[\forestoption{edge}]
              (!u.west) -| (.child anchor);}
                }{edge path={\noexpand\path[\forestoption{edge}]
              (!u.east) -| (.child anchor);},
                    }
                            }{}% end of level 1
                }% end for tree
    [LiDAR\\ (Light Detection\\and Ranging), E=red
        [Scanning, E=green
            [Spinning head with\\single-spot sensors, E=teal]
            [Moving mirrors/\\prisms, E=teal,
             before computing xy={s/.average={s}{siblings}}
             % or calign=child, calign child=2
                [Rotating/oscillating\\macro mirrors/prisms, E=orange]
                [Oscillating MEMS\\mirror, E=orange]
          ]
            [Optical phased-\\arrays, E=teal]
        ]
        [Non-scanning\\ (staring), E=green
              [Fixed (multi-)\\beam, E=teal]
              [Diffuse light cone\\ ``FLASH'' LiDAR, E=teal]
        ]
    ]
\end{forest}

\end{document}

在此处输入图片描述

您可以根据自己的意愿更改所用的节点颜色。

相关内容