16

Say I have a code to draw a flow chart, I want now a arrow from node 3 to node 1, how can I do that?

1<--|
|   |
2   |
|   |
3----

MWE

\documentclass[class=article,border=0pt]{standalone}

\usepackage{tikz}
\usetikzlibrary{shapes,arrows}

% Define block styles
\tikzset{
    block/.style={rectangle, draw, line width=0.5mm, black, text width=5em, text centered,
                  rounded corners, minimum height=2em},
    line/.style={draw, -latex}
}% <- if you insist in using this in the document add this % here.
\begin{document}
\begin{tikzpicture}[node distance = 1cm, auto]
    % Place nodes
    \node [block] (BLOCK1) {a};
    \node [block, below of=BLOCK1] (BLOCK2) {b};
    \node [block, below of=BLOCK2, node distance=1cm] (BLOCK3) {c};
    % Draw edges
    \path [line] (BLOCK1) -- (BLOCK2);
    \path [line] (BLOCK2) -- (BLOCK3);
\end{tikzpicture}
\end{document}
1

5 Answers 5

26

You can just add a line like:

\path [line] (BLOCK3) --++ (2cm,0cm) |- (BLOCK1);

This path starts at the BLOCK3 node. It then moves (--) to the point which has coordinates (2cm,0cm) relative to this point; hence one of the +s. The second + makes the resulting point the new point of reference. Without it the next part of the path would still be drawn "from" BLOCK3.

The next path description |- draws a right-angle path (vertical first, then horizontal) to BLOCK1. Had we used -| instead it would have been horizontal first, then vertical. Not that you would want that; I'm just including it for clarity.

output

8
  • Someday I'll have to figure out a way to remember this syntax -- not sure why I always have to do trial and error to get it right. :-) Commented Mar 14, 2013 at 2:02
  • Me too, I am kind of confused about this syntax, tried many times and cant get it right, haha. Thank you Matthew
    – Daniel
    Commented Mar 14, 2013 at 2:19
  • 3
    -- ++(2cm,0cm) seems easier to understand than --++ (2cm,0cm). Commented Mar 14, 2013 at 7:29
  • 1
    Ther ei sno accountin gfo rtaste, I guess. :-) Commented Mar 14, 2013 at 17:29
  • 1
    @Nicolás: I would agree it's easier to read than mine, but remembering just comes with a few repetitions. I try to follow DRY when coding TikZ, so if I want to change the name of BLOCK3 I only have to change it in one place. But there is room for both methods, to be sure. Commented Mar 18, 2014 at 16:35
19

A previous version of this answer explained the paths.ortho library that was published in my pgf repo on GitHub. The library is now part of my tikz-ext package which should be used instead (and has a proper manual).

The ext.paths.ortho library provides

  • the path operations r-ud, r-rl, r-du and r-lr, they can be used like -- or -| for example and
  • the keys udlr distance as well as for every operator one <operator> distance, which sets the distance between the middle part of the line and the nearest node.

Furthermore, nodes/coordinates can be placed at any position. Similar to the |- and -| operators, the corner points lie at 0.25 and 0.75; this can be set to 1/<n> and (<n>-1)/<n> with pacing=<n>, i.e. using spacing=3 sets the corner at 0.3333 and 0.6667. The default is 4.

There’s also the boolean only middle which sets the corner points at 0 and 1 respectively.

More of this is explained in my answer to Vertical and horizontal lines in pgf-tikz.


In your example, all you need to do after loading the library is

\path [line] (BLOCK3) r-rl (BLOCK1);

Code

\documentclass[tikz]{standalone}
\usetikzlibrary{positioning, ext.paths.ortho}
\tikzset{
  block/.style={rectangle,draw,minimum size=1cm},
  line/.style={draw, -latex},
}
\begin{document}
\begin{tikzpicture}[node distance = 1cm, auto]
% Place nodes
\node [block]                                         (BLOCK1) {a};
\node [block, below=    of BLOCK1]                    (BLOCK2) {b};
\node [block, below=2cm of BLOCK2, node distance=1cm] (BLOCK3) {c};
% Draw edges
\path [line] (BLOCK1) -- (BLOCK2);
\path [line] (BLOCK2) -- (BLOCK3);
\path [line] (BLOCK3) r-rl (BLOCK1);
\end{tikzpicture}
\begin{tikzpicture}[
  node distance = 1cm,
  /utils/temp/.style={#1/.style={to path={r-#1(\tikztotarget)\tikztonodes}}},
  /utils/temp/.list={ud, rl, du, lr}]
\node [block]             (a) {a};
\node [block, below=of a] (b) {b};
\node [block, right=of a] (c) {c};
\node [block, below=of c] (d) {d};

\path[line, very thick] (a) edge[ud] (c)
                        (c) edge[rl] (d)
                        (d) edge[du] (b)
                        (b) edge[lr] (a);

\path[line, green, thick, ortho/udlr distance=0.25cm] (a) edge[du] (c)
                                                      (c) edge[lr] (d)
                                                      (d) edge[ud] (b)
                                                      (b) edge[rl] (a);

\draw[red] (a) r-ud (c) r-rl (d) r-du (b) r-lr (a);
\end{tikzpicture}
\end{document}

Output 1

enter image description here enter image description here

3
  • This is 'fancy' but how has it got anything to do with what the OP asks? :) Commented Apr 13, 2015 at 0:08
  • 2
    @Svend \path [line] (BLOCK3) r-rl (BLOCK1); It seems I have removed the example of the question in my attempts to clean up my answer. Commented Apr 13, 2015 at 0:13
  • I see! I've never learned TikZ so I didn't knew that there is a easy fix. :) Commented Apr 13, 2015 at 0:33
