如何将样式应用于特定幻灯片上的现有 tikz 节点

发布于 2024-09-04 06:58:19 字数 1287 浏览 7 评论 0原文

这就是我想要做的

    \begin{tikzpicture}
    [node distance = 1cm, auto,font=\footnotesize,
    % STYLES
    every node/.style={node distance=1.3cm},
    comment/.style={rectangle, inner sep= 5pt, text width=4cm, node distance=0.25cm, font=},
    module/.style={rectangle, drop shadow, draw, fill=black!10, inner sep=5pt, text width=3cm, text badly centered, minimum height=0.8cm, font=\bfseries\footnotesize\sffamily,rounded corners},
    selected/.style={fill=red!40}]

    \node [module] (nodeA) {node A};
    \node [module, below of=nodeA] (nodeA) {node B};

    \only<1>{
      \node [comment, text width=6cm, right=0.25 of nodeA] {short description of Node A};
      \node [comment, text width=6cm, right=0.25 of nodeB] {short description of Node B};
     }

    \only<2>{
      \node [selected] (nodeA) {};
      \node [comment, text width=6cm, right=0.25 of nodeA] {long description of node A};
    }
    \only<3>{
      \node [selected] (nodeB) {};
      \node [comment, text width=6cm, right=0.25 of nodeA] {long description of node B};
    }
    \end{tikzpicture}

问题是

      \node [selected] (nodeB) {};

创建一个新节点,但我希望它应用现有节点的样式。有什么办法可以做到吗?

当然,我可以拥有处于选定状态和未选定状态的每个节点的副本,但我真的想要一个正常的解决方案。

This is what I'm trying to do

    \begin{tikzpicture}
    [node distance = 1cm, auto,font=\footnotesize,
    % STYLES
    every node/.style={node distance=1.3cm},
    comment/.style={rectangle, inner sep= 5pt, text width=4cm, node distance=0.25cm, font=},
    module/.style={rectangle, drop shadow, draw, fill=black!10, inner sep=5pt, text width=3cm, text badly centered, minimum height=0.8cm, font=\bfseries\footnotesize\sffamily,rounded corners},
    selected/.style={fill=red!40}]

    \node [module] (nodeA) {node A};
    \node [module, below of=nodeA] (nodeA) {node B};

    \only<1>{
      \node [comment, text width=6cm, right=0.25 of nodeA] {short description of Node A};
      \node [comment, text width=6cm, right=0.25 of nodeB] {short description of Node B};
     }

    \only<2>{
      \node [selected] (nodeA) {};
      \node [comment, text width=6cm, right=0.25 of nodeA] {long description of node A};
    }
    \only<3>{
      \node [selected] (nodeB) {};
      \node [comment, text width=6cm, right=0.25 of nodeA] {long description of node B};
    }
    \end{tikzpicture}

The problem is

      \node [selected] (nodeB) {};

creates a new node, but I want it to apply the style for the existing node. Is there any way to do so?

Of course I could have copies of every node in selected state and not-selected state, but I really want to have a normal solution.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

天邊彩虹 2024-09-11 06:58:19

我认为您不能按照您想要的方式执行此操作(假设我正确理解问题),因为一旦绘制了节点,就无法更改其外观。我建议使用 Beamer 的 \alt 宏:

\alt<2>{\node[module,selected] at (nodeA) {node A};}{\node[module] at (nodeA) {node A};}
\alt<3>{\node[module,selected] at (nodeB) {node B};}{\node[module] at (nodeB) {node B};}
\node[comment,text width=6cm,right=0.25 of nodeA]{\alt<2>{short description}{long description}};
\node[comment,text width=6cm,right=0.25 of nodeB]{\alt<3>{short description}{long description}};

或者类似的东西(你可能需要修改分号才能让它工作,我目前无法测试)。

另一种选择是实际上只绘制一个新节点。如果包含

\node[module,selected] at (nodeA) {node A};

\only<2> 中,则会在节点 A 的相同位置绘制一个看起来与节点 A 类似的节点,除了红色背景。新节点将覆盖原始节点A。

I don't think you can do this the way you want to (assuming I understand the question correctly), because once a node is drawn, there's no way to change its appearance. I'd suggest using Beamer's \alt macro:

\alt<2>{\node[module,selected] at (nodeA) {node A};}{\node[module] at (nodeA) {node A};}
\alt<3>{\node[module,selected] at (nodeB) {node B};}{\node[module] at (nodeB) {node B};}
\node[comment,text width=6cm,right=0.25 of nodeA]{\alt<2>{short description}{long description}};
\node[comment,text width=6cm,right=0.25 of nodeB]{\alt<3>{short description}{long description}};

