我正在尝试使用 tikz-tree 绘制大型家庭/目录树。我发现了这个问题在 Stackexchange 中,它几乎可以工作,但并不完全。使用答案中提供的代码,当我的树足够大时,我会得到重叠的文本。如果我不使用更紧密的意图,节点不会重叠,但我不会得到想要的意图(并且树变得太宽)。
清晰示例
\documentclass[11pt,a4paper]{report}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\makeatletter
\newcount\dirtree@lvl
\newcount\dirtree@plvl
\newcount\dirtree@clvl
\def\dirtree@growth{%
\ifnum\tikznumberofcurrentchild=1\relax
\global\advance\dirtree@plvl by 1
\expandafter\xdef\csname dirtree@p@\the\dirtree@plvl\endcsname{\the\dirtree@lvl}
\fi
\global\advance\dirtree@lvl by 1\relax
\dirtree@clvl=\dirtree@lvl
\advance\dirtree@clvl by -\csname dirtree@p@\the\dirtree@plvl\endcsname
\pgf@xa=1cm\relax
\pgf@ya=-0.5cm\relax
\pgf@ya=\dirtree@clvl\pgf@ya
\pgftransformshift{\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}%
\ifnum\tikznumberofcurrentchild=\tikznumberofchildren
\global\advance\dirtree@plvl by -1
\fi
}
\tikzset{
dirtree/.style={
growth function=\dirtree@growth,
growth parent anchor=south west,
parent anchor=south west,
every child node/.style={anchor=west},
edge from parent path={([xshift=2ex] \tikzparentnode\tikzparentanchor) |- (\tikzchildnode\tikzchildanchor)}
}
}
\tikzset{
dirtreemid/.style={
growth function=\dirtree@growth,
every node/.style={anchor=north},
every child node/.style={anchor=west},
edge from parent path={(\tikzparentnode\tikzparentanchor) |- (\tikzchildnode\tikzchildanchor)}
}
}
\makeatother
\begin{document}
\begin{tikzpicture}[dirtree]
\node {Maria}
child { node {Fuu}
child { node {Lii}
child { node {Lee}
child { node {Loo} }
child { node {Luu} }
}
child { node {Overlap}
child { node { Kim} }
child { node { Jou} }
}
}
child { node {Long text here}
}
}
child { node {Foo} };
\end{tikzpicture}
\\ \\
\begin{tikzpicture}[dirtreemid]
\node {Maria}
child { node {Fuu}
child { node {Lii}
child { node {Lee}
child { node {Loo} }
child { node {Luu} }
}
child { node {Overlap}
child { node { Kim} }
child { node { Jou} }
}
}
child { node {Long text here}
}
}
child { node {Foo} };
\end{tikzpicture}
\end{document}'
对于使用上述代码获得的参考图。我想要的是第一幅图像的节点缩进,而不重叠节点。
任何帮助是极大的赞赏!
答案1
我会使用这个,forest
因为它比其他选项更灵活、更强大。特别是,它可以使用更简洁的代码来构造树,而不需要太多的定义技巧。
编辑
根据评论中指定的额外要求,对此进行了编辑以满足两个条件:
- 使用新样式将给定级别的所有节点放在同一位置
tier
,从而确保缩进恒定; l
被指定来控制级别之间的距离(当前设置为15pt
- 根据需要调整)。
已edge path
进行相应调整,并inner sep
指定了保持紧凑而不会太过拥挤。同样,这些可以根据您的要求进一步修改。
\documentclass[tikz,varwidth,border=5pt,multi]{standalone}
\usepackage[utf8]{inputenc}
\usepackage{forest}
\begin{document}
\forestset{
my tier/.style={% align all nodes on a given level
tier/.wrap pgfmath arg={level##1}{level()},
},
}
\begin{forest}
for tree={
grow'=0,
child anchor=west,
parent anchor=south,
anchor=west,
calign=first,
s sep+=-5pt,
inner sep=2.5pt,
edge path={
\noexpand\path [draw, \forestoption{edge}]
(!u.south west) +(7.5pt,0) |- (.child anchor)\forestoption{edge label};
},
before typesetting nodes={
if n=1{
insert before={[, phantom, my tier]},
}{},
},
my tier,
fit=band,
before computing xy={% change the value of l to alter the distance between levels
l=15pt,
},
}
[Maria
[Fuu
[Lii
[Lee
[Loo]
[Luu]
]
[Overlap
[Kim]
[Jou]
]
]
[Long text here]
]
[Foo]
]
\end{forest}
\end{document}
答案2
由于 y 距离在全局定义中设置为 -0.5cm dirtree@growth
(第 17 行),因此可以在本例中将全局设置更改为 t0 -1cm,或者Overlay, Long text here and Foo
通过yshift=xx cm
语法手动调整这些重叠节点,如下所示。这是因为手动设置是局部更改,从而使生成的图像紧凑。
代码
\documentclass[11pt,a4paper]{report}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\makeatletter
\newcount\dirtree@lvl
\newcount\dirtree@plvl
\newcount\dirtree@clvl
\def\dirtree@growth{%
\ifnum\tikznumberofcurrentchild=1\relax
\global\advance\dirtree@plvl by 1
\expandafter\xdef\csname dirtree@p@\the\dirtree@plvl\endcsname{\the\dirtree@lvl}
\fi
\global\advance\dirtree@lvl by 1\relax
\dirtree@clvl=\dirtree@lvl
\advance\dirtree@clvl by -\csname dirtree@p@\the\dirtree@plvl\endcsname
\pgf@xa=1cm\relax
\pgf@ya=-0.5cm\relax % <--- here
\pgf@ya=\dirtree@clvl\pgf@ya
\pgftransformshift{\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}%
\ifnum\tikznumberofcurrentchild=\tikznumberofchildren
\global\advance\dirtree@plvl by -1
\fi
}
\tikzset{
dirtree/.style={
growth function=\dirtree@growth,
growth parent anchor=south west,
parent anchor=south west,
every node/.style={anchor=north},
every child node/.style={anchor=west},
edge from parent path={([xshift=2ex] \tikzparentnode\tikzparentanchor) |- (\tikzchildnode\tikzchildanchor)},
growth function=\dirtree@growth,
every node/.style={anchor=north},
every child node/.style={anchor=west},
edge from parent path= {([xshift=2ex]\tikzparentnode\tikzparentanchor) |- (\tikzchildnode\tikzchildanchor)},
}
}
\tikzset{
dirtreemid/.style={
growth function=\dirtree@growth,
every node/.style={anchor=north},
every child node/.style={anchor=west},
edge from parent path={(\tikzparentnode\tikzparentanchor) |- (\tikzchildnode\tikzchildanchor)},
}
}
\makeatother
\begin{document}
\begin{tikzpicture}[dirtree] %
\node {Maria}
child { node[] {Fuu}
child { node {Lii}
child { node {Lee}
child { node {Loo} }
child { node {Luu} }
}
child {node[yshift=-0.3cm] {Overlap}
child { node { Kim} }
child { node { Jou} }
}
}
child {node[yshift=-0.8cm] {Long text here}
}
}
child { node[yshift=-1cm] {Foo} };
\end{tikzpicture}
\\
\begin{tikzpicture}[dirtreemid]
\node {Maria}
child { node {Fuu}
child { node {Lii}
child { node {Lee}
child { node {Loo} }
child { node {Luu} }
}
child { node {Overlap}
child { node { Kim} }
child { node { Jou} }
}
}
child { node {Long text here}
}
}
child { node {Foo} };
\end{tikzpicture}
\end{document}