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'm trying to do this diagram using TikZ but I haven't managed to draw the curved arrow (see what I tried in the commented lines). How can I draw an arc between two Cartesian coordinates? How can I fit all the diagram into a rectangle? What I have did doesn't work...

I want something like this:

\draw [->, radius=r] (x1,y1)  arc (x2,y2);

I have tried the solution given in the comment but I'm not satisfied.

MWE

\documentclass[border=10pt]{standalone}
%\usepackage[margin=1cm]{geometry}
\usepackage{tikz,xcolor}
\usepackage{hyperref}
\usepackage{tkz-euclide}
\usetkzobj{all} 

\usetikzlibrary{shapes.geometric,arrows,positioning,fit,calc,}
\tikzset{
b/.style={draw, rectangle, rounded corners=2ex,minimum height=0.5in, minimum width=2in,align=center},
c/.style={draw, rectangle, rounded corners=2ex, minimum height=0.5in, minimum  width=2in,align=center, rotate=-90},
ar/.style={rounded corners=2ex,->,>=latex },  
myarrow/.style args={#1 colored by #2 and #3}{
    -stealth,line width=#1,#2,postaction={draw,-stealth,#3,line width=(#1)/3,
    shorten <=(#1)/3,shorten >=2*(#1)/3}, 
  }
}

\makeatletter
\newcommand{\gettikzxy}[3]{%
  \tikz@scan@one@point\pgfutil@firstofone#1\relax
  \edef#2{\the\pgf@x}%
  \edef#3{\the\pgf@y}%
}
\makeatother


\begin{document}
\begin{tikzpicture} 
       \node (client) [b] {Client};
       \node (serveur) [b, left=4 cm of client.west] {Serveur};
       \gettikzxy{(client)}{\axc}{\ayc}
       \draw[thick] (client.south) -- (\axc, \ayc - 300);
       \gettikzxy{(serveur)}{\axs}{\ays}
       \draw[thick] (serveur.south) -- (\axs, \ays - 300);
       \draw [ar] (\axc, \ayc - 100) -- node[above]{\parbox[t]{5cm}{\centering POST \nolinkurl{authentification/}\\username=user\&password=abc123}} (\axs, \ays -100);
       \draw [ar] (\axs, \ays - 150) -- node[above]{\parbox[t]{5cm}{\centering HTTP 200 OK\\ \color{green}{\{Token : "JWT"\}}}} (\axc, \ayc -150);
       \draw [ar] (\axc, \ayc - 200) -- node[above]{\parbox[t]{5cm}{\centering GET \nolinkurl{api/user/id}\\ \color{green}{JWT : Token} }} (\axs, \ays -200);

       \draw [ar] (\axc, \ayc - 250) -- node[below]{\parbox[t]{5cm}{\centering HTTP 200 OK\\ \color{green}{\{name : foo\} }}} (\axs, \ays -250);

       %\draw[->] (\axs,\ays - 200) arc (-120:30:5) ;
       % Draw the arc which center is (2,1)
       %\draw[thick,red] ([shift=(90:1cm)]\axs,\ays-175) arc (90:360:0.9cm);
      % \draw [->] (\axs,\ays-150)  arc (\axs,\ays-200,2.1);
       %\draw [<->] (0:2.1)  arc (0:60:2.1);
       %\draw [->,line width=5pt]  (\axs:-200) arc (\axs:-300);

       %\draw [ar] ([yshift=0.5cm]serveur.south)  -- node[above]{
    %                             \parbox[t]{5cm}{POST authentification/\\username=...\&password=..}} ([yshift=0.5cm]client.south);
       %\draw [ar] ([yshift=-0.5cm]client.south) -- ([yshift=-0.5cm]serveur.north);

\node [rectangle, opacity=0.2, fill=blue, fit=(client)(serveur),]{};
\draw[->, thick] (\axs-3,\ays-150) to[bend left=250] (\axs-3,\ays-200);
  \end{tikzpicture}

\end{document}

enter image description here

share|improve this question
    
see examples in tikz manual: 14.7 the arc operation, pp 152 -- 153 (for version 3.0.0). –  Zarko May 18 at 16:57
    
@Zarko I have looked to the manual and read many other question. But all are about arc between two point defined by polar coordinates. It's not the case with me. –  user230137 May 18 at 17:02
    
If it doesn't have to be part of a circle, you could do e.g. \draw (0,0) to[bend left=45] (2,0);. –  Torbjørn T. May 18 at 17:20
    
@TorbjørnT. Yes thanks, how about the radius? –  user230137 May 18 at 17:23
    
You can't really set the radius with that simple notation, it's not a circular arc but a bezier curve (I think). So it's very limited. –  Torbjørn T. May 18 at 17:36

1 Answer 1

up vote 4 down vote accepted

Well, here's a suggestion. It uses the accepted answer from What's the easiest way to draw the arc defined by three points in TikZ? to draw the arc. A third coordinate is placed midway between the two points, offset a bit to the left, and used as a midpoint for the arc. Modifying this offset changes the radius of the circle, although the offset is of course not the same as the radius.

I also changed how all the lines and arrows are drawn. Whether you think this is an improvement or not I'll leave for you to decide. Note that you can define a text width and alignment for nodes, so there is no need to add a \parbox in each node. See the new toptext style.

Regarding the background fill: The fit library lets you create a node that encompasses a list of other nodes. When you only add the two top nodes to this list, it will of course not cover the entire figure. What I did was to add a new node bottom at the end of one of the vertical lines, and add this to the fit= node list. (You could also use the anchors of the current bounding box node.) Using the backgrounds library I placed the fill on the background, so it doesn't cover up the other elements.

A final note: \color{green} is a switch that makes all the following text green. Hence, the final pair of braces in \color{green}{text} is not needed, and they wont limit the effect of \color. There is however a \textcolor command that does use such a syntax, \textcolor{green}{green text}. (Compare \textcolor{red}{red text} black text \color{red}{red text} still red text.)

\documentclass[border=10pt]{standalone}

\usepackage{tikz}
\usepackage{tkz-euclide}
\usetkzobj{all} 
\usetikzlibrary{shapes.geometric,arrows,positioning,fit,calc,backgrounds}

\usepackage{hyperref}

\tikzset{
   b/.style={
       draw,
       rectangle,
       rounded corners=2ex,
       minimum height=0.5in,
       minimum width=2in,
       align=center},
   c/.style={
      draw,
      rectangle,
      rounded corners=2ex,
      minimum height=0.5in,
      minimum width=2in,
      align=center,
      rotate=-90},
   ar/.style={
      rounded corners=2ex,
      ->,
      >=latex},  
   myarrow/.style args={#1 colored by #2 and #3}{
      -stealth,
      line width=#1,
      #2,
      postaction={draw,-stealth,#3,line width=(#1)/3,
      shorten <=(#1)/3,
      shorten >=2*(#1)/3}, 
      },
   toptext/.style={    % <-- New
      above,
      text width=5cm,
      align=center}
}

\begin{document}
\begin{tikzpicture} 
\node (client) [b] {Client};
\node (serveur) [b, left=4 cm of client.west] {Serveur};

% draw the vertical lines      
\draw [thick] (serveur.south) -- ++(0,-300pt);
\draw (client.south) -- ++(0,-300pt) coordinate (bottom);

% add a coordinate below serveur for given y-offsets from bottom of serveur
\foreach [count=\i] \y in {-100,-150,-200,-250}
  \path (serveur.south) ++(0,\y pt) coordinate (level \i);

\draw [ar] (level 1 -| client.south) -- node[toptext] {POST \nolinkurl{authentification/}\\username=user\&password=abc123} (level 1);

\draw [ar] (level 2) -- node[toptext] {HTTP 200 OK\\ \textcolor{green}{\{Token : "JWT"\}}} (level 2-| client.south);

\draw [ar] (level 3 -| client.south) -- node[toptext] {GET \nolinkurl{api/user/id}\\ \textcolor{green}{JWT : Token}} (level 3);

\draw [ar] (level 4 -| client.south) -- node[toptext,below] {HTTP 200 OK\\ \textcolor{green}{\{name : foo\}}} (level 4);


% define some coordinates
\coordinate (a) at ($(level 2) + (-3pt,0)$);
\coordinate (b) at ($(level 3) + (-3pt,0)$);
\coordinate (c) at ($(a)!0.5!(b) + (-1cm,0)$);  % modify the -1cm offset here

% Just to show the points used
\foreach \x in {a,b,c}
  \fill[red] (\x) circle[radius=2pt];

% Draw the arc through the points
\tkzCircumCenter(a,b,c)\tkzGetPoint{O}
\tikzset{compass style/.append style={-latex,thick,black}}
\tkzDrawArc(O,a)(b)  

% fill background
\begin{scope}[on background layer]      
  \node [rectangle, opacity=0.2, fill=blue, fit=(client)(serveur)(bottom)]{};
\end{scope}
\end{tikzpicture}

\end{document}

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.