My quest is to make a table which looks like this:
To good thing so far: I have succeeded in making this table.
The bad thing: I cannot include this in a normal \begin{table}\end{table} environment as the boundingbox of the tabular is not seen. All text is running over the table
Hopefully somebody can solve this. Either by giving my an alternative way to create this table, or by fixing the error in my code
The code below is using stuff from other answers I have found here: rounded corners shows how to make rounded corners around a table. The problem is: I want my first row with the column heading ABOVE line with rounded corners.
My idea to solve was easy: just adjust the clipping of the tabular such that I make a rounded corner of the first column, immediately go up, and then go to the other side:
------------------------------
R-| heading cols |
|first grey col value cols |
| |
R---------------------------------
At the locations of the R's I want to add the rounded corners.
The code I came up with is quite long, I will add it here. It is stand alone. This clipping idea comes from the first link. Also, I am adding a tikzmark A because I want the clipping path to automatically connect to the bottom of the first row. That idea was inspired by this exampleadd tikznode at corner. In order to get the y coordinates of this point A, I used this idea extract y coordinate
Here is the code, which should run stand alone
\documentclass{article}
\usepackage[dvipsnames,table]{xcolor}
\usepackage{array}
\usepackage{environ}
\usepackage{blindtext}
\usepackage{tikz}
\usepackage{etex}
\usetikzlibrary{calc, tikzmark}
\definecolor{lichtgrijs}{RGB}{236,236,236}
\newcolumntype{L}{>{\columncolor{lichtgrijs}}l}
\newsavebox{\tablebox}
\NewEnviron{rndtable}[1]{%
\addtolength{\extrarowheight}{1ex}%
\savebox{\tablebox}{%
\begin{tabular}{#1}%
\BODY%
\end{tabular}}%
\begin{tikzpicture} [overlay, remember picture]
\ExtractCoordinate{$(pic cs:A)$}
\begin{scope}
\useasboundingbox;
\clip[rounded corners=1ex]
(0,-\dp\tablebox) --
(\wd\tablebox,-\dp\tablebox) --
(\wd\tablebox,\ht\tablebox)
{
[rounded corners=0ex]--
(1ex,\ht\tablebox) --
(1ex,\YCoord-\RowDepth)}--
%(1ex,\ht\tablebox-3ex)}--
(0,\YCoord-\RowDepth) --
cycle;
\node at (0,-\dp\tablebox) [anchor=south west,inner sep=0pt]{\usebox{\tablebox}};
\end{scope}
\end{tikzpicture}
}
\begin{document}
\setlength\arrayrulewidth{1.2pt}
\edef\RowDepth{\the\dimexpr\arraystretch\dimexpr.3\baselineskip\relax\relax}
\newdimen\XCoord
\newdimen\YCoord
\newcommand*{\ExtractCoordinate}[1]{\path (#1); \pgfgetlastxy{\XCoord}{\YCoord};}%
%\blindtext[10]
%\begin{table}[tbp]
% \caption{bla}
\begin{rndtable}{Llr}
\rowcolor{white}
\tikzmark{A}
\textbf{Label} & \textbf{Naam} & \textbf{Leeftijd}\\
\arrayrulecolor{lichtgrijs} \hline
GK & Paul Robinson & 45\\
LB & Lucus Radebe & 23\\
DC & Michael Duberry & 84\\
DC & Dominic Matteo & 22\\
RB & Didier Domi & 34\\
MC & David Batty & 5\\
MC & Eirik Bakke & 58\\
MC & Jody Morris & 75\\
FW & Jamie McMaster & 13\\
ST & Alan Smith & 70\\
ST & Mark Viduka & 30\\
\arrayrulecolor{lichtgrijs}\hline
\end{rndtable}
%\end{table}
%\blindtext[10]
\end{document}
This code works and generates the tabular I have just show.
HOWEVER, apparently when I include the \begin{table} the size of the table is not recognized at all. If I would put text around the table (by uncommenting blindtext and begin{table}) it is running over the table. My suspicion is that it has to to with either the overlay option or that I use the savebox. Unfortunately I am not able to solve this. It looks like this:
Who knows how I can fix this script such that I can use it properly within a table environment ?
Any hints appreciated!
Regards
Eelco
EDIT:
The suggestion by Marmot about removing the overlay and useasboundingbox works. Now at least a tabular is nicely put into the table environment.
however: a new problem arises; when I want to include two or more tables, somehow every time I run the code the tables get another position. For instance, you can do
\blindtext[1]
\begin{table}[tbp]
\caption{First table}
\begin{rndtable}{Llr}
\rowcolor{white}
\tikzmark{A}
\textbf{Label} & \textbf{Naam} & \textbf{Leeftijd}\\
\arrayrulecolor{lichtgrijs} \hline
GK & Paul Robinson & 45\\
MC & Jody Morris & 75\\
FW & Jamie McMaster & 13\\
ST & Alan Smith & 70\\
ST & Mark Viduka & 30\\
\arrayrulecolor{lichtgrijs}\hline
\end{rndtable}
\end{table}
\blindtext[1]
\begin{table}[tbp]
\caption{Another table}
\begin{rndtable}{Llr}
\rowcolor{white}
\tikzmark{A}
\textbf{Label} & \textbf{Naam} & \textbf{Leeftijd}\\
\arrayrulecolor{lichtgrijs} \hline
GK & Paul Robinson & 45\\
LB & Lucus Radebe & 23\\
DC & Michael Duberry & 84\\
MC & Jody Morris & 75\\
FW & Jamie McMaster & 13\\
ST & Alan Smith & 70\\
ST & Mark Viduka & 30\\
\arrayrulecolor{lichtgrijs}\hline
\end{rndtable}
\end{table}
\blindtext[1]
\begin{table}[tbp]
\caption{Last table}
\begin{rndtable}{Llr}
\rowcolor{white}
\tikzmark{A}
\textbf{Label} & \textbf{Naam} & \textbf{Leeftijd}\\
\arrayrulecolor{lichtgrijs} \hline
GK & Paul Robinson & 45\\
LB & Lucus Radebe & 23\\
DC & Michael Duberry & 84\\
MC & Jody Morris & 75\\
FW & Jamie McMaster & 13\\
ST & Alan Smith & 70\\
ST & Mark Viduka & 30\\
\arrayrulecolor{lichtgrijs}\hline
\end{rndtable}
\end{table}
This will indeed make three tables, each in its own environment, but they get another location every time I run the code. Also the aux file changes with every run. Probably this has to do with those global vars XCoord and YCoord I use, combined with the savebox trick. But I need those to be able to find the location of the upper row and clip it properly. So this solution I came up with is still not usable.
Anybody knows how to solve this?
EDIT2:
The suggestion by Marmot to leave out the ExtractCoordinate line does not work as I need it to get the location of the bottom of the first row. I found this example here add tikznode at corner and here extract y coordinate
If I leave out ExtractCoordinate (as suggested by Marmot), the table looks like this:
As you can see, the upper rounded corners now always is exactly half way the table. It should be at the bottom of the first row (with the title columns).
Indeed, if I leave out this line with ExtractCoordinate, it fixes the problem of the jumping tables. But then I would need an alternative way to extract the ycoordinate from my tikzmark A. Any idea?
EDIT3:
At this point I almost got the example above working: the only thing it requires is to find an alternative way to extract the y coordinate of the tikzmark, since the trick with ExtractCoordinate is messing up the tables.
But just to be complete, I have also an alternative approach for making tables like this which is based on this idea tabular with rounded corners
My code looks like this:
\documentclass{article}
\usepackage[dvipsnames,table]{xcolor}
\usepackage{array}
\usepackage{blindtext}
\usepackage{tikz}
\usepackage{etex}
\usepackage[most]{tcolorbox}
\usepackage{tabularx}
\usetikzlibrary{calc, tikzmark}
\definecolor{lichtgrijs}{RGB}{236,236,236}
\newcolumntype{L}{>{\columncolor{lichtgrijs}}l}
\newcolumntype{Y}{>{\raggedleft\arraybackslash}X}
\newtcolorbox{twocoltable}[4][]{%
tabularx*={\renewcommand{\arraystretch}{1.2}}%
{>{\columncolor{lichtgrijs}\hsize=#3\linewidth}X>{\hsize=#4\linewidth}Y},
enlarge top initially by=1.5em,
enlarge bottom finally by=0em,
enhanced,
fontupper=\footnotesize,
breakable,
colframe=lichtgrijs,
colback=white,
arc=1mm,
outer arc=1mm,
clip upper,
rightrule=0pt,
sharp corners=east,
width=1\linewidth,
overlay=%
{
\node[anchor=south east] (ycoltit) at %
([xshift=-0cm, yshift=0.0\baselineskip]frame.north east)%
{{\footnotesize\textbf{#2}}};
},
#1
}
\begin{document}
\blindtext
\begin{table}[tbp]
\caption{Last table}
\begin{twocoltable}%
{\textbf{Leeftijd}}{0.8}{0.2}
Paul Robinson & 45\\
Lucus Radebe & 23\\
Michael Duberry & 84\\
Jody Morris & 75\\
Jamie McMaster & 13\\
Alan Smith & 70\\
Mark Viduka & 30\\
\end{twocoltable}
\end{table}
\blindtext
\end{document}
and the result looks like this
The only problem is that I need to add the column titles explicitly using the overlay inside newtcolorbox, which I don't like since I fix the number of columns in the definition (in this case two columns only). But this was the only way to get the column title above the line with the rounded corners. I case somebody knows a better way of doing this, it would be great as well
EDIT4:
Ignasis answer is the best so far. Still I was trying to vary some formats of the table which I know I am going to need, such as fixing the width of the column. The example I tried look like this
\begin{table}
\centering
\begin{tikzpicture}
\matrix[mymatrix,
column 3/.style={nodes={anchor=center}},
column 4/.style={nodes={anchor=east}, text width=2cm}] (A) {
Label & Naam & Leeftijd & Length in centimeters\\
MC & Jody Morris & 75 & 174\\
FW & Jamie McMaster & 13 & 184\\
ST & Alan Smith & 70 & 150\\
ST & Mark Viduka & 30 & 190\\ };
\tableback{A}{5}{4}
\end{tikzpicture}
\caption{Shorter on}
\end{table}
The result looks like this
As you can see, the column at the east is not aligned to the right anymore, and also to first row with the title should align with the bottom of the row. Any idea how to fix this?
EDIT 5:
In parallel with the solution of Ignasis with the matrix environment I have tried to fix my first attempt using the savebox. As Marmot pointed out I need to get rid of the ExtractCoord. This is what I did. My solution now looks like this
\documentclass{article}
\usepackage[dvipsnames,table]{xcolor}
\usepackage{array}
\usepackage{environ}
\usepackage{blindtext}
\usepackage{tikz}
\usepackage{etex} % required for savebox
%\usetikzlibrary{calc, tikzmark}
\usetikzlibrary{tikzmark}
\definecolor{lichtgrijs}{RGB}{236,236,236}
\newcolumntype{L}{>{\columncolor{lichtgrijs}}l}
%\renewcommand{\tikzmark}[2][]{%
% \tikz[remember picture,overlay]\coordinate[#1](#2);%
%}
%
\NewEnviron{rndtable}[2][\tablebox]{%
\addtolength{\extrarowheight}{1ex}%
\def\locbox{#1}
\savebox{\locbox}{%
\begin{tabular}{#2}%
\BODY%
\end{tabular}}%
\begin{tikzpicture} [remember picture]
\def\radius{1mm};
\edef\RowDepth{\the\dimexpr\arraystretch\dimexpr.3\baselineskip\relax\relax}
\coordinate (southwest) at (0,-\dp\locbox);
\coordinate (southeast) at (\wd\locbox,-\dp\locbox);
\coordinate (northeast) at (\wd\locbox,\ht\locbox);
\coordinate (northwest) at (0,\ht\locbox);
\coordinate (Pt) at ([xshift=\radius]northwest);
\coordinate (A) at (pic cs:A);
\coordinate (cellborder) at ([yshift=-\RowDepth]A);
\coordinate (Pb) at (cellborder -| Pt);
\coordinate (west) at (Pb -| northwest);
\begin{scope}
\clip[rounded corners=\radius]
(southwest) --
(southeast) --
(northeast)
{
% make straight corners for the cutout
[rounded corners=0ex]--
(Pt) --
(Pb)
}--
(west) --
cycle;
\node at (0,-\dp\locbox) [anchor=south west,inner sep=0pt]{\usebox{\locbox}};
% debugging circels
%\draw[red, fill] (Pt) circle[radius=2pt];
%\draw[green, fill] (A) circle[radius=2pt];
%\draw[blue, fill] (cellborder) circle[radius=2pt];
%\draw[yellow, fill] (Pb) circle[radius=2pt];
%\draw[orange, fill] (west) circle[radius=2pt];
\end{scope}
\end{tikzpicture}
}
\begin{document}
\setlength\arrayrulewidth{1.2pt}
\blindtext[1]
\newsavebox{\tablebox}
\begin{table}[tbp]
\caption{First table}
\begin{rndtable}[\tablebox]{Llr}
\rowcolor{white}
\tikzmark{A}
\textbf{Label} & \textbf{Naam} & \textbf{Leeftijd}\\
\arrayrulecolor{lichtgrijs} \hline
GK & Paul Robinson & 45\\
MC & Jody Morris & 75\\
FW & Jamie McMaster & 13\\
ST & Alan Smith & 70\\
ST & Mark Viduka & 30\\
\arrayrulecolor{lichtgrijs}\hline
\end{rndtable}
\end{table}
\blindtext[1]
\newsavebox{\otherbox}
\begin{table}[tbp]
\caption{Second table}
\begin{rndtable}[\otherbox]{Llr}
\rowcolor{white}
\tikzmark{A}
\textbf{Label} & \textbf{Naam} & \textbf{Leeftijd}\\
\arrayrulecolor{lichtgrijs} \hline
GK & Paul Robinson & 45\\
MC & Jody Morris & 75\\
FW & Jamie McMaster & 13\\
ST & Alan Smith & 70\\
ST & Mark Viduka & 30\\
\arrayrulecolor{lichtgrijs}\hline
\end{rndtable}
\end{table}
\blindtext[1]
\end{document}
For one table this works fine again. For two tables LaTeX keeps getting two alternating solutions for the table positions: one with the two tables at one page, one with the two tables as separate pages. I think it has to do with the savebox, that why I tried to add an extra parameter such that I can define a savebox for every table. Unfortunately this does not work. If I compare the aux files of two subsequent runs of xelatex, a diff on both files will show the following output:
9,13c9,13
< \@writefile{lot}{\contentsline {table}{\numberline {2}{\ignorespaces Second table}}{1}}
< \savepicturepage{pgfid3}{1}
< \pgfsyspdfmark {pgfid3}{9192734}{33349459}
< \savepicturepage{pgfid4}{1}
< \pgfsyspdfmark {pgfid4}{8799518}{30733844}
---
> \@writefile{lot}{\contentsline {table}{\numberline {2}{\ignorespaces Second table}}{2}}
> \savepicturepage{pgfid3}{2}
> \pgfsyspdfmark {pgfid3}{9192734}{41880784}
> \savepicturepage{pgfid4}{2}
> \pgfsyspdfmark {pgfid4}{8799518}{39265169}
The third run will have an aux file equal to the first run again. If this can be solved I prefer this solution above all since it makes use of a original tabular environment. If it cannot be solved I will fall back on the matrix solution, which is a great alternative
overlay
and\useasboundingbox;
.\ExtractCoordinate{$(pic cs:A)$}
. As far as I can see it is not good for anything here. You may give a pointer to the original code (if it exists) such that others can gauge what all these things were originally good for.