I've been trying to use this great answer https://tex.stackexchange.com/a/21167/116348 to provide multicolumn in a tikzcd environment. However I have two issues:
- the alignment is not correct (I expect the multicolumn cell to be horizontally centered while it's too much on the left)
- connecting arrows gives bad result (it seems to point to the place where the box would have been without the mutlicol)
- it is not made for multirow, or both multicol and multirow.
Any idea how to improve it?
MWE
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{cd}
\usetikzlibrary{backgrounds,positioning}
\usetikzlibrary{shapes,shapes.geometric,shapes.misc}
\usepackage{xparse}
\usetikzlibrary{matrix}
\makeatletter
%%% https://tex.stackexchange.com/a/21167/116348
\newdimen\multi@col@width
\newdimen\multi@col@margin
\newcount\multi@col@count
\multi@col@width=0pt
\tikzset{
multicol/.code={%
\global\multi@col@count=#1\relax
\global\let\orig@pgfmatrixendcode=\pgfmatrixendcode
\global\let\orig@pgfmatrixemptycode=\pgfmatrixemptycode
\def\pgfmatrixendcode##1{\orig@pgfmatrixendcode%
##1%
\pgfutil@tempdima=\pgf@picmaxx
\global\multi@col@margin=\pgf@picminx
\advance\pgfutil@tempdima by -\pgf@picminx
\divide\pgfutil@tempdima by #1\relax
\global\multi@col@width=\pgfutil@tempdima
\pgf@picmaxx=.5\multi@col@width
\pgf@picminx=-.5\multi@col@width
\global\pgf@picmaxx=\pgf@picmaxx
\global\pgf@picminx=\pgf@picminx
%% Proposed fix does not help (it actually breaks the initial example)
% \gdef\multi@adjust@position{%
% \setbox\pgf@matrix@cell=\hbox\bgroup
% \hfil\hskip-1.5\multi@col@margin
% \hfil\hskip-.5\multi@col@width
\gdef\multi@adjust@position{%
\setbox\pgf@matrix@cell=\hbox\bgroup
\hfil\hskip-\multi@col@margin
\hfil\hskip-.5\multi@col@width
\box\pgf@matrix@cell
\egroup
}%
\gdef\multi@temp{\aftergroup\multi@adjust@position}%
\aftergroup\multi@temp
}
\gdef\pgfmatrixemptycode{%
\orig@pgfmatrixemptycode
\global\advance\multi@col@count by -1\relax
\global\pgf@picmaxx=.5\multi@col@width
\global\pgf@picminx=-.5\multi@col@width
\ifnum\multi@col@count=1\relax
\global\let\pgfmatrixemptycode=\orig@pgfmatrixemptycode
\fi
}
}
}
\makeatother
\begin{document}
\tikzstyle{Z}=[fill=green]
Works but poorly aligned:
\begin{tikzcd}
|[Z]| \beta & |[Z,multicol=2]|\alpha+\beta+\delta+2\pi &&|[Z]| x\\
|[Z]| \beta \ar[r] & |[Z]| \beta \ar[r] & |[Z]| \beta \ar[r] & |[Z]| \beta
\end{tikzcd}\\
Arrows are not exactly the expected ones:
\begin{tikzcd}
|[Z]| \beta \ar[r] & |[Z,multicol=2]|\alpha+\beta+\delta+2\pi \ar[rr] &&|[Z]| x\\
|[Z]| \beta \ar[r] & |[Z]| \beta \ar[r] & |[Z]| \beta \ar[r] & |[Z]| \beta
\end{tikzcd}
\begin{tikzpicture}
\matrix[matrix of nodes,nodes={draw}] {
A &|[multicol=3]| A long entry spanning three columns &&& A \\
A B &|[multicol=2]| A shorter entry && A & D E F \\
A B & A B & A B C D E F & A B\\
};
\end{tikzpicture}
\end{document}
EDIT
To clarify what I want, here is a first draft:
If we want a more rigorous definition, I'd try to write it in term of an optimisation program: try to find the smaller figure such that:
- all normal (not multicol) node's center anchor are aligned on a grid pattern
- multicolumns nodes's center are vertically aligned to be on the same line as their neighbor nodes (similar for multirow)
- every right side of a node should be away by at least
column sep
(this value might change on per-column basis) from the left side of it's right neighbor and we place two separation coordinate on this segment, away bycolumnsep
(similar for bottom/row sep) - all couples of column separation coordinates for a given column should be vertically aligned (similar for rows)
- all nodes's centers should be midway between their closest left and right separation coordinate (similar for rows)
Hopefully this is constraint enough ^^
Actually I'm considering here only multicol or multirow nodes, but I guess we could define similar rules for nodes that share both multiple rows and lines (maybe by considering them as multiple stacked multicolumns rows, and adding additional constraints to align the top node with the bottom nodes).