13

I want to draw a node to be filled with a table containing data, and it should have (three) differently colored adjacent borders around it. Couldn't find anything in the PGF manual, on the Net, nor on this forum, so I came up with this MWE...

Nesting three tikzpicture environments feels like a BIG amateuristic kludge to me, and if not, how do I get rid of the white space in between the borders?

\documentclass[pdftex,dutch]{article}
\usepackage{babel}
\usepackage{tikz}

\begin{document}

\definecolor{lichtgrijs}{RGB}{232,232,232}
\definecolor{DE.rood}{RGB}{222,0,0}
\definecolor{DE.geel}{RGB}{255,207,0}

\begin{tikzpicture}
\node[rectangle,line width=0.5mm,draw=black] at (0,0)
{\begin{tikzpicture}
 \node[rectangle,line width=0.5mm,draw=DE.rood] at (0,0)
 {\begin{tikzpicture}
  \node[rectangle,line width=0.5mm,draw=DE.geel,fill=lichtgrijs] at (0,0) {Vliegtuig};
  \end{tikzpicture}};
 \end{tikzpicture}};
\end{tikzpicture}

\end{document}

My kludge

12

Like this?

enter image description here

\documentclass[dutch]{article}
\usepackage{babel}
\usepackage{tikz}
\usetikzlibrary{fit}

\definecolor{lichtgrijs}{RGB}{232,232,232}
\definecolor{DE.rood}{RGB}{222,0,0} % Rood in Duitse vlag
\definecolor{DE.geel}{RGB}{255,207,0} % Geel in Duitse vlag

\begin{document}
    \begin{tikzpicture}[
box/.style = {draw=#1, line width=0.5mm,inner sep=0.25mm}
                        ]
\node (n1) [box=DE.geel,
            fill=lichtgrijs, inner sep=2mm] at (0,0) {Vliegtuig};
\node (n2) [box=DE.rood, fit=(n1)] {};
\node (n3) [box=black,   fit=(n2)] {};
    \end{tikzpicture}
\end{document}

Some Notes:

  • never nest tikzpicture in tikzpicture, which may raise unexpected side effects;
  • the fit library of tikz is used to get what you want;
  • you can define node style, which merges all nodes in one, but I'd like first to know whether the illustrated result is what you're looking for :-)

addendum: here is a three-color node variation. In particular, append after command= option in a node style is used for the middle and the outer colors:

\documentclass[dutch]{article}
\usepackage{babel}
\usepackage{tikz}
\usetikzlibrary{fit}

\definecolor{lichtgrijs}{RGB}{232,232,232}
\definecolor{DE.rood}{RGB}{222,0,0} % Rood in Duitse vlag
\definecolor{DE.geel}{RGB}{255,207,0} % Geel in Duitse vlag

\begin{document}

    \begin{tikzpicture}[
tcb/.style = {% three color border
              draw=DE.geel, fill=lichtgrijs,
              line width=0.5mm,inner sep=2mm,
              append after command={\pgfextra{\let\LN\tikzlastnode
                    \node [draw=DE.rood, line width=0.5mm,
                           inner sep=0.25mm,fit=(\LN)] {};
                    \node [draw, line width=0.5mm,
                           inner sep=0.75mm,fit=(\LN)] {};
              }}}
                        ]
\node (n1) [tcb] {Vliegtuig};
    \end{tikzpicture}
\end{document}

The result is the same as before.

  • Yep, that's it! What an incredibly fast reply... – Petoetje59 Mar 3 at 19:54
  • 1
    @Zarko: Any time, Sir! ;) – Roboticist Mar 3 at 21:30
7

Just for fun:

\documentclass{standalone}% to avoid cropping
\usepackage{babel}% not needed for MWE
\usepackage{tikz}
\usetikzlibrary{calc}

\definecolor{lichtgrijs}{RGB}{232,232,232}
\definecolor{DE.rood}{RGB}{222,0,0}
\definecolor{DE.geel}{RGB}{255,207,0}

\begin{document}
\begin{tikzpicture}
\begin{scope}[line width=0.5mm]
  \node[draw=black,inner sep = 1.5mm] (n1) at (0,0) {Vliegtuig};
  \draw[DE.rood] ($(n1.south west)+(0.75mm,0.75mm)$) rectangle ($(n1.north east)+(-0.75mm,-0.75mm)$);
  \draw[DE.geel] ($(n1.south west)+(1.25mm,1.25mm)$) rectangle ($(n1.north east)+(-1.25mm,-1.25mm)$);
\end{scope}
\end{tikzpicture}
\end{document}

