# Proper way to draw a tikz flowchart with arrows pointing back and forth between two nodes

I apologize if this is a duplicate, but I'm having a hard time finding an elegant solution. I have something that "works," but feels wonky.

I'm making a presentation in beamer and I want to have boxes with arrows pointing back and forth between objects. Here's a mwe with an idea of what I would like to achieve:

\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{calc,arrows,shapes}

\begin{document}
\begin{frame}
\tikzstyle{service} = [draw, fill=blue!20]
\begin{figure}
\begin{tikzpicture}[node distance=2cm, auto,>=latex', thick]
\path[->] node[service] (svc1) {service 1};
\path[->] node[service, right of=svc1,xshift=2cm] (svc2) {service 2}
(svc1.10) edge node {restarts} (svc2.170);
\path[->] node[service, below of=svc2] (svc3) {service 3}
(svc2.280) edge node {configures} (svc3.80);
\path[<-] (svc2.240) edge node {} (svc3.120);
\path[<-] (svc1.-10) edge node {} (svc2.190);
\end{tikzpicture}
\end{figure}
\end{frame}
\end{document}


However, I believe that this seems like such a simple problem that a more elegant (automated) solution vs. putting in angles must exist.

-

A few tips to improve the code:

• Using (svc1.10) edge node {restarts} (svc2.170) might produce undesired results (not a perfectly horizontal rule) if the nodes are shifted; you can guarantee a horizontal line using the perpendicular coordinate system, as in

(svc1.10) edge node {restarts} (svc2.west|-svc1.10)


A similar remark for vertical rules. One might even define a style with arguments to automate a little this kind of double arrow.

• The syntax of = is deprecated, you should use the positioning library and = of.

• \tikzstyle is old syntax; you should use \tikzset instead.

The code:

\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{calc,arrows,shapes,positioning}

\begin{document}
\begin{frame}
\tikzset{service/.style={draw, fill=blue!20}}
\begin{figure}
\begin{tikzpicture}[node distance=1.5cm and 2cm, auto,>=latex', thick]
\path[->] node[service] (svc1) {service 1};
\path[->] node[service, right = of svc1] (svc2) {service 2}
(svc1.10) edge node {restarts} (svc2.west|-svc1.10);
\path[->] node[service, below = of svc2] (svc3) {service 3}
(svc2.280) edge node {configures} (svc2.280|-svc3.north);
\path[<-] (svc2.240) edge node {} (svc2.240|-svc3.north);
\path[<-] (svc1.-10) edge node {} (svc2.west|-svc1.-10);
\end{tikzpicture}
\end{figure}
\end{frame}
\end{document}


-
Thanks very much for the quick reply! Can you explain what (svc2.west|-svc1.10) means? I'm guessing it would mean that this end should be at svc2.west and perpendicular to -svc1.-10. Come to think of it, I can't really put it in words... –  zje Sep 5 '13 at 23:08
@zestrada Sure. (<a>|-(<b>)) has the x-coordinate of <a> and the y-coordinate of <b>; (<a>-|(<b>)) has the x-coordinate of <b> and the y-coordinate of <a>. –  Gonzalo Medina Sep 5 '13 at 23:11

Using tikz-cd’s shift right and shift left option.

Though, it is not possible to do edge[shift …=…] but

(<start>) {[shift …=…] edge … (<target>)}


One need to re-write the options as a to path to be able to use them as options to the edge.

## Code

\documentclass[tikz]{standalone}
\usepackage{tikz-cd}
\usetikzlibrary{arrows,positioning}
\tikzset{
shift left/.style ={commutative diagrams/shift left={#1}},
shift right/.style={commutative diagrams/shift right={#1}}
}
\begin{document}
\begin{tikzpicture}[
node distance=1.5cm and 2cm,
>=latex',
auto,
thick,
service/.style={draw, fill=blue!20},
]
\node[service] (svc1) {service 1};
\node[service, right = of svc1] (svc2) {service 2};
\node[service, below = of svc2] (svc3) {service 3};

\path[->, shift left=.75ex]
(svc1) edge node {restarts}   (svc2)
(svc2) edge node {configures} (svc3)
(svc3) edge                   (svc2)
(svc2) edge                   (svc1);
\end{tikzpicture}
\end{document}


-