使用 tikz 自下而上显示投影仪上的树

使用 tikz 自下而上显示投影仪上的树

揭示树(节点+边)之前已经被处理过,例如:

Beamer:使用 \visible 和 \only 与 TikZ 结合绘制图形存在问题

依次从下往上揭示树

使用不透明度技巧和投影仪中的叠加逐步显示 tikz 树

但是,我的想法略有不同,我不知道如何调整以前的答案以适应我的情况。这就是我想要的:我有一颗有 4 个叶节点的简单二叉树,例如:

\documentclass{beamer}

\usepackage{tikz}

\tikzset{
  invisible/.style={opacity=0},
  visible on/.style={alt=#1{}{invisible}},
  alt/.code args={<#1>#2#3}{%
    \alt<#1>{\pgfkeysalso{#2}}{\pgfkeysalso{#3}} % \pgfkeysalso doesn't change the path
  },
}

\begin{document}

\begin{frame}
  \tikzset{vertex/.style={circle,fill=white!25,minimum size=20pt,inner sep=0pt}}
  \tikzset{leaf/.style={circle,fill=white!25,minimum size=20pt,inner sep=0pt}}
  \tikzstyle{level 1}=[sibling distance=40mm, style={black,very thick,draw}]
  \tikzstyle{level 2}=[sibling distance=20mm, style={black,very thick,draw}]

  \begin{center}
  \begin{tikzpicture}[every node/.style={circle,draw, very thick}]
    \node[vertex,visible on=<3->,  label={[visible on=<3->, yshift=-1.2cm, align=center]above: car, bus, cat, dog}] (1) {}
    child{node[vertex, visible on=<2->, label={[visible on=<2->, yshift=-0.6cm, align=center]above:  car, bus}] (2) {}
      child{node[leaf,visible on=<1->, label={[yshift=0.1cm, align=center]below: car}] (6) {}}
      child{node[leaf, label={[yshift=0.1cm, align=center]below: bus}] (7) {}}
    }
    child {node[vertex, visible on=<2->, label={[visible on=<2->, yshift=-0.67cm, align=center]above: cat, dog}](3) {}
      child{node[leaf, label={[yshift=0.1cm, align=center]below: cat}] (4) {}}
      child{node[leaf, label={[yshift=0.1cm, align=center]below: dog}] (5) {}}
    };
  \end{tikzpicture}
  \end{center}
\end{frame}
\end{document}

我打算从底层开始显示节点和边。到目前为止,我只管理了节点。但我不清楚如何让边也一个接一个地出现。目前,所有边都已渲染。我已经尝试过,edge from parent[visible on=<2->]但没有成功。

我错过了什么?

PS:我是tikz新手。

答案1

我原本以为可以很容易地改编代码奎伯比尔贝尔处理这棵树。但是,我在为问题中的具有分支模式的树实施该解决方案时遇到了问题。

基于 Qrrbrbirlbel 的想法,我开发了一种替代方法,利用了forest的定制可能性。这些包括不仅定义新样式,还forest定义新选项的能力。这样做的好处是,一旦定义,您就可以像使用其他forest选项一样使用它们。例如,您可以使用\forestoption{<custom option>}在当前节点的上下文中获取自定义选项的值。您还可以应用各种处理程序forest供应,尽管我发现在这里我不需要这样做。

我们从控制可见性的 Beamer 覆盖规范的标准 TikZ 代码开始:

\tikzset{% set up for transitions using tikz with beamer overlays
  invisible/.style={opacity=0,text opacity=0},
  visible on/.style={alt=#1{}{invisible}},
  alt/.code args={<#1>#2#3}{%
    \alt<#1>{\pgfkeysalso{#2}}{\pgfkeysalso{#3}} % \pgfkeysalso doesn't change the path
  },
}

接下来,我们定义两个forest自定义选项。最终用户在树规范中实际上不需要这些选项,但它们将在内部使用:

\forestset{%
  declare toks={no node before}{1},
  declare toks={no edge before}{1},

这将设置选项no node before和每种情况下no edge before的默认值1。(因此默认是在每张幻灯片上显示所有内容。)

接下来,我们创建一个forest用于树规范的样式:

  not before/.style={
    no node before=#1,
    for children={
      no edge before=#1,
    }
  },

它采用单个参数,该参数应为当前节点应显示的第一张幻灯片的编号。它确定当前节点的可见性以及此节点与其子节点之间绘制的边的可见性。与 Qrrbrbirlbel 不同dont show before,这不会影响兄弟节点或祖先节点的可见性。只有当前节点及其子节点的边缘会受到影响。

最后,我们定义一个样式,bottom up它将激活树的可见性/不可见性。它应该用在树的前言中,这样就可以根据需要打开或关闭效果,而无需更改not before相关节点的值。

  bottom up/.style={% based on Qrrbrbirlbel's answer at https://tex.stackexchange.com/a/112895/
      /tikz/visible on=<\forestoption{no node before}->,
      /tikz/every label/.append style={visible on=<\forestoption{no node before}->},
      /tikz/every edge label/.append style={visible on=<\forestoption{no edge before}->},
      edge={/tikz/visible on=<\forestoption{no edge before}->},
  }

这是 Qrrbrbirlbel 代码的扩展,确保效果不仅适用于节点和边,也适用于边标签和标签。

然后我们可以轻松地指定树本身:

  \begin{forest}
    /tikz/every label/.append style={text height=1ex, label distance=5pt},
    for tree={
      circle,
      draw,
      very thick,
      edge={very thick},
      s sep+=10pt,
      fill=white!25,
      minimum size=20pt,
      bottom up,% activate the effect of not before for the tree
    }
    [, label=above:{car, bus, cat, dot}, not before=3% specify visibility
      [, label=above left:{car, bus}, not before=2% specify visibility
        [, label=below:car]
        [, label=below:bus]
      ]
      [, label=above right:{cat, dog}, not before=2% specify visibility
        [, label=below:cat]
        [, label=below:dog]
      ]
    ]
  \end{forest}

结果如下:

自下而上的树

完整代码:

\documentclass{beamer}
\usepackage{forest}

\tikzset{% set up for transitions using tikz with beamer overlays
  invisible/.style={opacity=0,text opacity=0},
  visible on/.style={alt=#1{}{invisible}},
  alt/.code args={<#1>#2#3}{%
    \alt<#1>{\pgfkeysalso{#2}}{\pgfkeysalso{#3}} % \pgfkeysalso doesn't change the path
  },
}
\forestset{%
  declare toks={no node before}{1},
  declare toks={no edge before}{1},
  not before/.style={
    no node before=#1,
    for children={
      no edge before=#1,
    }
  },
  bottom up/.style={% based on Qrrbrbirlbel's answer at https://tex.stackexchange.com/a/112895/
      /tikz/visible on=<\forestoption{no node before}->,
      /tikz/every label/.append style={visible on=<\forestoption{no node before}->},
      /tikz/every edge label/.append style={visible on=<\forestoption{no edge before}->},
      edge={/tikz/visible on=<\forestoption{no edge before}->},
  }
}

\begin{document}
\begin{frame}
  \centering
  \begin{forest}
    /tikz/every label/.append style={text height=1ex, label distance=5pt},
    for tree={
      circle,
      draw,
      very thick,
      edge={very thick},
      s sep+=10pt,
      fill=white!25,
      minimum size=20pt,
      bottom up,
    }
    [, label=above:{car, bus, cat, dot}, not before=3
      [, label=above left:{car, bus}, not before=2
        [, label=below:car]
        [, label=below:bus]
      ]
      [, label=above right:{cat, dog}, not before=2
        [, label=below:cat]
        [, label=below:dog]
      ]
    ]
  \end{forest}
\end{frame}
\end{document}

相关内容