7

How can I make an arrow first go right then up and then to the left, if two nodes above/below each other in a vertical line. (The direct vertical line down is already used, which is why I want the arrow to go right, up and then left).

Like this:

enter image description here

My code:

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric, arrows}

\tikzstyle{startstop} = [rectangle, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=blue!30]

\tikzstyle{io} = [trapezium, trapezium left angle=70, trapezium right angle=110, minimum width=3cm, minimum height=1cm, text centered, draw=black]

\tikzstyle{process} = [rectangle, minimum width=3cm, minimum height=1cm, text centered, draw=black]

\tikzstyle{decision} = [diamond, minimum width=3cm, minimum height=1cm, text centered, draw=black]

\tikzstyle{arrow} = [thick,->,>=stealth]
%
\begin{document}
\centering
\begin{tikzpicture}[node distance=5cm]

\node (start)   [startstop]                 {Filling a cup with water};
\node (p1)      [process, below of=start]   {Walk to the kitchen.};
\draw [arrow] (start) -- (p1);

\node (d1) [decision, below of=p1, yshift=1cm] {In front of correct cupboard?};
\node (p2) [process, right of=d1] {Walk to correct one.};
\node (p3) [process, below of=d1] {Grab a glas.};
\draw[arrow](p1) -- (d1);
\draw [arrow] (d1) -- node [anchor=south] {no} (p2);
\draw [arrow] (d1) -- node [anchor=west] {yes} (p3);
\node (d2) [decision, below of=p2] {In front of correct one?};
\draw [arrow] (d2) -- node [anchor=south]{yes}(p3);
\draw [arrow] (d2)   node [anchor=west] {no} (p2);
 \draw[arrow] (p2) -- (d2);
\end{tikzpicture}
\end{document}
Davislor
  • 44,045
Billy
  • 83

3 Answers3

6

Your code does not effectively control the separation of the nodes, since the diamond requires more space, so you must use the positioning library, which allows you to place the nodes relative to a certain distance \node(label_node)[style_name, on grid, below=distance cm of label_node]{Node_Text_content}; , among other modifications, style declarations must be in a separated line, allowing enable or disable some using % and leave them as comments, or add a comment to make more readable the code, finally in the case of the diamond you can use text width to allow texts to be multiline.

RESULT:

enter image description here

MWE:

% By J. Leon
%Use MIT licence, and beerware.
\documentclass[border=20pt]{standalone}
\usepackage[usenames,dvipsnames]{xcolor}
\usepackage{tikz}
\usetikzlibrary{arrows,shapes,positioning}
\definecolor{WIRE}{HTML}{002FA7} % Klein Blue

%Declaration of Styles, this code struture allow to enable or unable style modifiers.
\tikzstyle{startstop}=[
    rectangle, 
    minimum width=3cm, 
    minimum height=1cm, 
    text centered, 
    draw=black, 
    fill=blue!30
    ]
\tikzstyle{io}=[
    trapezium, 
    trapezium left angle=70, 
    trapezium right angle=110, 
    minimum width=3cm, 
    minimum height=1cm, 
    text centered,
    draw=black
    ]
\tikzstyle{process}=[
    rectangle,
    minimum width=3cm,
    minimum height=1cm,
    text centered,
    draw=black
    ]

\tikzstyle{decision}=[
    diamond,
    text width =2cm, % <-- Added to enable multiline text
    minimum width=4cm,
    minimum height=4cm,
    text centered, % Also you can white multiline using line1\\ line2
    draw=black
    ]
\tikzstyle{arrow}=[
    thick,
    ->,
    >=stealth
    ]

\begin{document}
    \begin{tikzpicture}[
        %Global Config
        %font=\sf
    ]
% Positioning the nodes using positioning library
\node (start) [startstop] {Filling a cup with water};
\node (p1) [process, on grid, below=2cm of start]{Walk to the kitchen.};
\node (d1) [decision, on grid, below=3.5cm of p1] {In front of correct cupboard?}; 
\node (p2) [process, on grid, right=5cm of d1] {Walk to correct one.}; 
\node (p3) [process, on grid, below=4cm of d1] {Grab a glas.};
\node (d2) [decision, on grid, below=4cm of p2] {In front of correct one?};

% Draw the arrows
\draw [arrow] (start) -- (p1);
\draw [arrow] (p1) -- (d1);
\draw [arrow] (d1) -- node [anchor=south] {no} (p2);
\draw [arrow] (d1) -- node [anchor=west] {yes} (p3); 
\draw [arrow] (d2) -- node [anchor=south]{yes}(p3);
\draw[arrow] (p2) -- (d2);

% Draw Special arrows 
\draw [arrow] (d2) --  node[anchor=east, above=2pt ] {no} ++(3.5,0) |- (p2);

    \end{tikzpicture}
\end{document}
J Leon V.
  • 11,533
  • 16
  • 47
5

I think your diagram could further be improved (for example with multiline text within the nodes).

See also: Should \tikzset or \tikzstyle be used to define TikZ styles?

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric, arrows, positioning}

