9

I want to create a table with arrows between some cells, for which I've used tabularx and TkiZ. I have the following problems:

  • Text in cells aligned vertically to the center and at the same heigh (TikZ nodes are not inline with normal cells text in a same row).
  • Inability to align to the center with \begin{center}•\end{center}.
  • I don't know how to fix the size of the cells.

This is what I currently have:

Code

\documentclass{article} \usepackage{tabularx} \usepackage{tikz} \tikzset{every picture/.style={remember picture}} \begin{document} \begin{tabularx}{\textwidth}{r|c|c|c|c|l} &$D_1$&$D_2$&$D_3$&$D_4$&foo\\ \cline{1-6} $O_1$&\tikz[baseline]{\node (a11) {50};}&\tikz[baseline]{\node (a12) {0};}&&&50\\[2em] \cline{1-6} $O_2$&&\tikz[baseline]{\node (a22) {60};}&&&60\\[2em] \cline{1-6} $O_3$&&\tikz[baseline]{\node (a32) {10};}&\tikz[baseline]{\node (a33) {30};}&\tikz[baseline]{\node (a34) {10};}&50\\[2em] \cline{1-6} $O_4$&&&&\tikz[baseline]{\node (a44) {50};}&50\\[2em] \cline{1-6} bar&50&70&30&60&210\\ \end{tabularx} \begin{tikzpicture}[overlay] \path[thick,->] (a11) edge (a12); \path[thick,->] (a12) edge (a22); \path[thick,->] (a22) edge (a32); \path[thick,->] (a32) edge (a33); \path[thick,->] (a33) edge (a34); \path[thick,->] (a34) edge (a44); \end{tikzpicture} \end{document} 

Output

Besides, I get the following warnings:

Underfull \hbox (badness 10000) in alignment at lines 13--13

Overfull \hbox (15.0pt too wide) in paragraph at lines 13--22

1
  • 1
    The Overfull \hbox (15.0pt too wide)... warning comes from not using \noindent right before \begin{tabularx} (your table starts a paragraph so it receives the standard indentation). Commented Mar 2, 2014 at 4:03

4 Answers 4

9

Another possible solution where the OP code is used but slightly modified. The underfull problem is taken care by adding an X column in the last column so that \textwidth is satisfied.

The OP's tikz struture in the cell is redefined as tikzmark taking two arguments. and connected by \link macro.

Create a new column type M with horizontal and vertical centering:

