3

I use TikZ to create pictures in LaTeX. My picture consists of a rectangle with nine split parts. Every part has its own text inside the node, for example, "local variables, and temporaries":

\nodepart{eight} \structtwenty Saved registers, local variables, and temporaries

My problem is the text is not centered in the node, but on top and bottom of the node, can any help, below is the whole TeX file:

\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} 
3
  • First of all, welcome. Did you really need \struct...? If you remove them, it will work. You can define the vertical spacing with inner ysep=.
    – cacamailg
    May 5, 2013 at 17:54
  • @cacamailg wouldn't inner ysep apply to all parts of the node? Apparently the OP wants to have each part with a different vertical spacing between the border and the contents. May 5, 2013 at 22:30
  • @GonzaloMedina inner sep applies to all. I said that because I didn't understand that @vampire wanted different vertical spacing.
    – cacamailg
    May 5, 2013 at 23:20

2 Answers 2

3

In the node content, you can use a \parbox with centered alignment and predefined width and height; the \Textbox command receives two arguments:

\Textbox{<length>}{<text>}

where <lenght> is any valid length that lets you specify the height for the box, and <text> is the content for the box:

\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} 

enter image description here

Instead of the standard \vdots command, I used the version \rvdots from the answer to How to vertically center the \vdots in this node? to avoid some additional spacing at the top included by default in \vdots.

9
  • The \rvdots macro from How to vertically center the \vdots in this node? might come in handy. May 5, 2013 at 20:57
  • @Qrrbrbirlbel indeed! I've added it to my answer. Thanks. May 5, 2013 at 22:31
  • @GonzaloMedina You can redefine the \textbox command to set a default width.
    – cacamailg
    May 5, 2013 at 23:22
  • Other way to have centralized vertical dots is to use the ellipsis package and add in the preamble \newcommand\rvdots{\rotatebox{90}{\dots}}.
    – cacamailg
    May 5, 2013 at 23:32
  • @cacamailg I don't understand your first comment; \textbox has a fixed width that can be changed using \Textwd. May 5, 2013 at 23:54
1

A TikZ-only alternative of Gonzalo Medina’s answer that uses the internal (with text width set already present) \pgfutil@minipage which is—in LaTeX—simply let to \minipage and therefore similar to \parbox.

There also did exist an alternative that adds a \vrule to \tikz@textfont (which is set by the /tikz/font key). That worked well for one-liners but not for the nodes with more than one line because the internal minipage is top-aligned so a fix that uses c has been needed anyway. In addition to that, the first node part (one or text) seemed a little bit reluctant to the vertical alignment (I lost track because the original \vdots macro also messes with the vertical spacing).

There also exists a heights key so the heights can be set in advance.

Code

\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} 

Output

enter image description here

3
  • thank you, but not compile on my linux box, maybe I need to install the standalone.cls file.
    – vampire
    May 6, 2013 at 16:06
  • @vampire The standalone class is not needed for the answer. I have updated the answer with the stand article class. May 6, 2013 at 16:17
  • yeah, it's compiled ok, and the solution is great, thank you so much:)
    – vampire
    May 7, 2013 at 14:30

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .