6

Say I want to draw something like a flow chart, that is nodes connected by arrows that sometimes merge. This would be a typical pattern:

enter image description here

I used the following code to create this small example:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning,calc,arrows.meta}

\begin{document}
  \begin{tikzpicture}
    \node[draw] (a) {A};
    \node[draw,right=of a] (b) {B};
    \node[draw,below=5mm of b] (c) {C};

    \path[-{LaTeX[]}] (b) edge (c);
    \draw (a) |- ($(b)!0.5!(c)$);
  \end{tikzpicture}
\end{document}

Now the line from A hits the one between B and C precisely at its middle point. Given the arrow tip, however, this is not the visually most pleasant position. We'd want it to hit the middle point between the end of the arrow tip and B.

Short of tinkering with magic constants, how can we do this using TikZ?

  • Try to change \draw (a) |- ($(b)!0.5!(c)$) to \draw (a) |- ($(b)!0.45!(c)$)... – Zarko Jun 3 '16 at 15:14
  • @cfr, is there a predefined length containing the "current" arrow length? Thanks! – Rmano Jun 3 '16 at 17:58
  • @Rmano In some sense, there must be. I think it depends on the current line width, though and it might depend on the arrow tip, too. I don't know if it is predefined in the sense that you could use it to automatically figure out the adjustment, though, because TikZ may not set it until it is actually asked for the tip. I'm not certain of this. I'll try to look after. – cfr Jun 3 '16 at 19:20
  • @Zarko That would be "magic constant" style; the factor would be different for every instance. – Raphael Jun 3 '16 at 21:44
4

Here's a first pass which adjusts automatically for the current line width but not for the kind of arrow tip. It also requires modification if the direction direction/angle of the path differs or if the arrow points in the opposite direction, for example.

\documentclass[tikz,border=10pt,multi]{standalone}
\usetikzlibrary{positioning,calc,arrows.meta}
\begin{document}
\begin{tikzpicture}
  [
    every node/.append style={draw},
    my adjustment/.store in=\arrowadjust,
    % by default, for this type of arrow tip, length=3pt 4.5 0.8 [ref. p. 185]
    arrow line/.style={%
      draw,
      -{LaTeX[]},
      my adjustment={.5*(3pt + 4.5*\pgflinewidth)}
    },
  ]
  \node (a) {A};
  \node [right=of a] (b) {B};
  \node [below=5mm of b] (c) {C};
  \path [arrow line] (a) |- ([yshift=\arrowadjust]$(b)!0.5!(c)$) (b) -- (c);
\end{tikzpicture}
\end{document}

first pass

You can find the values for the arrow(s) you are interested in in the file texmf-dist/tex/generic/pgf/libraries/pgflibraryarrows.meta.code.tex:

\pgfdeclarearrow{
  name = Latex,
  defaults = {
    length  = +3pt 4.5 .8,% +2.8pt 3 0.8,
    width' = +0pt .75,
    line width = +0pt 1 1,
  },

(LaTeX is an alias for Latex).

  • This is nice but only works for arrows that to perfectly vertical or horizontal, and you need to know which way they face. – Raphael Jun 4 '16 at 15:17
  • @Raphael Yes, you do. I tried to figure something out with shorten but it started getting very complicated and you'd still need to know whether you had > or <. – cfr Jun 4 '16 at 15:30
  • I can believe that; there's probably no neat solution without added support from PGF. FWIW, knowing < or > is much weaker than knowing the angle. – Raphael Jun 4 '16 at 15:32

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.