Tikz:在创建节点之后/之前以某种样式添加任意节点/路径

Tikz:在创建节点之后/之前以某种样式添加任意节点/路径

我想弄清楚如何创建一种样式,基本上在节点顶部(或甚至在后面,如果可能的话)添加一些节点/路径。我尝试了一下,append after command最终设法添加了几个节点,但我找不到如何添加任意代码,尤其是我无法添加路径。继续的好方法是什么?

谢谢你!

梅威瑟:

\documentclass[]{beamer}
\usepackage{tikz}
\usetikzlibrary{positioning,fit,backgrounds,decorations.pathreplacing,calc,math,matrix}
\usepackage{forest}


% My style
\tikzstyle{myboxes}=[draw=#1,fill=#1!20,rounded corners,anchor=base]

\begin{document}

\begin{frame}{My test}
  \begin{figure}
    \centering
    \begin{tikzpicture}[
        n/.style={myboxes=orange},
        keep name/.style={prefix after command={\pgfextra{\let\fixname\tikzlastnode}}},
        c/.style={
          keep name,
          append after command={
            node [
              at=(\fixname.north),
              inner sep=3pt,
              draw=red,
              thick,
              inner sep=-\pgflinewidth,
              cross out
              ] {}
            node [
              at=(\fixname.south),
              inner sep=3pt,
              draw=green,
              thick,
              inner sep=-\pgflinewidth,
              cross out
              ] {}
            % Does not work
            % draw [red,very thick] (\fixname.north) -- (\fixname.south)
          }
        }
        ]
      \matrix[matrix of nodes, row sep=2mm](sel){
        |[n,c]|A\\
        |[n,c]|C \\
        |[n]|B\\
      };      
    \end{tikzpicture}
  \end{figure}
\end{frame}
\end{document}

-- 编辑 -- 我尝试path picture按照 marmot 的建议进行操作,但不幸的是我无法超出边界框:

在此处输入图片描述

\documentclass[]{beamer}
\usepackage{tikz}
\usetikzlibrary{positioning,fit,backgrounds,decorations.pathreplacing,calc,math,matrix}
\usepackage{forest}


% My style
\tikzstyle{myboxes}=[draw=#1,fill=#1!20,rounded corners,anchor=base]

\begin{document}

\begin{frame}{My test}
  \begin{figure}
    \centering
    \begin{tikzpicture}[
        n/.style={myboxes=orange},
        c/.style={
          path picture = {
            \draw[-latex] ($(path picture bounding box.north west)$) -- ($(path picture bounding box.south east)$);
            \draw[-latex] ($(path picture bounding box.north west)$) -- ($(path picture bounding box.north east)$);
          }
        }
        ]
      \matrix[matrix of nodes, row sep=2mm](sel){
        |[n,c]|A\\
        |[n,c]|C \\
        |[n]|B\\
      };      
    \end{tikzpicture}
  \end{figure}
\end{frame}
\end{document}

-- 编辑 2 -- 正如 Ignasi 所注意到的,最好的通用解决方案似乎是 Marmot 提出的解决方案这里。然而它不适用于矩阵,因为矩阵中有层,所以基本上所有点都集中在中心点附近……

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{calc,matrix,positioning}
\usetikzlibrary{backgrounds}
\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground}
\tikzset{
  % keep name/.style={prefix after command={\pgfextra{\let\fixname\tikzlastnode}}},
  myt/.style={
    % keep name,
    fill=green!30,
    rounded corners,
    draw=green,
    append after command={\pgfextra%
      % \fixname does not solve the problem either
      \begin{pgfonlayer}{background} 
        \draw[-latex,blue] (\tikzlastnode.north west) -- (\tikzlastnode.south east);
        \node[orange] at (\tikzlastnode.north) {\tiny \scalebox{.5}{A}};
        \node[orange] at (\tikzlastnode.south) {\tiny \scalebox{.5}{B}};
      \end{pgfonlayer}
      \node[] at ($(\tikzlastnode.east)!.5!(\tikzlastnode.north east)$) {\tiny \scalebox{.5}{Samelevel}};
      \begin{pgfonlayer}{foreground} 
        \draw[-latex,red] (\tikzlastnode.south west) -- (\tikzlastnode.north east);
        \node[purple] at (\tikzlastnode.east) {\tiny \scalebox{.5}{D}};
        \node[purple] at (\tikzlastnode.west) {\tiny \scalebox{.5}{C}};
      \end{pgfonlayer}
      \endpgfextra}
  }
}
\begin{document}
\begin{tikzpicture}
  \node[myt](a){a};
  \node[right=of a, myt](b){b};
  \node[myt, right=of b](c){c};
  \matrix[matrix of nodes, right=of c](matrixname){
    |[myt]|U & |[myt]|V \\
    |[myt]|W & |[myt]|X \\
  };
\end{tikzpicture}
\end{document}

输出在单个节点上有效:

在此处输入图片描述

但不适用于矩阵:

在此处输入图片描述

-- 编辑 3 和 4 --

在提出使用之后pics,我尝试了一下,确实看起来非常强大。唯一的问题是图片并不是真正的风格,但它们可以很好地模拟风格,甚至可以“组合”它们,也可以将它们包含在矩阵中。请参阅下面的代码和图片:

在此处输入图片描述

\documentclass[]{article}

\usepackage{tikz}
\usetikzlibrary{arrows,positioning,shapes,calc}
\begin{document}

\tikzset{
  % Args: style of the main node, content of the main node
  % and color of back arrow and node
  pics/addarrows/.style args={#1/#2/#3}{
    code = {
      \node[rounded corners, #1,opacity=0] (tmpnode) {#2};
      \draw[-latex,#3] ($(tmpnode.west)+(-0.2,0)$) -- ($(tmpnode.east)+(0.2,0)$);
      \node[rounded corners, #1] {#2};
      \draw[-latex] (tmpnode.south west) -- (tmpnode.north east);
      \draw[-latex] (tmpnode.north west) -- (tmpnode.south east);
      \node[fill=#3,circle,inner sep=2pt] at (tmpnode.south) {};
    }},
  % Creates a shortcut
  pics/defarrows/.style args={#1}{
    code = {
      \pic{addarrows={draw=red,fill=red!20}/#1/red};
    }
  },
  pics/composableHorizVert/.style={
    code={
      \begin{scope}[transparency group, opacity=0]
        #1
      \end{scope}
      \draw[-latex] ($(tmpnode.west)+(-0.2,0)$) -- ($(tmpnode.east)+(0.2,0)$);
      #1
      \draw[-latex] ($(tmpnode.north)+(0,0.2)$) -- ($(tmpnode.south)+(0,-0.2)$);
    }
  },
  pics/composableDiag/.style={
    code={
      \begin{scope}[transparency group, opacity=0]
        #1
      \end{scope}
      \draw[-latex] ($(tmpnode.north west)+(-0.2,0.2)$) -- ($(tmpnode.south east)+(0.2,-0.2)$);
      #1
      \draw[-latex] ($(tmpnode.north east)+(0.2,0.2)$) -- ($(tmpnode.south west)+(-0.2,-0.2)$);
    }
  }
}

Some defaults pics on a matrix:\\
\begin{tikzpicture}[auto]  
  \matrix[](matrixname){
    \pic{defarrows=A}; & \pic{defarrows=B}; \\
    \pic{defarrows=C}; & \pic{defarrows=DEF};\\
  };
\end{tikzpicture}

Some pics with arguments that specify the ``main node style'':\\
\begin{tikzpicture}[auto]  
  \pic [local bounding box=picgreen] {addarrows={draw=green,fill=green!20,ellipse}/My text/purple};
  \pic [below right=of picgreen,local bounding box=picyellow] {addarrows={draw=orange,fill=yellow,ellipse}/My text/red};
  % NB: If you want to specify a specific node inside the pic, you can always try to specify
  % a name through a new argument
  \draw[-latex,dashed] (picgreen) -- (picyellow);
\end{tikzpicture}

Show that it's possible to compose ``pics styles'':\\
\begin{tikzpicture}[baseline]
  \pic{composableHorizVert={\node[name=tmpnode,fill=red!30]{A};}};
\end{tikzpicture}
+
\begin{tikzpicture}[baseline]
  \pic{composableDiag={\node[name=tmpnode,fill=red!30]{A};}};
\end{tikzpicture}
=
\begin{tikzpicture}[baseline]
  \pic{composableHorizVert={\pic{composableDiag={\node[name=tmpnode,fill=red!30]{A};}};}};
\end{tikzpicture}

\end{document}

答案1

您的问题包含以下所有要素:

  • 使用添加路径的某些部分append after command
  • 这条添加的路径可能是一个pic
  • 您可以在pic特定图层(背景、主图层、背景)上绘图
  • 如果您不希望添加的绘图修改边界框,您可以使用pgfinterruptboundingbox环境。

下面是在节点的上方和后方t绘制图片的样式示例:a

\documentclass[tikz,border=7pt]{standalone}
\usetikzlibrary{backgrounds,matrix}
\tikzset{
  a/.pic = {
    \begin{pgfinterruptboundingbox}
      \node[black,rotate=45,fill=white,draw] (over) {over the node};
      \draw[bend left,-latex] (over.east) to[out=90,looseness=7] (#1.east);
      \begin{scope}[on background layer]
        \node[black,rotate=-45,scale=2] {behind the node};
      \end{scope}
    \end{pgfinterruptboundingbox}
  },
  t/.style={
    append after command={
      (\tikzlastnode.center) pic{a=\tikzlastnode}
    }
  }
}
\begin{document}
  \begin{tikzpicture}
    \filldraw[red] (0,3) circle (1pt) node[t,draw,fill=yellow,scale=3]{Node};
    \matrix[matrix of nodes, row sep=2mm,n/.style={text width=16mm,fill=blue!10},draw=purple](sel){
        |[n]|A\\
        |[n,t]|C \\
        |[n]|B\\
      };
  \path (-5,-5) (5,5);
  \end{tikzpicture}
\end{document}

在此处输入图片描述

答案2

在其他节点的任意位置(甚至后面)添加节点的最佳方式是使用labels。标签是节点,它们可以有自己的样式。

您的代码适合声明c为标签样式:

\documentclass[]{beamer}
\usepackage{tikz}
\usetikzlibrary{matrix, shapes.misc}

% My style
\tikzset{
    myboxes/.style={
        draw=#1,fill=#1!20,rounded corners,anchor=base}
}

\begin{document}

\begin{frame}[fragile]{My test}
  \begin{figure}
    \centering
    \begin{tikzpicture}[
        n/.style={myboxes=orange},
        c/.style={
            inner sep=3pt,
          draw=#1,
          thick,
          inner sep=-\pgflinewidth,
          cross out
          },
        d/.style={
            inner sep=3pt,
          draw=#1,
          minimum size=1cm,
          behind path,
          thick,
          inner sep=-\pgflinewidth,
          cross out,
          },
        ]
      \matrix[matrix of nodes, row sep=2mm](sel){
        |[n,label={[c=red]:},label={[c=green]below:}]|A\\
        |[n,label={[c=blue]right:a}]|C \\
        |[n,label={[d=green]center:behind}]|B\\
      };      
    \end{tikzpicture}
  \end{figure}
\end{frame}
\end{document}

在此处输入图片描述

相关内容