Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Just for fun I wanted to reproduce the memory of Can't get split rectangle to shrink small enough in this TikZ picture using a matrix of nodes avoiding the use of \foreach loops to place nodes.

My intention was to use a matrix of alu nodes with nodes in empty cells option (no need of typing each particular node) and a particular column of controlcache nodes.

After some tests I've found some problems which I don't know how to solve. You can look at the following code and results.

First test (right figure): If I use a matrix of alu nodes and overwrite some column with controlcache nodes (multipart nodes), filling colors disappear. I've test to follow advices in Matrix of nodes column style inconsistency but I could not find the solution.

Second test (left matrix): If the whole matrix is made with controlcache nodes, the filling colors keep its value and there is no problem overwriting them with alu nodes even with particular filling colors.

Could you explain this contradiction?

And a second problem with nodes alignment. If you look carefully, blue alu nodes in the left matrix are misaligned with controlcache nodes, while gray controlcache ones are misaligned in second matrix. The reason and solution (0.5\pgflinewidth yshift) are in Andrew Stacey addendum to Jake's answer to the original question.

May be a better solution would be to draw two matrices, one for controlcache and another one for alu but I would like to know to control particular multipart nodes within a matrix.

\documentclass[border=3mm]{standalone}

\usepackage[rgb,hyperref]{xcolor}
\usepackage{tikz}

% Define colors
\definecolor{shade1}{rgb}{0.9, 0.9, 0.9}
\definecolor{shade2}{rgb}{0.75, 0.75, 0.75}
\definecolor{shade3}{rgb}{0.5, 0.5, 0.5}
\definecolor{shade4}{rgb}{0.35, 0.35, 0.35}

% Load TikZ libraries
\usetikzlibrary{shapes,matrix}
\usetikzlibrary{positioning}

% Text settings
\newcommand{\figureTextSize}{\tiny}

% Figure element lengths
\newlength{\gpgpuElemSep}
\setlength{\gpgpuElemSep}{1mm}
\newlength{\gpgpuElemSize}
\setlength{\gpgpuElemSize}{8mm}

% TikZ styles
\newcommand{\arrowStyle}{stealth}
\newcommand{\bendAngle}{45}
\newcommand{\lineThickness}{semithick}
\tikzstyle{box} = [%
  draw,
  rectangle,
  \lineThickness,
]

\begin{document}
\begingroup
\figureTextSize
\begin{tikzpicture}[%
    every node/.style={%
      node distance=0.375\gpgpuElemSep,
    },
    component/.style={%
      box,
      minimum size=0.42\gpgpuElemSize,
      inner sep=0pt,
    },
    alu/.style={%
      component,
      fill=shade1,
      outer sep=0pt
    },
    controlcache/.style={%
      component,
      rectangle split,
      rectangle split parts=2,
      rectangle split part fill={shade2, shade3},
      rectangle split every empty part={},
      rectangle split empty part height=0.21\gpgpuElemSize-\pgflinewidth,
    },
    layoutalu/.style={%
    matrix of nodes,
        nodes in empty cells,
    nodes=alu,
    column sep=\gpgpuElemSep,
    row sep=\gpgpuElemSep
},
layoutcc/.style={%
    matrix of nodes,
    nodes in empty cells,
    nodes=controlcache,
    column sep=\gpgpuElemSep,
    row sep=\gpgpuElemSep
}
  ]

\matrix (alu) 
   [layoutcc, 
    column 3/.style={nodes={alu,yshift=-.5\pgflinewidth}},
    row 2 column 5/.style={nodes={alu,fill=blue!15}}]
{ & & & & & & & \\ 
  & & & & & & & \\
  & & & & & & & \\
  & & & & & & & \\
  & & & & &|[alu,fill=blue!15]| & & \\
  & & & & & & & \\
  & & & & & & & \\
};

\matrix[right = 1cm of alu.east] (alu2) 
  [layoutalu, 
   column 3/.style={nodes={controlcache,fill=red!30,yshift=.5\pgflinewidth}},
   column 5/.style={nodes={rectangle split part fill={red,blue},controlcache}}]
{ & & & & & & & \\ 
  & & & & & & & \\
  & & & & & & & \\
  & & & & & & & \\
  & & & & & & & \\
  & & & & & & & \\
  & & & & & & & \\
};
\end{tikzpicture}
\endgroup
\end{document}

enter image description here

share|improve this question
add comment

1 Answer

up vote 6 down vote accepted

The first problem, the colours, is due to the fact that the fill option overrides the rectangle split part fill option, even when the latter is given last. This is actually documented (S48.6, p452 of PGF2.10), but you have to notice that rectangle split part fill sets rectangle split part use custom fill and that it is this second key that is overriden by the fill option.

Actually, it's not that it is overridden. Rather it is that the paths for the components are drawn first and then the outer frame path is drawn after - it probably looks nicer that way - so if the outer frame path is filled then it goes on top of the paths for the components. You can try:

\node[rectangle split, rectangle split parts=2, rectangle split empty part height=.25cm, rectangle split part fill={red,blue},fill=orange,opacity=.5] {};