\tikzset{
    startstop/.style={
        rectangle, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=blue!30
    },
    io/.style={
        trapezium, trapezium left angle=70, trapezium right angle=110, minimum width=3cm, minimum height=1cm, text centered, draw=black
    },
    process/.style ={
        rectangle, minimum width=3cm, minimum height=1cm, text centered, draw=black
    },
    decision/.style ={
        diamond, minimum width=3cm, minimum height=1cm, text centered, draw=black
    },
    arrow/.style = {
        thick,->,>=stealth
    },
}
%
\begin{document}
    \centering
    \begin{tikzpicture}[node distance=5cm]

    \node (start)   [startstop]                 {Filling a cup with water};
    \node (p1)      [process, below of=start]   {Walk to the kitchen.};
    \draw [arrow] (start) -- (p1);

    \node (d1) [decision, below of=p1, yshift=1cm] {In front of correct cupboard?};
    \node (p2) [process, right of=d1] {Walk to correct one.};
    \node (p3) [process, below of=d1] {Grab a glas.};
    \draw[arrow](p1) -- (d1);
    \draw [arrow] (d1) -- node [anchor=south] {no} (p2);
    \draw [arrow] (d1) -- node [anchor=west] {yes} (p3);
    \node (d2) [decision, below of=p2] {In front of correct one?};
    \draw [arrow] (d2) -- node [anchor=south]{yes}(p3);
    \draw [arrow] (d2) --  node[above=2pt] {no} ++(3,0) |- (p2);
    \draw[arrow] (p2) -- (d2);
    \end{tikzpicture}
\end{document}

enter image description here

However, I would use a TikZ matrix and do something like this:

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric, arrows, positioning, matrix}

\tikzset{
    startstop/.style={
        rectangle, text width=3cm, minimum height=1cm, text centered, draw=black, fill=blue!30, anchor=center
    },
    io/.style={
        trapezium, trapezium left angle=70, trapezium right angle=110, text width=3cm, minimum height=1cm, text centered, draw=black, anchor=center
    },
    process/.style ={
        rectangle, text width=3cm, minimum height=1cm, text centered, draw=black, anchor=center
    },
    decision/.style ={
        diamond, text width=3cm, minimum height=1cm, text centered, draw=black, anchor=center
    },
    arrow/.style = {
        thick,->,>=stealth
    },
}
%
\begin{document}
    \centering
    \begin{tikzpicture}
    \matrix[
        matrix of nodes, 
        column sep =20pt,
        row sep = 40pt,
        ]{
        |[name=start,startstop]|   {Filling a cup with water}\\
        |[name=p1,process]|  {Walk to\\ the kitchen.}\\ 
        |[name=d1,decision]|  {In front of \\ correct cupboard?}
            &|[name=p2,process]| {Walk to\\ correct one.} \\[-20pt] 
        |[name=p3,process]| {Grab a glas.}
            &|[name=d2,decision]| {In front of correct one?}\\
    };
    \draw[arrow] (start) -- (p1);
    \draw[arrow] (p1) -- (d1);
    \draw[arrow] (d1) -- node[above, near start] {no} (p2);
    \draw[arrow] (d1) -- node[above left, near start] {yes} (p3);
    \draw[arrow] (d2) -- node[above, near start] {yes} (p3);
    \draw[arrow] (d2) -- node[above, near start] {no} ++(3,0) |- (p2);
    \draw[arrow] (p2) -- (d2);
    \end{tikzpicture}
\end{document}

enter image description here

CarLaTeX
  • 62,716
2
  • your question is duplicate to many similar question, for example write-easily-a-tikz-flowchart, how-to-draw-a-return-arrow-from-node-3-to-node-1, etc.
  • an alternative solution with some (small) effort to make code more concise:

    \documentclass{article}
    \usepackage[utf8]{inputenc}
    \usepackage{tikz}
    \usetikzlibrary{arrows.meta,
                    calc, chains,
                    quotes,
                    positioning,
                    shapes.geometric}
    
    \begin{document}
        \centering
        \begin{tikzpicture}[auto,
        node distance = 8mm and 12mm,
          start chain = going below,
          base/.style = {draw, text width=32mm, minimum height=8mm, outer sep=0pt,
                         align=center, on chain},
    startstop/.style = {base, fill=blue!30},
      process/.style = {base},
     decision/.style = {base, diamond, aspect=1.3,
                        inner sep=0pt}
                            ]
    \node (start)   [startstop] {Filling a cup with water};
    \node (p1)      [process]   {Walk to the kitchen.};
    \node (d1)      [decision]  {In front of correct cupboard?};
    \node (p3)      [process]   {Grab a glas.};
    \node (p2)      [process, right=of d1]  {Walk to correct one.};
    \node (d2)      [decision]  {In front of correct one?};
        %
    \draw[semithick,-Triangle]
        (start)   edge (p1)
        (p1)      edge (d1)
        (d1)      edge["yes"] (p3)
        (d1)      edge["no"]  (p2)
        (p2)      edge (d2)
        (p3)      edge["yes"] (d2)
        (d2.east)  to ["no"] + (1,0)
                   |- (p2);
        \end{tikzpicture}
    \end{document}
    

enter image description here

Zarko
  • 296,517