Tikz: Draw thick arrows with text inside between coordinates

arrowsdiagramstikz-pgf

I would like to draw arrows with text inside them like in the example below that I sketched in Visio:

Example sketch with boxes and arrows

The following code gives a nice arrow shape, but I can't manage to rotate the text in the downward arrow to read from the right like the double arrow. Also, positioning the arrows would be easier if they could be drawn between coordinates instead of as nodes.

I would also like to be able to stretch the arrows (ideally relative to coordinates instead of specifying absolute lengths) like in the "longer arrow".

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{shapes.arrows}

\tikzset{MyArrow/.style={single arrow, draw=black, minimum width=10mm, minimum height=30mm,
                         inner sep=0mm, single arrow head extend=1mm}}
                         
\begin{document}

\begin{tikzpicture}

\draw[] (0,0) rectangle +(2,3)  node[midway] {Box 1};
\draw[] (4,0) rectangle +(2,3)  node[midway] {Box 2};
\path[] (1,3.5) node[anchor=tip,MyArrow,rotate=270] {single down};
\path[] (5,3.5) node[anchor=west,MyArrow,rotate=90,double arrow] {double up / down};

\end{tikzpicture}

\end{document}

Best Answer

Welcome to TeX.SX! You can use the option shape border rotate to only rotate the shape of the node. In combination with the regular rotate option, you are then able to rotate arrow and inner text separately.

As for positioning such arrows between two nodes or coordinates, you can use the same technique you already used to place the lables to the rectangles: First create a path between two nodes or two coordinates and then place an arrow-shaped node midways (or somewhere else) on this path.

\documentclass[border=1mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.arrows}

\tikzset{MyArrow/.style={single arrow, draw=black, minimum width=10mm, minimum height=30mm, inner sep=0mm, single arrow head extend=1mm}}
                         
\begin{document}
\begin{tikzpicture}

\draw[] (0,0) rectangle +(2,3) node[midway] (box1) {Box 1};

\draw[] (6,0) rectangle +(2,3) node[midway] (box2) {Box 2}; 

\path (box1) -- (box2) node[midway, MyArrow] {right}; 

\path (box1) -- (box2) node[midway, MyArrow, shape border rotate=180, yshift=30] {left}; 

\path (box1) -- (box2) node[midway, MyArrow, double arrow, yshift=-30] {left/right}; 

\path (box1) -- +(0,3.5) node[pos=1, MyArrow, rotate=90] {right}; 

\path (box2) -- +(0,3.5) node[pos=1, MyArrow, rotate=90, shape border rotate=180] {left}; 
%      ^ you can also place a coordinate like (0,0) here

\end{tikzpicture}
\end{document}

enter image description here


Update

Since the OP added some more requirements to their first question, I came up with an update to my original answer.

To match the thickness of the double arrows to the thickness of the single arrows, you could just add the option double arrow head extend to your style and assign it the same value as the option single arrow head extend. Both options will only have an effect if the shape is a single arrow or a double arrow, so it is safe to add both at once.

In order to get arrows stretching over the distance between two coordinates or nodes, you could use the approach described in this answer. I added a new style that takes two coordinates or node names (connected by --) as argument and calculates the length of the arrow from this information.

Note: in order for this to work, you need to load the calc library.

\documentclass[border=1mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.arrows, calc}

\tikzset{
    MyArrow/.style={
        single arrow, draw=black, minimum width=10mm, minimum height=30mm, inner sep=0mm, single arrow head extend=1mm, double arrow head extend=1mm
    },
    MyLongArrow/.style args={#1 -- #2}{
        insert path={let \p1=($(#1)-(#2)$) in}, 
        single arrow, draw=black, minimum width=10mm, minimum height={veclen(\x1,\y1)-30mm}, inner sep=0mm, single arrow head extend=1mm, double arrow head extend=1mm
    }
}

\begin{document}
\begin{tikzpicture}

\draw[] (0,0) rectangle +(2,5) node[midway] (box1) {Box 1};

\draw[] (6,0) rectangle +(2,5)  node[midway] (box2) {Box 2}; 

\draw[] (12,0) rectangle +(2,5)  node[midway] (box3) {Box 3}; 

\path (box1) -- (box2) node[midway, MyArrow, yshift=15] {right}; 

\path (box1) -- (box2) node[midway, MyArrow, shape border rotate=180, yshift=45] {left}; 

\path (box1) -- (box2) node[midway, MyArrow, double arrow, yshift=-15] {left/right}; 

\path (box1) -- (box3) node[midway, MyLongArrow={box1 -- box3}, yshift=-45] {right}; 

\end{tikzpicture}
\end{document}

enter image description here