How to create a table with fixed-width cells and use cellcolor and multicolumn to create time bars? Or: How to substitute ganttbar with tabular?

Failing to combine a gantt chart with a table I now try to avoid the gantt chart by just using a tabular environment. However I like to keep some neat features of the -package and I'm facing some problems.

The idea

I'm creating a table with a column of row names. Then are following 24 columns of exactly equal width. In the header I use two times multicolumns of 12 columns each to get the years 2017 and 2018. Below there are 8 multicolumns of 3 columns each to model the quarters of each year. Finally I'm trying to use cellcolor to get a kind of timebar spanning a certain amount of months. It should look like this:

I included one timebar (macro see below) which consists of 6 months which are empty, 12 months which are filled with gray and again 6 empty months.

\timebar{title}{6}{12}{6}


First problem

As my quarters all have the same width I'm actually exptecting the following MWE to work as intended. It shows different timebars with the same number of months, but shifted. But as you can see, it's mess.

\documentclass{article}

\usepackage{xcolor}
\usepackage{booktabs,array}

\newcolumntype{C}{>{\centering}m{0.03\textwidth}}

\usepackage{colortbl}
\newcommand{\Year}[1]{  \multicolumn{12}{c|}{#1} }
\newcommand{\Quarter}[1]{\multicolumn{3}{C|}{#1}}
\newcommand{\FourQuarters}{\Quarter{I} & \Quarter{II} & \Quarter{III} & \Quarter{IV} }
\newcommand{\timebar}[4]{ #1 & \multicolumn{ #2 }{c}{} & \multicolumn{#3}{c}{{\cellcolor{black!20!white}}} & \multicolumn{#4}{c|}{}  }

\begin{document}

\section{sectiontitle}\label{sec:sectiontitle}

\begin{table}[h]
\caption{table}
\centering
\begin{tabular}{c | cccccccccccc | cccccccccccc | }
\toprule
\multicolumn{1}{l|}{Title} & \Year{2017} & \Year{2018} \\
\multicolumn{1}{l|}{Subtitle} & \FourQuarters & \FourQuarters \\
\hline
\timebar{A}{1}{12}{11} \\
\timebar{A}{2}{12}{10} \\
\timebar{A}{3}{12}{9} \\
\timebar{A}{4}{12}{8} \\
\timebar{A}{5}{12}{7} \\
\timebar{A}{6}{12}{6} \\
\timebar{A}{7}{12}{5} \\
\timebar{A}{8}{12}{4} \\
\timebar{A}{9}{12}{3} \\
\timebar{A}{10}{12}{2} \\
\timebar{A}{11}{12}{1} \\
\timebar{A}{1}{12}{11} \\
\bottomrule
\end{tabular}
\end{table}

\end{document}


Every bar should be shifted by one month in every row, but have the same length. That's what I get:

Why is that so? How can I fix that?

Second problem

My plan is to imitate the ganttbar package, which offers a bar like:

\ganttbar{Title}{7}{22} %\\ Title, First month, last month


My new timebar command looks as follows:

\timebar{Title}{6}{15}{3} %\\ Title, number months before timebar,
%\\        number months of timebar,
%\\        number months after timebar


To achieve the same format with my timebar like in the ganttbar I would need to do some simple calculations in my macro:

\newcommand{\timebar}[4]{ \ref{#1} & \nameref{#1}
& \multicolumn{#2 % should be Startmonth - 1
}{c}{}
& \multicolumn{#3 % should be Endmonth - Startmonth
}{c}{{\cellcolor{black!20!white}}}
& \multicolumn{#4 % should be Totalmonths - Endmonth + 1
}{c|}{}  }


So externally I want two numeric arguments:

• #2 - first month of bar
• #3 - last month of bar

Internally the macro needs three arguments:

• #2 - 1 - number of cells of first multicolumn
• #3 - #2 - number of cells of second multicolumn
• 24 - #3 + 1 - number of cells of third multicolumn

Further the cases \timebar{A}{0}{12}{12} and \timebar{A}{12}{12}{0} are not possible, as there is an alignment tab too much. Is there an easy solution?

How can I do that calculations? So finally my timebar has the same arguments as the ganttbar above?

For reference: the gantt chart

This is how the gantt chart would look like:

\documentclass{scrreprt}

\usepackage[top=25mm, bottom=20mm, left=20mm, right=20mm, foot=20mm]{geometry}
\usepackage{booktabs}

\usepackage{translator}
\usepackage{pgfgantt}

\ganttset{
vgrid = dotted,
hgrid = dotted,
newline shortcut=true,
%
y unit title = 15pt,
title height = 1,
y unit chart = 15pt,
x unit=0.014\textwidth,
%
canvas/.style={
shape=rectangle,
draw=black,
line width = 0.4pt,
},
group peaks tip position=0,
group label node/.append style={align=right},
%
bar label node/.append style={align=right},
bar/.append style={fill=gray!20!white},
bar height=0.3,
bar top shift=0.3,
group top shift=0.5,
%
group peaks width=2,
%
milestone left shift=-1,
milestone right shift=2}

\begin{document}
\begin{table}[h]
\setlength{\tabcolsep}{0pt}
\caption{my gantt chartt}
\label{tab:gantt}
\centering
\begin{tabular}{@{}c@{}}
\toprule
\begin{ganttchart}{1}{24}
\gantttitle[]{2017}{12} \gantttitle[]{2018}{12}  \\
\gantttitle{I}{3}\gantttitle{II}{3}\gantttitle{III}{3}\gantttitle{IV}{3}
\gantttitle{I}{3}\gantttitle{II}{3}\gantttitle{III}{3}\gantttitle{IV}{3} \\
\ganttbar{A}{1}{12}\\
\ganttbar{A}{2}{13}\\
\ganttbar{A}{3}{14}\\
\ganttbar{A}{4}{15}\\
\ganttbar{A}{5}{16}\\
\ganttbar{A}{6}{17}\\
\ganttbar{A}{7}{18}\\
\ganttbar{A}{8}{19}\\
\ganttbar{A}{9}{20}\\
\ganttbar{A}{10}{21}\\
\ganttbar{A}{11}{22}\\
\ganttbar{A}{12}{23}\\
\ganttbar{A}{13}{24}
\end{ganttchart}%
\end{tabular}
\end{table}
\end{document}


This should be the final result, just without using the ganttbar package, as it lacks a lot of features I need.

This question will get a bounty as soon as possible.

• What do you want to add/subtract? As long it's only integers, use \the\numexpr Number1 + Number2 – user31729 Jun 7 '16 at 10:06
• @ChristianHupfer Basically I want my macro to have two arguments startmonth #1 and endmonth #2 which are integer numbers. But within my macro I internally actually need three arguments: #1-1, #2-#1 and 24-#2. – thewaywewalk Jun 7 '16 at 10:08
• #1 is a label name, as far as I can see from \timebar – user31729 Jun 7 '16 at 10:11
• Please edit your post and specify exactly, what the desired result should be for some example combinations of Start and Endmonth – user31729 Jun 7 '16 at 10:56
• @ChristianHupfer Though the current example shows the result I expect, if I change the numbers, nothing works anymore. And I don't know why. I'm working on it. I get back to you. Sorry. – thewaywewalk Jun 7 '16 at 13:16

A better version:

\documentclass{article}

\usepackage{xcolor}
\usepackage{booktabs}

\usepackage{colortbl}
\newcommand{\TotalMonths}{24}
\newcommand{\Year}[1]{  \multicolumn{12}{c|}{#1} }
\newcommand{\Quarter}[1]{\multicolumn{3}{c|}{#1}}
\newcommand{\FourQuarters}{\Quarter{I} & \Quarter{II} & \Quarter{III} & \Quarter{IV} }
\newcommand{\timebar}[3]{%
\ref{#1} &
\nameref{#1} &
\multicolumn{\the\numexpr#2-1}{c}{} &
\multicolumn{\the\numexpr#3-#2}{c}{{\cellcolor{black!20!white}}}
& \multicolumn{\the\numexpr\TotalMonths-#3+1}{c|}{}
}

\begin{document}

\section{sectiontitle}\label{sec:sectiontitle}

\begin{table}[h]
\caption{table}
\centering
\begin{tabular}{cc | *{12}{c} | *{12}{c} | }
\toprule
\multicolumn{2}{l|}{Title} & \Year{2017} & \Year{2018} \\
\multicolumn{2}{l|}{Subtitle} & \FourQuarters & \FourQuarters \\
\hline
\timebar{sec:sectiontitle}{7}{22} \\
\timebar{sec:sectiontitle}{3}{16} \\
\bottomrule
\end{tabular}
\end{table}

\end{document}

• I'll update soon – user31729 Jun 7 '16 at 10:15
• @thewaywewalk: The missing 1 puzzled me already. I've provided a better version. you don't need \the\numexpr for both operands – user31729 Jun 7 '16 at 10:30
• actually there is another problem: the cases where #2 = 1 and #3 = 24 - because there are too many alignment tabs. Do you have spontaneous idea? – thewaywewalk Jun 7 '16 at 10:39
• @thewaywewalk: Yes, I noted that already. Your formula is wrong ;-) – user31729 Jun 7 '16 at 10:41

With some inspiration in this answer I came up with the following solution using a loop:

\documentclass{article}
\usepackage[table]{xcolor}
\usepackage{booktabs,array,multicol}

\newcommand*\TAB{&}

\long\def\gloop #1\grepeat
{\gdef \giterate {#1\expandafter \giterate \grepeat }\giterate  }
\let\grepeat\fi

\newcounter{n}
\newcounter{m}
\newcounter{TotalMonths}

\newlength{\colwidth}
\setlength{\colwidth}{2mm}

\newcommand{\TotalMonths}{24}
\newcommand{\Year}[1]{  \multicolumn{12}{|c|}{#1}}
\newcommand{\Quarter}[1]{\multicolumn{3}{|c|}{#1}}
\newcommand{\FourQuarters}{\Quarter{I} & \Quarter{II} & \Quarter{III} & \Quarter{IV}}

\newcommand{\timebar}[3]{
\setcounter{TotalMonths}{\TotalMonths}%
\setcounter{n}{1}
\setcounter{m}{-1}
\stepcounter{TotalMonths}%
#1 & B
\gloop
\stepcounter{n}%
\stepcounter{m}%
\TAB
\ifnum #2<\value{n} \ifnum #3>\value{m}%
{\cellcolor{black!20!white}}\hspace*{\colwidth}%
\else
\hspace*{\colwidth}%
\fi
\else
\hspace*{\colwidth}%
\fi
\ifnum \value{TotalMonths}>\value{n}
\grepeat
}

\begin{document}

\begin{table}[h]
\caption{table}
\centering
\setlength{\tabcolsep}{0pt}
\begin{tabular}{ p{2cm}p{2cm} | *{12}{c}  *{12}{c} | c  }
\toprule
\multicolumn{2}{l}{Title} & \Year{2017} & \Year{2018} \\
\multicolumn{2}{l}{Subtitle} & \FourQuarters & \FourQuarters \\
\hline
\timebar{Hello World}{1}{10} \\
\timebar{Hello World}{2}{11} \\
\timebar{Hello World}{3}{12} \\
\timebar{Hello World}{4}{24} \\
\bottomrule
\end{tabular}
\end{table}

\end{document}