如何在 TikZ 中相对定位 \pics?

如何在 TikZ 中相对定位 \pics?

以下代码创建了两种样式\pic。目标是将\pics 定位为垂直相对的椭圆相距 1em,水平相邻的椭圆相距 1em。(后者当然仅适用于水平方向最接近的椭圆的行 - 另一行中的椭圆由于垂直对齐而可能相距更远)。

使用和\pic来相对定位s会出错。绝对定位似乎也行不通,因为椭圆的宽度是未知的(想象一下代码与椭圆中的其他文本值重复使用)。right=ofbelow=of

如何才能\pic正确定位 s 呢?

\documentclass[tikz]{standalone}
\usetikzlibrary{positioning,calc,fit,shapes}
\tikzset {
  factor/.style = {draw, ellipse},
  indicator/.style = {draw, rectangle, outer sep=0},
  arr/.style={-latex},
  pics/collDown/.style n args={2}{
    code={%
      \node[indicator] ({#1}1) {{#1}};
      \node[factor, above=2em of {#1}1] (#1) {#2};
      \draw[arr] (#1) -- ({#1}1.north);
    }
  },
  pics/collUp/.style n args={2}{
    code={%
      \node[indicator] ({#1}1) {{#1}};
      \node[factor, below=2em of {#1}1] (#1) {#2};
      \draw[arr] (#1) -- ({#1}1.south);
    }
  }
}

\begin{document}
\begin{tikzpicture}
  \pic[local bounding box=a] {collUp={A}{Some text}};
  \pic[local bounding box=b, right=1em of a] {collUp={B}{More text}};
  \pic[local bounding box=c, below=1em of a] {collDown={C}{Weird stuff}};
  \pic[local bounding box=d, below=1em of b] {collDown={D}{I'm giving up}};
  \pic at (0,-5) {collUp={A}{Some text}};
  \pic at (3,-5) {collUp={B}{More text}};
  \pic at (0,-9) {collDown={C}{Weird stuff}};
  \pic at (3,-9) {collDown={D}{I'm giving up}};
\end{tikzpicture}
\end{document}

图表

答案1

这是一个非常好的问题,并且有一个非常简单的方法可以实现这一点:将包装pic在一个矩阵中(只有一个条目)。您还可以为此编写一个宏,如下所示\ppic

\documentclass[tikz]{standalone}
\usetikzlibrary{positioning,calc,fit,shapes}
\tikzset {
  factor/.style = {draw, ellipse},
  indicator/.style = {draw, rectangle, outer sep=0},
  arr/.style={-latex},
  pics/collDown/.style n args={2}{
    code={%
      \node[indicator] ({#1}1) {{#1}};
      \node[factor, above=2em of {#1}1] (#1) {#2};
      \draw[arr] (#1) -- ({#1}1.north);
    }
  },
  pics/collUp/.style n args={2}{
    code={%
      \node[indicator] ({#1}1) {{#1}};
      \node[factor, below=2em of {#1}1] (#1) {#2};
      \draw[arr] (#1) -- ({#1}1.south);
    }
  }
}

\begin{document}
\begin{tikzpicture}
  \node[matrix] (a){\pic {collUp={A}{Some text}};\\};
  \node[matrix,right=1em of a] (b) {\pic {collUp={B}{More text}};\\};
  \node[matrix,below=1em of a] (c){\pic{collDown={C}{Weird stuff}};\\};
  \node[matrix,below=1em of b]  (d){\pic{collDown={D}{I'm giving up}};\\};
\end{tikzpicture}

\newcommand{\ppic}[2][]{
\node[matrix,#1]{\pic{#2};\\ };}
\begin{tikzpicture}
  \ppic[local bounding box=a] {collUp={A}{Some text}};
  \ppic[local bounding box=b, right=1em of a] {collUp={B}{More text}};
  \ppic[local bounding box=c, below=1em of a] {collDown={C}{Weird stuff}};
  \ppic[local bounding box=d, below=1em of b] {collDown={D}{I'm giving up}};
\end{tikzpicture}
\end{document}

在此处输入图片描述

如果您担心矩形不对齐,您可能需要统一椭圆的大小。

\documentclass[tikz]{standalone}
\usepackage{eqparbox}
\usetikzlibrary{positioning,calc,fit,shapes}
\newbox\eqnodebox
\tikzset{equal size/.style={execute at begin
    node={\setbox\eqnodebox=\hbox\bgroup\vphantom{Hg}},
    execute at end node={\egroup\eqmakebox[#1][c]{\copy\eqnodebox}}},
    equal size/.default=A,
  factor/.style = {draw, ellipse,equal size},
  indicator/.style = {draw, rectangle, outer sep=0},
  arr/.style={-latex},
  pics/collDown/.style n args={2}{
    code={%
      \node[indicator] ({#1}1) {{#1}};
      \node[factor, above=2em of {#1}1] (#1) {#2};
      \draw[arr] (#1) -- ({#1}1.north);
    }
  },
  pics/collUp/.style n args={2}{
    code={%
      \node[indicator] ({#1}1) {{#1}};
      \node[factor, below=2em of {#1}1] (#1) {#2};
      \draw[arr] (#1) -- ({#1}1.south);
    }
  }
}

\begin{document}
\begin{tikzpicture}
  \node[matrix] (a){\pic {collUp={A}{Some text}};\\};
  \node[matrix,right=1em of a] (b) {\pic {collUp={B}{More text}};\\};
  \node[matrix,below=1em of a] (c){\pic{collDown={C}{Weird stuff}};\\};
  \node[matrix,below=1em of b]  (d){\pic{collDown={D}{I'm giving up}};\\};
\end{tikzpicture}
\end{document}

在此处输入图片描述

节点样式equal size采用一个参数,可以将其视为指示器/标签。所有具有相同标签的节点组都将具有相同的宽度。

答案2

看了楼主的上述评论,我建议使用下面的代码(这是最简单的吗?)。一个简单的图形应该用一个简单的代码绘制。所有节点都是具有绝对定位的节点,但参数\ab\h使代码变得灵活,也就是说,人们可以根据需要轻松控制距离。洋红色线用于检查水平对齐。

在此处输入图片描述

\documentclass[tikz,border=5mm]{standalone}
\usetikzlibrary{shapes}
\begin{document}
\begin{tikzpicture}[>=stealth]
\def\a{3.5} \def\b{4} \def\h{1.2}
\path[every node/.style={draw}]
(0,0)    node (A) {A}
(\a,0)   node (B) {B}
(0,-\b)  node (C) {C}
(\a,-\b) node (D) {D};
\path[every node/.style={draw,ellipse}]
(A)+(-90:\h) node (At) {Some text}
(B)+(-90:\h) node (Bt) {More text}
(C)+(90:\h)  node (Ct) {Weird stuff}
(D)+(90:\h)  node (Dt) {I'm giving up};

\foreach \p in {A,B,C,D} \draw[->] (\p t)--(\p);

% check for horizontal alignment
\draw[cyan] (current bounding box.south west) rectangle (current bounding box.north east);
\draw[thin,magenta,shorten >=-1.2cm,shorten <=-1.2cm] 
(A.base)--(B.base) (C.base)--(D.base)
(At.base)--(Bt.base) (Ct.base)--(Dt.base);
\end{tikzpicture}
\end{document}

更新正如 Kpym 所建议的,代码稍微短一些。

在此处输入图片描述

\documentclass[tikz,border=5mm]{standalone}
\usetikzlibrary{shapes}
\begin{document}
\begin{tikzpicture}\def\a{3.5} \def\b{4} \def\h{1.2}
\path[nodes=draw]
(0,0)    node (A) {A} +(-90:\h) node[ellipse] (At) {Some text}
(\a,0)   node (B) {B} +(-90:\h) node[ellipse] (Bt) {More text}
(0,-\b)  node (C) {C} +(90:\h)  node[ellipse] (Ct) {Weird stuff}
(\a,-\b) node (D) {D} +(90:\h)  node[ellipse] (Dt) {I'm giving up}; 
\foreach \p in {A,B,C,D} \draw[-stealth] (\p t)--(\p);
\end{tikzpicture}
\end{document}

答案3

text depth在所有节点上使用相同的解决方案

\documentclass[tikz]{standalone}
\usetikzlibrary{positioning,calc,fit,shapes}
\tikzset {
  factor/.style = {draw, ellipse,text depth=0.2ex},
  indicator/.style = {draw, rectangle, outer sep=0,text depth=0.2ex},
  arr/.style={-latex},
  pics/collDown/.style n args={2}{
    code={%
      \node[indicator] ({#1}1) {{#1}};
      \node[factor, above=2em of {#1}1] (#1) {#2};
      \draw[arr] (#1) -- ({#1}1.north);
    }
  },
  pics/collUp/.style n args={2}{
    code={%
      \node[indicator] ({#1}1) {{#1}};
      \node[factor, below=2em of {#1}1] (#1) {#2};
      \draw[arr] (#1) -- ({#1}1.south);
    }
  }
}

\begin{document}
\begin{tikzpicture}
%  \pic[local bounding box=a] {collUp={A}{Some text}};
%  \pic[local bounding box=b, right=1em of a] {collUp={B}{More text}};
%  \pic[local bounding box=c, below=1em of a] {collDown={C}{Weird stuff}};
%  \pic[local bounding box=d, below=1em of b] {collDown={D}{I'm giving up}};
  \pic at (0,-5) {collUp={A}{Some text}};
  \pic at (3,-5) {collUp={B}{More text}};
  \pic at (0,-9) {collDown={C}{Weird stuff}};
  \pic at (3,-9) {collDown={D}{I'm giving up}};
\end{tikzpicture}
\end{document}

在此处输入图片描述

相关内容