Or something like that (you might have to tinker with the semicolons to get it to work, I can't test that at the moment).

Another option would be to actually just draw a new node. If you include

\node[module,selected] at (nodeA) {node A};

inside \only<2>, that will draw a node that looks just like node A, except with a red background, at the same position at node A. The new node will cover up the original node A.

℡寂寞咖啡 2024-09-11 06:58:19

有时,为了避免重复,最好这样做:

% #1    Overlay specs.
% #2    Style name.
% #4    Style properties.
\def\onlystyle<#1>#2#3{%
    \alt<#1>{%
        \tikzset{#2/.style = {#3}}
    }{%
        \tikzset{#2/.style = {}}
    }%
}

然后,例如,如果将其放在框架中:

\onlystyle<2>{selected}{fill = red}

样式 selected 将定义为 fill = red 在动画的第二张幻灯片上,并且作为一种样式,对其他所有幻灯片都没有任何影响。然后,您可以编写一个可读的图形,例如:

\begin{tikzpicture}
    \node           at (0, 0) {A};
    \node[selected] at (1, 0) {B};
    \node           at (2, 0) {C};
\end{tikzpicture}

“B”节点将在第二张幻灯片上突出显示。这样,您就不必复制粘贴大量的节点定义。
当然,它不能应用于每一个动画需求,但我喜欢将这种技术保留在我的袖子里。

Sometimes, to avoid repetitions, it may be nice to do something like this:

% #1    Overlay specs.
% #2    Style name.
% #4    Style properties.
\def\onlystyle<#1>#2#3{%
    \alt<#1>{%
        \tikzset{#2/.style = {#3}}
    }{%
        \tikzset{#2/.style = {}}
    }%
}

Then, if you put, for example, this within a frame:

\onlystyle<2>{selected}{fill = red}

the style selected will be defined as fill = red on the second slide of the animation, and as a style with no effect whatsoever on every other slide. Then, you can write a readable figure such as:

\begin{tikzpicture}
    \node           at (0, 0) {A};
    \node[selected] at (1, 0) {B};
    \node           at (2, 0) {C};
\end{tikzpicture}

and the “B” node will be highlighted on the second slide. This way, you don't have to copy-paste tons of node definitions.
Of course, it cannot be applied to every single animation need, but I like to keep this technique up my sleeve.

初心 2024-09-11 06:58:19

我发现了另一种解决方案,与以前的所有解决方案(包括我之前发布的解决方案)相比,它具有优势(更多功能!)。

首先我提到改进的解决方案,然后解释为什么它实际上比所有其他解决方案显示出更多的功能。

以下解决方案改编自 我该如何制作Beamer 覆盖 TikZ 节点属性?,使用额外的 tikz 库,并使用幻灯片编号相关属性的参数(当然,对于幻灯片编号)。请注意,tikz 设置现在必须在框架外完成。

\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{overlay-beamer-styles}
\begin{document}

\begin{frame}{With code/node duplication (explicit frame numbers)}
  \begin{tikzpicture}
  [every node/.style={draw,circle},
   redStyle/.style={fill=red},
   blueStyle/.style={fill=blue}]
   
  \node<1> [] (A) {A};          % no style
  \node<2> [redStyle]  (A) {A}; % red style
  \node<3> [blueStyle] (A) {A}; % blue style

  \node [right of=A] (B) {B};
  \draw [-latex] (A) -- (B) ;
  \end{tikzpicture}
\end{frame}


\tikzset{
  every node/.style={draw,circle},
  redStyle/.style={fill=red},     redStyle on/.style={alt=#1{redStyle}{}},
  blueStyle/.style={fill=blue}, blueStyle on/.style={alt=#1{blueStyle}{}}}
\begin{frame}{\textbf{Without} code/node duplication (explicit frame numbers)}
  \begin{tikzpicture}
  \node [redStyle on=<2>,blueStyle on=<3>] (A) {A};   
  \node [right of=A] (B) {B};
  \draw [-latex] (A) -- (B) ;
  \end{tikzpicture}
\end{frame}


\tikzset{
  every node/.style={draw,circle},
  redStyle/.style={fill=red},     redStyle on/.style={alt=#1{redStyle}{}},
  blueStyle/.style={fill=blue}, blueStyle on/.style={alt=#1{blueStyle}{}}}
\begin{frame}{\textbf{Without} code/node duplication (relative frame numbers)}
  \begin{tikzpicture}
  \node [redStyle on=<+(1)>,blueStyle on=<+(1)>] (A) {A};   
  \node [right of=A] (B) {B};
  \draw [-latex] (A) -- (B) ;
  \end{tikzpicture}
\end{frame}

\end{document}

现在解释为什么这个解决方案是迄今为止最好的解决方案,即它具有哪些附加功能以及它们为什么(或何时)相关。嗯,只是因为相应的属性不必在同一帧内不同用途的相同幻灯片编号上显示。简单的例子:

假设您有一个简单的树,即具有连接它们的有向边的节点。假设您想将特定幻灯片中的某些边缘设为粗体。当然,你有多个边缘,所以很明显它们不会同时变得粗体!一些边缘在帧编号 m 到 n 处变粗,其他边缘在 x 和 y 处变粗。现在可以通过使用节点(或在本例中为边)属性 timedBold on=timedBold on= 轻松实现这一点。

I found yet another solution, which has advantages (more functionality!) compared to all previous solutions, including the one I posted before.

First I mention the improved solution, then I explain why it actually shows more functionality than all other solutions.

The following solution, adapted from How can I make Beamer overlays with TikZ node attributes?, uses an additional tikz library and uses a parameter for the slide number-dependent attribute (for the slide numbers, of course). Note that the tikz setting has to be done outside the frame now.

\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{overlay-beamer-styles}
\begin{document}

\begin{frame}{With code/node duplication (explicit frame numbers)}
  \begin{tikzpicture}
  [every node/.style={draw,circle},
   redStyle/.style={fill=red},
   blueStyle/.style={fill=blue}]
   
  \node<1> [] (A) {A};          % no style
  \node<2> [redStyle]  (A) {A}; % red style
  \node<3> [blueStyle] (A) {A}; % blue style

  \node [right of=A] (B) {B};
  \draw [-latex] (A) -- (B) ;
  \end{tikzpicture}
\end{frame}


\tikzset{
  every node/.style={draw,circle},
  redStyle/.style={fill=red},     redStyle on/.style={alt=#1{redStyle}{}},
  blueStyle/.style={fill=blue}, blueStyle on/.style={alt=#1{blueStyle}{}}}
\begin{frame}{\textbf{Without} code/node duplication (explicit frame numbers)}
  \begin{tikzpicture}
  \node [redStyle on=<2>,blueStyle on=<3>] (A) {A};   
  \node [right of=A] (B) {B};
  \draw [-latex] (A) -- (B) ;
  \end{tikzpicture}
\end{frame}


\tikzset{
  every node/.style={draw,circle},
  redStyle/.style={fill=red},     redStyle on/.style={alt=#1{redStyle}{}},
  blueStyle/.style={fill=blue}, blueStyle on/.style={alt=#1{blueStyle}{}}}
\begin{frame}{\textbf{Without} code/node duplication (relative frame numbers)}
  \begin{tikzpicture}
  \node [redStyle on=<+(1)>,blueStyle on=<+(1)>] (A) {A};   
  \node [right of=A] (B) {B};
  \draw [-latex] (A) -- (B) ;
  \end{tikzpicture}
\end{frame}

\end{document}

Now the explanation why this solution is the best mentioned so far, i.e. which additional features it has and why (or when) they are relevant. Well, simply because the respective property does not have to show at the same slide number for different usages within the same frame. Simple example:

Let's say you have a simple tree, i.e. nodes with directed edges connecting them. Say you want to make some of the edges bold in specific slides. Of course you have multiple edges, so clearly they do not all become bold at the very same time! Some edges get bold at frame numbers m to n, others get bold at x and y. This can now be trivially realized with using the node (or edge, in this case) properties timedBold on=<m-n> and timedBold on=<x,y>.

箜明 2024-09-11 06:58:19

请注意,还有另一种可能性,对我来说,这似乎比前两个建议更好一些,因为它的代码重复更少(与 David Z 的解决方案相比),并且因为(与 Alice M. 的解决方案相比),您不需要需要定义一个必须在框架之外定义的新命令(尽管定义这个附加命令可能对任何人来说都不是问题)。原则上,以下建议似乎与 Alice M 的建议密切相关。

无论如何,解决方案是直接应用 如何在使用 Beamer 叠加层时修改 TikZ 中的节点

基本上只是根据帧数重新定义样式。请参阅以下最小示例,第二帧或第三帧。 (我重新做了一个最小的例子,因为我认为给定的例子极其复杂;它肯定不是一个最小的例子,而且也不能单独工作。)

\documentclass{beamer}
\usepackage{tikz}
\begin{document}

\begin{frame}{With code/node duplication (explicit frame numbers)}
  \begin{tikzpicture}
  [every node/.style={draw,circle},
   redStyle/.style={fill=red},
   blueStyle/.style={fill=blue}]
   
  \node<1> [] (A) {A};          % no style
  \node<2> [redStyle]  (A) {A}; % red style
  \node<3> [blueStyle] (A) {A}; % blue style

  \node [right of=A] (B) {B};
  \draw [-latex] (A) -- (B) ;
  \end{tikzpicture}
\end{frame}

\begin{frame}{\textbf{Without} code/node duplication (explicit frame numbers)}
  \only<1>{\tikzset{colorStyle/.style={}}}          % no style
  \only<2>{\tikzset{colorStyle/.style={fill=red}}}  % red style
  \only<3>{\tikzset{colorStyle/.style={fill=blue}}} % blue style

  \begin{tikzpicture}
  [every node/.style={draw,circle}]
    
  \node [colorStyle] (A) {A}; % frame-dependent style
  \node [right of=A] (B) {B};
  \draw [-latex] (A) -- (B) ;
  \end{tikzpicture}
\end{frame}

\begin{frame}{\textbf{Without} code/node duplication (relative frame numbers)}
  \only<+>{\tikzset{colorStyle/.style={}}}          % no style
  \only<+>{\tikzset{colorStyle/.style={fill=red}}}  % red style
  \only<+>{\tikzset{colorStyle/.style={fill=blue}}} % blue style

  \begin{tikzpicture}
  [every node/.style={draw,circle}]
    
  \node [colorStyle] (A) {A}; % frame-dependent style
  \node [right of=A] (B) {B};
  \draw [-latex] (A) -- (B) ;
  \end{tikzpicture}
\end{frame}

\end{document}

Note that there is yet another possibility, which to me seems a bit better than the previous two suggestions, because it has less code duplication (compared to David Z's solution), and because (compared to Alice M.'s solution) you do not need to define a new command that you had to define outside the frame (though defining this additional command is probably not an issue to anybody). In principle, the following suggestion seems to be closely related to the suggestion by Alice M.

Anyway, the solution is a direct application of How to modify a node in TikZ when using beamer's overlays.

Is basically just re-defines a style based on the frame number. See the following minimal example, second or third frame. (I re-did the minimal example since I regard the given one extremely complicated; it was certainly not a minimal example, and also not working on its own.)

\documentclass{beamer}
\usepackage{tikz}
\begin{document}

\begin{frame}{With code/node duplication (explicit frame numbers)}
  \begin{tikzpicture}
  [every node/.style={draw,circle},
   redStyle/.style={fill=red},
   blueStyle/.style={fill=blue}]
   
  \node<1> [] (A) {A};          % no style
  \node<2> [redStyle]  (A) {A}; % red style
  \node<3> [blueStyle] (A) {A}; % blue style

  \node [right of=A] (B) {B};
  \draw [-latex] (A) -- (B) ;
  \end{tikzpicture}
\end{frame}

\begin{frame}{\textbf{Without} code/node duplication (explicit frame numbers)}
  \only<1>{\tikzset{colorStyle/.style={}}}          % no style
  \only<2>{\tikzset{colorStyle/.style={fill=red}}}  % red style
  \only<3>{\tikzset{colorStyle/.style={fill=blue}}} % blue style

  \begin{tikzpicture}
  [every node/.style={draw,circle}]
    
  \node [colorStyle] (A) {A}; % frame-dependent style
  \node [right of=A] (B) {B};
  \draw [-latex] (A) -- (B) ;
  \end{tikzpicture}
\end{frame}

\begin{frame}{\textbf{Without} code/node duplication (relative frame numbers)}
  \only<+>{\tikzset{colorStyle/.style={}}}          % no style
  \only<+>{\tikzset{colorStyle/.style={fill=red}}}  % red style
  \only<+>{\tikzset{colorStyle/.style={fill=blue}}} % blue style

  \begin{tikzpicture}
  [every node/.style={draw,circle}]
    
  \node [colorStyle] (A) {A}; % frame-dependent style
  \node [right of=A] (B) {B};
  \draw [-latex] (A) -- (B) ;
  \end{tikzpicture}
\end{frame}

\end{document}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文