我已经尝试使用 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);
或者,您可以使用out
和in
指令,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}