3

How can I place two multicolumn tables (tableA and tableB) side by side and draw arrows from cell in tableA to another cell in tableB?

I have tried this Arrows between two tables and its also working ok with simple tables. But if I try to use nested nodes to create multiple columns it goes wrong.

What to do?

This is what I have tried, but if I change the labels to longer words like "Copenhagen" the whole cell gets very wide and it looks weird on the page. Is it something with the margin I have to change? How should I add border in nested nodes?

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart,matrix,positioning}
\begin{document}
\begin{tikzpicture}
\node[rectangle split, rectangle split parts=3,draw,inner sep=2ex] (A) at (0,1)
{
\begin{tikzpicture}
\node[rectangle,text height=2em] (1st) {a11};
\node[rectangle,text height=2em,right=of 1st] (2nd) {a21};
\end{tikzpicture}
\nodepart{two}
\begin{tikzpicture}
\node[rectangle,text height=2em] (1st) {a12};
\node[rectangle,text height=2em,right=of 1st] (2nd) {a22};
\end{tikzpicture}
\nodepart{three}
\begin{tikzpicture}
\node[rectangle,text height=2em] (1st) {a13};
\node[rectangle,text height=2em,right=of 1st] (2nd) {a23};
\end{tikzpicture}};

\node[rectangle split, rectangle split parts=3,draw,inner sep=2ex] (B) at (7,1)
{\begin{tikzpicture}
\node[rectangle,text height=2em] (1st) {b11};
\node[rectangle,text height=2em,right=of 1st] (2nd) {b21};
\end{tikzpicture}
\nodepart{two}
\begin{tikzpicture}
\node[rectangle,text height=2em] (1st) {b12};
\node[rectangle,text height=2em,right=of 1st] (2nd) {b22};
\end{tikzpicture}
\nodepart{three}
\begin{tikzpicture}
\node[rectangle,text height=2em] (1st) {b13};
\node[rectangle,text height=2em,right=of 1st] (2nd) {b23};
\end{tikzpicture}};
\draw[->] (A.two east) -- (B.text west);
\draw[->] (B.two west) -- (A.text east);
\end{tikzpicture}
\end{document}
  • 1
    Welcome to the site! The link you provide is very helpful; it would be great if you could post a small complete minimal working example (MWE) that demonstrates the trouble that you're having. Welcome! – cmhughes Jul 4 '14 at 13:03
  • In particular, are we talking tikzpictures, tabulars or floats? – John Kormylo Jul 4 '14 at 13:56
  • @cmhughes I've added my code, I hope you guys understand my problem. Thanks. – freddy Jul 4 '14 at 14:25
  • 1
    Please make your example compilable. We can not work with just a snippet. Thanks. – LaRiFaRi Jul 4 '14 at 14:26
  • You are using nested tikzpictures, which makes the problem harder. Why don't use one matrix per "table", all in the same tikzpicture? – JLDiaz Jul 4 '14 at 14:59
3

If regular tabulars are an option, then I would suggest drawing your tabulars in the normal way (i.e. use whichever packages etc. you usually use and like) and then adding the arrows as an overlay using tikzmark. This library lets you add marks in the LaTeX code of the tabulars (or whatever else) and then use those marks to position drawing commands which can overlay the text.

For example:

