![森林 v.2](https://linux22.com/image/238977/%E6%A3%AE%E6%9E%97%20v.2.png)
今天是个好日子 -
是否有一种快速有效的方法来绘制目录树结构(又名深度缩进列表),就像unix的tree命令一样,也就是说,是否有办法使用TikZ绘制以下内容?
root
|
|--- dir1
| |
| |-- a1
| |-- a2
|--- dir2
|--- dir3
我已经检查了 tikz-tree 和 tikz-qtree,但是这些包总是希望树平衡地生长,而不是向下然后向右生长。
任何建议都将不胜感激。
谢谢。
答案1
我刚刚在使用 TikZ 的垂直树。下面的代码似乎有效,尽管我承认我没有对其进行全面测试,并且编造了一些数字,因此刚刚起作用。
让我们从一些输出开始:
代码如下:
\documentclass[border=10]{standalone}
\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=-1cm\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,
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 {toplevel}
child { node {Foo}
child { node {foo} }
child { node {bar} }
child { node {baz} }
}
child { node {Bar}
child { node {foo} }
child { node {foo} }
child { node {foo} }
child { node {foo} }
child { node {bar} }
child { node {baz} }
}
child { node {Baz}
child { node {foo} }
child { node {bar} }
child { node {baz} }
};
\end{tikzpicture}
\end{document}
我们定义了一个新的增长函数。我们的想法是,我们有一个全局计数器,用于跟踪到目前为止我们已处理的节点数,并根据此来定位子节点。主要问题是树的构建方式:每个分支的原点是父节点。因此,我们想要应用绝对变换(从根节点开始的总高度),但必须首先考虑相对变换。这需要一点簿记,但一旦弄清楚了,剩下的就……一帆风顺了。
边缘比较简单 - 我们只需将它们定义为|-
,即垂直的,然后是水平的。
答案2
这里有两个概念使用 来实现这一点TikZ
。第一个概念画的线不够多,第二个概念画的线太多了。我想每个级别都需要计数器。如果再次出现相同的级别并为其画一条线,这些计数器就会增加,而当遇到更高的级别时,它们会重置,例如,就像人们主要用 来实现的那样
\usepackage{chngcntr}
\counterwithin{leveltwo}{levelone}
可能我这周就能完成,但别指望了。以下是我目前所做的事情:
\documentclass[parskip,14pt]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}
\newcounter{treeline}
\newcommand{\treeroot}[1]{% Title
\node[above] at (0,0) {#1};%
\setcounter{treeline}{0}
}
\newcommand{\treeentry}[2]{% Title, Level
\draw[->] (#2-1,-\value{treeline}/2) -- (#2-1,-\value{treeline}/2-0.5) -- (#2+0.5,-\value{treeline}/2-0.5) node[right] {#1};
\stepcounter{treeline}
}
\newcommand{\altentry}[2]{% Title, Level
\draw[->] (#2-1,-\value{treeline}/2) -- (#2-1,-\value{treeline}/2-0.5) -- (#2+0.5,-\value{treeline}/2-0.5) node[right] {#1};
\foreach \x in {1,...,#2}
{ \draw (\x-1,-\value{treeline}/2) -- (\x-1,-\value{treeline}/2-0.5);
}
\stepcounter{treeline}
}
\begin{document}
\begin{tikzpicture}
\treeroot{$\sqrt{of\ all\ evil}$}
\treeentry{Bla}{1}
\treeentry{Bla}{2}
\treeentry{Bla}{3}
\treeentry{Bla}{2}
\treeentry{Bla}{2}
\treeentry{Bla}{3}
\treeentry{Bla}{3}
\treeentry{Bla}{3}
\treeentry{Bla}{3}
\treeentry{Bla}{3}
\treeentry{Bla}{4}
\treeentry{Bla}{4}
\treeentry{Bla}{4}
\treeentry{Bla}{4}
\treeentry{Bla}{4}
\treeentry{Bla}{4}
\treeentry{Bla}{1}
\treeentry{Bla}{1}
\treeentry{Bla}{2}
\treeentry{Bla}{3}
\treeentry{Bla}{2}
\treeentry{Bla}{2}
\treeentry{Bla}{3}
\treeentry{Bla}{1}
\end{tikzpicture}
\hspace{2cm}
\begin{tikzpicture}
\treeroot{$\sqrt{of\ all\ evil}$}
\altentry{Bla}{1}
\altentry{Bla}{2}
\altentry{Bla}{3}
\altentry{Bla}{2}
\altentry{Bla}{2}
\altentry{Bla}{3}
\altentry{Bla}{3}
\altentry{Bla}{3}
\altentry{Bla}{3}
\altentry{Bla}{3}
\altentry{Bla}{4}
\altentry{Bla}{4}
\altentry{Bla}{4}
\altentry{Bla}{4}
\altentry{Bla}{4}
\altentry{Bla}{4}
\altentry{Bla}{1}
\altentry{Bla}{1}
\altentry{Bla}{2}
\altentry{Bla}{3}
\altentry{Bla}{2}
\altentry{Bla}{2}
\altentry{Bla}{3}
\altentry{Bla}{1}
\end{tikzpicture}
\end{document}
结果如下:
答案3
更新:Forest 现在或多或少提供了这种开箱即用的样式。如果您需要针对旧版本 Forest 的解决方案(无论出于何种原因),请参阅下面我原来的回答,了解合适样式的定义。
森林 v.2
这是一个forest
使用库folder
提供的样式的解决方案edges
。这需要 Forest 版本 2。
\documentclass[tikz, border=5pt, multi]{standalone}
\usepackage[edges]{forest}
\begin{document}
\begin{forest}
for tree={%
folder,
grow'=0,
fit=band,
}
[root
[bin
]
[etc
[X11]
[cron.d]
[default]
]
[local
[bin]
[etc]
[texlive
[2014
[bin]
[readme-html.dir]
[texmf-config]
[texmf-dist]
[texmf-var]
]
[texmf-local]
]
]
[usr
[bin]
[include]
[share]
]
[var
[cache]
[log]
[spool]
[tmp]
]
]
\end{forest}
\end{document}
森林 v.1
这是我最初的forest
解决方案,它定义了一种新样式dir tree
,可以使用 版本 1 来排版这种格式的树forest
。
\documentclass[tikz, border=5pt, multi]{standalone}
\usepackage{forest}
\usetikzlibrary{arrows.meta}
\forestset{
dir tree/.style={
for tree={
parent anchor=south west,
child anchor=west,
anchor=mid west,
inner ysep=1pt,
grow'=0,
align=left,
edge path={
\noexpand\path [draw, \forestoption{edge}] (!u.parent anchor) ++(1em,0) |- (.child anchor)\forestoption{edge label};
},
font=\sffamily,
if n children=0{}{
delay={
prepend={[,phantom, calign with current]}
}
},
fit=band,
before computing xy={
l=2em
}
},
}
}
\begin{document}
\begin{forest}
dir tree
[root
[bin
]
[etc
[X11]
[cron.d]
[default]
]
[local
[bin]
[etc]
[texlive
[2014
[bin]
[readme-html.dir]
[texmf-config]
[texmf-dist]
[texmf-var]
]
[texmf-local]
]
]
[usr
[bin]
[include]
[share]
]
[var
[cache]
[log]
[spool]
[tmp]
]
]
\end{forest}
\end{document}
答案4
使用该库的另一个示例tikz
trees
:
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{trees}
\usepackage{xcolor}
\begin{document}
\tikzstyle{every node}=[thick,anchor=west, rounded corners, font={\scriptsize\ttfamily}, inner sep=2.5pt]
\tikzstyle{selected}=[draw=blue,fill=blue!10]
\tikzstyle{root}=[selected, fill=blue!30]
\begin{tikzpicture}[%
scale=.7,
grow via three points={one child at (0.5,-0.65) and
two children at (0.5,-0.65) and (0.5,-1.1)},
edge from parent path={(\tikzparentnode.south) |- (\tikzchildnode.west)}]
\node [root] {src}
child { node [selected] {asf}
child { node [selected] {avr32}
child { node [selected] {drivers}
child { node [selected] {canif}
child { node {canif.h}}
child { node {canif.c}}
}
}
}
}
child { node at (0,-3.5) [selected] {net}
child { node [selected] {can}
child { node {can.h}}
child { node {can\_mob.h}}
child { node {can\_mob.c}}
child { node {can\_port.h}}
child { node {can\_port.c}}
child { node {can\_trcv.h}}
child { node {can\_trcv.c}}
}
}
child { node at (0,-8) {\dots}};
\end{tikzpicture}
\end{document}