# Arrows in tables, or matrices

I have been experimenting with LaTeX for a couple of years now, but still consider myself a neophyte.

I spent much of yesterday trying to create a table. I am trying to create a table with three columns, and five rows, each of the columns should contain a left justified text string. 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.

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? 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

• Welcome to TeX.SX! Please help us to help you and add a minimal working example (MWE) that illustrates your problem. It will be much easier for us to reproduce your situation and find out what the issue is when we see compilable code, starting with \documentclass{...} and ending with \end{document}. That is, show us your code! – cfr Nov 14 '14 at 2:32

Here are two different solutions.

The first solution uses a tabular environment and \tikzmark to control the position of where the arrows should go:

\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}


Note: I define two macros \tikzmarkup and \tikzmarkhf. The up version raises the position of the \tikzmark vertically. The hf version essentially shoves the \tikzmark against the right hand side of the minipage it inhabits. (I wanted to define something like \tikzmark* to do this, but kept running into parsing errors.)

pic cs:C1 names the node created by \tikzmark{C1}. \tikzmark uses the pic canvas; so to be able to refer to the node from outside of where it was defined, you'll have to reference it in terms of the canvas it was rendered on.

The second solution is done completely within a tikzpicture and uses the facilities of the fit library:

\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}


I think, even if I misunderstood quite what you wanted, you should get enough of an idea from these two examples to create what you need.

I suspect that using a tikz matrix might work even better, but I have not played much with that and it's very unfamiliar territory.

UPDATE

Plain straight arrows from one row to the next are not very attractive. Here they are if you want them:

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


Alternatively, you can use the out and in directives to to as in

\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);


which is a bit more attractive.

Possibly, you have the following in mind:

\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);


(Better images to be posted later, I can't do that from my current work station.)

• Many thanks for your solutions, they have given me much to think about. How would I go about removing the elbows in the arrows? I simply need a straight vertical arrow? I think that it has something to do with the \node at code, but am not sure. – grazer Nov 14 '14 at 20:55
• @grazer I've added a few more examples of how to work this from within the tikzpicture environment. Something very similar can be done in the example with an overlay on the tabular environment. – A.Ellett Nov 14 '14 at 21:29