to verify this.

So you need to put fill=none in appropriate places. Simplest is to put it directly in the controlcache style. Since alu is a normal rectangle, specifying the fill option for that simply replaces the earlier fill option and that's why the behaviour is different for the second case.

The second problem is perhaps more subtle, and it took a while to figure out; though having figured it out then I see that it too is in the documentation (S38.1, p375 in PGF2.10). It's to do with the alignment of the nodes. Using the matrix of nodes key sets the anchors to base. You can test this with the following by commenting out the matrix of nodes key (remember to load the matrix library):

\begin{tikzpicture}
\matrix[matrix of nodes]
{
\node {a}; & \node{very}; & \node{long}; & \node{word}; & \node{with}; & \node{syzygies}; \\
};
\end{tikzpicture}

The reason that this is an issue is because of where the rectangle split puts its base anchor if there is no text. The ordinary rectangle puts it at the same place as the centre. The rectangle split puts it at the inner edge of the upper box. This is half a line width higher than the centre anchor. So to remove this behaviour, we need to reset the anchor to center with an appropriate nodes={anchor=center} in the layoutalu and layoutcc styles.

Putting those together, we get:

\documentclass[border=3mm]{standalone}
%\url{http://tex.stackexchange.com/q/29891/86}
\usepackage[rgb,hyperref]{xcolor}
\usepackage{tikz}

% Define colors
\definecolor{shade1}{rgb}{0.9, 0.9, 0.9}
\definecolor{shade2}{rgb}{0.75, 0.75, 0.75}
\definecolor{shade3}{rgb}{0.5, 0.5, 0.5}
\definecolor{shade4}{rgb}{0.35, 0.35, 0.35}

% Load TikZ libraries
\usetikzlibrary{shapes,matrix}
\usetikzlibrary{positioning}

% Text settings
\newcommand{\figureTextSize}{\tiny}

% Figure element lengths
\newlength{\gpgpuElemSep}
\setlength{\gpgpuElemSep}{1mm}
\newlength{\gpgpuElemSize}
\setlength{\gpgpuElemSize}{8mm}

% TikZ styles
\newcommand{\arrowStyle}{stealth}
\newcommand{\bendAngle}{45}
\newcommand{\lineThickness}{semithick}
\tikzstyle{box} = [%
  draw,
  rectangle,
  \lineThickness,
]

\begin{document}
\begingroup
\figureTextSize
\begin{tikzpicture}[%
    every node/.style={%
      node distance=0.375\gpgpuElemSep,
    },
    component/.style={%
      box,
      minimum size=0.42\gpgpuElemSize,
      inner sep=0pt,
    },
    alu/.style={%
      component,
      fill=shade1,
      outer sep=0pt
    },
    controlcache/.style={%
      component,
      fill=none,
      rectangle split,
      rectangle split parts=2,
      rectangle split part fill={shade2, shade3},
      rectangle split every empty part={},
      rectangle split empty part height=0.21\gpgpuElemSize-\pgflinewidth,
    },
    layoutalu/.style={%
    matrix of nodes,
        nodes in empty cells,
    nodes={anchor=center},
    nodes=alu,
    column sep=\gpgpuElemSep,
    row sep=\gpgpuElemSep
},
layoutcc/.style={%
    matrix of nodes,
    nodes in empty cells,
    nodes={anchor=center},
    nodes=controlcache,
    column sep=\gpgpuElemSep,
    row sep=\gpgpuElemSep
}
  ]

\matrix (alu) 
   [layoutcc, 
    column 3/.style={nodes={alu}},
    row 2 column 5/.style={nodes={alu,fill=blue!15}}]
{ & & & & & & & \\ 
  & & & & & & & \\
  & & & & & & & \\
  & & & & & & & \\
  & & & & &|[alu,fill=blue!15]| & & \\
  & & & & & & & \\
  & & & & & & & \\
};

\matrix[right = 1cm of alu.east] (alu2) 
  [layoutalu, 
   column 3/.style={nodes={controlcache,fill=red!30}},
   column 5/.style={nodes={rectangle split part fill={red,blue},controlcache}}]
{ & & & & & & & \\ 
  & & & & & & & \\
  & & & & & & & \\
  & & & & & & & \\
  & & & & & & & \\
  & & & & & & & \\
  & & & & & & & \\
};
\end{tikzpicture}
\endgroup
\end{document}

With result:

Multipart rectangles in a matrix

which, due to the size, does not look a lot different (apart from the colours)! But I can assure you that there is a difference.

Incidentally, my references to the documentation are not intended as "You should have read the manual better". I only found them after investigation, and I consider neither to be obvious. In particular, I only figured out the second after drawing lots and lots of test pictures.

Lastly, your pictures are great for showing that optical illusion where little grey circles appear in between the rectangles.

share|improve this answer
    
Thank you. Once you know where to look, it's easier to find the solution. ASAP I will apply your improvements to write another answer to gablin's question. –  Ignasi Oct 3 '11 at 14:40
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.