Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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.

share|improve this question

2 Answers 2

up vote 7 down vote accepted

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}

enter image description here

share|improve this answer
    
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
1  
@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}

Output

enter image description here

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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