2

For example, that for positioning of edge labels is controlled by auto=right option. Than the position of edge labels should be on right side of edges regarding on their direction. However, in the cases when labels are aligned with edges' slopes, than their positions become independent on edges direction:

\documentclass[tikz, margin=3mm]{standalone}
\usetikzlibrary{positioning, quotes}

\begin{document}
    \begin{tikzpicture}[auto=right,  % <---
                        node distance=20mm and 20mm]
\coordinate[label=below:$A$]                (a);
\coordinate[above right=of a, label=$B$]    (b);
\coordinate[right=of a, label=below:$C$]    (c);
\coordinate[above right=of c, label=$D$]    (d);
%
\draw[->]   (a) to["$ab$"] (b) (c) to["$cd$",sloped] (d);
%\draw[->]   (b) to["$ba$"] (a) (d) to["$dc$",sloped] (c);
    \end{tikzpicture}
\end{document}

enter image description here

and at opposite direction:

enter image description here

I expected that in the second case all labels will be on the same side of edges, but they aren't. Does meaning of auto=right for sloped labels are changed?

3

TikZ intelligently (or semi-intelligently ;-) interprets right. If you do not want TikZ to do that, you need to add the allow upside down key. Then the label will be always on the right side of the path, but may be upside-down.

\documentclass[tikz, margin=3mm]{standalone}
\usetikzlibrary{positioning, quotes}

\begin{document}
    \begin{tikzpicture}[auto=right,  % <---
                        node distance=20mm and 20mm,allow upside down]
\coordinate[label=below:$A$]                (a);
\coordinate[above right=of a, label=$B$]    (b);
\coordinate[right=of a, label=below:$C$]    (c);
\coordinate[above right=of c, label=$D$]    (d);
%
\draw[->]   (a) to["$ab$"] (b) (c) to["$cd$",sloped] (d);
    \end{tikzpicture}
\begin{tikzpicture}[auto=right,  % <---
                        node distance=20mm and 20mm,allow upside down]
\coordinate[label=below:$A$]                (a);
\coordinate[above right=of a, label=$B$]    (b);
\coordinate[right=of a, label=below:$C$]    (c);
\coordinate[above right=of c, label=$D$]    (d);
%
\draw[->]   (b) to["$ba$"] (a) (d) to["$dc$",sloped] (c);
    \end{tikzpicture}
\end{document}

enter image description here

On the other hand, if you do not allow upside down, TikZ will rotate the label by 180 degrees where appropriate, and then the roles of left and right, and of above and below, get swapped.

ADDENDUM: Some first steps towards an automatic solution. The allow upside down key, or, more precisely, the \ifpgfallowupsidedownattime if, gets really used in \pgftransformlineattime and \pgftransformcurveattime. One can actually modify these macros to give you something like an automatic solution. THESE ARE ONLY THE FIRST STEPS and I really only look at \pgftransformlineattime (but the changes for \pgftransformcurveattime are analogous). This code now checks if TikZ adds the additional rotation of 180 degrees, and if so, it changes the anchors such that the node position gets swapped. (In principle the swap code should also work, but it doesn't, perhaps because it gets executed too late.) Here are codes and results:

\documentclass[tikz, margin=3mm]{standalone}
\newif\iftikzrotateback
\newif\iftikzneedtorotateback
\tikzneedtorotatebackfalse
\tikzset{rotate back/.is if=tikzrotateback,
auto rotate nodes/.style={rotate back=true}}
\makeatletter
\def\pgftransformlineattime#1#2#3{%
  \pgf@process{#2}%
  \pgf@xb=\pgf@x% xb/yb = start point
  \pgf@yb=\pgf@y%
  \pgf@process{#3}%
  \pgf@xc=\pgf@x% xc/yc = end point
  \pgf@yc=\pgf@y%
  \pgftransformshift{\pgfpointlineattime{#1}{\pgfqpoint{\pgf@xb}{\pgf@yb}}{\pgfqpoint{\pgf@xc}{\pgf@yc}}}%
  \ifpgfresetnontranslationattime%
    \pgftransformresetnontranslations%
  \fi%
  \global\tikzneedtorotatebackfalse
  \ifpgfslopedattime%
    \advance\pgf@xc by-\pgf@xb%
    \advance\pgf@yc by-\pgf@yb%
    \ifpgfallowupsidedownattime%
    \else%
      \ifdim\pgf@xc<0pt%
        \iftikzrotateback%   
         \global\tikzneedtorotatebacktrue%
        \fi%
        \pgf@xc=-\pgf@xc%
        \pgf@yc=-\pgf@yc%
      \fi%
    \fi%
    \pgf@x=\pgf@xc%
    \pgf@y=\pgf@yc%
    \iftikzneedtorotateback%
% this is the swap code but at the moment I cannot make it work
%      \def\tikz@temp{left}%
%    \ifx\tikz@auto@anchor@direction\tikz@temp%
%      \def\tikz@auto@anchor@direction{right}%
%    \else%
%      \def\tikz@auto@anchor@direction{left}%
%    \fi%
     \def\mynorth{north}%
     \ifx\tikz@anchor\mynorth%
      \edef\my@tikz@anchor{south}%
     \fi%
     \def\mysouth{south}%
     \ifx\tikz@anchor\mysouth%
      \edef\my@tikz@anchor{north}%
     \fi% and so on and so forth, maybe there is already a function that s
     \edef\tikz@anchor{\my@tikz@anchor}%
    \fi% swaps the anchors in TikZ
    \pgfpointnormalised{}% x/y = normalised vector
    \pgf@ya=-\pgf@y%
    \pgftransformcm%
     {\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@y}}%
     {\pgf@sys@tonumber{\pgf@ya}}{\pgf@sys@tonumber{\pgf@x}}{\pgfpointorigin}%
  \fi%
}
\makeatother

\usetikzlibrary{positioning, quotes}

\begin{document}
    \begin{tikzpicture}[auto=right,  % <---
                        node distance=20mm and 20mm,auto rotate nodes]
\coordinate[label=below:$A$]                (a);
\coordinate[above right=of a, label=$B$]    (b);
\coordinate[right=of a, label=below:$C$]    (c);
\coordinate[above right=of c, label=$D$]    (d);
%
\draw[->]   (a) to["$ab$"] (b) (c) to["$cd$",sloped] (d);
    \end{tikzpicture}
\begin{tikzpicture}[auto=right,  % <---
                        node distance=20mm and 20mm,auto rotate nodes]
\coordinate[label=below:$A$]                (a);
\coordinate[above right=of a, label=$B$]    (b);
\coordinate[right=of a, label=below:$C$]    (c);
\coordinate[above right=of c, label=$D$]    (d);
%
\draw[->]   (b) to["$ba$"] (a) (d) to["$dc$",sloped] (c);
    \end{tikzpicture}
\end{document}

enter image description here

  • Thank you for for pointing me to allow upside down. Now I see that now is better stick with "not-automatic" solution and such a cases and rather add swap option. Maybe will be one day defined allow upside down swap function which will do my manually for now :-). For accepting answer I will wait a while. – Zarko Oct 27 at 9:08
  • @Zarko It is somewhat nontrivial to make a fully automatic solution work. The allow up side down key is really used in pgfcoretransformations.code.tex but there it just adds a rotation by 180 degrees if the end point is left of the start point. At this point, TikZ does not know how far the node/label is away from the line, otherwise one could just shift the node to the other side. That means that if you want a fully automatic solution you will need to modify commands beyond just \pgftransformlineattime and \pgftransformcurveattime. This is quite some effort, and may break things. – Schrödinger's cat Oct 27 at 9:17
  • I imagine, that this is not trivial. In case this was easy, it would have already been done :-). Thank you again for explanation. – Zarko Oct 27 at 9:27
  • @Zarko I was wrong, one actually can make it work, at least in simple examples. I added a "proof of principle". A real solution would IMHO only make sense if the developers of TikZ are interested in it, and agree to add it once it is sufficiently stable. – Schrödinger's cat Oct 27 at 9:54
  • Thank you. A weather prognoses here is that this Sunday is the last sonny ... I will be back latter afternoon and test your last proposal. – Zarko Oct 27 at 10:09

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.