![你能帮助改进森林图吗?](https://linux22.com/image/471990/%E4%BD%A0%E8%83%BD%E5%B8%AE%E5%8A%A9%E6%94%B9%E8%BF%9B%E6%A3%AE%E6%9E%97%E5%9B%BE%E5%90%97%EF%BC%9F.png)
我正在寻求改进这个图表,特别是顶部与框重叠的连接箭头。
\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
答案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}