[Tex/LaTex] TikZ: position a node depending on width of text

arrowslabelsnodespositioningtikz-pgf

I need to use TikZ to draw two horizontally-spaced nodes, and an arrow between them, labelled by some text. But the arrow has to be exactly the right length to fit the text, and this will be part of a macro which could be called with text of highly variable length. The problem is that I don't know the width of the text until I've drawn the arrow and labelled it, but I have to place the nodes before I can draw the arrow. TikZ must have a solution for this – any ideas?

Edit: the intention is for the arrow to reach right up to both nodes, so that it is clearly going 'from' the first node to the second, and for the arrow to only be just long enough for the text to fit as a label. So, the more text, the longer the arrow, and the further apart the nodes; the less text, the closer the nodes become.

Best Answer

You could measure the width of the text (see also How can I use an hbox inside a TikZ environment for text dimension measurement?) and use this value to position the node:

\documentclass{article}
\usepackage{tikz}

\newlength{\mylabelwidth}
\begin{document}
\begin{tikzpicture}
  \node[draw] (A) {A};
  \settowidth{\mylabelwidth}{\pgfinterruptpicture some label \endpgfinterruptpicture}
  \node[draw,right] (B) at ([xshift=\mylabelwidth+10pt]A.east) {B};
  \draw[->] (A) --(B) node [midway,above] {some label};
\end{tikzpicture}
\end{document}

Alternatievly, you could place the arrow label as normal, properly aligned node and then draw the arrow and other node relative to it:

\documentclass{article}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
  \node[draw](A) {A};
  % The distance between the arrow and the nodes is defined by the `inner ysep` and `innser xsep` values, respectively:
  \node[inner ysep=2.5pt,inner xsep=5pt,above right] (ABlabel) at (A.east) {some label};
  \node[draw,right] (B) at (ABlabel.south east) {B};
  \draw[->] (A) --(B);
\end{tikzpicture}

\end{document}

Both lead to the same result:

Result