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}
Qrrbrbirlbel
  • 119,821
Daniel
  • 1,816
  • You could also use Jake's solution to http://tex.stackexchange.com/questions/55068/is-there-a-tikz-equivalent-to-the-pstricks-ncbar-command – Torbjørn T. Mar 14 '13 at 07:40

5 Answers5

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

Matthew Leingang
  • 44,937
  • 14
  • 131
  • 195
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

Qrrbrbirlbel
  • 119,821
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}

Peter Grill
  • 223,288
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

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

Franck Pastor
  • 18,756