6

I want to use tikz to generate adjacent rectangles having label on each border.

7     6 5   3 2    0
_______________
|____|____|____|

I've tried this:

\begin{tikzpicture}
      \node[above left] (b) at (0,0) {7};
      \node[above left] (b) at (2,0) {6};
      ... %same for the others
      \draw (0,0) rectangle (2,1);
      \draw (2,0) rectangle (5,1);
      \draw (5,0) rectangle (8,1);
\end{tikzpicture}

But the output is not as I want, the label are not above the rectangles. I guess its because the rectangle is not defined with the node or something like that.

Is it possible to do that with tikz? If yes how should I do it?

3
  • You can draw a rectangle and place a node above the rectangle or you can draw a node and a label above with \node[draw,rectangle, minimum width =...,minimum height=...,label=above:name]{};. You can see tex.stackexchange.com/questions/13401/… but there are others answers about your request. Jul 19, 2012 at 12:51
  • You are placing the node at (0,0) (the lower left corner of the rectangle) instead of at (0,1) (the upper left corner).
    – Caramdir
    Jul 19, 2012 at 16:00
  • @Caramdir that's correct. I understand this more with the suggested solutions Jul 19, 2012 at 16:10

4 Answers 4

7

Like this?

\documentclass{article}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
      \node[above right] at (0,1) {7};
      \node[above left]  at (2,1) {6};
      \node[above right] at (2,1) {5};
      \node[above left]  at (5,1) {3};
      \node[above right] at (5,1) {2};
      \node[above left]  at (8,1) {0};
      \draw (0,0) rectangle (2,1);
      \draw (2,0) rectangle (5,1);
      \draw (5,0) rectangle (8,1);
\end{tikzpicture}

\end{document}

enter image description here


Edit 1: Here's an automated version. You specify the coordinates of the rectangle, the labels, the labels position and a text to be written at the center of the rectangle:

\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}
\usepackage{xifthen}

\newdimen\xfirst
\newdimen\yfirst
\newdimen\xsecond
\newdimen\ysecond

\newcommand{\ybig}{}
\newcommand{\ysmall}{}
\newcommand{\xbig}{}
\newcommand{\xsmall}{}

