在 tikz 中,是否可以定义一个节点并稍后设置其位置?

在 tikz 中,是否可以定义一个节点并稍后设置其位置?

我正在尝试绘制一个图表,但我的代码变得太杂乱,难以阅读。出于代码样式的目的,是否可以先在一个地方定义一个节点,然后再调整其位置?

假设我有这样一些简单的事情:

\documentclass{standalone}
\usepackage{tikz}

\makeatletter
\tikzstyle{mystyle} = [rectangle,rounded corners,fill=blue!20]
\makeatother

\begin{document}
    \begin{tikzpicture}[font=\sffamily]    
        \node[mystyle](node1) at (0, 0) {A};
        \node[mystyle](node2) [left of=node1] {B};
    \end{tikzpicture}
\end{document}

我想要做的是:

\begin{tikzpicture}[font=\sffamily]    
    \node[mystyle](node1) {A};
    \node[mystyle](node2) {B};

    \somecommand (node1) at (0, 0)
    \somecommand (node2) [left of=node1] 

\end{tikzpicture}

那可能吗?

或者可以变成这样:

\begin{tikzpicture}[font=\sffamily]

\matrix  {
    \node[mystyle](node1){A}; & \node[mystyle](node3){D}; \\
    \node[mystyle](node2){B}; & \node[mystyle](node4){C}; \\
};

\end{tikzpicture}

变成这样:

\begin{tikzpicture}[font=\sffamily]

\node[mystyle](node1){A};
\node[mystyle](node2){B};
\node[mystyle](node3){C};
\node[mystyle](node4){D};

\matrix  {
    \something (node1); & \something (node3); \\
    \something (node2); & \something (node4); \\
};

\end{tikzpicture}

有什么办法可以做到这一点?

答案1

我不确定你到底在做什么,所以这可能完全没有帮助。如果是这样,只要说出来我就可以删除它。

您可以使用pics 来定义小图片,以便以后反复重复使用。

从技术上讲,您可以pic为每个所需的节点创建一个,然后在相关点调用相关代码。但是,我认为这实际上是对语法的滥用。但是,如果您要创建许多类似的节点,那么这样做就非常合理了。

请注意,尽管pics 非常像节点,但它们并不完全像节点,因此在您的实际文档中可能根本无法正常工作。

\documentclass[border=5pt,mult,tikz]{standalone}

