The labels are placed intelligently, always to the left of the arrow. That's the default direction of the TikZ auto
option that's installed by TikZ-CD.
Though, it only knows left
and right
, meaning the nodes along a path are placed either to the left or the right of the path. (The swap
('
) key just checks which one's active and installs the other one.)
I don't like how this is implemented in the original code but we can extend this either way to also accept
auto = above
where the nodes are always placed above the path (or to the right for vertical lines) and
auto = below
where the nodes are always placed below the path (or to the left for vertical lines).
The swap
key is rewritten so that it also can deal with these new additions.
This is still some dumb kind of intelligence since it will never be able to check whether it looks good or if the node is on the “outside” of your diagram.
You could of course create an automatic placement that places the nodes above the paths when they're diagonal and below it when it's a purely horizontal path but the more complex your diagrams get the more these will not be helpful, in my opinion.
For example, in the second diagram which I believe to be equivalent to the first all the nodes should be on the other side so that they're on the “outer” side of the diagram but TikZ won't be able to figure that out without tremendous help from the outside (i.e. another tool that analyzes the diagram).
This way, the nodes are at least consistenzly placed above or below a path which I think will help a lot. You will always look at these diagram once before you're going to be finished with them.
Code
\documentclass[tikz,convert]{standalone}
\usetikzlibrary{cd}
\makeatletter
\tikzset{
swap/.style={swap auto/.expand once=\tikz@auto@anchor@direction},
swap auto/.is choice,
/utils/temp/.style args={#1=#2}{
swap auto/#1/.code=\def\tikz@auto@anchor@direction{#2}},
/utils/temp/.list={left=right, right=left, above=below, below=above}
}
\def\tikz@install@auto@anchor@above{%
\let\tikz@do@auto@anchor\tikz@auto@anchor@on
\def\tikz@auto@anchor@direction{above}}
\def\tikz@auto@anchor@above{%
\tikz@auto@pre\tikz@auto@anchor@above@\tikz@auto@post}
\def\tikz@install@auto@anchor@below{%
\let\tikz@do@auto@anchor\tikz@auto@anchor@on
\def\tikz@auto@anchor@direction{below}}
\def\tikz@auto@anchor@below{%
\tikz@auto@pre\tikz@auto@anchor@below@\tikz@auto@post}
\def\tikz@auto@anchor@above@{%
\def\tikz@anchor{south}%
\ifdim\pgf@x>0.05pt
\ifdim\pgf@y>0.05pt
\def\tikz@anchor{south east}%
\else\ifdim\pgf@y<-0.05pt
\def\tikz@anchor{south west}%
\fi\fi
\else\ifdim\pgf@x<-0.05pt
\ifdim\pgf@y>0.05pt
\def\tikz@anchor{south east}%
\else\ifdim\pgf@y<-0.05pt
\def\tikz@anchor{south east}%
\fi\fi
\else
\ifdim\pgf@y>0pt
\def\tikz@anchor{east}%
\else
\def\tikz@anchor{west}%
\fi
\fi\fi
}
\def\tikz@auto@anchor@below@{%
\def\tikz@anchor{north}%
\ifdim\pgf@x>0.05pt
\ifdim\pgf@y>0.05pt
\def\tikz@anchor{north west}%
\else\ifdim\pgf@y<-0.05pt
\def\tikz@anchor{north east}%
\fi\fi
\else\ifdim\pgf@x<-0.05pt
\ifdim\pgf@y>0.05pt
\def\tikz@anchor{north east}%
\else\ifdim\pgf@y<-0.05pt
\def\tikz@anchor{north west}%
\fi\fi
\else
\ifdim\pgf@y>0pt
\def\tikz@anchor{west}%
\else
\def\tikz@anchor{east}%
\fi
\fi\fi}
\makeatother
\begin{document}
\begin{tikzcd}[row sep=large, auto=above]
& C \arrow[ld, "f"]
\arrow[rd, "g"]
\arrow[d, "!h" , dashed] \\
A
& A \times B \arrow[r, "\pi_B"']
\arrow[l, "\pi_A"']
& B
\end{tikzcd}
\begin{tikzcd}[row sep=large, auto=below]
A
& A \times B \arrow[r, "\pi_B"']
\arrow[l, "\pi_A"']
& B \\
& C \arrow[lu, "f"]
\arrow[ru, "g"]
\arrow[u, "!h"', dashed]
\end{tikzcd}
\end{document}
Output