Like this?
Although I must confess I don't have yet the general solution, for this particular case the effect was achieved by drawing the arrow from TN to TM instead of TM to TN. This way the arrow was drawn after the horizontal one. And of course I used leftarrow
to get the arrowtip right.
\documentclass{article}
\usepackage{tikz-cd}
\begin{document}
\[
\begin{tikzcd}[ampersand replacement=\&,column sep=small]
GM \arrow[pos=0.75]{rr}{\models_{M}}
\arrow[two heads,swap]{dr}{e_{M}}
\arrow[swap]{dd}{Gf}
\& \&
R^{FM}
\arrow{dd}{R^{Ff}} \\
\& T M
\arrow[tail,swap]{ru}{m_{M}}
\& \\
GN \arrow[pos=0.75,crossing over]{rr}{\models_{N}}
\arrow[two heads,swap]{dr}{e_{N}}
\& \& R^{FN} \\
\& T N
\arrow[leftarrow,pos=0.25,crossing over]{uu}{T f} % <<----- HERE
\arrow[tail,swap]{ru}{m_{N}} \&
\end{tikzcd}
\]
\end{document}
Update: a more general solution
The above solution is ad-hoc and works only for this particular example. The general solution would allow to draw any additional arrow between two any nodes of the already typeset commutative diagram.
The idea is the following. Since internally tikzcd
uses a matrix of nodes
to typeset each node of the diagram, why wouldn't be possible to use those nodes as part of a path drawn after the diagram?
The idea is reasonable, but there are some issues here:
- What are the names of each node in the diagram? Would it be possible to use the syntax
[(name)]
normally allowed inside a tikz matrix of nodes
? Answer: no it is not possible, that would break the code of the \arrow
macro, which relies in the auto-generated names for the nodes.
- Then there are autogenerated names? Which are those names? Answer: They all begin with
\tikzmatrixname
and have the suffix -row-column
. So for example, the first node of this diagram, (with label GM) would be \tikzmatrixname-1-1
, the central node (TM) is \tikzmatrixname-2-2
, and so on.
So it would be possible to add \draw (\tikzmatrixname-1-1) to[bend left] (\tikzmatrixname-2-2)
; for example, after the matrix is done? i.e: this for example:
\begin{tikzcd}[ampersand replacement=\&,column sep=small]
GM \arrow[pos=0.75]{rr}{\models_{M}}
[...]
\arrow[tail,swap]{ru}{m_{N}} \&
% After all nodes are in the matris, draw some extra arrows
\draw[bend left] (\tikzmatrixname-1-1) to[bend left] (\tikzmatrixname-2-2);
\end{tikzcd}
Answer: Sadly, the answer is no, this is not possible because of the way tikcd
handles the diagram. Inside the tikzcd
environment, surprisingly enought, no tikz
commands can be issued. Indeed, all tikz
commands are undefined, because the tikzcd
environment is not a tikzpicture
environment. This explains why you cannot use \node
, \draw
nor any other command.
What tikzcd
does is, each time you use the command \arrow
or other equivalent, to compute the appropiate \path
command, but instead of "executing" it, it is stored in a list with all the other paths resulting from other \arrow
commands. At the end of the tikzcd
environment, a tikzpicture
is created, which contains the matrix of nodes
, and inside that picture, finally the list of \path
commands is executed, drawing all the arrows.
So, what can we do?
It would be great if tikzcd
provided a kind of \drawAtTheEnd
command, which allows for storing any tikz drawing command in the same way that the list of paths, and execute that stored commands at the end of the tikzcd
environment. This way we could add other arrows, decorations, define node coordinates with overlay, remember picture
to be accessed from other parts of the page, etc.
In the meanwhile, I coded a hack which allows to insert a new path into the internal list used by tikzcd. The macro is called \latearrow
and it takes four arguments:
- The tikz options of the arrow (you can pass colours,
to path
s, pos
, etc
- The name of the starting node, without the
\tikzmatrixnode
part. I.e: to refer to GM node you will call it 1-1
, the node TM will be 2-2
, and so on.
- The name of the ending node (also without the
\tikzmatrixnode
part)
- The text for the label in the arrow.
Using that macro, you can first draw your complete commutative diagram except for the arrow from TM to TN, and then add that arrow at the end with the syntax:
\latearrow{pos=0.75,crossing over}{2-2}{4-2}{T f}
As said, it is a quick&dirty hack, and does not use the same syntax than other arrows, does not allow for style options for the label, and I'm not sure if it would break anything, but apparently it works. Here is the code:
\documentclass{article}
\usepackage{tikz-cd}
\makeatletter
\def\latearrow#1#2#3#4{%
\toks@\expandafter{\tikzcd@savedpaths\path[/tikz/commutative diagrams/every arrow,#1]}%
\global\edef\tikzcd@savedpaths{%
\the\toks@%
(\tikzmatrixname-#2)% \noexpand\tikzcd@sourceanchor)%
to%
node[/tikz/commutative diagrams/every label] {$#4$}
(\tikzmatrixname-#3)% \noexpand\tikzcd@targetanchor)
;}}
\makeatother
\begin{document}
\[
\begin{tikzcd}[ampersand replacement=\&,column sep=small]
GM \arrow[pos=0.75]{rr}{\models_{M}}
\arrow[two heads,swap]{dr}{e_{M}}
\arrow[swap]{dd}{Gf}
\& \&
R^{FM}
\arrow{dd}{R^{Ff}} \\
\& T M
\arrow[tail,swap]{ru}{m_{M}}
\& \\
GN \arrow[pos=0.75]{rr}{\models_{N}}
\arrow[two heads,swap]{dr}{e_{N}}
\& \& R^{FN} \\
\& T N
\arrow[tail,swap]{ru}{m_{N}} \&
\latearrow{pos=0.75,crossing over}{2-2}{4-2}{T f}
\latearrow{red, bend left}{1-1}{2-2}{x}
\end{tikzcd}
\]
\end{document}
Note that I added a blue
option to this arrow, to demonstrate that it works. Just for fun, I added also a red curved "late arrow" from GM to TM.
This is the result:
Improved version
In this improved version, you can apply a scaling factor to the arrow:
\documentclass{article}
\usepackage{tikz-cd}
\usetikzlibrary{decorations.markings,intersections}
\tikzset{%
scalearrow/.style n args={3}{
decoration={
markings,
mark=at position (1-#1)/2*\pgfdecoratedpathlength
with {\coordinate (#2);},
mark=at position (1+#1)/2*\pgfdecoratedpathlength
with {\coordinate (#3);},
},
postaction=decorate,
}
}
\begin{document}
\noindent
Scaling factor=1 (no scaling):\par
\begin{tikzcd}[row sep=huge,column sep=huge]
A \dar\rar & B\dar\dlar[phantom,scalearrow={1}{start}{end}]\arrow[dr,Rightarrow,to path= (start) -- (end)] \\
C \rar & D
\end{tikzcd}
\par\medskip
\noindent
Scaling factor=0.5:\par
\begin{tikzcd}[row sep=huge,column sep=huge]
A \dar\rar & B\dar\dlar[phantom,scalearrow={0.5}{start}{end}]\arrow[dr,Rightarrow,to path= (start) -- (end)] \\
C \rar & D
\end{tikzcd}
\par\medskip
\noindent
Two arrows, each with scaling factor=0.3333:\par
\begin{tikzcd}[row sep=huge,column sep=huge]
A
\dar\rar
&
B
\dar
\dlar[phantom,scalearrow={0.3333}{starta}{enda}]
\arrow[dr,Rightarrow,to path= (starta) -- (enda)] &
C
\dar\lar
\\
D \rar
&
E
&
F
\lar
\ular[phantom,scalearrow={0.3333}{startb}{endb}]
\arrow[ul,Rightarrow,to path= (startb) -- (endb)]
\end{tikzcd}
\end{document}
The idea is to measure the path length using a decoration and \pgfdecoratedpathlength
and to place two marks along the path such that the distance between those marks is the path length scaled by the desired factor.
This is achieved by using a "phantom" arrow with the scalearrow
style; in this style you set the scaling factor (first argument for the style) and two names internally used for the start and end of the scaled path so, for example,
\dar[phantom,scalearrow={0.3333}{name1}{name2
places a downwards arrow from the current node (let's refer to it as X
) to the node below it (let's refer to it as Y
) and sets two internal coordinates called name1
and name2
at the exact position along the path from X
to Y
in such a way that now you can use those names to draw the scaled arrow (using a factor of 0.3333
for the scaling) using, for example
\arrow[d,Rightarrow,to path= (name1) -- (name2)]
First version
One option using shorten
:
\documentclass{article}
\usepackage{tikz-cd}
\begin{document}
\begin{tikzcd}[column sep = large, row sep = large]
* \dar \rar &* \dar \dlar[Rightarrow,shorten >= 10pt,shorten <= 10pt]{} \\
* \rar &*
\end{tikzcd}
\end{document}
Best Answer
edge
is a bit of a strange beast, and you need to useto
here instead:I think what is happending with the
edge
is that there are two paths, the first a very short one from(B)
to(B.north east)
. But I haven't yet be able to verify this.Update: thanks to the pointer to https://tex.stackexchange.com/a/82495/15925 from Torbjørn T. this is indeed the case. In your code the main path, i.e. with the
edge
parts removed, iswhich in the above code produces
with the strangely placed arrowhead you experienced.
The full code for this last diagram is: