表格或矩阵中的箭头

表格或矩阵中的箭头

我已经尝试使用 LaTeX 几年了,但仍然认为自己还是新手。

我昨天花了很多时间尝试创建一个表格。我试图创建一个有三列五行的表格,每列都应包含一个左对齐的文本字符串。在第二列文本的右侧,我想绘制一个垂直箭头,从第 2 行的中间到第 5 行的中间,垂直从上到下。在第三列文本的右侧,我想绘制一个箭头,从第 5 行的中间到第 2 行的中间。另一个问题是,我需要在这两列中包含多行文本。

我的直觉是,使用 Tikz 应该可以实现这一点,而且我也可以接近这一点,但我似乎无法完全做到这一点。Tikz 是正确的选择吗?我应该为箭头添加两个额外的列吗?或者有没有办法将此箭头包含在与文本相同的单元格中,偏移 0.5em。Tikz 可以处理多行节点吗?我对 Tikz 完全陌生

答案1

这里有两种不同的解决方案。

第一个解决方案是使用tabular环境\tikzmark来控制箭头的位置:

\documentclass{article}
\usepackage[margin=0.5in]{geometry}

\usepackage{tikz}
\usetikzlibrary{calc,tikzmark}
\usetikzlibrary{arrows.meta}
\tikzset{%%
  my dot/.style={fill,circle,inner sep=1.5pt},
  >={To[scale=2]}
  }

\def\tikzmarkhf#1{\hspace{\fill}\tikzmark{#1}}
\def\tikzmarkup#1{\raisebox{2ex}{\tikzmark{#1}}}

\usepackage{array}
\newcolumntype{P}{p{2in}}
\renewcommand\arraystretch{1.75}

\def\longtexta{the lazy dog jumped over the sleep fox}
\def\longtextb{To the right of the text in the second text column I would like to draw a vertical arrow from the middle of row 2 to the middle of row 5, going vertically from top to bottom. To the right of the text in the third column I would like to draw an arrow going from the middle of row 5 to the middle of row 2. One further wrinkle is that I need to include multiple lines of text in these two columns.}
\def\longtextc{My gut feeling is that this should be possible using Tikz, and I can come close, but I just can not seem to quite get this right. Is Tikz the right way to go?}
\def\longtextd{Should I add two extra columns for the arrows, or is there a way to include this arrow in the same cell as the text, offset by 0.5em. Can Tikz handle multi-line nodes. I am completely new to Tikz}

\begin{document}


\begin{tabular}{PP@{\hspace{1.5cm}}P}
 \longtexta & \longtextb                               & \longtextc \\
 \longtexta & \tikzmarkup{A1}\longtextc\tikzmarkhf{A2} & \tikzmarkup{C1}\longtextc\tikzmarkhf{C2} \\
 \longtexta & \longtextb                               & \longtextc \\
 \longtextb & \longtexta                               & \longtextc \\
 \longtexta & \longtextb                               & \tikzmarkup{B1}\longtextc\tikzmarkhf{B2} \\
\end{tabular}
\begin{tikzpicture}[overlay,remember picture]

  \node (A)  at ($({pic cs:A1}-|{pic cs:A2})!0.5!(pic cs:A2)$) {};
  \node (Bl) at ($({pic cs:B1}|-{pic cs:B2})!0.5!(pic cs:B1)$) {};

  \draw[arrows=-Stealth] (A) -- ($(A)!0.5!(A-|Bl)$) -- ($(A|-Bl)!0.5!(Bl)$) -- (Bl);

  \node (C)  at ($({pic cs:C1}-|{pic cs:C2})!0.5!(pic cs:C2)$) {};
  \node (Br) at ($({pic cs:B1}-|{pic cs:B2})!0.5!(pic cs:B2)$) {};

  \draw[arrows=Stealth-] (C) -- ($(C)+(0.75cm,0)$) -- 
                         ($(Br)+(0.75cm,0)$)  -- (Br);

\end{tikzpicture}

\end{document}

注意:我定义了两个宏\tikzmarkup\tikzmarkhf向上版本垂直提升了位置\tikzmark高频版本本质上是将 推到\tikzmark它所在的小页面的右侧。(我想定义类似的东西\tikzmark*来做到这一点,但一直遇到解析错误。)

pic cs:C1命名由 创建的节点\tikzmark{C1}\tikzmark使用pic画布;因此,为了能够从定义节点的外部引用该节点,您必须根据渲染它的画布来引用它。

在此处输入图片描述

第二种解决方案完全在内部完成tikzpicture,并使用了库的功能fit

\documentclass{article}
\usepackage[margin=0.5in]{geometry}

\usepackage{tikz}
\usetikzlibrary{calc,fit}
\usetikzlibrary{arrows.meta}
\tikzset{%%
  my dot/.style={fill,circle,inner sep=1.5pt},
  >={To[scale=2]}
  }


\usepackage{array}
\newcolumntype{P}{p{2in}}

\def\longtexta{the lazy dog jumped over the sleep fox}
\def\longtextb{To the right of the text in the second text column I would like to draw a vertical arrow from the middle of row 2 to the middle of row 5, going vertically from top to bottom. To the right of the text in the third column I would like to draw an arrow going from the middle of row 5 to the middle of row 2. One further wrinkle is that I need to include multiple lines of text in these two columns.}
\def\longtextc{My gut feeling is that this should be possible using Tikz, and I can come close, but I just can not seem to quite get this right. Is Tikz the right way to go?}
\def\longtextd{Should I add two extra columns for the arrows, or is there a way to include this arrow in the same cell as the text, offset by 0.5em. Can Tikz handle multi-line nodes. I am completely new to Tikz}

\def\aepar#1{\parbox[t]{2in}{#1}}

\begin{document}

\begin{tikzpicture}

  \node (Q1) at (0,0) {};

  \foreach \myA/\myB/\myC [count=\mycnt from 1] in {\longtexta/\longtextb/\longtextc,
                                                    \longtexta/\longtextc/\longtextc,
                                                    \longtexta/\longtextb/\longtextc,
                                                    \longtextb/\longtexta/\longtextc,
                                                    \longtexta/\longtextb/\longtextc
                                                    }
  {
    \node[anchor=north west] (A\mycnt) at (Q\mycnt) {\aepar\myA};
    \node[anchor=north west] (B\mycnt) at ($(A\mycnt.north east)+(2ex,0)$) {\aepar\myB};
    \node[anchor=north west] (C\mycnt) at ($(B\mycnt.north east)+(1cm,0)$) {\aepar\myC};
    %% use "fit" to get the correct size of the row
    \node[fit=(A\mycnt)(B\mycnt)(C\mycnt)] (row\mycnt){};
    \pgfmathsetmacro\next{int(\mycnt+1)}
    \node (Qt\next) at ($(row\mycnt.south)+(0,-2ex)$) {};
    \node (Q\next)  at (Qt\next-|A\mycnt.west) {};
  }

  \draw [arrows=-Stealth]
        (B2.east) -- ($(B2.east)!0.5!(B2.east-|C5.west)$)
                  -- ($(B2.east|-C5.west)!0.5!(C5.west)$)
                  -- (C5.west);

  \draw [arrows=-Stealth]
        (C5.east) -- ($(C5.east)+(0.5cm,0)$)
                  -- ($(C2.east)+(0.5cm,0)$)
                  -- (C2.east);
\end{tikzpicture}

\end{document}

在此处输入图片描述

我认为,即使我误解了你想要什么,你也应该从这两个例子中获得足够的想法来创建你需要的东西。

我怀疑使用tikz矩阵可能会效果更好,但我还没有尝试过很多次,而且这是一个非常陌生的领域。

更新

从一行到下一行的普通直箭头不太美观。如果您需要,可以参考以下链接:

\draw[arrows=-Stealth] (B2.east) -- (C5.west);
\draw[arrows=-Stealth] (C5.east) -- (C2.east);

或者,您可以使用outin指令,to

\draw [arrows=-Stealth]
      (B2.east) to [out=-60,in=120,looseness=0.70] (C5.west);

\draw [arrows=-Stealth]
      (C5.east) to [out=60,in=-60,looseness=0.5]
                (C2.east);

这更有吸引力。

在此处输入图片描述

您可能想到了以下几点:

\draw [arrows=-Stealth]
      ($(B2.east)!0.5!(B2.east-|C5.west)$)
      --
      ($(C5.west-|B2.east)!0.5!(C5.west)$);

\draw [arrows=-Stealth]
      ([xshift=0.5cm]C5.east) -- ([xshift=0.5cm]C2.east);

在此处输入图片描述

(稍后会发布更好的图像,但我无法从我当前的工作站做到这一点。)

答案2

{NiceTabular}这是使用和 TikZ 的解决方案,使用表格单元格下nicematrix创建的 TikZ 节点来绘制箭头。nicematrix

\documentclass{article}
\usepackage[margin=0.5in]{geometry}
\usepackage{nicematrix}
\usepackage{tikz}
\usetikzlibrary{arrows.meta,ext.paths.ortho}

\newcolumntype{P}{p{2in}}
\renewcommand\arraystretch{1.75}

\def\longtexta{the lazy dog jumped over the sleep fox}
\def\longtextb{To the right of the text in the second text column I would like to draw a vertical arrow from the middle of row 2 to the middle of row 5, going vertically from top to bottom. To the right of the text in the third column I would like to draw an arrow going from the middle of row 5 to the middle of row 2. One further wrinkle is that I need to include multiple lines of text in these two columns.}
\def\longtextc{My gut feeling is that this should be possible using Tikz, and I can come close, but I just can not seem to quite get this right. Is Tikz the right way to go?}
\def\longtextd{Should I add two extra columns for the arrows, or is there a way to include this arrow in the same cell as the text, offset by 0.5em. Can Tikz handle multi-line nodes. I am completely new to Tikz}

\begin{document}

\begin{NiceTabular}{PP@{\hspace{1.5cm}}P}
 \longtexta & \longtextb & \longtextc \\
 \longtexta & \longtextc & \longtextc \\
 \longtexta & \longtextb & \longtextc \\
 \longtextb & \longtexta & \longtextc \\
 \longtexta & \longtextb & \longtextc \\
\CodeAfter
  \begin{tikzpicture} [-Stealth, shorten < = 3pt, shorten > = 3pt]
    \draw (2-2.east) -|- (5-3.west) ; 
    \draw (5-3.east) -- ++(6mm,0pt) |- (2-3.east) ; 
  \end{tikzpicture}
\end{NiceTabular}

\end{document}

上述代码的输出

相关内容