demo

  • Did you use another text font? P.S. Good job! – manooooh Mar 3 at 22:19
  • That's a nice answer! (+1) If you made it a pic with a tiny bit of extra effort you could make the thing rotatable, which the other answers could not (unless one wants to add rotate fit over and over). – user121799 Mar 3 at 23:24
7

Without TikZ, only \colorboxes.

I've added \usepackage{picture} to use the widths/lengths not specified in multiples of \unitlength.

I've added \usepackage{calc} for convenience, to do calculations in \setlength (you can avoid it if you use \addtolength).

I've used \makebox(\myxxxwidth, \myxxxheight){...} to specify the width and total height of the boxes.

I've calculated the width of the boxes this way:

width of the border + width of the content + width of the border

that is

width of the content + double of the width of the border

You can set the border widths as you like.

The same for heights.

I've created a new command \mybox for convenience, you can even modify it to set the border widths as a parameter/parameters, if you like.

\documentclass[pdftex,dutch]{article}
\usepackage{babel}

\usepackage{xcolor}
\usepackage{picture}% see here: https://tex.stackexchange.com/a/48238/101651
\usepackage{calc}
\newlength{\mygraywidth}
\newlength{\mygrayheight}
\newlength{\myyellowwidth}
\newlength{\myyellowheight}
\newlength{\myredwidth}
\newlength{\myredheight}
\newlength{\myblackwidth}
\newlength{\myblackheight}

\definecolor{lichtgrijs}{RGB}{232,232,232}
\definecolor{DE.rood}{RGB}{222,0,0}
\definecolor{DE.geel}{RGB}{255,207,0}

