# TikZ: positioning label at the end of a path

I'm trying in TikZ to find a general way to draw an arrow and label it at the end. Something like this works reasonably well:

\draw[->] (0, 0) -- (1, 3) node[pos=1.1]{$\vec{v}$};


However, depending on the orientation, if the label is too long, then the label can overlap the arrow:

\draw[->] (0, 0) -- (3, 0) node[pos=1.1]{$\vec{v} + \vec{w}$};


What I would ideally like is, for the latter arrow, the left side is at pos=1.1. I know I can do this in this specific case by using node[pos=1.1, anchor=west], but I'm looking for something more general (so that I could abstract this all and define a command to do it automatically).

One approach I considered was trying to find the width and height of the label and move the label using those values. So, 2 questions: Is there a way to find the width/height? Or, alternatively, is there a better approach?

-
Hi Janet, welcome to the site! Do you want the length of the arrow to be fixed, as it is in your example? Or would you be happy with placing the nodes first, and drawing the arrow afterwards? That approach would be much easier. –  Jake Jan 5 '13 at 16:24
Note that it wouldn't be enough to find the height and width of the node, you'd also need the orientation of the line pointing at the node, so you know in which direction to shift the node. –  Jake Jan 5 '13 at 16:35
Is a relative position (1.1) the best here? That way the distance between the end of the line and the node differ for different line lengths. –  Qrrbrbirlbel Jan 5 '13 at 16:45

For straight lines (--) a special to path could be the solution.

I have defined three to styles:

1. a=<node text>: relative positioning
• a position=<pos amount> (default 1.1)
2. aa=<node text>: absolute positioning
• aa distance=<length> (default 1ex)
3. bb: absolute positioning but saves the coordinate and the angle for later use:
• \xVecN: the x value,
• \yVecN: the y value,
• \aVecB: the anchor angle.
• The bb style uses these values internally.
• aa distance=<length> (default 1ex)

The lines in the code sample that are marked with % debug can be removed; they are only there to show how the styles work.

## Code

\documentclass[tikz,border=2pt]{standalone}
\usetikzlibrary{calc}
\newcommand*{\qrrAposition}{1.1}
\tikzset{
a style/.style={% this style should be set to further change the behaviour of the nodes that are now hidden inside
draw, % debug
},
a position/.code={\pgfmathsetmacro\qrrAposition{#1}},
a/.style={% relative position
to path={
let \p1=(\tikztostart),
\p2=(\tikztotarget),
\n1={atan2(\x2-\x1,\y2-\y1)} in
-- (\tikztotarget) \tikztonodes node[pos=\qrrAposition, anchor=\n1-180, a style] {#1}
node[pos=\qrrAposition, fill=black, circle, inner sep=0.6pt] {}% debug
}
},
aa distance/.initial=1ex,
aa/.style={% fixed distance
to path={
let \p1=(\tikztostart),
\p2=(\tikztotarget),
\n1={atan2(\x2-\x1,\y2-\y1)} in
-- (\tikztotarget) \tikztonodes node[anchor=\n1-180, a style] at ($(\tikztotarget)+(\n1:\the\qrrAadistance)$) {#1}
node[fill=black, circle, inner sep=0.6pt] at ($(\tikztotarget)+(\n1:\the\qrrAadistance)$) {} % debug
}
},
b/.style={% later usage
to path={
let \p1=(\tikztostart),
\p2=(\tikztotarget),
\n1={atan2(\x2-\x1,\y2-\y1)},
\p{node}=($(\tikztotarget)+(\n1:\the\qrrAadistance)$)
in
-- (\tikztotarget) \tikztonodes
\pgfextra{\xdef\aVecN{\n1-180}\xdef\xVecN{\x{node}}\xdef\yVecN{\y{node}}}
}
},
bb style/.style={
anchor=\aVecN,
at={(\xVecN,\yVecN)},
a style,
},
}
\begin{document}
\begin{tikzpicture}
\draw[->] (0, 0) to[a=$\vec{v}$] (1, 3);
\draw[->] (0, 0) to[aa=$\vec{v} + \vec{w}$] (3, 0);
\draw[->] (0, 0) to[bb] (1, -3);
\node[bb style] {$\vec{v} + \vec{w} + (0, -6)$};
\end{tikzpicture}
\end{document}


## % debug

### How it works

\foreach \angle in {0,2,...,358}{
\begin{tikzpicture}
\path[use as bounding box] (-2.5,-2) -- (2.5,2);
\draw[->] (0, 0) to[aa=$\vec{v} + \vec{w}$] (\angle:1cm);
\end{tikzpicture}
}


### Difference between absolute and relative positioning

\foreach \l in {0.1,0.2,...,2.9,3.0,2.9,...,0.2}{
\begin{tikzpicture}
\path (0,0) -- (0:4.5cm);
\draw[->]              (0, 0) to[a =$\vec{v} + \vec{w}$] (0:\l);
\draw[yshift=-.7cm,->] (0, 0) to[aa=$\vec{v} + \vec{w}$] (0:\l);
\end{tikzpicture}
}


### Output

-
Thank you! I wasn't aware that anchor could take an angle, so that is good to know. But you're right that absolute positioning makes more sense, and I like that better. One small typo in the code above for anyone else following along: b/.style should be bb/.style –  Janet Jan 5 '13 at 22:26