4

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:

enter image description here

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:

enter image description here

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:

enter image description here

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?

3 Answers 3

3

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}

result

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

2
  • 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. Commented Feb 27, 2016 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
    Commented Feb 27, 2016 at 9:15
3

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

enter image description here

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}
2

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:

enter image description here

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}
2
  • 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.
    – N. Virgo
    Commented Feb 27, 2016 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. Commented Feb 27, 2016 at 9:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .