我使用 TikZ 在 LaTeX 中创建图片。我的图片由一个分为九个部分的矩形组成。每个部分在节点内都有自己的文本,例如“局部变量和临时变量”:
\nodepart{eight} \structtwenty Saved registers, local variables, and temporaries
我的问题是文本没有位于节点的中心,而是位于节点的顶部和底部,有什么帮助吗,下面是整个 TeX 文件:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{decorations.pathreplacing}
\usetikzlibrary{shapes,arrows,positioning}
\def\structforty{\vrule depth 4cm width 0pt}
\def\structsix{\vrule depth 0.14cm width 0pt}
\def\struceleven{\vrule depth 1.1cm width 0pt}
\def\strucfourteen{\vrule depth 1.1cm width 0pt}
\def\structtwenty{\vrule depth 1.9cm width 0pt}
\begin{document}
\begin{tikzpicture}[auto,
rect/.style={
rectangle split, rectangle split parts=9,
draw,rectangle split part align=center,draw, thick,
text width=3cm,
text centered, %minimum height=26em,
% font=\ttfamily,
align=center, rectangle split part align={center,left},
rectangle split part align=midway,
rectangle split part fill={gray!30, blue!20, blue!15, blue!20,blue!15,blue!15,green!15,green!20,green!30}
}]
\node (stack) [rect] {
\nodepart {one}\structforty $\vdots$
\nodepart {two}\struceleven $\vdots$
\nodepart{three}\structsix Argument n
\nodepart{four} \struceleven $\vdots$
\nodepart{five} \structsix Argument 1
\nodepart{six} \structsix Return Address
\nodepart{seven} \structsix Saved \%ebp
\nodepart{eight} \structtwenty Saved registers, local variables, and temporaries
\nodepart{nine} \strucfourteen Argument build area
};
\end{tikzpicture}
\end{document}
答案1
在节点内容中,可以使用\parbox
居中对齐和预定义宽度和高度; \Textbox 命令接收两个参数:
\Textbox{<length>}{<text>}
其中<lenght>
是允许您指定框高度的任意有效长度,<text>
是框的内容:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{decorations.pathreplacing}
\usetikzlibrary{shapes,arrows,positioning}
\newlength\Textwd
\setlength\Textwd{3cm}
\newcommand\Textbox[2]{%
\parbox[c][#1][c]{\Textwd}{\centering#2}}
\makeatletter
\DeclareRobustCommand{\rvdots}{%
\vbox{
\baselineskip4\p@\lineskiplimit\z@
\kern-\p@
\hbox{.}\hbox{.}\hbox{.}
}}
\makeatother
\begin{document}
\begin{tikzpicture}[auto,
rect/.style={
rectangle split, rectangle split parts=9,
draw, thick,
text width=3cm,
text centered,
rectangle split part fill={gray!30, blue!20, blue!15, blue!20,blue!15,blue!15,green!15,green!20,green!30}
}]
\node (stack) [rect] {
\nodepart {one} \Textbox{1cm}{$\rvdots$}
\nodepart {two} \Textbox{1cm}{$\rvdots$}
\nodepart{three} \Textbox{1.5cm}{Argument n}
\nodepart{four} \Textbox{1cm}{$\rvdots$}
\nodepart{five} \Textbox{1.5cm}{Argument 1}
\nodepart{six} \Textbox{1cm}{Return Address}
\nodepart{seven} \Textbox{1cm}{Saved \%ebp}
\nodepart{eight} \Textbox{3cm}{Saved registers, local variables, and temporaries}
\nodepart{nine} \Textbox{2cm}{Argument build area}
};
\end{tikzpicture}
\end{document}
我没有使用标准命令,而是使用了答案中的\vdots
版本\rvdots
如何使此节点中的 \vdots 垂直居中?以避免在顶部默认包含一些额外的间距\vdots
。
答案2
Gonzalo Medina 的答案的 TikZ 专属替代方案,它使用内部(text width
已经存在设置)\pgfutil@minipage
,在 LaTeX 中,只需让 为\minipage
,因此类似于\parbox
。
确实存在一种替代方案,即添加一个\vrule
to \tikz@textfont
(由键设置/tikz/font
)。这对于单行代码很有效,但对于多行节点则不然,因为内部minipage
是t
操作对齐的,所以c
无论如何都需要使用 进行修复。除此之外,第一个节点部分(one
或text
)似乎有点不愿意垂直对齐(我失去了踪迹,因为原始\vdots
宏也会弄乱垂直间距)。
还存在一个heights
键,因此可以提前设置高度。
代码
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{shapes}
\makeatletter
\DeclareRobustCommand{\rvdots}{%
\vbox{
\baselineskip4\p@\lineskiplimit\z@
\kern-\p@
\hbox{.}\hbox{.}\hbox{.}}}
\tikzset{
heights/.code={
\def\pgf@tempb{}%
\foreach \qrr@tikz@rs@height[count=\qrr@tikz@count from 1] in {#1}{
\edef\pgf@tempa{\noexpand\pgfkeysalso{/tikz/every \pgf@lib@sh@toalpha\qrr@tikz@count\space node part/.append style={height={\qrr@tikz@rs@height}}}}%
\ifnum\qrr@tikz@count=1\relax % allows to use \nodepart{text} (or not at all for the first part)
\edef\pgf@tempa{\unexpanded\expandafter{\pgf@tempa}\noexpand\pgfkeysalso{/tikz/every text node part/.append style={height={\qrr@tikz@rs@height}}}}%
\fi
\expandafter\pgfutil@g@addto@macro\expandafter\pgf@tempb\expandafter{\pgf@tempa}
}
\pgf@tempb
},
height/.code={%
\expandafter\def\expandafter\pgfutil@minipage\expandafter[\expandafter##\expandafter 1\expandafter]\expandafter{\pgfutil@minipage[][#1][c]}% LaTeX only!
}
}
\makeatother
\tikzset{rect/.style={
draw,
rectangle split,
rectangle split parts=9,
rectangle split part align=center,
draw,
font=\ttfamily, % still works
thick,
text width=3cm,
align=center,
rectangle split part align={center,left,right},
rectangle split part fill={gray!30, blue!20, blue!15, blue!20,blue!15,blue!15,green!15,green!20,green!30},
}}
\begin{document}
\begin{tikzpicture}[auto]
\node (stack) [rect] {
\nodepart[height=1cm]{one} $\rvdots$
\nodepart[height=1cm]{two} $\rvdots$
\nodepart[height=1.5cm]{three} Argument n
\nodepart[height=1cm]{four} $\rvdots$
\nodepart[height=1.5cm]{five} Argument 1
\nodepart[height=1cm]{six} Return Address
\nodepart[height=1cm]{seven} Saved \%ebp
\nodepart[height=3cm]{eight} Saved registers, local variables, and temporaries
\nodepart[height=2cm]{nine} Argument build area
};
\end{tikzpicture}
\begin{tikzpicture}[auto,rect/.append style={heights={1cm,1cm,1.5cm,1cm,1.5cm,1cm,1cm,3cm,2cm}}]
\node (stack) [rect] {
% \nodepart{text}
$\rvdots$
\nodepart{two} $\rvdots$
\nodepart{three} Argument n
\nodepart{four} $\rvdots$
\nodepart{five} Argument 1
\nodepart{six} Return Address
\nodepart{seven} Saved \%ebp
\nodepart{eight} Saved registers, local variables, and temporaries
\nodepart{nine} Argument build area
};
\end{tikzpicture}
\end{document}