3

I am aware that TikZ tries to create shapes based on minimum size and the text content, but I wish to create some rectangles of arbitrary size as the ones in the following figure:

my figure

As you can see, the width of the "Requested size" rectangle should be equal to the total width of the "Free block" rectangles, yet each "Free block" and each "Used block" rectangle has a different width, even if they have the same text.

I have tried to tackled it with a matrix like this example, but I could really not set the rectangle's width, as I am not messing around with "text width" inside the nodes. This is what I have written so far for the last line of the figure:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{shapes,matrix,positioning}
\begin{document}
\begin{tikzpicture}[field/.style={outer sep=0pt, draw, minimum
  height=12mm, minimum width=#1\linewidth,font=\small,anchor=center,
    text width=18mm,align=center}]
    \matrix (A) [matrix of nodes, column sep=-\pgflinewidth,
    row 1/.style={nodes={field=.1}}] {
      |[field=.2,draw=none]| Memory layout &
        |[field=.3,fill=red]| Used block &
        |[fill=green]| Free block &
        |[fill=green]| Free block &
        |[field=.2, fill=green]| Free block &
        |[fill=red]| Used block \\
    };
\end{tikzpicture}
\end{document}

And this is the output:

MVP Output

Thanks in advance!

Edit: As @OlgaK commented, my code was using different names for the shape, so I have fixed the code and the output image.

JoKo
  • 33
  • text width would certainly be the quickest solution here. I don't it would interfere with your nodes as long as your text is around the same length. – Alenanno Apr 21 '16 at 17:40
  • Your code gives mistake. Correction "memory block field" instead of "field" and you arrive to another picture – Olga K Apr 21 '16 at 17:42

2 Answers2

3

Another solution using calc library (thanks to wrtlprnft for his correction)

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{shapes,matrix,positioning,calc}
\begin{document}
\begin{tikzpicture}[field/.style={%
    outer sep=0pt, draw, minimum height=12mm, 
    minimum width=#1\linewidth, font=\small, anchor=center,
    text width=18mm,align=center}]

    \matrix (A) [matrix of nodes, column sep=-\pgflinewidth,
           row 1/.style={nodes={field=.1}}] {%
      |[field=.2,draw=none]| Memory layout &
      |[field=.3,fill=red]| Used block &
      |[fill=green]| Free block &
      |[fill=green]| Free block &
      |[field=.2, fill=green]| Free block &
      |[fill=red]| Used block \\
    };

    \draw let \p1=($(A-1-5.north east)-(A-1-3.south west)$)
     in node[fill=green, inner sep=0pt, draw, 
     minimum width=\x1-\pgflinewidth, minimum height=\y1, 
     above right=1mm and 0pt of A-1-3.north west]{Requested size};
\end{tikzpicture}
\end{document}

![enter image description here

These zoomed fragments shows limit details

enter image description here ... enter image description here

Ignasi
  • 136,588
  • 1
    I've used this quite a few times myself, but sometimes one notices that the width is not exactly as desired: to be correct, you also have to subtract the current value of line width (by default 0.4pt) from the minimum width (which is annoying) or set outer xsep=0 (which draws the node as desired, but moves anchors). – wrtlprnft Apr 21 '16 at 19:05
  • @wrtlprnft Thank you, I've applied your suggestion. – Ignasi Apr 21 '16 at 19:17
1

a solution but there are certainly better

enter image description here

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{positioning, calc,intersections,shapes,matrix,fit}
\begin{document}
\begin{tikzpicture}[memory block field/.style={outer sep=0pt, draw, minimum
  height=12mm, minimum width=#1\linewidth,font=\small,anchor=center,
    text width=18mm,align=center}]
    \matrix (A) [matrix of nodes, column sep=-\pgflinewidth,
    row 1/.style={nodes={memory block field=.1}}] {
      |[memory block field=.2,draw=none]| Memory layout &
        |[memory block field=.3,fill=red]| Used block &
        |[fill=green]| Free block &
        |[fill=green]| Free block &
        |[memory block field=.2, fill=green]| Free block &
        |[fill=red]| Used block \\
    };

\coordinate[above=5em of A-1-5.east] (aa);
\coordinate[above=5em of A-1-3.west] (bb);

\node[fill=green,inner sep=0,draw, fit=(aa) (bb), minimum
  height=12mm,]{Requested size};

\end{tikzpicture}

\end{document}
rpapa
  • 12,350
  • 1
    I'd suggest: \node[fill=green,inner sep=0,draw, fit=(A-1-3.north west) (A-1-5.south east), minimum height=12mm,yshift=5em, anchor=south, label=center:Requested size]{}; Fit coordinates only define node size, you can shift it as you want, so no aux coordinates are necessary. A second point is about text of fitting nodes, it's better to use label=center:... and leave node's text empty. Please look at p 622 in pgfmanual. – Ignasi Apr 21 '16 at 18:47