\renewcommand\tabularxcolumn[1]{m{#1}} \newcolumntype{M}{>{\centering\arraybackslash}m{1cm}} 

enter image description here

Code

\documentclass{article} \usepackage[margin=1in]{geometry} \usepackage{tabularx} \usepackage{tikz} %\tikzset{every picture/.style={remember picture}} \renewcommand\tabularxcolumn[1]{m{#1}} \newcolumntype{M}{>{\centering\arraybackslash}m{1cm}} \newcommand\tikzmark[2]{% \tikz[remember picture,baseline] \node[inner sep=2pt,outer sep=0] (#1){#2};% } \newcommand\link[2]{% \begin{tikzpicture}[remember picture, overlay, >=stealth, shift={(0,0)}] \draw[->] (#1) to (#2); \end{tikzpicture}% } \begin{document} \noindent \begin{tabularx}{\textwidth}{M|M|M|M|M|MX} &$D_1$ &$D_2$ &$D_3$ &$D_4$& foo &\\ \cline{1-6} $O_1$&\tikzmark{a}{50}&\tikzmark{b}{0} & & & 50 &\\[2em] \cline{1-6} $O_2$& &\tikzmark{c}{60}& & &60 &\\[2em] \cline{1-6} $O_3$& &\tikzmark{d}{10}&\tikzmark{e}{30}&\tikzmark{f}{10}&50 &\\[2em] \cline{1-6} $O_4$& & & &\tikzmark{g}{50}&{50} &\\[2em] \cline{1-6} bar&50&70&30&60&210 \\ \end{tabularx} \link{a}{b} \link{b}{c} \link{c}{d} \link{d}{e} \link{e}{f} \link{f}{g} \end{document} 
3
  • 1
    very nice, I like this solution best; did you know that tikzmark has its own package? Commented Mar 2, 2014 at 6:09
  • @cmhughes -- Thank you sir, quite encouraging. As to the question: Yes, but thinking the tikzmark macro should be sufficient to give a shot. Commented Mar 2, 2014 at 6:35
  • In the last row bar&50&70&30&60&210 \\ I would add an ampersand, i.e., bar&50&70&30&60&210& \\ . Otherwise if the height is changed, e.g., \\[2em], the 210 is on the row's ceiling. Commented May 24, 2018 at 20:09
8

I'd suggest you to draw the whole matrix as a TikZ matrix; this gives you easy control over the attributes of the cells (I added some colors just optionally):

\documentclass{article} \usepackage{tikz} \usetikzlibrary{matrix} \tikzset{ table/.style={ matrix of nodes, row sep=-\pgflinewidth, column sep=-\pgflinewidth, nodes={rectangle,text width=3em,align=center}, text depth=1.25ex, text height=2.5ex, nodes in empty cells }, row 1/.style={nodes={fill=green!10,text depth=0.4ex,text height=2ex}}, row 6/.style={nodes={text depth=0.4ex,text height=2ex}}, column 1/.style={nodes={fill=green!10}}, } \begin{document} \begin{tikzpicture} % the matrix entries \matrix (mat) [table] { & $D_1$ & $D_2$ & $D_3$ & $D_4$ & foo \\ $O_1$ & 50 & 0 & & & 50 \\ $O_2$ & & 60 & & & 60 \\ $O_3$ & & 10 & 30 & 10 & 50 \\ $O_4$ & & & & 50 & 50 \\ bar & 50 & 70 & 30 & 60 & 210 \\ }; % the matrix rules \foreach \x in {1,...,5} { \draw ([xshift=-.5\pgflinewidth]mat-\x-1.south west) -- ([xshift=-.5\pgflinewidth]mat-\x-6.south east); } \foreach \x in {1,...,5} { \draw ([yshift=.5\pgflinewidth]mat-1-\x.north east) -- ([yshift=.5\pgflinewidth]mat-6-\x.south east); } % the arrows \begin{scope}[shorten >=7pt,shorten <= 7pt] \draw[->] (mat-2-2.center) -- (mat-2-3.center); \draw[->] (mat-2-3.center) -- (mat-3-3.center); \draw[->] (mat-3-3.center) -- (mat-4-3.center); \draw[->] (mat-4-3.center) -- (mat-4-4.center); \draw[->] (mat-4-4.center) -- (mat-4-5.center); \draw[->] (mat-4-5.center) -- (mat-5-5.center); \end{scope} \end{tikzpicture} \end{document} 

enter image description here

0
4

Here is a way to do it with laps and stacks:

\documentclass{article} \usepackage{tabularx} \usepackage{graphicx} \usepackage{stackengine} \def\RA{\rlap{\scalebox{1.6}{$\rightarrow$}}} \def\DA{\bclap{\scalebox{1.6}{$\downarrow$}}} \def\mystrut{\rule{0ex}{3ex}} \begin{document} \setstackgap{S}{6pt} \begin{tabularx}{\textwidth}{r|c|c|c|c|l} &$D_1$&$D_2$&$D_3$&$D_4$&foo\\ \cline{1-6} \mystrut$O_1$&50\RA&\stackunder{0}{\DA}&&&50\\[2em] \cline{1-6} \mystrut$O_2$&&\stackunder{60}{\DA}&&&60\\[2em] \cline{1-6} \mystrut$O_3$&&10\RA&30\RA&\stackunder{10}{\DA}&50\\[2em] \cline{1-6} \mystrut$O_4$&&&&50&50\\[2em] \cline{1-6} \mystrut bar&50&70&30&60&210\\ \end{tabularx} \end{document} 

enter image description here

And here is an alternative presentation:

\documentclass{article} \usepackage{tabularx} \usepackage{graphicx} \usepackage{stackengine} \def\RA{\rlap{\scalebox{1.6}{$\rightarrow$}}} \def\DA{\smash{\bclap{\scalebox{1.6}{$\downarrow$}}}} \def\mystrut{\rule[-2ex]{0ex}{6ex}} \begin{document} \setstackgap{S}{6pt} \setstackgap{L}{7pt} \begin{tabularx}{\textwidth}{r|c|c|c|c|l} &$D_1$&$D_2$&$D_3$&$D_4$&foo\\ \cline{1-6} \mystrut$O_1$&50\RA&\stackunder{0}{\DA}&&&50\\ \cline{1-6} \mystrut$O_2$&&\stackunder{60}{\DA}&&&60\\ \cline{1-6} \mystrut$O_3$&&10\RA&30\RA&\stackunder{10}{\DA}&50\\ \cline{1-6} \mystrut$O_4$&&&&50&50\\ \cline{1-6} \mystrut bar&50&70&30&60&210\\ \end{tabularx} \end{document} 

enter image description here

2

With {NiceTabular} of nicematrix and TikZ to draw the arrows.

\documentclass{article} \usepackage{nicematrix,tikz} \usetikzlibrary{arrows.meta} \begin{document} \begin{center} \setlength{\tabcolsep}{0pt} \begin{NiceTabular} [columns-width=1cm,hvlines-except-borders] {>{\rule[-4mm]{0pt}{1cm}}*{6}{c}} & $D_1$ & $D_2$ & $D_3$ & $D_4$ & foo \\ $O_1$ & 50 & 0 & & & 50 \\ $O_2$ & & 60 & & & 60 \\ $O_3$ & & 10 & 30 & 10 & 50 \\ $O_4$ & & & & 50 & 50 \\ bar & 50 & 70 & 30 & 60 & 210 \\ \CodeAfter \begin{tikzpicture} [->, shorten < = 1mm, shorten > = 1mm] \draw (2-2) -- (2-3) ; \draw (2-3) -- (3-3) ; \draw (3-3) -- (4-3) ; \draw (4-3) -- (4-4) ; \draw (4-4) -- (4-5) ; \draw (4-5) -- (5-5) ; \end{tikzpicture} \end{NiceTabular} \end{center} \end{document} 

Output of the above code

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.