5

I'm drawing a kind of sequence diagram but I don't want to calculate every position.

I want to use relative coordinates. With the command coodinate I set the first coordinate (0.25,14.25) as a, but I want to select a second coordinate (0.25,14.75).

Is there a way to do this?

%Actor
\draw[dashed] (0.25,15) -- (0.25,0)  node[above=15] {User};
\draw[dashed] (6,15) -- (6,0)  node[above=15] {HMI};
\draw[dashed] (12,15) -- (12,0) node[above=15] {Server1};
\draw[dashed] (18,15) -- (18,0) node[above=15] {Server2};
%
%Blocks
\begin{scriptsize}
\draw[line width=5pt] (0.25,14.25) -- (0.25,14.75)  node[midway, right] {Test} coordinate (a);
\end{scriptsize}
%
%Arrows
\begin{scope}[>=latex]
\draw[->,black] (a) -- (6,14);
\end{scope}
  • Welcome. Please can you add a complete MWE? What are packages that you use? – Sebastiano Mar 5 '17 at 20:16
6

You can do this using the calc library (See Section 13.5 Coordinate Calculations of the pgf manual):

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}

\begin{tikzpicture}
  \coordinate (a) at (2,2);
  \coordinate (b) at (0,-2);
  \node[draw=red] at (a) {a};
  \node[draw=red] at (b) {b};
  \draw[help lines] (-1,-3) grid (3,3);
  \draw ($ (a) + (0,1) $) -- ($ (b) + (0,1) $);
\end{tikzpicture}
\end{document}
3

I think you have it a bit confused. Your coordinate (a) (which is an empty node) is really (0.25,14.75), at the end of the path.

To have a "marker" for the start and end of the path you can do:

    %Blocks
    \begin{scriptsize}
        \draw[line width=5pt] (0.25,14.25) coordinate(b) -- 
             (0.25,14.75)  node[midway, right] {Test} coordinate (a);
    \end{scriptsize}
    %
    %Arrows
    \begin{scope}[>=latex]
        \draw[->,black] (a) -- ++(1,0) node {a};
        \draw[->,black] (b) -- ++(1,0) node {b};
    \end{scope}

and you'll have (partial graph):

Partial shot of the result

In general, you can have node on whichever part of the path, with the pos key; if you add

        \draw[line width=5pt] (0.25,14.25) coordinate(b) -- 
           (0.25,14.75)  node[midway, right] {Test} 
           coordinate (a)  coordinate[pos=0.5](c);

and

       \draw[->,black] (c) -- ++(2,0) node {c};

you have:

Adding a point in the middle

Notice also that the midway keys is really another way of saying pos=0.5.

2

First Answer: Use the package tikz-uml, it offers also support for sequence diagrams. See perso.ensta-paristech.fr/~kielbasi/tikzuml; the sequence diagrams are documented here.

Second Answer: If you want to do it yourself using the tikz commands directly, I suggest to

  • use commands for constants, like \xUser and \xHmi for the horizontal positions of the time lines

  • use nodes for actors and actions and name them

  • define styles for the parameters of the nodes.

Then it will be easy to adjust and extend the diagram. Here is an example how you can do it.

enter image description here

\documentclass[border=3pt]{standalone}
\usepackage{tikz}
\tikzset
  {actor/.style={font=\ttfamily},
   action/.style 2 args= % first arg is length in mm, second arg is label
     {minimum width=3mm,minimum height=#1mm,inner sep=0pt,
      draw,fill=blue!30,anchor=north,label={right:\scriptsize#2}
     },
   message/.style={-stealth,font=\scriptsize\bfseries},
   timeline/.style={dashed}
  }
\begin{document}
\begin{tikzpicture}[x=1mm,y=1mm]
  % horizontal position of actors (in mm)
  \newcommand\xUser{0}
  \newcommand\xHmi{20}
  \newcommand\xSa {40}
  \newcommand\xSb {60}
  % actors
  \node[actor] (user-0) at (\xUser,0) {User}; 
  \node[actor] (hmi-0)  at (\xHmi ,0) {HMI};
  \node[actor] (s1-0)   at (\xSa  ,0) {Server1};
  \node[actor] (s2-0)   at (\xSb  ,0) {Server2};
  % time lines
  \newcommand\yTimeMax{-65}
  \draw[timeline] (user-0) -- +(0,\yTimeMax); % example for relative positioning
  \draw[timeline] (hmi-0)  -- +(0,\yTimeMax);
  \draw[timeline] (s1-0)   -- +(0,\yTimeMax);
  \draw[timeline] (s2-0)   -- +(0,\yTimeMax);
  % actions (first arg is length in mm, second arg is label)
  \node[action={10}{$A_1$}] (user-1) at (\xUser,-10) {};
  \node[action={ 5}{$A_2$}] (hmi-1)  at (\xHmi ,-20) {};
  \node[action={15}{$A_3$}] (s1-1)   at (\xSa  ,-25) {};
  \node[action={10}{$A_4$}] (user-2) at (\xUser,-50) {};
  % messages
  \draw[message] (user-1.south east) -- node[above]{a} (hmi-1.north west);
  \draw[message] (hmi-1.south east)  -- node[above]{b} (s1-1.north west);
  \draw[message] (s1-1.south west)   -- node[above]{c} (user-2.north east);
\end{tikzpicture}
\end{document}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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