这是一个已经讨论过的问题这里和这里。讨论的解决方案之一是使用fit
覆盖空单元格。但是,在尝试时,它显示了空单元格和其他单元格之间的对齐问题。这是讨论线程中的 MWE,其中对齐问题出在:
\documentclass[xcolor=dvipsnames, 14pt]{beamer}
\usepackage{lmodern}
\usepackage{tikz}
\usetikzlibrary{matrix, fit}
\begin{document}
\begin{frame}
\begin{tikzpicture} [
block/.style ={rectangle
%,text width=6em
, draw
, minimum height=4em
, minimum width=4em
, outer sep=0pt}
]
\matrix (table) [%
matrix of nodes
, nodes in empty cells
, ampersand replacement=\&
, nodes=block
] {%
A \& B \& C \& D \\
E \& \& \& G \\
H \& I \& J \& \\
K \& L \& M \& \\
};
%\node[fit=(table-2-2)(table-2-3), inner sep=0pt]{F};
%\node[fit=(table-3-4)(table-4-4), inner sep=0pt]{N};
\end{tikzpicture}
\end{frame}
\end{document}
为什么我需要多列单元格?我实际上想绘制以下堆叠
我设法在 tikz 中完成了此操作,但代码非常不优雅(xshift、yshfit 之类的调整)。我希望 Matrix 可以作为更好的解决方案,但遇到了上述对齐问题。以下是我调整解决方案的 MWE:
\documentclass[xcolor=dvipsnames, 14pt]{beamer}
\usepackage{lmodern}
\usepackage{tikz}
\usetikzlibrary{matrix, fit}
\begin{document}
\begin{frame}
\centering
\footnotesize
\begin{tikzpicture}[
, every node/.style={
, rectangle, rounded corners=1mm % the shape
, very thick , draw % the border
, fill=orange!50
}]
\node [minimum width=.6\textwidth] (a) {AAAA};
\node [minimum width=.3\textwidth] (b) at (a.north) [xshift=-16mm, yshift=4mm] {B};
\node [minimum width=.07\textwidth] (c) at (b.east) [xshift=5mm] {CCC};
\node [minimum width=.20\textwidth] (d) at (c.east) [xshift=12mm] {DDDDD};
\end{tikzpicture}
\end{frame}
\end{document}
答案1
对于对齐问题,您可以使用键text height
、text depth
和row sep
:column sep
\documentclass[xcolor=dvipsnames, 14pt]{beamer}
\usepackage{lmodern}
\usepackage{tikz}
\usetikzlibrary{matrix, fit}
\begin{document}
\begin{frame}
\begin{tikzpicture} [
block/.style ={rectangle
, draw
, text height=2em
, minimum width=4em,
, text depth=1em
, outer sep=0pt}
]
\matrix (table) [%
matrix of nodes
, nodes in empty cells
, ampersand replacement=\&
, nodes=block
, row sep=-\pgflinewidth
, column sep=-\pgflinewidth
] {%
A \& B \& C \& D \\
E \& \& \& G \\
H \& I \& J \& \\
K \& L \& M \& \\
};
\end{tikzpicture}
\end{frame}
\end{document}
对于其他布局,借用一些杰克的代码来自他的回答创建一个适合其他两个节点水平宽度的节点)来自动计算更宽的节点:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning,calc,fit}
\definecolor{myorange}{RGB}{250,192,116}
\pgfkeys{
/tikz/node distance/.append code={
\pgfkeyssetvalue{/tikz/node distance value}{#1}
}
}
\newcommand\widernode[5][myorange]{
\node[
#1,
inner sep=0pt,
shift=($(#2.south)-(#2.north)$),
yshift=-\pgfkeysvalueof{/tikz/node distance value},
fit={(#2) (#3)},
line width=1pt,
label=center:{\sffamily\bfseries#4}] (#5) {};
}
\begin{document}
\begin{tikzpicture}[node distance=5pt,outer sep=0pt,
block/.style={
line width=1pt,
draw=black,
fill=myorange,
rounded corners,
text width=#1,
font={\sffamily\bfseries},
align=center,
text height=12pt,
text depth=9pt
},
block/.default=1.5cm
]
\node[block=3cm] (a) {AAA};
\node[block=4.5cm,right=of a] (b) {BBB};
\node[block,right=of b] (c) {CCC};
\widernode[block]{a}{c}{DDD}{d}
\end{tikzpicture}
\end{document}
答案2
下面链接答案中的代码包含在positioning-plus
图书馆在第二个例子中,其用途超出了链接答案所提供的内容。
对齐问题有两个原因:
- 该
matrix of nodes
样式将矩阵中每个节点的锚点设置为base
(通常是您想要的)。 - 空单元格是空的,因此空文本框的基线与节点的中心高度相同,因此会稍微低一点对齐。
可以通过center
再次使用锚点来恢复此操作,但如果所有节点文本的高度和深度不相同,此操作将失败(如果其中一个节点的文本比 宽,则会发生类似情况<minimum width> - 2 <inner xsep>
)。对于普通的单行文本,您可以\strut
在每个节点中使用 来修复此问题,并应用键font
。
对于多列和多行,我实际上会将其设置nodes in empty cells
为 false 并使用未绘制的节点(以便它稍后可以用作参考但不可见)。而不是fit
,我会使用我的span
密钥我的另一个答案到TikZ:使节点高度跨越其他几个节点。span
样式仅设置正确的minimum width
s 和minimum height
s,位置必须用at (fit bounding box)
(由键创建的伪节点)设置span
。因为它不会改变text depth
,或者text height
文本的垂直位置不会改变。
代码
\documentclass[tikz,convert=false]{standalone}
\usepackage{lmodern}
\usetikzlibrary{matrix, positioning-plus}
\tikzset{
block/.style={
rectangle,
draw,
minimum height=4em,
minimum width=4em,
outer sep=0pt,
% anchor=center,
font=\strut},
empty cells are empty/.style={
execute at empty cell={\node[draw=none,fill=none]{};},
nodes in empty cells=false
},
overlapping lines in matrices/.style={
row sep=-\pgflinewidth,
column sep=-\pgflinewidth}
}
\begin{document}
\begin{tikzpicture}
\matrix (table) [%
matrix of nodes,
ampersand replacement=\&,
nodes=block,
overlapping lines in matrices,
empty cells are empty
] {%
A \& B \& C \& D \\
e \& \& \& G \\
H \& I \& J \& \\
K \& L \& M \& \\
};
\node[block, span=(table-2-2)(table-2-3)] at (fit bounding box) {F};
\node[block, span=(table-3-4)(table-4-4)] at (fit bounding box) {N};
\end{tikzpicture}
\end{document}
输出
对于您的其他图表,我再次建议不要使用和fit
进行手动调整。最好使用带有其键的库(是语法)。xshift
yshift
positioning
node distance
<vertical distance> and <horizontal distance>
对于第一个代码示例,节点b
、c
和d
以水平方式放置right=of <previous node>
(该chains
库可以帮助创建许多节点)。positioning
使用上面链接的答案中的代码再次改进了键,以便您可以使用below=of -(b)(d)
这意味着新节点将在 和 下方创建b
,d
并且具有 ,minimal width
以便它水平跨越两个节点。
第二个示例首先放置a
节点,然后将节点b
和d
放置在上方,但西对齐和东对齐,因此键为west above
和east above
。这些键由我的positioning-plus
图书馆。
就像above
将自己的锚点设置为south
而将引用节点的锚点设置为一样north
,west above
将自己的锚点设置为north west
而将引用节点的锚点设置为south west
。定位键的概述可以在我的另一个答案。
然后,第四个节点就简单地放置在和c
的边界之间。这不会检查s 的有效性,也不会使用水平节点距离。b
d
minimum width
代码
\documentclass[tikz,convert=false]{standalone}
\usepackage{lmodern}
\usetikzlibrary{positioning-plus}
\tikzset{
node distance=+2mm and +2mm,
every node/.style={
rectangle,
rounded corners=1mm,
very thick,
draw,
fill=orange!50
}
}
\begin{document}
\begin{tikzpicture}% Code A
\node[minimum width=+.3\textwidth] (b) {B};
\node[minimum width=+.07\textwidth, right=of b] (c) {C};
\node[minimum width=+.2\textwidth, right=of c] (d) {D};
\node[below=of -(b)(d)] (a) {AAAA};
\end{tikzpicture}
\begin{tikzpicture}% Code B
\node[minimum width=.6\textwidth] (a) {AAAA};
\node[minimum width=+.3\textwidth, west above=of a] (b) {B};
% or: \node[minimum width=+.3\textwidth, above=of a.north west, anchor=south west] (b) {B};
\node[minimum width=+.2\textwidth, east above=of a] (d) {D};
% or: \node[minimum width=+.2\textwidth, above=of a.north east, anchor=south east] (d) {D};
\path (b) -- node[minimum width=+.07\textwidth] (c) {C} (d);% places the node (c) in the
% middle between (b) and (d)
\end{tikzpicture}
\end{document}