# Positioning of nodes relative to edges in tikz

Earlier I asked a question about labelling the edges of graphs with arrows. Zarko presented a solution that, stripped down to its minimum, looks like this:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\usepackage{mathtools}
\begin{document}
\begin{tikzpicture}
\node (A) at (0,0) {A};
\node (B) at (1,1.5) {B};
\draw (B) --  node[sloped,above] {$\xleftarrow{2}$}  (A);
\end{tikzpicture}
\end{document}


Here is the result:

It looks great in the context of what I'm doing, but I don't like the way the number is slanted - I'd like it to be positioned where it is, but to be upright, like this:

I thought I could do this by defining a second node with a greater outer sep and without the sloped modifier, like this:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}
\node (A) at (0,0) {A};
\node (B) at (1,1.5) {B};
\draw (B) --  node[sloped,above] {$\leftarrow$} node[above,outer sep=6pt] {\scriptsize{2}}  (A);
\end{tikzpicture}
\end{document}


However, as you can see this doesn't put the number where I want it, since it's literally above the midpoint of the line, rather than "above" relative to its slope:

Is there a way that I can position the node in the same way as if it was sloped (i.e. by moving a set distance along a line perpendicular to the edge), without the node's contents being sloped? Or is there some other way to achieve the effect I'm after?

You could use an empty sloped node to get the correct position and then use that node's center anchor to place a the desired un-sloped node.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}
\node (A) at (0,0) {A};
\node (B) at (1,1.5) {B};
\draw (B) --  node[sloped,above] {$\leftarrow$} node[sloped,above,outer sep=9pt] (x) {} (A);
\node at (x) {\scriptsize{2}};
\end{tikzpicture}
\end{document}


However, the placement doesn't look quite right, so you probably need to manually shift the node position a bit.

• IMHO, using outer sep to shift the node is not a good idea as that is not what it is intended for. You are already apply an above to move the node and then you need to apply a shift to get it to the correct spot. That was the reason I went directly to the shift in my solution. – Peter Grill Feb 27 '16 at 9:06
• @PeterGrill: You're right, it's a hack. However, it's the only way I know to move the node in a direction perpendicular to the path. I'd generally prefer only needing to fiddle with one coordinate instead of two, although in this case it does look better if you tweak both. – wrtlprnft Feb 27 '16 at 9:15

The coordinate of the new node are relative to the main arrow, not relative to the node. So, one way to do it would be to apply a shift to the new node:

## Code:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}
\node (A) at (0,0) {A};
\node (B) at (1,1.5) {B};
\draw (B) --  node[sloped,above] {$\leftarrow$} node[shift={(-0.8em,2.1ex)}] {\scriptsize{2}}  (A);
\end{tikzpicture}
\end{document}

• Won't this require manual adjustment of every label though? I want to position it relative to the orientation of the edge so that I won't have to do that. – Nathaniel Feb 27 '16 at 9:47
• @Nathaniel: Probably. Perhaps Zarko's solution is the way to go. Personally I would have drawn the arrow with tikz instead of using a symbol. – Peter Grill Feb 27 '16 at 9:50

Well, my second solution in answer to which you provide link, can be refined as follows:

I changes the size and tip of arrows in pic as well their distance from path to which are added, and add default values for most common pic type. For this solution the TikZ library arrows.meta is not necessary anymore.

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{chains,positioning}

\begin{document}
\begin{tikzpicture}[
start chain = A going right,
pics/AB/.style args = {#1/#2/#3}{code={
\draw[solid,thin,->]
(-2mm,#1 1.5mm) -- node [#2,font=\footnotesize,inner sep=1pt] {#3} ++ (4mm,0mm);}
},
pics/AB/.default=/left/1,
pics/BA/.style args = {#1/#2/#3}{code={
\draw[solid,thin,<-]
(-2mm,#1 1.5mm) -- node [#2,font=\footnotesize,inner sep=1pt] {#3} ++ (4mm,0mm);}
},
]
\begin{scope}[every node/.style={circle, draw, minimum size=1.5em,
inner sep=2pt, on chain}]
\foreach \i in {1,...,5} \node {};
%
\node (B-1) [below=of A-2] {A};
\node (B-2) [below=of A-4] {B};
\end{scope}
\begin{scope}[sloped]
\draw[densely dotted, thick]
(A-1) -- (A-2)
(A-2) -- pic {BA=/above/1} (A-3)
(A-3) -- (A-4)
(A-4) -- pic {AB=/above/1} (A-5);
\draw[thick]    (B-1) -- pic {AB} (A-2)
(B-1) -- pic {AB=-/below right/1} (A-3)
%
(B-2) -- pic {BA=-/below left/1} (A-3)
(B-2) -- pic {AB} (A-4)
;
%
\draw[double]   (A-1) --  (B-1)
(A-5) -- pic {BA=-/below right/2} (B-2);
\end{scope}
\end{tikzpicture}
\end{document}