我需要
- 使表示节点的所有矩形在每一层都具有相同的大小,或者至少具有相同的大小。
- 有额外的有向弧:具体来说,我需要一条从 (1,3) 到 (1,4)、从 (1,4) 到 (8,5)、从 (8,5) 到 (4,6) 以及从 (4,6) 到 (0,7) 的有向弧。也就是说,使用当前结构,我只能得到一个前任,但我需要多个潜在前任。通过修改我的代码可以实现这一点吗?如果不行,那么哪种结构更好?
\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{shapes.multipart}
\tikzset{block/.style={
font=\sffamily,
draw=black,
thin,
fill=white!50,
rectangle split,
rectangle split horizontal,
rectangle split parts=#1,
outer sep=0pt},
}
\begin{document}
\def\lvld{1.2} % Choose level distance
\pgfmathsetmacro\shft{-6*\lvld} % Calculate the yshift for the green tree
\begin{tikzpicture}[level distance=\lvld cm,
level 1/.style={sibling distance=4cm},
level 2/.style={sibling distance=3.5cm},
level 3/.style={sibling distance=2.5cm},
level 4/.style={sibling distance=1.5cm},
edgedown/.style={edge from parent/.style={draw=black,thick,-latex}}%,
%edgeup/.style={edge from parent/.style={draw=green!50!black,thick,latex-}}
]
\node[block=1][label=right:{(0,0)}] (A) {(1,58)}
[grow=down,edgedown]
child {node[block=1][label=right:{(0,0)}] (B1) {(7,59)}
child {node[block=1][label=left:{(0,0)}] (C1) {(3,40)}
child {node[block=1][label=left:{(0,0)}] (D1) {(9,1)}
child {node[block=1][label=left:{(0,0)}] (E1) {(65,1)}
child {node[block=1][label=left:{(0,0)}] (F1) {(1,63)}}
child {node[block=1][label=right:{(0,0)}] (F2) {(0,7)}} }
child {node[block=1][label=right:{(0,0)}] (E2) {(4,6)}}}
child {node[block=1][label=right:{(0,0)}] (D2) {(8,5)}}
}
child {node[block=1][label=right:{(0,0)}] (C2) {(1,4)}} }
child {node[block=1][label=right:{(0,0)}] (B2) {(1,3)}}
\end{tikzpicture}
\end{document}
答案1
这种事情forest
可以做得很好,因为即使这不是一棵树,所以我们需要一些黑客技术,自动化仍然让我们可以轻松地产生均匀的,有图案的间距,我们可以根据需要在(非)树的序言中进行调整。
我不知道‘等距居中’是什么意思,更不要说它适用于什么,所以这只是一个例子。
代码计算最宽节点并为所有节点设置该宽度。它比原始版本更系统地放置标签(当然,如果存在某些原因导致发散,您可以更改它)。森林倾向于产生非常紧凑的树,因此我们也稍微增加了兄弟分离度(s sep'+=10pt
)。您可能还想增加级别之间的距离(例如l sep+'=10pt
)或使用大于的东西10pt
。如果这还不够,您可以稍后更直接地修改间距(如果需要)。
节点排版两次:第一次确定最宽,第二次将尺寸应用于所有节点。因此,我只在第二次添加边框,因为第一次排版没有实际意义。
如果您确实希望整棵树都使用相同的标签,那么显然只需设置它即可。不过,我假设这只是举个例子,因为人们很少想通过反复重复来强调某个值是恒定的。因此,我只是(0,0)
像您一样将其用作占位符。
\documentclass[tikz,border=5pt]{standalone}
% ateb: https://tex.stackexchange.com/a/713546/
\usepackage{forest}
\usetikzlibrary{arrows.meta}
\begin{document}
\begin{forest}
for tree={%
edge+={-Latex},
anchor=base,
align=@{}c@{},
font=\sffamily,
s sep'+=10pt,
if={ > On= On> & {n}{2} {level}{1} }{%
edge path'={%
(!uu2.parent anchor) edge (.child anchor)
(!u.parent anchor) -- (.child anchor)
},
}{%
edge path'={(!u.parent anchor) -- (.child anchor)},
},
},
my label/.style={%
if n=2{%
label={[my label style]right:{#1}},
}{%
label={[my label style]left:{#1}},
},
},
/tikz/my label style/.style={font=\sffamily},
before computing xy={%
tempdima/.max={ > OOw2+d {max x}{min x}{#1-#2} }{tree},
for tree={%
minimum width/.register=tempdima,
draw,
thin,
},
typeset nodes,
},
[{(1,58)}, my label={(0,0)}
[{(7,59)}, my label={(0,0)}
[{(3,40)}, my label={(0,0)}
[{(9,1)}, my label={(0,0)}
[{(65,1)}, my label={(0,0)}
[{(1,63)}, my label={(0,0)}]
[{(0,7)}, my label={(0,0)}]
]
[{(4,6)}, my label={(0,0)}]
]
[{(8,5)}, my label={(0,0)}]
]
[{(1,4)}, my label={(0,0)}]
]
[{(1,3)}, my label={(0,0)}]
]
\end{forest}
\end{document}
请注意,由于 KDE6/Okular 中的一个错误,我粘贴的图像现在很糟糕,尽管 PDF 没问题。我对糟糕的质量表示歉意。它应该足够清晰,以展示节点的均匀间距。这基本上是标准化其宽度的功能。
我保证,这些箭实际上并不是毛茸茸的;它们的毛茸茸完全是在奥克拉的眼睛里。
答案2
只需将它们手动添加到套件中作为节点之间的路径即可。在这里,我创建了一个scope
向所有路径添加箭头的every path/.style
\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{shapes.multipart}
\tikzset{block/.style={
font=\sffamily,
draw=black,
thin,
fill=white!50,
rectangle split,
rectangle split horizontal,
rectangle split parts=#1,
outer sep=0pt},
}
\begin{document}
\def\lvld{1.2} % Choose level distance
\pgfmathsetmacro\shft{-6*\lvld} % Calculate the yshift for the green tree
\begin{tikzpicture}[level distance=\lvld cm,
level 1/.style={sibling distance=4cm},
level 2/.style={sibling distance=3.5cm},
level 3/.style={sibling distance=2.5cm},
level 4/.style={sibling distance=1.5cm},
edgedown/.style={edge from parent/.style={draw=black,thick,-latex}}%,
%edgeup/.style={edge from parent/.style={draw=green!50!black,thick,latex-}}
]
\node[block=1][label=right:{(0,0)}] (A) {(1,58)}
[grow=down,edgedown]
child {node[block=1][label=right:{(0,0)}] (B1) {(7,59)}
child {node[block=1][label=left:{(0,0)}] (C1) {(3,40)}
child {node[block=1][label=left:{(0,0)}] (D1) {(9,1)}
child {node[block=1][label=left:{(0,0)}] (E1) {(65,1)}
child {node[block=1][label=left:{(0,0)}] (F1) {(1,63)}}
child {node[block=1][label=right:{(0,0)}] (F2) {(0,7)}} }
child {node[block=1][label=right:{(0,0)}] (E2) {(4,6)}}}
child {node[block=1][label=right:{(0,0)}] (D2) {(8,5)}}
}
child {node[block=1][label=right:{(0,0)}] (C2) {(1,4)}} }
child {node[block=1][label=right:{(0,0)}] (B2) {(1,3)}};
\begin{scope}[every path/.style={thick,-{latex}}]
\draw (B2)--(C2);
\draw(C2)--(D2);
\draw (D2)--(E2);
\draw(E2)--(F2);
\end{scope}
\end{tikzpicture}
\end{document}
为了使所有节点垂直对齐:
兄弟距离参数在每个级别上只需相同:sibling distance=2cm
\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{shapes.multipart}
\tikzset{block/.style={
font=\sffamily,
draw=black,
thin,
fill=white!50,
rectangle split,
rectangle split horizontal,
rectangle split parts=#1,
outer sep=0pt},
}
\begin{document}
\def\lvld{1.2} % Choose level distance
\pgfmathsetmacro\shft{-6*\lvld} % Calculate the yshift for the green tree
\begin{tikzpicture}[level distance=\lvld cm,
sibling distance=2cm,
edgedown/.style={edge from parent/.style={draw=black,thick,-latex}}%,
%edgeup/.style={edge from parent/.style={draw=green!50!black,thick,latex-}}
]
\node[block=1][label=right:{(0,0)}] (A) {(1,58)}
[grow=down,edgedown]
child {node[block=1][label=right:{(0,0)}] (B1) {(7,59)}
child {node[block=1][label=left:{(0,0)}] (C1) {(3,40)}
child {node[block=1][label=left:{(0,0)}] (D1) {(9,1)}
child {node[block=1][label=left:{(0,0)}] (E1) {(65,1)}
child {node[block=1][label=left:{(0,0)}] (F1) {(1,63)}}
child {node[block=1][label=right:{(0,0)}] (F2) {(0,7)}} }
child {node[block=1][label=right:{(0,0)}] (E2) {(4,6)}}}
child {node[block=1][label=right:{(0,0)}] (D2) {(8,5)}}
}
child {node[block=1][label=right:{(0,0)}] (C2) {(1,4)}} }
child {node[block=1][label=right:{(0,0)}] (B2) {(1,3)}};
\begin{scope}[every path/.style={thick,-{latex}}]
\draw (B2)--(C2);
\draw(C2)--(D2);
\draw (D2)--(E2);
\draw(E2)--(F2);
\end{scope}
\end{tikzpicture}
\end{document}