\documentclass{article}
\usepackage{array,tikz}
\usetikzlibrary{tikzmark,arrows.meta}
\newcolumntype{M}{>{\centering\mbox{}\vfill\arraybackslash}m{50pt}<{\vfill}}
\begin{document}

  \begin{tabular}{|*{2}{M|}}
    \hline
    \tikzmark{la11}a11\tikzmark{ra11}   &   \tikzmark{la21}a21\tikzmark{ra21}\\\hline
    \tikzmark{la12}a12\tikzmark{ra12}   &   \tikzmark{la22}a22\tikzmark{ra22}\\\hline
    \tikzmark{la13}a13\tikzmark{ra13}   &   \tikzmark{la23}a23\tikzmark{ra23}\\\hline
  \end{tabular}
  \hskip 50pt
  \begin{tabular}{|*{2}{M|}}
    \hline
    \tikzmark{lb11}b11\tikzmark{rb11}   &   \tikzmark{lb21}b21\tikzmark{rb21}\\\hline
    \tikzmark{lb12}b12\tikzmark{rb12}   &   \tikzmark{lb22}b22\tikzmark{rb22}\\\hline
    \tikzmark{lb13}b13\tikzmark{rb13}   &   \tikzmark{lb23}b23\tikzmark{rb23}\\\hline
  \end{tabular}

  \begin{tikzpicture}
    [
      remember picture,
      overlay,
      -latex,
      color=blue!75!green,
      yshift=1ex,
      shorten >=1pt,
      shorten <=1pt,
    ]
    \draw ({pic cs:ra21}) -- ({pic cs:lb13});
    \draw ({pic cs:ra23}) -- ({pic cs:lb21});
    \draw ({pic cs:ra13}) -- ({pic cs:la21});
    \draw ({pic cs:rb13}) -- ({pic cs:lb22});
    \draw ({pic cs:lb12}) -- ({pic cs:ra22});
    \draw ({pic cs:lb23}) to [bend left] ({pic cs:ra13});
    \draw ({pic cs:ra11}) to [bend left] ({pic cs:lb11});
  \end{tikzpicture}

\end{document}

I've added two marks for each cell but obviously you really only need to add the marks you go onto use in the tikzpicture environment.

Arrows positioned over tabulars using <code>tikzmark</code>

Note that I've added a central line to each tabular dividing the two columns as you mentioned wanting this in the comments on JLDiaz's answer but the nice thing about this is that you can adjust the tabulars using all the usual formatting commands however you like.

4

Following my own advice in a previous comment, there is a solution which uses \matrix for creating the tables, which makes easy to connect the individual cells as shown at the end.

The only problem was to draw the lines which separate rows. I was unable to do it via some style for the matrix, so I had to resort to coding a macro specific for this task (but generic enough for any matrix dimensions).

\usetikzlibrary{matrix,positioning}

\tikzset{  % Define some styles
  my table/.style = {
    matrix of nodes,
    nodes = {minimum width=3em, minimum height=2.5em, inner sep=3pt},
    draw,
    inner sep=0pt,
  },
  my arrow/.style = {
    -latex,
    shorten >= -5pt,
    shorten <= -5pt,
    blue!50!black!60,
  }
}

% Macro to draw the lines between rows
\def\drawLineBelowRow#1#2{% #1: row number, #2: matrix name
  \draw (#2.west|-#2-#1-1.south) -- (#2.east|-#2-#1-1.south);
}

\begin{tikzpicture}   
\matrix[my table] (A) { % First table (it is called A)
   a11        & a21 \\
   a21        & a22 \\
   Copenhagen & a22 \\
};
\drawLineBelowRow{1}{A}
\drawLineBelowRow{2}{A}

\matrix[my table, right=of A] (B) { % Second table (it is called B)
   b11 & b21 \\
   b21 & b22 \\
   b31 & b22 \\
};
\drawLineBelowRow{1}{B}
\drawLineBelowRow{2}{B}

% Drawing arrows between particular cells of each table is easy:
\draw[my arrow] (A-2-2) -- (B-1-1);
\draw[my arrow] (A-3-1) -- (B-2-2);

\end{tikzpicture}

Result:

Result

  • Better solutions than mine, but how do I add an border between the cells in the tables? – freddy Jul 4 '14 at 23:25
  • @freddy Your original code didn't have borders either. Your question implied you wanted to add arrows to the existing tables but apparently that's not the case. Please update your question to make clear exactly what you are trying to do. For example, based on your original question and current comment, I wouldn't use tikzpictures for the tables at all. But I guess you have reasons for this so please explain them. – cfr Jul 4 '14 at 23:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.