![如何更好地在手工构建的家谱中绘制连接线](https://linux22.com/image/444944/%E5%A6%82%E4%BD%95%E6%9B%B4%E5%A5%BD%E5%9C%B0%E5%9C%A8%E6%89%8B%E5%B7%A5%E6%9E%84%E5%BB%BA%E7%9A%84%E5%AE%B6%E8%B0%B1%E4%B8%AD%E7%BB%98%E5%88%B6%E8%BF%9E%E6%8E%A5%E7%BA%BF.png)
经过几天的失败尝试后genealogytree
,我决定用 tikz 手动绘制家谱。我对 MWE 有两个问题:
连接节点 nBob 和 nAlice 的双线是否可以与 nBob(“Bob”)的顶线对齐,而不是与它的垂直中点对齐?
除了手动指定所有这些坐标之外,还有没有更有效的方法来绘制连接子节点的线?我不介意指定节点的坐标(事实上,这比尝试genealogytree
合理地放置节点更容易)。但如果能画出水平线,然后将其连接到子节点,而不必指定垂直连接器的坐标,那就太好了。
\documentclass[varwidth,margin=10pt]{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
% How to align double line with "Bob" instead of vertical midpoint of (nBob)?
\node[text width=2cm] (nBob) at (2,0) {\centering Bob\\the giant\par};
\node (nAlice) at (6,0) {Alice};
\draw[double] (nBob) -- (nAlice);
\node (nBobby) at (1.5,-2) {Bobby};
\node (nAlly) at (4.5,-2) {Ally};
\node (nOops) at (7.5,-2) {Oops};
% How to draw these lines more efficiently?
\draw (4.25,0) -- (4.25,-1);
\draw (1.5,-1) -- (7.5,-1);
\draw (1.5,-1) -- (nBobby);
\draw (4.5,-1) -- (nAlly);
\draw (7.5,-1) -- (nOops);
\end{tikzpicture}
\end{document}
编辑:以下是 Ignasi 的回答,我在其中引入了一个新问题:Sally。Sally 是 Bob 的孩子,但母亲没有显示出来。有两个问题(我刚刚解决了一个水平对齐问题。)
- 从 nBob 到 nSally 的线经过标签“巨人”
- 我不明白为什么
\draw (aux) -- (aux|-aux2) (aux2);
有效
增强的 MWE:
\documentclass[varwidth,margin=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}
\node[minimum width=1.5cm, label={[anchor=north, yshift=1mm]below:the giant}] (nBob) {Bob};
\node[minimum width=1.5cm,right=4cm of nBob] (nAlice) {Alice};
\draw[double] (nBob) -- coordinate[pos=.6] (aux) (nAlice);
\node[below=of nBob] (nSally) {Sally};
\node[right=of nSally] (nBobby) {Bobby};
\node[right=of nBobby] (nAlly) {Ally};
\node[right=of nAlly] (nOops) {Oops};
\draw (nBob) -- coordinate[pos=0.75] (aux2) (nSally);
\draw (aux) -- (aux|-aux2) (aux2); % don't understand this line
\draw (nBobby) -- (nBobby|-aux2)-|(nAlly);
\draw (nBobby) -- (nBobby|-aux2)-|(nOops);
\end{tikzpicture}
\end{document}
答案1
可能有更好的解决方案,但这个技巧可以解决问题。不使用节点multiline
,而是将第二行添加为标签。这样Bob
和Alice
就对齐了。
关于定位,我认为最好使用positioning
库的相对定位。角落可以用|-
或来解决-|
,正如@hpekristiansen 建议的那样。
\documentclass[varwidth,margin=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}
% How to align double line with "Bob" instead of vertical midpoint of (nBob)?
\node[minimum width=1.5cm, label={[anchor=north, yshift=1mm]below:the giant}] (nBob) {Bob};
\node[minimum width=1.5cm,right=4cm of nBob] (nAlice) {Alice};
\draw[double] (nBob) -- coordinate (aux) (nAlice);
\node[below=of aux] (nAlly) {Ally};
\node[left=of nAlly] (nBobby) {Bobby};
\node[right=of nAlly] (nOops) {Oops};
% How to draw these lines more efficiently?
\draw (aux) -- coordinate[pos=0.75] (aux2) (nAlly);
\draw (nBobby) -- (nBobby|-aux2)-|(nOops);
\end{tikzpicture}
\end{document}
更新后问题的答案:
为了避免垂直线穿过“巨人”的问题,我们可以给label
(每个label
都是一个node
)添加一个名字,并在标签和Sally之间画一条线。
有关奇怪的线\draw (aux) -- (aux|-aux2) (aux2);
。意思是在 和 的一条垂直线与 的一条水平线aux
的交点之间画一条线,然后再次将笔放在 上。最后这个动作不是必须的。应该是。aux
aux2
aux2
\draw (aux)--(aux|-aux2);
\documentclass[varwidth,margin=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}
\node[minimum width=1.5cm, label={[anchor=north, yshift=1mm, name=giant]below:the giant}] (nBob) {Bob};
\node[minimum width=1.5cm,right=4cm of nBob] (nAlice) {Alice};
\draw[double] (nBob) -- coordinate[pos=.6] (aux) (nAlice);
\node[below=of nBob] (nSally) {Sally};
\node[right=of nSally] (nBobby) {Bobby};
\node[right=of nBobby] (nAlly) {Ally};
\node[right=of nAlly] (nOops) {Oops};
\draw (giant) -- coordinate[pos=0.5] (aux2) (nSally);
\draw (aux) -- (aux|-aux2);% (aux2); % don't understand this line
\draw (nBobby) -- (nBobby|-aux2)-|(nAlly);
\draw (nBobby) -- (nBobby|-aux2)-|(nOops);
\end{tikzpicture}
\end{document}
答案2
附赠forest
礼包(娱乐用):
\documentclass[border=3.141592]{standalone}
\usepackage[edges]{forest}
\usetikzlibrary{positioning}
\tikzset{node distance=17mm}
\begin{document}
\begin{forest}
for tree = {
% nodes style
align=center,
inner sep = 2pt,
% tree style
child anchor = north,
grow = south,
forked edge,
l sep = 12mm,
s sep = 2mm,
fork sep = 6mm,
}
%
[ ,coordinate, name=r
[Ally]
[Bobby,before computing xy={s/.average={s}{siblings}}]
[Oops]
]
\node (B) [left =of r, align=center] {Bob\\ the gaint};
\node (A) [right=of r] {Allice};
\draw[double] (B) -- (A);
\draw (B) -- ++ (0,-1.2) node[below] {Sue};
\end{forest}
\end{document}