4

One way to do it is to access the east anchor points, applying an xshift and draw form there:

enter image description here

Note:

  • As per Matthew Leingang's answer, there is also the |- syntax, but I always have to either look that up or do trial and error to get it right.

Code:

\documentclass[class=article,border=2pt]{standalone}

\usepackage{tikz}
\usetikzlibrary{shapes,arrows}

% Define block styles
\tikzset{
    block/.style={rectangle, draw, line width=0.5mm, black, text width=5em, text centered,                 rounded corners, minimum height=2em},
    line/.style={draw, -latex}
}% <- if you insist in using this in the document add this % here.
\begin{document}
\begin{tikzpicture}[node distance = 1cm, auto]
    % Place nodes
    \node [block] (BLOCK1) {a};
    \node [block, below of=BLOCK1] (BLOCK2) {b};
    \node [block, below of=BLOCK2, node distance=1cm] (BLOCK3) {c};
    % Draw edges
    \path [line] (BLOCK1) -- (BLOCK2);
    \path [line] (BLOCK2) -- (BLOCK3);

\path [line, red, thick] (BLOCK3.east) --
    ([xshift=0.5cm]BLOCK3.east) --
    ([xshift=0.5cm]BLOCK1.east) --
    (BLOCK1.east);
\end{tikzpicture}
\end{document}
1

A MetaPost solution with the boxes package, combined with the MetaFun format (for the smoothed corners of the bounding boxes).

\documentclass[border=2mm]{standalone}
\usepackage{luamplib}
  \mplibsetformat{metafun}
  \mplibtextextlabel{enable}
\begin{document}
  \begin{mplibcode}
    input boxes;
    numeric len; len := cm;
    beginfig(1); 
      boxjoin(a.s - b.n = (0, .5cm));
      forsuffixes m = a, b, c:
        boxit.m(str m); 
        m.e - m.w = (1.5cm, 0); m.n - m.s = (0, 5mm);
      endfor
      forsuffixes m = a, b, c:
        drawunboxed(m);
        draw (bpath m) cornered 2mm;
      endfor
      drawarrow a.s -- b.n; drawarrow b.s -- c.n;
      drawarrow c.e -- c.e + (len, 0) -- a.e + (len, 0) -- a.e withcolor red;
    endfig; 
  \end{mplibcode}
\end{document}

To be processed with LuaLaTeX.

enter image description here

1

A PSTricks solution:

\documentclass{article}

\usepackage{multido}
\usepackage{pstricks}
\usepackage{xfp}

% horizontal width of ``back to start'' arrow
\def\arrow{1}

% \diagram[<box width>,<box height>](<number of boxes>){<box separation>}
\def\diagram[#1,#2](#3)#4{%
\begin{pspicture}(\fpeval{#1+\arrow},\fpeval{#3*#2+(#3-1)*#4})
  \multido{\rA = 0+\fpeval{#2+#4},
           \rB = \fpeval{#2/2}+\fpeval{#2+#4},
           \i = #3+-1}{#3}{%
    \psframe[framearc = 0.3](0,\rA)(#1,\fpeval{\rA+#2})
    \rput(\fpeval{#1/2},\rB){$\i$}}
  \multido{\r = #2+\fpeval{#2+#4}}{\fpeval{#3-1}}{%
    \psline{<-}(\fpeval{#1/2},\r)(\fpeval{#1/2},\fpeval{\r+#4})}
  \psline{->}%
    (#1,\fpeval{#2/2})%
    (\fpeval{#1+\arrow},\fpeval{#2/2})%
    (\fpeval{#1+\arrow},\fpeval{(#3-0.5)*#2+(#3-1)*#4})%
    (#1,\fpeval{(#3-0.5)*#2+(#3-1)*#4})
\end{pspicture}}

\begin{document}

\diagram[2.2,1](4){0.5} \qquad
\diagram[1.5,2](3){0.3} \qquad
\diagram[2.5,1](5){0.7}

\end{document}

output

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .