GeneralNeed help formatting stack diagrams

LaTeX specific issues not fitting into one of the other forums of this category.
Post Reply
vengefultacos
Posts: 2
Joined: Wed Jun 04, 2008 9:59 pm

Need help formatting stack diagrams

Post by vengefultacos »

I'm losing my mind trying to format stack diagrams. These diagrams show what is on several different stacks before and after an operation. What I would like would to be have a series of stacked boxes showing the content of each stack, with an arrow in between the "before" and "after" set of stacks. A crude ASCII approximation:

Code: Select all

       Before                           After 
_________    _________           __________   ___________
|N Stack |  | O Stack |          | N Stack |  | O Stack |
----------  ----------           -----------  -----------
| Value1 |  | Object1 |          |         |  | Object2 |
----------  -----------   ---->  -----------  -----------
| Value2 |
----------
One of the features I am looking for is the ability to not have to specify widths for the individual stack tables. I would like them to take up as little horizontal space as possible. I also want them to be top-aligned, with the top of all stacks being aligned, and the arrow, if possible, aligned half-way down the longest stack.

I need to avoid using any specific measurements because eventually these diagrams will be automatically generated by a script. Getting the script to figure out how large each element should be would be a nightmare, and would something I would expect our layout package to do for us.

I've tried doing this with tables within minipages (and then varwidth):

Code: Select all

\begin{table}[ht]
\small
\begin{varwidth}[t]{0.5\linewidth}\centering
\begin{tabular}{|c|}
\hline
\textbf{N}\\
\hline
N1\\
\hline
N2\\
\hline
\end{tabular}
\end{varwidth}
\hspace{0.5cm}
\begin{varwidth}[t]{0.5\linewidth}
\centering
\begin{tabular}{|c|}
\hline
\textbf{O}\\
\hline
O1\\
\hline
\end{tabular}
\end{varwidth}
\end{table}
The issue there is that I cannot seem to find a way to get the tables to be top-aligned. LaTeX seems to want to align them based on their centers, even if I specify the "[t]" option to the minipages/varwidths.

Next, I tried using several graphics packages. I tried using the Dot-notation used by Graphviz, since MikTeX seems to work OK with it. Unfortunately, it has the same issue... you cannot top-align nodes in Graphviz... it lays them out the way it wants.

Finally, I turned to PGF/Tikz, since it seemed really powerful, and capable of of just about anything.

Code: Select all

\begin{tikzpicture}
\node[rectangle  split,  rectangle  split  parts=2,  draw,  anchor=north, text width=5em] (n1)
{N
\nodepart{second}
N1 \\
N2
};

\node[fill=green!65!black, single arrow, draw, right=of n1] (arrow)  {};

\node[rectangle  split,  rectangle  split  parts=2,  draw,  anchor=north, right=of arrow] (n2)
{N
\nodepart{second}
N3
};
\end{tikzpicture}

\begin{tikzpicture}[start chain, every  node/.style={draw} text  node  part/.style={text  centered}]
\node[on chain, rectangle  split,  rectangle  split  parts=2,  draw, text width=1cm] (n1)
{N
\nodepart{second}
N1\\
N2
};

\node[on chain, rectangle  split,  rectangle  split  parts=2,  draw] (o1)  
{O
\nodepart{second}
O1
};
\begin{scope}[start branch=arrow]
	\node[fill=green!65!black, single arrow, draw, on chain=going below right] (arrow)  {};
\end{scope}

\node[on chain, rectangle  split,  rectangle  split  parts=2,  draw] (n2)
{N
\nodepart{second}
N3
};

\node[on chain,rectangle  split,  rectangle  split  parts=2,  draw] (o2)
{O
\nodepart{second}
O2
};

\end{tikzpicture}

\vspace{1in}

\begin{tikzpicture}

	\matrix[draw,column  sep=10pt, anchor=north] (before)
	{
		\node[rectangle split, 
				rectangle  split  parts=2, 
				rectangle  split  part  fill={gray!20, white!100}, 
				draw, 
				anchor=north] (n1)
			{N
				\nodepart{second}
				N1 % can't use \\ here because tikz will think it's the end of the matrix row
				Bar
			};
		&
		\node[rectangle split, 
				rectangle  split  parts=2, 
				rectangle  split  part  fill={gray!20, white!100}, 
				draw, 
				anchor=north] (o1)  
			{O
				\nodepart{second}
				LargeObjectName
			}; 
		&
		\node[fill=green!65!black, single arrow, draw, minimum height=20pt, below=10pt] (arrow)  {};
		&
    	\node[rectangle  split,  
    		rectangle  split  parts=2,
    		rectangle  split  part  fill={gray!20, white!100},
    		draw, 
    		anchor=north] (n2)
			{N
				\nodepart{second}
				N3
			};
		&
		\node[rectangle  split,  
			rectangle  split  parts=2,  
			rectangle  split  part  fill={gray!20, white!100},
			draw, 
			anchor=north] (o2)  
			{O
				\nodepart{second}
				LargeObjectName
			}; 
		\\
	};
\end{tikzpicture}


Unfortunately, it has the a large number of blind spots that prevent me from doing what I need to do:
  • Using relatively aligned nodes or nodes on a chain results in the nodes being aligned along their centers, not by their tops, even if I tell them to anchor to their "north point." I can't seem to find any option that will align nodes by anything other than their centerpoints. I can manually add fudge factors to get a specific diagram to line up, but that's not an option with the automatically generated diagrams.
  • Sticking the nodes into a matrix does solve the alignment problem.... but it breaks the ability to insert linebreaks into the text, which I need to use show the contents of the stacks one on top of the other.
So, I'm at my wit's end. It's frustrating, since I have worked with other layout systems in the past which would be a breeze to do this in... I've been pounding my head against it for days. Anyone have any ideas?

Recommended reading 2024:

LaTeXguide.org • LaTeX-Cookbook.net • TikZ.org

NEW: TikZ book now 40% off at Amazon.com for a short time.

localghost
Site Moderator
Posts: 9202
Joined: Fri Feb 02, 2007 12:06 pm

Need help formatting stack diagrams

Post by localghost »

Since I can't compile the code using the pgf/tikZ package, you have to provide a minimal working example (MWE). This MWE has to contain the libraries (included by \usetikzlibrary{<library>}) from pgf/tikZ that are necessary to compile without any error.


Best regards
Thorsten
propell
Posts: 44
Joined: Fri May 30, 2008 11:16 am

Need help formatting stack diagrams

Post by propell »

vengefultacos wrote: Using relatively aligned nodes or nodes on a chain results in the nodes being aligned along their centers, not by their tops, even if I tell them to anchor to their "north point." I can't seem to find any option that will align nodes by anything other than their centerpoints. I can manually add fudge factors to get a specific diagram to line up, but that's not an option with the automatically generated diagrams.
The problem here is probably that you have not used the correct anchors. Here is something that is working for me:

Code: Select all

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning,shapes}
\begin{document}

\begin{tikzpicture}[stack/.style={
    rectangle  split,  rectangle  split  parts=2,  
    draw,  text width=5em}]
    \node[stack] (n1){
        N
        \nodepart{second}
        N1 \\
        N2
    };


\node[fill=green!65!black, single arrow, draw, right=0.5cm of n1] (arrow)  {aa};

\node[stack,right=2cm of n1.north east,anchor=north west] (n2){
    N
    \nodepart{second}
    N3
    };
\end{tikzpicture}
\end{document}
When you write left=of n1 the node will be placed relatively to the west anchor of n1. If you want to align it with the top, use left=of n1.north, anchor=north
Sticking the nodes into a matrix does solve the alignment problem.... but it breaks the ability to insert linebreaks into the text, which I need to use show the contents of the stacks one on top of the other.
This is not correct. In order to allow \\ in a node inside a matrix, you have to set the width of the node. This means that you can write:

Code: Select all

 \matrix[draw,column  sep=10pt, anchor=north] (before)
   {
      \node[rectangle split,
            rectangle  split  parts=2,
            rectangle  split  part  fill={gray!20, white!100},
            draw,
            anchor=north,text width=3cm] (n1) % <----- text width
         {N
            \nodepart{second}
            N1 \\ % you can use a newline character here
            Bar
         };
      &
...
Hope this helps.

- Kjell Magne Fauske
vengefultacos
Posts: 2
Joined: Wed Jun 04, 2008 9:59 pm

Need help formatting stack diagrams

Post by vengefultacos »

propell wrote: The problem here is probably that you have not used the correct anchors. Here is something that is working for me:
Kjell,

That's right... I hadn't been paying enough attention to the node shapes and what anchors they offer. After looking over the documentation again, I saw an example on placing relative to an anchor and hacked something into working using:

Code: Select all

above right=0mm and 3em of nb.north east,  anchor=north,
Your solution is a lot simpler.

Thanks!
Gary
Post Reply