在 tikz 中,如果我启用nodes in empty cells=true
,则会在矩阵的每个空单元格中添加一个节点。我想将每个空节点转换为shape=coordinate
(和不是作为一个节点inner sep=0pt
,因为这些节点仍然有几个像素宽),否则空节点会占用一些空间。
是否有可能以某种方式使用仅适用于空节点的不同样式?
梅威瑟:
\documentclass{article}
\usepackage{tikz-cd}
\begin{document}
With inner sep=0pt (see the gaps, I don't want to use start anchor=center because not all nodes want to be linked from the center):\\
\noindent\begin{tikzcd}[
nodes in empty cells=true,
/tikz/every node/.style={
nodes={draw,inner sep=0pt,outer sep=0pt},
},
]
\rar[-] & \rar[-] & Hey
\end{tikzcd}
With shape coordinate (no more gaps, but ALL nodes are turned into coordinate… and disappear I could force another shape using shape=rectangle, but I don't want to manually change all nodes):\\
\noindent\begin{tikzcd}[
nodes in empty cells=true,
/tikz/every node/.style={
nodes={draw,shape=coordinate},
},
]
\rar[-] & \rar[-] & Hey\\
\end{tikzcd}
\end{document}
答案1
该matrix
库(由 TikZ-CD 使用matrix of nodes
,并matrix of math nodes
简单地使用execute at empty cell
检查是否nodes in empty cells
设置为 true,如果是则放置一个空节点。
我们可以nodes in empty cells
通过指定以下代码来覆盖它(忽略切换)
execute at empty cell={
\coordinate[
yshift=axis_height,
name=\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn
]
}
这axis_height
是必要的,因为同一行中的其他节点位于其基线,并且这些节点的垂直中心位于是=axis_height
是 PGFMath 函数/值,TikZ-CD 自身形状使用它asymmetrical rectangle
作为其垂直中心。(这样做是为了让同一行单元格之间的箭头始终保持水平,并且大致处于自然高度,就像减号一样。)
这基本上也是当您使用|[*]|
第一个示例时发生的情况,因为实际上没有单元格是空的。
其中有\arrow
et al 的将是一个节点。
我将劫持一个内部 TikZ 钩子来设置节点的形状,coordinate
除非它已经是了,因为那时我们不需要再做一次axis_height
转变。
这将防止您拥有真正的空节点,即没有文本或显式的节点text width = 0pt
将产生坐标。
为此,我将设置一个切换开关,以便只有当它设置为 true(这是 的默认值empty cells as coordinate despite arrow
)时才会进行此检查。
我正在覆盖处理语法的宏|…|
,这样就不会检查它是否“空”(除非您empty node check
再次切换)。
代码
%\documentclass{article}
\documentclass[varwidth]{standalone}
\usepackage{tikz-cd}
\makeatletter
% a coordinate in an empty cell needs some special care about axis_height
\def\tikzcd@emptycell@coordinate{%
\coordinate[yshift=axis_height,name=\tikzmatrixname
-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn];}
% overwriting original, a explicit || node shouldn't become a coordinate
\def\tikz@lib@matrix@with@options|#1|{\tikz@lib@matrix@plainfalse\node
[empty node check=false,name=\tikzmatrixname-\the\pgfmatrixcurrentrow
-\the\pgfmatrixcurrentcolumn]#1\bgroup\tikz@lib@matrix@startup}%
\newif\iftikz@emptynodecheck
\tikzcdset{
/tikz/empty node check/.is if=tikz@emptynodecheck,
empty cells as coordinates despite arrow/.style={
/tikz/empty node check,
/tikz/every matrix/.append style={
/tikz/execute at empty cell=\tikzcd@emptycell@coordinate,
/tikz/every node/.append code={%
\tikz@addoption{%
\iftikz@emptynodecheck
\ifdim\wd\pgfnodeparttextbox=0pt %
\pgfutil@ifx\tikz@shape\tikz@coordinate@text{}{%
\def\tikz@shape{coordinate}%
\pgftransformyshift{axis_height}}%
\fi\fi}}}}}
\makeatother
\NewExpandableDocumentCommand{\mycircle}{}{|[circle, draw, inner sep=3pt]|}
\setlength\parindent{0pt}% just for this
\begin{document}
Each ``empty'' cell gets \texttt{|[*]|}
to force a coordinate at the right height.\par
\begin{tikzcd}[
cells={nodes=draw},
/tikz/*/.style={shape=coordinate, yshift=axis_height}]
|[*]| \rar[-] & |[*]| \rar[-] & Hey
\end{tikzcd}
With \texttt{empty cells as coordinate despite arrow}
real empty cells as well as ``empty'', i.\,e. cells
with \verb|\ar|, \verb|\arrow|, \verb|\rar|, \dots
gets detected.\par
\begin{tikzcd}[
empty cells as coordinates despite arrow,
cells={nodes=draw}, arrows=-]
\rar & & Hey \lar & \mycircle \lar
\end{tikzcd}
\end{document}