9

I have the following Tikz code:

\usetikzlibrary{positioning}
\begin{tikzpicture}
    \tikzstyle{bordered} = [draw,thick,inner sep=5,minimum size=10,minimum width=100,font=\sffamily]
    \tikzstyle{arrow} = [thick,-latex,font=\sffamily]

    \node [] (init) {};
    \node [bordered,below=of init] (image) {App Image};
    \node [bordered,below=of image] (running) {Running Container};
    \node [bordered,below=of running] (stopped) {Persisted Container};

    \draw [arrow] (init) -- (image) node [midway,right] {Install};
    \draw [arrow] (image) -- (running) node [midway,right] {Start};
    \draw [arrow] (running) -- (stopped) node [midway,right] {Terminate or Kill};
    \draw [arrow] (stopped.west) -- (running.west) node [midway,left] {Start};
    \draw [arrow] (stopped.west) -- (image.west) node [midway,left] {Reset};
\end{tikzpicture}

This results in:

enter image description here

I want the last two edges to be at at distance from their nodes, at a right angle. Here's a depiction of what I want:

enter image description here

I could do it by adding invisible nodes next to each "real" node, but I think there must be a better and more comfortable solution?

9

There are probably various approaches to this. This example shows one that I frequently use.

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

\begin{tikzpicture}
    \tikzstyle{bordered} = [draw,thick,inner sep=5,minimum size=10,minimum width=100,font=\sffamily]
    \tikzstyle{arrow} = [thick,-latex,font=\sffamily]

    \node [] (init) {};
    \node [bordered,below=of init] (image) {App Image};
    \node [bordered,below=of image] (running) {Running Container};
    \node [bordered,below=of running] (stopped) {Persisted Container};

    \draw [arrow] (init) -- (image) node [midway,right] {Install};
    \draw [arrow] (image) -- (running) node [midway,right] {Start};
    \draw [arrow] (running) -- (stopped) node [midway,right] {Terminate or Kill};


    \draw [arrow] ($(stopped.west)+(0,2pt)$)  -- 
                  ++(-1em,0)                  -- 
                  ($(running.west)+(-1em,0)$) 
                  node [midway,right] {Start} -- 
                  (running.west);

    \draw [arrow] ($(stopped.west)+(0,-2pt)$) -- 
                  ++(-2em,0)                  -- 
                  ($(image.west)+(-2em,0)$) 
                  node [midway,left] {Reset}  -- 
                  (image.west) ;
\end{tikzpicture}

\end{document}

enter image description here

  • Thank you so much! That's exactly what I wanted. Accepted your answer - can't upvote because of current reputation here, sorry :( – ctitze Apr 7 '15 at 15:11
  • Upvoted your answer now as I have enough reputation :) – ctitze Apr 7 '15 at 16:00
5

Somewhat simpler variant using the perpendicular syntax (|- or -|):

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

\begin{tikzpicture}
    \tikzstyle{bordered} = [draw,thick,inner sep=5,minimum size=10,minimum width=100,font=\sffamily]
    \tikzstyle{arrow} = [thick,-latex,font=\sffamily]

    \node [] (init) {};
    \node [bordered,below=of init] (image) {App Image};
    \node [bordered,below=of image] (running) {Running Container};
    \node [bordered,below=of running] (stopped) {Persisted Container};

    \draw [arrow] (init) -- (image) node [midway,right] {Install};
    \draw [arrow] (image) -- (running) node [midway,right] {Start};
    \draw [arrow] (running) -- (stopped) node [midway,right] {Terminate or Kill};


    \draw [arrow] 
          (stopped.west) ++ (up:2pt) 
          -- ++(left:1em) 
          |- (running.west)
          node[pos=0.25,right]{Start} ;

    \draw [arrow] 
    (stopped.west) ++ (down:2pt)
          -- ++(left:2em) 
          |- (image.west)
          node[pos=0.25,left]{Reset};