\newcommand{\mybox}[1]{%
    \setlength{\mygraywidth}{\widthof{#1}+4mm}
    \setlength{\mygrayheight}{\totalheightof{#1}+4mm}
    \setlength{\myyellowwidth}{\mygraywidth+1mm}
    \setlength{\myyellowheight}{\mygrayheight+1mm}
    \setlength{\myredwidth}{\myyellowwidth+1mm}
    \setlength{\myredheight}{\myyellowheight+1mm}
    \setlength{\myblackwidth}{\myredwidth+1mm}
    \setlength{\myblackheight}{\myredheight+1mm}
    \colorbox{black}{\makebox(\myblackwidth,\myblackheight){%
        \colorbox{DE.rood}{\makebox(\myredwidth,\myredheight){%
            \colorbox{DE.geel}{\makebox(\myyellowwidth,\myyellowheight){% 
                \colorbox{lichtgrijs}{\makebox(\mygraywidth, \mygrayheight){%
                #1}}%
            }}%
        }}%
    }}%
    }

\begin{document}

\mybox{Vliegtuig}

\vspace{4ex}

\mybox{Do you like it?}

\end{document}

enter image description here

  • Would've been the best solution... but unfortunately there appears to be no option to set the border width. – Petoetje59 Mar 3 at 21:26
  • @Petoetje59 See my renewed answer. Let me know if you like it. – CarLaTeX Mar 4 at 7:05
4

Another possibility is to use preaction to draw the node multiple times. Here I define the rainbow style that can be user as rainbow={color1,color2,...} where color1 is the most external color.

The advantage of this method is that it can be used with any shape and with arbitrary number of colors.

Note: the node should be filled to hide the inner overlapping.

\documentclass[tikz,border=7pt]{standalone}
\usetikzlibrary{shapes.symbols}
% the german colors
\definecolor{lichtgrijs}{RGB}{232,232,232}
\definecolor{DE.rood}{RGB}{222,0,0}
\definecolor{DE.geel}{RGB}{255,207,0}
% define the rainbow style
\tikzset{
  next color/.style={preaction={draw=#1,next width}},
  next width/.code={
    \pgfkeysalso{line width/.expanded={\rainbowwidth pt}}
    \pgfmathsetmacro{\rainbowwidth}{\rainbowwidth-\rainbowstep} % decrease the rainbow width
    \xdef\rainbowwidth{\rainbowwidth} % set the rainbow width global
  },
  rainbow/.style={next color/.list={#1}},
  rainbow/.prefix code={
    \edef\rainbowstep{\the\pgflinewidth}
    \foreach[count=\i]~in{#1}{} % count the number of colors
    \pgfmathsetmacro{\rainbowwidth}{\i*\rainbowstep}
  }
}

\begin{document}
\tikz
  \path
    node[line width=0.5mm,fill=lichtgrijs,rainbow={black,DE.rood,DE.geel}] at (0,0) {Vliegtuig}
    node[cloud,line width=1mm,inner sep=-4,fill=white,rainbow={red,orange,yellow,green,blue,purple}] at (3,0) {Regenbogen};
\end{document}

enter image description here

  • 2
    Very nice work! – AndréC Mar 4 at 7:51
  • 1
    For me this is the best solution here. Also because it can be rotated and so on without extra efforts. – user121799 Mar 5 at 18:40
3

You do not need a library for that, and you can make things much more automatic by just supplying the list of colors. Then it boils down to saying

\node[inner sep=8pt,line width=2pt,multicolor rectangle={DE.rood,DE.geel}] {Vliegtuig};

This strategy can be applied to other node shapes, too, if needed.

Here is the code.

\documentclass[pdftex,dutch]{article}
\usepackage{babel}
\usepackage{tikz}

\begin{document}

\definecolor{lichtgrijs}{RGB}{232,232,232}
\definecolor{DE.rood}{RGB}{222,0,0}
\definecolor{DE.geel}{RGB}{255,207,0}

\begin{tikzpicture}[multicolor rectangle/.style={draw,path picture={
\foreach \CPP [count=\YPP] in {#1}
{\draw[\CPP] ([xshift=\YPP*\pgflinewidth,yshift=\YPP*\pgflinewidth]path picture bounding box.south west)
rectangle ([xshift=-\YPP*\pgflinewidth,yshift=-\YPP*\pgflinewidth]path picture bounding box.north east); }}}]
\node[inner sep=8pt,line width=2pt,multicolor rectangle={DE.rood,DE.geel}] {Vliegtuig};
\end{tikzpicture}

\end{document}

enter image description here

In case it bugs you that you have to set the inner sep by hand, this can be taken care of at the expense of a slightly longer code.

0

I understand that "I want to draw a node to be filled with a table containing data" means "I want to type a table containing data with a colorfull background and border". For this I prefer to use tcolorbox. First option uses tcbox which adjusts the box to its contents while the second solution adjusts table size to text width unless you set some other width. borderline options allows to define extra color borders.

\documentclass{article}
\usepackage[most]{tcolorbox}
\usepackage{lmodern}
\usepackage{array, booktabs, tabularx, colortbl}

\newcolumntype{Y}{>{\raggedleft\arraybackslash}X}

\definecolor{lichtgrijs}{RGB}{232,232,232}
\definecolor{DE.rood}{RGB}{222,0,0}
\definecolor{DE.geel}{RGB}{255,207,0}

\newtcbox{mytable}[1][]{%
    enhanced,
    sharp corners,
    fonttitle=\bfseries\sffamily,
    fontupper=\normalsize\sffamily,
    colback=lichtgrijs,
    colframe=DE.geel,
    colbacktitle=white,
    coltitle=black,center title,
    borderline={.5mm}{-.5mm}{DE.rood},
    borderline={.5mm}{-1mm}{black},
    #1 }

\newtcolorbox{tctable}[1][]{%
    enhanced,
    sharp corners,
    fonttitle=\bfseries\sffamily,
    fontupper=\normalsize\sffamily,
    colback=lichtgrijs,
    colframe=DE.geel,
    colbacktitle=lichtgrijs,
    coltitle=black,
    center title,
    borderline={.5mm}{-.5mm}{DE.rood},
    borderline={.5mm}{-1mm}{black},
    tabularx={XYYYYY},
    #1
}

\begin{document}

\mytable{
\begin{tabular}{lrrrrr}
\toprule
\multicolumn{6}{c}{\bfseries My table}\\
\midrule
Red & 1000.00 & 2000.00 & 3000.00 & 4000.00 & 10000.00\\
Green & 2000.00 & 3000.00 & 4000.00 & 5000.00 & 14000.00\\
Blue & 3000.00 & 4000.00 & 5000.00 & 6000.00 & 18000.00\\
Sum & 6000.00 & 9000.00 & 12000.00 & 15000.00 & 42000.00\\
\bottomrule
\end{tabular}}

\begin{tctable}[title=My table]
Red & 1000.00 & 2000.00 & 3000.00 & 4000.00 & 10000.00\\
Green & 2000.00 & 3000.00 & 4000.00 & 5000.00 & 14000.00\\
Blue & 3000.00 & 4000.00 & 5000.00 & 6000.00 & 18000.00\\
Sum & 6000.00 & 9000.00 & 12000.00 & 15000.00 & 42000.00
\end{tctable}
\end{document}

enter image description here

  • There's an embarrassment of choices here! As usual I'll go for the shortest and simplest that does the job, and that was Zarko's code. – Petoetje59 Mar 4 at 18:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.