你能帮助改进森林图吗?

你能帮助改进森林图吗?

我正在寻求改进这个图表,特别是顶部与框重叠的连接箭头。

\documentclass{article}
\usepackage[margin=1cm]{geometry}
\usepackage{pdflscape}
\usepackage{forest}
\usepackage{capt-of}
\usetikzlibrary{shadows,arrows}
\newgeometry{left=1cm,right=1cm,bottom=1cm}

\tikzset{parent/.style={align=center,text width=2cm, fill=blue!40,rounded corners=2pt,inner sep=2pt},
    child/.style={align=center,text width=2.0cm,fill=orange!60,rounded corners=2pt,inner sep=1pt,outer sep=0pt},
    grandchild/.style={fill=white,text width=1.7cm}
}
\usepackage{hyperref}
\begin{document}

\begin{landscape}
\begin{forest}
for tree={%
    thick,
    drop shadow,
    l sep=1.0cm,
    s sep=0.6cm,
    node options={draw,font={\small}},
    edge={semithick,-latex},
    where level=0{parent}{},
    where level=1{
        minimum height=1cm,
        child,
        parent anchor=south west,
        tier=p,
        l sep=0.25cm,
        for descendants={%
            grandchild,
            minimum height=0.6cm,
            %l sep=0.5cm,
%            s sep=0.5cm,
            anchor=115,
            edge path={
                \noexpand\path[\forestoption{edge}]
                (!to tier=p.parent anchor) |-(.child anchor)\forestoption{edge label};
            },
        }
    }{},
}
[(Phoenician)\\ GREEK
    [Palaeo-Hispanic %heading
        [North-east\\
         Celtiberian
            [South-West\\
                South-east
            ]
        ]
    ],
    [Etruscan
        [Latin
            [\textit{Rhaetian} 
                [\href{http://en.wikipedia.org/wiki/Gallic}{Gallic}
                    [\href{http://en.wikipedia.org/wiki/Venetic}{Venetic}
                      [Faliscan
                        [Northern Picene
                          Southern Picene\\
                            [Oscan
                              [Umbrian]
                            ]
                          ]
                       ]
                    ]
                ]
            ]
        ]
    ]
    [\href{http://en.wikipedia.org/wiki/Gothic_language}{Gothic}]
    [Glagolitic
       [Croatian]
     ]   
    [Cyrillic
        [Russian
         [Ukrainian
         [Bulgarian
          [Serb]
            ] 
        ]  
     ]  
   ]  
  [Anatolian
    [Carian
      [Lydian
        [Lycian
          [\nameref{s:pamphylian}
            [Phrygian
              [\nameref{s:pisidian}
                [\nameref{s:sidetic}]
            ]
          ]
        ]
      ]
  ]
  ]
  ]
  [Armenian]
  [Georgian]
  [Coptic
    [Nubian]
  ]
]
\end{forest}
\captionof{figure}{Abridged family tree of some Greek-derived scripts.}
\label{fig:greekderived}
\end{landscape}


\restoregeometry
\newpage

\section{Pamphylian}\label{s:pamphylian}
\section{Pisidian}\label{s:pisidian}
\section{Sidetic}\label{s:sidetic}
\end{document}

在此处输入图片描述

答案1

您可以使用分叉边缘:

在此处输入图片描述

只需添加\useforestlibrary{edges}到您的序言并添加for children={forked edge}到根节点:

[(Phoenician)\\ GREEK, for children={forked edge}

答案2

forked edges也是我的第一个想法,但我对离开根的边的效果并不完全满意。虽然原始版本为子级提供了明显不同的路径,但使用forked edges统一了第一段路径。所以我想知道是否有可能分散边的起点(如原始版本),同时使用类似于forked edges(如Sandy G 的回答)。

ext.paths.ortho库扩展了可用于绘制路径的语法,其中包括|-|先向下,然后横穿,然后向下。此外,[distance=<dimension>]还可以调整从起点到第一个转弯的距离,使每条路径与其相邻路径分开。如果将此功能与根边界上的交错起点相结合,结果将结合我想要的功能。

ortho tree是一种forest结合了这些特性并自动从根节点交错路径的样式。我还对现有代码进行了轻微调整,以避免某些叶子节点比其他叶子节点缩进更多,在两个方向上正确对齐根节点的子节点,并使用 sans 字体(通常在图表中更受欢迎,尤其是在较小尺寸的图表中)。

修改后的树

请注意,最左边的橙色节点不再低于该层上的其他节点,并且杂散叶不再比其兄弟节点缩进更多。ortho tree定义为与具有任意数量子节点的根节点一起使用。 如果子节点数为偶数,则根节点与 对齐calign=midpoint。 如果数量为奇数(如本例),则calign with current edge应用于中间子节点。

请注意,重新定义\section只是为了举例,不应该在实际文档中使用!

代码:

\documentclass[border=5pt]{standalone}
% ateb: https://tex.stackexchange.com/a/705321/ addaswyd o gwestion Yiannis Lazarides: https://tex.stackexchange.com/q/705204/
\usepackage{forest}
\usetikzlibrary{shadows,arrows,ext.paths.ortho}

\tikzset{%
  yl parent/.style={align=center,text width=2cm, fill=blue!40,rounded corners=2pt,inner sep=2pt},
  yl child/.style={align=center,text width=2.0cm,fill=orange!60,rounded corners=2pt,inner sep=1pt,outer sep=0pt},
  yl grandchild/.style={fill=white,text width=1.7cm}
}
\forestset{%
  declare count register={adjusted root child count},
  declare boolean register={root children odd},
  ortho tree/.style={%
    before typesetting nodes={%
      calculate root children,
      if root children odd={%
        for nodewalk={%
          fake=root,
          n/.register=adjusted root child count
        }{calign with current edge},
      }{!r.calign=midpoint},
    },
    before drawing tree={%
      tempcountb/.process={ Rw+n {adjusted root child count}{2*##1-2} },
      tempdima/.process={ OOOw3+d {!r.max x}{!r.min x}{!r.n children}{(##1-##2)/(##3+1)}},
      tempdimb/.process={ ORw2+d {!r.l sep}{tempcountb}{##1/##2} },
      for nodewalk={fake=r,1,while nodewalk valid={next}{next}}{%
        if={> OR= R & {n}{adjusted root child count} {root children odd} }{%
          edge path'=(!u.children) -- (.child anchor)
        }{%
          if={ > OR< {n}{adjusted root child count} } {%
            edge path'/.process={ OSRw2+P lRw2+P w2 {n}{tempdima}{##1*##2} {tempdimb}{##1*##2} {(!u.south west) ++(##1pt,0pt) |-|[distance=##2pt] (.child anchor) } },
          }{%
            edge path'/.process={ OSRw2+P lRw2+P w2 {n'}{tempdima}{##1*##2} {tempdimb}{##1*##2} {(!u.south east) ++(-##1pt,0pt) |-|[distance=##2pt] (.child anchor) } },
          }%
        }%
      },
    },
    where level=1{
      parent anchor=south west,
      anchor=parent,
      child anchor=parent,
      tier=pxx,
      for descendants={%
        child anchor=west,
        edge path'={
          (!to tier=pxx.parent anchor) |-(.child anchor)
        },
      },
    }{},
  },
  calculate root children/.style={%
    if={>Ow+P{!r.n children}{isodd(##1)}}{%
      adjusted root child count/.process={ Ow+n {!r.n children} {(##1+1)/2}},
      root children odd,
    }{%
      adjusted root child count/.process={ Ow+n {!r.n children} {(##1+2)/2}},
      not root children odd,
    },
  },
}
\usepackage{hyperref}
\makeatletter
% only for the example because standalone doesn't define \section!
\RenewDocumentCommand \section { m }{\def\@currentlabelname{#1}\refstepcounter{section}}
\makeatother
\begin{document}
\begin{forest}
  for tree={%
    thick,
    drop shadow,
    l sep'=1.0cm,
    s sep'=0.6cm,
    draw,
    font={\small\sffamily},
    edge={semithick,-latex},
  },
  where level=0{yl parent}{},
  where level=1{
    minimum height=1cm,
    yl child,
    l sep'=0.25cm,
    for descendants={%
      yl grandchild,
      minimum height=0.6cm,
      xshift=5pt,
    },
  }{},
  ortho tree,
  [(Phoenician)\\ GREEK% [c]
    [Palaeo-Hispanic %heading
      [North-east\\
      Celtiberian
        [South-West\\
        South-east
        ]
      ]
    ]
    [Etruscan
      [Latin
        [\textit{Rhaetian} 
          [\href{http://en.wikipedia.org/wiki/Gallic}{Gallic}
            [\href{http://en.wikipedia.org/wiki/Venetic}{Venetic}
              [Faliscan
                [Northern Picene
                Southern Picene\\
                  [Oscan
                    [Umbrian]
                  ]
                ]
              ]
            ]
          ]
        ]
      ]
    ]
    [\href{http://en.wikipedia.org/wiki/Gothic_language}{Gothic}]
    [Glagolitic
      [Croatian]
    ]   
    [Cyrillic
      [Russian
        [Ukrainian
          [Bulgarian
            [Serb]
          ] 
        ]  
      ]  
    ]  
    [Anatolian
      [Carian
        [Lydian
          [Lycian
            [\nameref{s:pamphylian}
              [Phrygian
                [\nameref{s:pisidian}
                  [\nameref{s:sidetic}]
                ]
              ]
            ]
          ]
        ]
      ]
    ]
    [Armenian]
    [Georgian]
    [Coptic
      [Nubian]
    ]
  ]
\end{forest}
\section{Pamphylian}\label{s:pamphylian}
\section{Pisidian}\label{s:pisidian}
\section{Sidetic}\label{s:sidetic}

\end{document}

相关内容