\end{tikzpicture}

\end{document}
3

A PSTricks solution:

\documentclass{article}

\usepackage{pstricks}
\usepackage{xfp}

% parameters
\def\boxWidth{3.4}
\def\boxHeight{0.7}
\def\separation{1}
\def\arrow{0.4}

% simplifies notation
\def\constA#1#2{\fpeval{#1*\boxHeight+#2*\separation}}
\def\constB#1{\fpeval{1+#1*\arrow}}
\def\constC#1{\fpeval{\constB{2}+#1*\boxWidth}}


\begin{document}

\psset{arrows = ->}
\begin{pspicture}(\fpeval{1+2*\arrow+max(\boxWidth,\boxWidth/2+2.85)},
                  \fpeval{3*(\boxHeight+\separation)})
  \psline(\constC{0.5},\constA{3}{3})(\constC{0.5},\constA{3}{2})
  \uput[r](\constC{0.5},\constA{2.5}{3}){Install}
  \psframe(\constB{2},\constA{2}{2})(\constC{1},\constA{3}{2})
  \rput(\constC{0.5},\constA{2.5}{2}){App Image}
  \psline(\constC{0.5},\constA{2}{2})(\constC{0.5},\constA{2}{1})
  \uput[r](\constC{0.5},\constA{2}{1.5}){Start}
  \psframe(\constB{2},\constA{1}{1})(\constC{1},\constA{2}{1})
  \rput(\constC{0.5},\constA{1.5}{1}){Running Container}
  \uput[r](\constC{0.5},\constA{1}{0.5}){Terminate or Kill}
  \psline(\constC{0.5},\constA{1}{1})(\constC{0.5},\constA{1}{0})
  \psframe(\constB{2},0)(\constC{1},\constA{1}{0})
  \rput(\constC{0.5},\constA{0.5}{0}){Persisted Container}
  \psline(\constB{2},\fpeval{1/3*\boxHeight})%
         (1,\fpeval{1/3*\boxHeight})%
         (1,\constA{2.5}{2})%
         (\constB{2},\constA{2.5}{2})
  \uput[l](1,\constA{1.5}{1}){Reset}
  \psline(\constB{2},\fpeval{2/3*\boxHeight})%
         (\constB{1},\fpeval{2/3*\boxHeight})%
         (\constB{1},\constA{1.5}{1})%
         (\constB{2},\constA{1.5}{1})
  \uput[r](\constB{1},\constA{1}{0.5}){Start}
\end{pspicture}

\end{document}

output

All you have to do is change the values of the parameters and the drawing will be adjusted accordingly.

1

Very late ... so more or less for exercise; an alternative, compact code:

\documentclass[border=3mm,tikz]{standalone}
\usetikzlibrary{arrows.meta,chains,quotes}

    \begin{document}
\begin{tikzpicture}[
           auto, 
           font = \sffamily,
  node distance = 12mm,
    start chain = going below,
bordered/.style = {draw, thick, 
                   minimum height=6mm, minimum width=33mm, text depth=0.25ex,
                   on chain},
   arrow/.style = {thick,-{Latex[]}},
      sy/.style = {yshift=#1 mm}
                    ]
\coordinate[on chain] (init);
    \node (image)   [bordered] {App Image};
    \node (running) [bordered] {Running Container};
    \node (stopped) [bordered] {Persisted Container};
\path[arrow]
    (init)      edge["Install"]             (image)
    (image)     edge["Start"]               (running)
    (running)   edge["Terminate or Kill"]   (stopped);
\draw[arrow]    ([sy=+1] stopped.west) -- + (-0.5,0) 
                |- node[pos=0.25,swap] {Start}  (running);
\draw[arrow]    ([sy=-1] stopped.west) -- + (-0.7,0) 
                |- node[pos=0.25] {Reset}  (image);
\end{tikzpicture}
    \end{document}

enter image description here

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.