4

I am trying to adapt the solution proposed by @JLDiaz to Spanning a cell across several rows in TikZ-matrix in order to have multiple multi-rows within a TikZ matrix.

This is what I currently have:

\documentclass[tikz]{standalone}
\usetikzlibrary{matrix,calc,fit}

\begin{document}

\newlength{\csep}
\setlength{\csep}{1.5mm}

\newlength{\twidth}
\setlength{\twidth}{25mm}

\begin{tikzpicture}[auto, node distance=2cm,font=\small,
    every node/.style={inner sep=0pt,rectangle, minimum height=2.5em, text centered},
    comp/.style={draw,very thick,text width=\twidth,fill=blue!10}]
\matrix (m) [ampersand replacement=\&,column sep=\csep, row sep=3mm]
{
\node (l5) [comp] {5}; \& \\
\node (l4) [comp] {4}; \& \\
\node (l3) [comp] {3}; \& \node[comp]{3'};\\
\node (l2) [comp] {2};\\
\node (l1) [comp] {1};\\
};
\coordinate (aux5) at  ($(l5.north east) + (\csep,0)$);
\coordinate (aux4) at ($(l4.south east) + (\csep+\twidth,0)$);
\node[comp, fit=(aux4)(aux5), inner sep=-.6pt] (X45) {}; 
\node[text width=3cm, text centered, anchor=center] at (X45.center) {4' 5'};

\coordinate (aux2) at  ($(l2.north east) + (\csep,0)$);
\coordinate (aux1) at ($(l1.south east) + (\csep+\twidth,0)$);
\node[comp, fit=(aux1)(aux2),  inner sep=-.6pt]
(X12) {}; 
\node[text width=3cm, text centered, anchor=center] at (X12.center) {1' 2'};

\end{tikzpicture}

\end{document}

enter image description here

However, the boxes "4' 5'" and "3'" do not have equal width:

enter image description here

How can I make all boxes in the second column have the same width?

And: Is there an easier solution to get some boxes spanning multiple rows than to create those aux coordinates?

  • if you drop draw from comp style, it works ok. This is because you don't take the line width into account when you calculate aux. You can correct this by putting \csep+\twidth+3*\pgflinewidth in place of \csep+\twidth. – Kpym Oct 11 '15 at 11:28
2

Those boxes are not equally wide because of the negative inner sep values. Make them zero. Also in the definition of aux coordinates you have to add 1.5\pgflinewidth like:

\coordinate (aux5) at  ($(l5.north east) + (\csep+1.5\pgflinewidth,-1.5\pgflinewidth)$);
\coordinate (aux4) at ($(l4.south east) + (\csep+\twidth+1.5\pgflinewidth,1.5\pgflinewidth)$);
\node[comp, fit=(aux4)(aux5), inner sep=0pt,outer sep=0pt] (X45) {};
\node[text width=3cm, text centered, anchor=center] at (X45.center) {4' 5'};

The full code:

\documentclass[tikz]{standalone}
\usetikzlibrary{matrix,calc,fit}

\begin{document}

\newlength{\csep}
\setlength{\csep}{1.5mm}

\newlength{\twidth}
\setlength{\twidth}{25mm}

\begin{tikzpicture}[auto, node distance=2cm,font=\small,
    every node/.style={inner sep=0pt,rectangle, minimum height=2.5em, text centered},
    comp/.style={draw,very thick,text width=\twidth,fill=blue!10}]
\matrix (m) [ampersand replacement=\&,column sep=\csep, row sep=3mm]
{
\node (l5) [comp] {5}; \& \\
\node (l4) [comp] {4}; \& \\
\node (l3) [comp] {3}; \& \node[comp]{3'};\\
\node (l2) [comp] {2};\\
\node (l1) [comp] {1};\\
};
\coordinate (aux5) at  ($(l5.north east) + (\csep+1.5\pgflinewidth,-1.5\pgflinewidth)$);
\coordinate (aux4) at ($(l4.south east) + (\csep+\twidth+1.5\pgflinewidth,1.5\pgflinewidth)$);
\node[comp, fit=(aux4)(aux5), inner sep=0pt,outer sep=0pt] (X45) {};
\node[text width=3cm, text centered, anchor=center] at (X45.center) {4' 5'};

\coordinate (aux2) at  ($(l2.north east) + (\csep+1.5\pgflinewidth,-1.5\pgflinewidth)$);
\coordinate (aux1) at ($(l1.south east) + (\csep+\twidth+1.5\pgflinewidth,1.5\pgflinewidth)$);
\node[comp, fit=(aux1)(aux2),  inner sep=0pt]
(X12) {};
\node[text width=3cm, text centered, anchor=center] at (X12.center) {1' 2'};

\end{tikzpicture}

\end{document}

enter image description here

  • it looks like box "5" and box "4' 5'" are not aligned at the top, and box "4" and box "4' 5'" are not aligned at the bottom; how can that be solved? – m.s. Oct 11 '15 at 11:02
  • 1
    @m.s. My fault. Now they are aligned. I forgot to do adjustments in y coordinate earlier. – user11232 Oct 11 '15 at 11:21
3

I don't know what is behind of decision to use matrix as base for desired image. It can be relative simple (to my opinion more than with use of matrix) to draw with out use of matrix:

\documentclass[border=3mm,
               tikz,
               preview]{standalone}
\usetikzlibrary{calc,chains}

    \begin{document}
\newlength{\twidth}
\setlength{\twidth}{25mm}
    \begin{tikzpicture}[
    node distance = 5mm,
      start chain = going above,       
every node/.style = {rectangle, draw, ultra thick, fill=blue!10,
                     text width=\twidth, minimum height=2.5em, 
                     inner sep=1mm, outer sep=0mm,
                     text centered, font=\small,
                     on chain},
                        ]
% first column
\node (l1) {1};\\
\node (l2) {2};\\
\node (l3) {3};\\
\node (l4) {4};\\
\node (l5) {5};\\
% second column
\path   let \p1 = (l1.south),
            \p2 = (l2.north),
            \n1 = {veclen(\x2-\x1,\y2-\y1)} in
        node[above right =0mm and 3mm of l1.south east,
             minimum height=\n1] {1' 2'}
        node {3'}
        node[minimum height=\n1] {4' 5'};
    \end{tikzpicture}
\end{document}

As can be seen, node are put chains. Heights of taller nodes in second column is calculated with distance between first two lover nodes in the first column. Until the nodes in the first column has equal heights, this simplification doesn't make troubles.

enter image description here

2

Following code shows an alternative to Harish Kumar solution. It also uses fit library and draws multirow nodes after matrix but shows how to do it without calc library and a second node for node's text.

\node[comp, fit={(l2.north-|l32.west) (l1.south-|l32.east)},  
      inner sep=0pt, label=center:{1' 2'}] (X12) {};

defines a fitting node with two corners declared with perpendicular coordinates system. Label with center option is used to place node's contents.

In order to make fit node with equal size as second column node, outer sep=0pt must be added to comp style.

\documentclass[tikz]{standalone}
\usetikzlibrary{matrix,fit}

\begin{document}

\newlength{\csep}
\setlength{\csep}{1.5mm}

\newlength{\twidth}
\setlength{\twidth}{25mm}

\begin{tikzpicture}[auto, node distance=2cm,font=\small,
    every node/.style={inner sep=0pt,rectangle, minimum height=2.5em, text centered},
    comp/.style={draw,very thick,text width=\twidth,fill=blue!10,outer sep=0pt}]
\matrix (m) [ampersand replacement=\&,column sep=\csep, row sep=3mm]
{
\node (l5) [comp] {5}; \& \\
\node (l4) [comp] {4}; \& \\
\node (l3) [comp] {3}; \& \node (l32) [comp]{3'};\\
\node (l2) [comp] {2};\\
\node (l1) [comp] {1};\\
};
\node[comp, fit={(l5.north-|l32.west) (l4.south-|l32.east)}, 
       inner sep=0pt, outer sep=0pt, label=center:{4' 5'}] (X45) {};

\node[comp, fit={(l2.north-|l32.west) (l1.south-|l32.east)},  
       inner sep=0pt, label=center:{1' 2'}]
(X12) {};

\end{tikzpicture}

\end{document}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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