3

I'm trying to create a TikZ version of this table, made in LibreOffice Draw.

Draw Table

I'm quite new to TikZ, and don't really know what I'm doing, but have followed an example here and have built this table:

Table in TikZ

\usepackage{xcolor,array}
\usepackage{tikz}
\begin{document}
\usetikzlibrary{matrix,positioning}

\tikzset{ 
table/.style={
  matrix of nodes,
  row sep=-\pgflinewidth,
  column sep=-\pgflinewidth,
  nodes={rectangle,draw=black,text width=2ex,align=center},
  text depth=0.25ex,
  text height=1ex,
  nodes in empty cells
  },
texto/.style={font=\footnotesize\sffamily},
title/.style={font=\small\sffamily}
}


\newcommand\CellText[2]{%
  \node[texto,left=of mat#1,anchor=east]
  at (mat#1.west)
  {#2};
}

\newcommand\SlText[2]{%
  \node[texto,left=of mat#1,anchor=south]
  at ([xshift=3ex]mat#1.north)
  {#2};
}

\newcommand\SIundertext[2]{%
  \node[texto,left=of mat#1,anchor=east]
  at ([xshift=3ex]mat#1.south)
  {#2};
}

\newcommand\RowTitle[2]{%
\node[title,left=6.3cm of mat#1,anchor=west]
  at (mat#1.north west)
  {#2};
}
\begin{tikzpicture}[node distance =0pt and 0.5cm]

\matrix[table] (mat11) 
{
 & & |[fill=gray]| & |[fill=gray]|& & &|[fill=gray]|\\
};

\SlText{11-1-1}{0}
\SlText{11-1-2}{\ldots}
\SlText{11-1-3}{$h-1$}
\SlText{11-1-4}{$h$}
\SlText{11-1-5}{$h+1$}
\SlText{11-1-6}{\ldots}
\SlText{11-1-7}{$b$}

\SIundertext{11-1-1}{0}
\SIundertext{11-1-1}{0}
\SIundertext{11-1-2}{$\epsilon$}
\SIundertext{11-1-3}{$(h-2)\epsilon$}
\SIundertext{11-1-4}{$(h-1)\epsilon$}
\SIundertext{11-1-5}{$h\epsilon$}
\SIundertext{11-1-6}{$(h+1)\epsilon$}
\SIundertext{11-1-7}{$\xi\epsilon$}

\RowTitle{11}{Time bin};
\CellText{11-1-1}{Coverage};

\end{tikzpicture}
\end{document}

I guess my questions are: 1. How can I make the text above line up vertically? 2. How can I label the text above? (Bin) 3. How can I label the text below? (Time) 4. How can I fix up the text below?

Any help greatly appreciated.

EDIT, additional question: I don't suppose you know of any way to create a 'broken table' sort of effect, where the ellipses are, or another way to make it more obvious that the time is broken up?

Moriambar
  • 11,466
homebrand
  • 177
  • The follow up question should really be posted as a new question. But very briefly here, you could write something like \node[anchor=east] at (mat11-1-5.east) {Testing 123}; called from outside of the matrix. – A.Ellett Sep 22 '13 at 05:27

1 Answers1

4

Here's your code cleaned up a bit and closer to what you want.

\documentclass{article}
\usepackage{xcolor,array}
\usepackage{tikz}
\usetikzlibrary{matrix,positioning}
\usetikzlibrary{calc}

\tikzset
  { 
    table/.style={matrix of nodes,
                  row sep=-\pgflinewidth,
                  column sep=-\pgflinewidth,
                  nodes={rectangle,
                         draw=black,
                         text width=2ex,
                         align=center,
                         minimum width=1.5cm
                        },
                  text depth=0.25ex,
                  text height=1ex,
                  nodes in empty cells
                 },
    texto/.style={font=\footnotesize\sffamily},
    title/.style={font=\small\sffamily},
    my top text/.style={font=\small\sffamily},
    my bottom text/.style={font=\sffamily\footnotesize}
  }

\newcommand\CellText[2]{%
  \node[texto,left=of mat#1,anchor=east]
  at (mat#1.west)
  {#2};
}

\newcommand\SlText[2]{\node[my top text,anchor=base]         at ($(mat#1.north)+(0,1.0ex)$) {#2};}
\newcommand\SIundertext[2]{\node[my bottom text,anchor=base] at ($(mat#1.south west)-(0,2.0ex)$) {#2};}

\newcommand\RowTitle[2]{%
\node[title,left=6.3cm of mat#1,anchor=west]
  at (mat#1.north west)
  {#2};
}

\begin{document}

\begin{tikzpicture}[node distance=0pt and 0.5cm]

  \matrix[table] (mat11) { & & |[fill=gray]| & |[fill=gray]| & & & |[fill=gray]| \\ };

  \foreach \x/\y in {1/$0$,
                     2/$\ldots$,
                     3/$h-1$,
                     4/$h$,
                     5/$h+1$,
                     6/$\ldots$,
                     7/$b$}
  { \SlText{11-1-\x}{\y} }

  \foreach \x/\y in {1/$0$,
                     2/$\epsilon$,
                     3/$(h-2)\epsilon$,
                     4/$(h-1)\epsilon$,
                     5/$h\epsilon$,
                     6/$(h+1)\epsilon$,
                     7/$\xi\epsilon$}
    { \SIundertext{11-1-\x}{\y} }
    \node[my bottom text] at ($(mat11-1-7.south east)-(0,1.5ex)$) { $(\xi+1)\epsilon$ };

  \node[my top text,anchor=base east]    at ($(mat11-1-1.north west)-(2ex,0)+(0,1.0ex)$) {Bin};
  \node[my bottom text,anchor=base east] at ($(mat11-1-1.south west)-(2ex,0)-(0,2.0ex)$) {Time};
  \node[title,anchor=east]          at ($(mat11-1-1.west)-(2cm,0)$) {Coverage};

\end{tikzpicture}
\end{document}

enter image description here

I've made a couple of changes. I would suggest that you create names for your own styles that help convey what they're for: such as my top text vs. textto. Also, instead of writing \SlText or \SIundertext multiple times, you can use a \foreach loop to iterate over only the positions you want paired up with their text. (Also, it's potentially a bit confusing to write \SI... for a macro not connected with the siunitx package.) I used minimum width=1.5cm to enlarge the nodes which make up your time line.

I used the calc library to help position text above and below the nodes in the matrix. Generally, the call to the TikZ libraries should occur in the preamble.

UPDATE FOR BROKEN TIME LINE

I've modified the code slightly to give the impression of a broken line at the points of ellipsis:

\documentclass{article}
\usepackage{xcolor,array}
\usepackage{tikz}
\usetikzlibrary{matrix,positioning}
\usetikzlibrary{calc}
\usetikzlibrary{decorations.pathmorphing}

\tikzset
  { 
    table/.style={matrix of nodes,
                  row sep=-\pgflinewidth,
                  column sep=-\pgflinewidth,
                  nodes={rectangle,
                         draw=black,
                         text width=2ex,
                         align=center,
                         minimum width=1.5cm
                        },
                  text depth=0.25ex,
                  text height=1ex,
                  nodes in empty cells
                 },
    texto/.style={font=\footnotesize\sffamily},
    title/.style={font=\small\sffamily},
    my top text/.style={font=\small\sffamily},
    my bottom text/.style={font=\sffamily\footnotesize}
  }

\newcommand\CellText[2]{%
  \node[texto,left=of mat#1,anchor=east]
  at (mat#1.west)
  {#2};
}

\newcommand\SlText[2]{\node[my top text,anchor=base] at ($(mat#1.north)+(0,1.0ex)$) {#2};}
\newcommand\SIundertext[2]{\node[my bottom text,anchor=base] at ($(mat#1.south west)-(0,2.0ex)$) {#2};}

\newcommand\RowTitle[2]{%
\node[title,left=6.3cm of mat#1,anchor=west]
  at (mat#1.north west)
  {#2};
}

\begin{document}

\begin{tikzpicture}[node distance=0pt and 0.5cm]

  \matrix[table] (mat11) { & |[draw=none,alias=gap A]| & |[fill=gray]| & |[fill=gray]| & & |[draw=none,alias=gap B]| & |[fill=gray]| \\ };

  \foreach \x/\y in {1/$0$,
                     3/$h-1$,
                     4/$h$,
                     5/$h+1$,
                     7/$b$}
  { \SlText{11-1-\x}{\y} }

  \foreach \x/\y in {1/$0$,
                     2/$\epsilon$,
                     3/$(h-2)\epsilon$,
                     4/$(h-1)\epsilon$,
                     5/$h\epsilon$,
                     6/$(h+1)\epsilon$,
                     7/$\xi\epsilon$}
    { \SIundertext{11-1-\x}{\y} }
    \node at (mat11-1-2.center) {$\ldots$};
    \node at (mat11-1-6.center) {$\ldots$};
    \node[my bottom text] at ($(mat11-1-7.south east)-(0,1.5ex)$) { $(\xi+1)\epsilon$ };

  %% create ragged edges for ellipsis in time line
  \coordinate (intrusion for box)     at (2.75ex,   0  );
  \coordinate (vertical border adj)   at (  0  , 0.2pt);
  \coordinate (horizontal border adj) at (0.2pt,   0  );

  \foreach \x in {A,B}{
  \draw ($(gap \x.south west)+(intrusion for box)+(vertical border adj)$)     -- 
        ($(gap \x.south west)+(horizontal border adj)+(vertical border adj)$) --
        ($(gap \x.north west)+(horizontal border adj)-(vertical border adj)$) --
        ($(gap \x.north west)+(intrusion for box)-(vertical border adj)$);
  %      \draw [decorate,decoration={random steps,segment length=1pt,amplitude=0.5pt}]                                                                                                                      
  \draw [decorate,decoration={zigzag,segment length=4pt,amplitude=2pt}]                                                                                                                      
        ($(gap \x.north west)+(intrusion for box)-(vertical border adj)$) --
        ($(gap \x.south west)+(intrusion for box)+(vertical border adj)$);

  \draw ($(gap \x.south east)-(intrusion for box)+(vertical border adj)$)     -- 
        ($(gap \x.south east)-(horizontal border adj)+(vertical border adj)$) --
        ($(gap \x.north east)-(horizontal border adj)-(vertical border adj)$) --
        ($(gap \x.north east)-(intrusion for box)-(vertical border adj)$);
  \draw [decorate,decoration={zigzag,segment length=4pt,amplitude=2pt}]                                                                                                                      
        ($(gap \x.north east)-(intrusion for box)-(vertical border adj)$) --
        ($(gap \x.south east)-(intrusion for box)+(vertical border adj)$);
  }

  \node[my top text,anchor=base east]    at ($(mat11-1-1.north west)-(2ex,0)+(0,1ex)$) {Bin};
  \node[my bottom text,anchor=base east] at ($(mat11-1-1.south west)-(2ex,0)-(0,2.0ex)$) {Time};
  \node[title,anchor=east]          at ($(mat11-1-1.west)-(2cm,0)$) {Coverage};

\end{tikzpicture}
\end{document}

which produces

enter image description here

Not particularly eligant, and I'm pretty sure this is not quite the effect that you want. I'll work on it some more.

A.Ellett
  • 50,533
  • You're a wizard, it's beautiful! I don't suppose you know of any way to create a 'broken table' sort of effect, where the ellipses are, or another way to make it more obvious that the time is broken up? (should this go as a separate question?) – homebrand Sep 22 '13 at 03:27
  • @homebrand That should probably go in another question. I'm pretty new to TikZ myself. It's been a bumpy ride, but I'm getting to like it. Nevertheless, I'll think about and see what I can come up with. Probably something from the decoration library. – A.Ellett Sep 22 '13 at 03:35
  • 1
    @homebrand Check out the answer to Torn page effect. You shouldn't need the framed package. But look at how @JLDiaz defines the torn page decoration. – A.Ellett Sep 22 '13 at 03:40
  • 1
    @homebrand I've posted something that might be like what you want. Let me know. – A.Ellett Sep 22 '13 at 04:09
  • @homebrand I just noticed that I forgot to align the text above and below the timeline along their baseline. I've modified the examples to include this (since it is part of what you were asking for). – A.Ellett Sep 22 '13 at 04:40
  • That's great, exactly what I was looking for! Couple of extra small things edited into original question. – homebrand Sep 22 '13 at 05:18
  • @homebrand Your follow up should definitely be posted as its own new question. – A.Ellett Sep 22 '13 at 05:22