1

While following some company's graphic guidelines, I tried to make a custom tabular using tikz.

Custom tabular with tikz

Here is the MWE:

\documentclass[11pt,a4paper]{article}
\usepackage[latin1]{inputenc}

\usepackage{xcolor}
\definecolor{CustomBlue}{RGB}{13,88,129}
\definecolor{CustomBlue2}{RGB}{90,111,131}

\usepackage{tikz}
\usetikzlibrary{positioning}

\begin{document}
    \begin{table}[h]
        \centering
        \newcommand{\filler}[1]{
            \coordinate[xshift=.5cm] (sw) at (#1.south west);
            \coordinate[xshift=-0.35cm, yshift=-1pt] (1) at (#1.south east);
            \filldraw[white, ultra thin, transform canvas={yshift=0.5pt}] (#1.south east) -- (sw) -- ++(0,-1pt) -- (1) -- ++(0,-1pt) -- ++(0.35,0) --cycle;
        }
        \tikzset{header/.style={draw, fill, rectangle, color=CustomBlue, text=white, minimum width=3cm, minimum height=.5cm, text width=3.8cm, align=left}}
        \tikzset{table/.style={draw, fill, rectangle, color=#1, text=black, minimum width=3cm,text width=3.8cm, align = left},
            table/.default={CustomBlue!20}}
        \begin{tikzpicture}
        \node[header] (A1) {\begin{tabular}{l}
            \textbf{Some header}
            \end{tabular}};
        \node[table=CustomBlue2!70, text=white, below=0 of A1](A2) {
            \begin{tabular}{l}
            Some item \\
            Another item
            \end{tabular}
        };
        \filler{A1}

        \node[table=CustomBlue2!70, text= white, below=0 of A2] (A3) {
            \begin{tabular}{l}
            A total
            \end{tabular}
        };
        \filler{A2}

        \node[header, right= .15cm of A1] (B1) {\begin{tabular}{l}
            \textbf{Another header}
            \end{tabular}};
        \node[table, below=0 of B1] (B2) {
            \begin{tabular}{l}
            Some value \\
            Some other value
            \end{tabular}
        };
        \filler{B1}
        \node[table, below=0 of B2] (B3) {
            \begin{tabular}{l}
            ~
            \end{tabular}
        };
        \filler{B2}

        \node[header, right= .15cm of B1] (C1) {
            \bfseries
            \begin{tabular}{l}
            Last header
            \end{tabular}
        };
        \node[table, below=0 of C1] (C2) {
            \begin{tabular}{l}
            Almost the last item\\
            The last one
            \end{tabular}
        };
        \filler{C1}
        \node[table, below=0 of C2] (C3) {
            \begin{tabular}{l}
            Oh, forgot that one
            \end{tabular}
        };
        \filler{C2}

        \end{tikzpicture}
    \end{table}
\end{document}

That code is somewhat inelegant and long (not really reusable several times in a document). I'm trying to make a custom tabular environment which would basically look like:

\begin{customTabular}{l|l|l}
    Some header & Another header & Last header\\
    \customLine\\
        Some item & Some value & Almost the last item\\
    Another item & Some other value & The last one\\
    \customLine \\
    A total & & Oh, forgot that one
\end{customTabular}

Any hint on how I may do that? (I'm not really asking for a full code, but rather guidelines). Many thanks!

0

2 Answers 2

2

Some more evolved way (also using matrix), perhaps with some more work can be made into a command or an environment.

Some key aspects:

  • Uses the nodes-families tikz library (from user @Qrrbrbirlbel) to ensure all nodes from the same column have the same width and from the same row have the same height (like it's done here)

  • Uses backgrounds library to draw the bakgrounds.

  • Uses pbox to make the paragraphs text cells.

  • If the \tikzsets can be made to work within the \foreaches it will be fairly easy to make a command out of this.

  • The built in styles column <num> don't work to set up the Minimum Width node family, that's why it has to be given explicitly (issue is brought up in the previous linked question).

MWE

\documentclass{standalone}

\usepackage{tikz,pbox}
\usetikzlibrary{matrix,backgrounds,nodes-families}

\definecolor{CustomBlue}{RGB}{13,88,129}
\definecolor{CustomBlue2}{RGB}{90,111,131}

\tikzset{%
    hline/.style={white, thick, shorten >=10pt},
    vline/.style={white, ultra thick}
}

\begin{document}
  \begin{tikzpicture}
    \def\nrows{3}\def\ncols{3}
    %\foreach \i in{1,...,\nrows}{\tikzset{row \i/.style={Minimum Height=r\i,Text Height=th\i,Text Depth=td\i}}}; % This does not work (some expansion issue maybe)
    %\foreach \i in {1,...,\ncols}{\tikzset{col \i/.style={Minimum Width=c\i}}}; % This does not work (some expansion issue maybe)
    \tikzset{col 1/.style={Minimum Width=c1}}
    \tikzset{col 2/.style={Minimum Width=c2}}
    \tikzset{col 3/.style={Minimum Width=c3}}
    \tikzset{row 1/.style={Minimum Height=r1,Text Height=th1,Text Depth=td1}}
    \tikzset{row 2/.style={Minimum Height=r2,Text Height=th2,Text Depth=td2}}
    \tikzset{row 3/.style={Minimum Height=r3,Text Height=th3,Text Depth=td3}}
    \matrix (M) [matrix of nodes, nodes in empty cells,
    inner sep=0pt,
    nodes={text=white, inner sep=1ex, font=\bfseries}]{
    |[col 1]| Some header & |[col 2]| Another header & |[col 3]| Last header\\
    |[col 1]| \pbox{6cm}{Some item \\ Another item} & |[col 2]| \pbox{6cm}{Some value \\ Some other value} & |[col 3]| \pbox{6cm}{Almost the last item \\ The last one} \\
    |[col 1]| A total & |[col 2]| & |[col 3]| Oh, forgot that one\\
    };
    \pgfmathparse{\nrows-1}
    \foreach \i in {1,...,\pgfmathresult} \foreach \j in {1,...,\ncols} \draw[hline] (M-\i-\j.south east) ++(0,-\pgflinewidth) -- ++(-10pt,0) (M-\i-\j.south east) -- (M-\i-\j.south west);
    \pgfmathparse{\ncols-1}
    \foreach \j in {1,...,\pgfmathresult} \draw[vline] (M-1-\j.north east) -- (M-\nrows-\j.south east);
    \begin{scope}[on background layer]
      \fill[CustomBlue!20] (M.north west) rectangle (M.south east);
      \fill[CustomBlue2!70] (M.north west) rectangle (M-\nrows-1.south east);
      \fill[CustomBlue] (M.north west) rectangle (M-1-\ncols.south east-|M.north east);
    \end{scope}
  \end{tikzpicture}
\end{document}

enter image description here

1
  • That's exactly what I was looking for, some small tweaks and it will be perfect. Many thanks!
    – MiniBN
    Jan 4, 2017 at 8:39
4

Just an starting point:

\documentclass[tikz,border=2mm]{standalone}
\usetikzlibrary{positioning, matrix}

\begin{document}
\begin{tikzpicture}[mynode/.style={minimum width=4cm, minimum height=6mm, 
    outer sep=0pt, text width=3.5cm, align=left,    fill=blue!30, anchor=center},
    header/.style={mynode, fill=blue!30!black, text=white, font=\bfseries},
    firstcol/.style={mynode, fill=black!30, text=white} ]

    \matrix (A) [matrix of nodes, column sep=2mm, row sep=0pt,
        nodes in empty cells,
        nodes=mynode,
        row 1/.style={nodes=header},
        column 1/.style={nodes=firstcol},
        row 1 column 1/.style={nodes=header}]
        {Some header & Another header & Last header \\
        Some item & Some value & Almost the last item \\ 
        Another item & Some other value & The last one \\ 
        A total &  & Oh, forgot that one \\ };

    \foreach \i in {1,...,3}{
        \draw[line width=1mm, white, shorten >=5mm] (A-1-\i.south east) --  (A-1-\i.south west);    
        \draw[line width=1mm, white, shorten >=5mm] (A-4-\i.north east) --  (A-4-\i.north west);    
        }
\end{tikzpicture}
\end{document}

enter image description here

You must log in to answer this question.

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