[Tex/LaTex] how to distribute several arrows vertically in TikZ

graphicstikz-pgf

I am currently working on a paper, where I need to create few TikZ graphics that contain rectangles with multiple arrows between them.

This is a simple example with only one arrow:

enter image description here

\tikzstyle{myblock} = [rectangle, draw, minimum height=3cm] 
\begin{tikzpicture}
    \node (foo)[myblock]{foo};
    \node (bar)[myblock,right-of=foo,xshift=5cm]{bar};
    \draw[->] (foo) -- node[below] {arrow text} (bar);
    % more arrows here
\end{tikzpicture}

Between different (TikZ) pictures the number of arrows and height of the two blocks differ (in one picture both of them always have the same height). The text is always short enough to fit into a single line.

Given two rectangles and a certain amount of arrows (with different directions and text), how do I distribute them equally over the height of the two blocks? Is there any automation of TikZ I could use?

Best Answer

This is quite straight forward in the sense that you can use calc library of tikz and access the points between two points with any ratio. For example, ($(foo.north east)!0.25!(foo.south east)$) is the point that is 25% away from foo.north east on the line connecting foo.north east and foo.south east. Hence we could use

\draw[->] ($(foo.north east)!0.25!(foo.south east)$) -- node[below] 
          {arrow text} ($(bar.north west)!0.25!(bar.south west)$);

Full code will be

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning,calc}
\begin{document}
  \tikzset{myblock/.style = {rectangle, draw, minimum height=3cm}
  }
\begin{tikzpicture}
    \node (foo)[myblock]{foo};
    \node (bar)[myblock,right of=foo,xshift=5cm]{bar};
    \draw[->] ($(foo.north east)!0.25!(foo.south east)$) -- node[below] {arrow text} ($(bar.north west)!0.25!(bar.south west)$);
    \draw[->] ($(foo.north east)!0.5!(foo.south east)$) -- node[below] {arrow text} ($(bar.north west)!0.5!(bar.south west)$);
    \draw[->] ($(foo.north east)!0.75!(foo.south east)$) -- node[below] {arrow text} ($(bar.north west)!0.75!(bar.south west)$);
    % more arrows here
\end{tikzpicture}
\end{document}

enter image description here

Adding to this you can also use a \foreach loop to draw the lines and reduce the code lines.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning,calc}
\begin{document}
  \tikzset{myblock/.style = {rectangle, draw, minimum height=3cm}
  }
\begin{tikzpicture}
    \node (foo)[myblock]{foo};
    \node (bar)[myblock,right of=foo,xshift=5cm]{bar};
    \foreach \a/\b in {0.25/arrow text,0.5/arrow,0.75/text}{
    \draw[->] ($(foo.north east)!\a!(foo.south east)$) -- node[below] {\b} ($(bar.north west)!\a!(bar.south west)$);
   }
    % more arrows here
\end{tikzpicture}
\end{document}
Related Question