最近,我经常想通过一系列图片来说明图算法,例如
我目前的做法是创建一个链,然后tikzpicture
在每个节点中放置一个嵌套。如您所见,这会破坏节点放置并使树木倾斜(预期的行为是所有树木在红色填充跳跃之前看起来都一样)。
目前,我猜测原因最好的是链库,因为如果我用其他放置外部节点的方法替换链,树就会正确绘制。所以我的问题是,如何在不牺牲链库易用性的情况下正确绘制树。
以下是生成上述示例的代码:
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{chains}
\begin{document}
\begin{tikzpicture}[
% Chain style
start chain,
node distance = 1cm,
every on chain/.style = {join},
every join/.style = {->, draw=black, line width = 1pt},
]
\foreach \i in {1,...,3} {
\node [on chain, rectangle, draw=black, dashed] {
\begin{tikzpicture}[
% Tree style
cvertex/.style = {solid, circle, draw=black, line width=1pt, inner sep = 4pt},
cedge/.style = {solid, draw=black, line width=1pt},
edge from parent/.style = {cedge},
level distance = 1cm,
sibling distance = 1cm,
%
% Animation styles
highlighted/.style = { fill = red },
step base/.style = { o/.style={cvertex}, l/.style={cvertex}, r/.style={cvertex} },
step 1/.style = {step base, o/.append style = {highlighted} },
step 2/.style = {step base, l/.append style = {highlighted} },
step 3/.style = {step base, r/.append style = {highlighted} },
step \i
]
\node [o] {}
child { node [l] {} }
child { node [r] {} }
;
\end{tikzpicture}
};
}
\end{tikzpicture}
\end{document}
答案1
不确定为什么链会弄乱内部图片中的节点,我觉得应该有一个简单的解决方案,但这里有一个使用pic
PGF 3.0 语法的想法。它本质上创造了一种在链上的错觉pic
,因此可以做类似的事情:
\begin{scope}[start chain=going right, every join/.style={-stealth},
style 1/.style=, style 2/.style=, style 3/.style=]
\foreach \i in {1,...,3}
\pic [style \i/.style={fill=red}] {graph={
\node [style 1] {} child { node [style 2] {} } child { node [style 3] {} };
}};
\end{scope}
这将产生这样的结果:
下面的代码pic
显示了一个更极端的例子:
\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{chains, fit}
\begin{document}
\newbox\picbox
\begin{tikzpicture}[graph/.pic={
\pgfinterruptpicture%
% Interrupt the picture and put the graph in a box.
\global\setbox\picbox=\hbox{\pgfpicture%
% Set default tree options
\tikzset{every node/.style={circle, draw, inner sep=0.0625cm},
level distance=0.5cm, sibling distance=.5cm}%
#1
\endpgfpicture}%
\endpgfinterruptpicture%
% Put box in a separate node otherwise some parameters
% (e.g., dashing) will be inherited by the picture in the \picbox.
\node [on chain, join, outer sep=0pt] (@) {\copy\picbox};
% Fit the dashed box around the existing box.
\node [draw, fit=(@), inner sep=0pt, dashed] {};
}]
\begin{scope}[start chain=going right, every join/.style={-stealth}]
\pic {graph={
\node [fill=red] {} child { node {} } child { node {} };
}};
\pic {graph={
\node {} child { node [fill=red] {} } child { node {} };
}};
\pic [continue chain=going below] {graph={
\node {} child { node {} } child { node [fill=red] {} };
}};
\pic [continue chain=going left] {graph={
\node {} child { node {} } child { node {}
child { node [fill=green] {} } child { node {} } };
}};
\pic [continue chain=going below] {graph={
\node {} child { node {} } child { node {}
child { node {} } child { node [fill=blue] {} } };
}};
\pic [continue chain=going right] {graph={
\node [fill=red] {}
[level 2/.style={sibling distance=.25cm}]
child { node [fill=yellow] {}
child { node [fill=pink] {} }
child { node [fill=green] {} }
}
child { node [fill=orange] {}
child { node [fill=purple] {} }
child { node [fill=blue] {} }
};
}};
\end{scope}
\end{tikzpicture}
\end{document}
另一种方法是使用新的图表材料,必须用以下方法进行编译lualatex
:
\documentclass[tikz, border=5]{standalone}
\usetikzlibrary{graphs,graphdrawing}
\usegdlibrary{trees}
\usetikzlibrary{chains}
\begin{document}
\begin{tikzpicture}[start chain=going right, every join/.style={->}]
\foreach \i in {1,2,3}
\node [on chain, join, draw, dashed]{
\tikz[solid]
\graph [tree layout, nodes={circle, draw}, empty nodes, s\i/.style={/tikz/fill=red}]
{ 1[s1/.try] -- {2[s2/.try], [s3/.try]3} }; };
\end{tikzpicture}
\end{document}