\begin{document}

  \tikzset{
    font=\sffamily,
    mystyle/.style = {rectangle, rounded corners, fill=blue!20},
  }

  \begin{tikzpicture}% abuse of pics?
    [
      node1/.pic={
        \node [mystyle, pic actions] (node1) {A};
      },
      node2/.pic={
        \node [mystyle, pic actions] (node2) {B};
      },
    ]
    \pic at (0,0) {node1};
    \pic [left of=node1] {node2};
  \end{tikzpicture}

  \begin{tikzpicture}% more sensible use of pics?
    [
      my node/.pic={
        \node [mystyle] {#1};
      },
    ]

    \matrix  {
      \pic {my node={A}}; & \pic {my node={D}}; \\
      \pic {my node={B}}; & \pic {my node={C}}; \\
    };

  \end{tikzpicture}

\end{document}

比如,如果您需要引用图片以便在它们之间画线,那么您就不能像处理节点那样直接处理它们,因为它们不会像节点那样自动获取锚点。但是,您可以使用特殊语法将命名坐标添加到图片中,以供以后使用。其工作方式是,您在定义中添加特定的命名坐标(-my point)(注意连字符),然后将名称传递给图片,就像传递给节点一样(my pic)。然后,您可以将命名点引用为例如my pic-my point。据我所知,这比使用实际节点效率低,但这可能不是一个大问题,除非您的图片非常大,否则使用图片会明显减慢编译时间。

下面是一个示例,它在定义中添加了一些命名坐标my node,然后使用它们来放置红色圆圈,这些圆圈对应于图片本身中定义的节点的各种锚点。这显然只是为了说明目的:在实践中,你肯定不希望到处都是小红圆圈!但重点是你可以使用这些坐标来绘制节点之间的线条或其他任何东西。

  \begin{tikzpicture}% more sensible use of pics?
    [
      my node/.pic={
        \node (-center) [mystyle] {#1};
      \foreach \i in {north,south,east,west,north west,north east,south west,south east}
        \coordinate (-\i) at (-center.\i);
      },
    ]

    \matrix  {
      \pic (a) {my node={A}}; & \pic (d) {my node={D}}; \\
      \pic (b) {my node={B}}; & \pic (c) {my node={C}}; \\
    };

    \foreach \i in {a,b,c,d}
      \foreach \j in  {north,south,east,west,north west,north east,south west,south east,center}
        \path [fill=red] (\i-\j) circle (.5pt);;

  \end{tikzpicture}

命名图片坐标

答案2

您也可以定义自己的构建\node内容的宏。左边是您提供的手动指定的示例,右边是通过调用获得的示例\Node

在此处输入图片描述

笔记:

代码:

\documentclass{article}
\usepackage{tikz}

\tikzset{mystyle/.style={rectangle,rounded corners,fill=blue!20}}

\newcommand{\Node}[2][]{%
    % #1 = node options
    % #2 = node text
    \node[mystyle,#1] (node1) at (0,0) {#2}
}%


\begin{document}
    \begin{tikzpicture}[font=\sffamily]    
        \node[mystyle](node1) at (0, 0) {A};
        \node[mystyle](node2) [left of=node1] {B};
    \end{tikzpicture}    
    \hspace*{2.0cm}
    \begin{tikzpicture}[font=\sffamily]    
        \Node{A};
        \Node[left of=node1]{B};
    \end{tikzpicture}

    \bigskip\par
    \begin{tikzpicture}[font=\sffamily]    
        \matrix  {
            \node[mystyle](node1){A}; & \node[mystyle](node3){D}; \\
            \node[mystyle](node2){B}; & \node[mystyle](node4){C}; \\
        };
    \end{tikzpicture}
    \hspace*{2.0cm}
    \begin{tikzpicture}[font=\sffamily]    
        \matrix  {
            \Node{A}; & \Node{D}; \\
            \Node{B}; & \Node{C}; \\
        };
    \end{tikzpicture}
\end{document}

答案3

样式可以大大提高可读性。

这是仅使用样式的概念证明。

这个想法是为每个命名节点定义一种<name-of-node>pos样式,以便您可以通过使用atleft等键定义此样式来指定定位,与节点的创建点分开。

\documentclass{standalone}
\usepackage{tikz}

\tikzset{
  mynode/.style = {
    rectangle,
    rounded corners,
    fill=blue!20,
    name=#1,
    #1pos/.try
  },
  position of/.style args={#1 is #2}{
    #1pos/.style={#2}
  }
}

\begin{document}

    \begin{tikzpicture}[
      font=\sffamily,
      position of=node1 is {at={(0,0)}},
      position of=node2 is {left of=node1}
    ]
      \node[mynode=node1] {A};
      \node[mynode=node2] {B};
    \end{tikzpicture}

\end{document}

此处的样式position of仅用于提高可读性node1pos/.style={...}

如果您希望在创建后指定坐标(不是必需的),您可以将图形包装在宏定义中:

\documentclass{standalone}
\usepackage{tikz}

\tikzset{
  mynode/.style = {
    rectangle,
    rounded corners,
    fill=blue!20,
    name=#1,
    #1pos/.try
  },
  % Only necessary for option 2
  position of/.style args={#1 is #2}{
    #1pos/.style={#2}
  }
}

\begin{document}

  \newcommand{\makepicture}[1][]{
    \begin{tikzpicture}[font=\sffamily,#1]
        \node[mynode=node1] {A};
        \node[mynode=node2] {B};
    \end{tikzpicture}
  }

  % Option 1
  \makepicture[
    node1pos/.style={at={(0,0)}},
    node2pos/.style={left of=node1}
  ]

  % Option 2
  \makepicture[
    position of=node1 is {at={(0,0)}},
    position of=node2 is {left of=node1}
  ]

\end{document}

相关内容