\newcommand{\labeledrectangle}[6]% first point, second point, first label, second label, direction (l r t b), rectangle label
{   \path (#1);
    \pgfgetlastxy{\xfirst}{\yfirst};
    \path (#2);
    \pgfgetlastxy{\xsecond}{\ysecond};
    \draw (#1) rectangle node {#6} (#2);
    \ifthenelse{\lengthtest{\yfirst > \ysecond}}%
        {   \xdef\ybig{\yfirst}
            \xdef\ysmall{\ysecond}
        }%
        {   \xdef\ybig{\ysecond}
            \xdef\ysmall{\yfirst}
        }
    \ifthenelse{\lengthtest{\xfirst > \xsecond}}%
        {   \xdef\xbig{\xfirst}
            \xdef\xsmall{\xsecond}
        }%
        {   \xdef\xbig{\xsecond}
            \xdef\xsmall{\xfirst}
        }
    \ifthenelse{\equal{#5}{l}}      
        {   \node[above left] at (\xsmall,\ysmall) {#3};
            \node[below left] at (\xsmall,\ybig) {#4};
        }{}
    \ifthenelse{\equal{#5}{r}}      
        {   \node[above right] at (\xbig,\ysmall) {#3};
            \node[below right] at (\xbig,\ybig) {#4};
        }{}
    \ifthenelse{\equal{#5}{t}}      
        {   \node[above right] at (\xsmall,\ybig) {#3};
            \node[above left] at (\xbig,\ybig) {#4};
        }{}
    \ifthenelse{\equal{#5}{b}}      
        {   \node[below right] at (\xsmall,\ysmall) {#3};
            \node[below left] at (\xbig,\ysmall) {#4};
        }{}         
}

\begin{document}

\begin{tikzpicture}
    \labeledrectangle{0.1,0.1}{3,1}{a}{b}{t}{top}
    \labeledrectangle{-0.1,0.1}{-4,3}{c}{d}{l}{left}
    \labeledrectangle{-0.1,-0.1}{-2.5,-2.5}{e}{f}{b}{bottom}
    \labeledrectangle{0.1,-0.1}{1,-3}{g}{h}{r}{right}
\end{tikzpicture}

\begin{tikzpicture}
    \labeledrectangle{0,0}{2,1}{7}{6}{t}{}
    \labeledrectangle{2,0}{5,1}{5}{3}{t}{}
    \labeledrectangle{5,0}{8,1}{2}{0}{t}{}
\end{tikzpicture}

\end{document}

enter image description here

1
  • yeah, maybe I did something wrong.. It was my first idea, don't know it didn't work. Thanks Jul 19, 2012 at 13:05
8

Yet another approach, but not a TikZ one (with embellishments):

\documentclass{article}
\usepackage{bytefield}
\begin{document}
\begin{bytefield}[%
    endianness=big,
    bitwidth=1em,
    bitformatting={\small},
    ]{8}
\bitheader{0,2,3,5-7}\\
\bitbox{2}{x}
\bitbox{3}{}
\bitbox{3}{z}\\
\end{bytefield}
\end{document}

Crop from output PDF

3
  • This is nice :-), thanks for your post Jul 19, 2012 at 13:17
  • Wow, looks exactly like what I did, only as a ready package. Good to know! Jul 19, 2012 at 13:42
  • @TomBombadil: Yes, it's worth having a look at the manual (bytefield.pdf); there's even more stuff to enjoy & tweak in there. Jul 19, 2012 at 15:06
3

Another approach:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc,positioning}

\tikzset{myrectangle/.code n args={3}{%
        \node[above] at ($(#1.north west)!0.15!(#1.north)$){#2};
         \node[above] at ($(#1.north east)!0.15!(#1.north)$){#3};
    }
}

\begin{document}
\begin{tikzpicture}
\node[rectangle,draw,minimum width=2cm, minimum height=1cm](a){};
\node[myrectangle={a}{7}{6}]{};

\node[rectangle,draw,minimum width=2cm, minimum height=1cm,right=0cm of a](b) {};
\node[myrectangle={b}{5}{3}]{};

\node[rectangle,draw,minimum width=2cm, minimum height=1cm,right=0cm of b](c) {};
\node[myrectangle={c}{2}{0}]{};
\end{tikzpicture}

\begin{tikzpicture}
\node[rectangle,draw,minimum width=1.5cm, minimum height=0.5cm](a){};
\node[myrectangle={a}{7}{6}]{};

\node[rectangle,draw,minimum width=1.5cm, minimum height=0.5cm,right=0cm of a](b) {};
\node[myrectangle={b}{5}{3}]{};

\node[rectangle,draw,minimum width=1.5cm, minimum height=0.5cm,right=0cm of b](c) {};
\node[myrectangle={c}{2}{0}]{};
\end{tikzpicture}

\end{document}

enter image description here

3

PSTricks can provide us with a faster compilation. :-)

enter image description here

\documentclass[border=0pt]{standalone}

\usepackage{pstricks-add}
\usepackage{multido}

\newcount\j

\newcommand\CreateDiagram[3]{%
    \begin{pspicture}[showgrid=false](-#2,0)(0,\dimexpr#1\psyunit+9pt\relax)
        \psframe(-#2,0)(0,#1)
        \uput{2pt}[135](0,#1){0}
        \uput{2pt}[45](-#2,#1){#2}
        \psforeach{\i}{#3}
        {
            \psline(-\i,#1)(-\i,0)
            \uput{2pt}[45](-\i,#1){\i}
            \j\i\advance\j1\relax
            \uput{2pt}[135](-\i,#1){\the\j}
        }
    \end{pspicture}}

\begin{document}
    \CreateDiagram{1}{7}{2,5}%{height}{max}{list}
\end{document}

You must log in to answer this question.

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