7

I want to create a series of rectangles, each with a different shade. The shade varies from white to black. I want to make the white (first) rectangle visible by drawing its border.

My first step is to draw all the rectangles, without any conditional code:

\documentclass{standalone}
\usepackage[rgb]{xcolor}
\usepackage{tikz}
\usetikzlibrary{chains}
\begin{document}
  \begin{tikzpicture}[start chain=chroma going below,
              node distance=2mm,
              every node/.style={shape=rectangle,minimum size=1cm},
              ]
    \foreach \n [evaluate=\n as \value using 1-\n*0.125] in {0,...,8}
    {
      \definecolor{tmpc}{Hsb}{0,0,\value}
      \draw node[on chain,fill=tmpc] {};
    }
  \end{tikzpicture}
\end{document}

I tried to replace the foreach code with this:

    {
      \definecolor{tmpc}{Hsb}{0,0,\value}
      \draw node[on chain,fill=tmpc] {}
      \ifnum\n=0
        (\tikzlastnode) [late options={draw}] % no effect
        (\tikzlastnode.east) [draw] -- ++(1cm,0) % drawn correctly
      \fi
      ; % ends the path
    }

Adding draw to the node options directly works. Only the late options don't behave like I expect them to do - maybe I'm not understanding something here? I have added code to see if the ifnum code is actually executed, and it is indeed.

Is there a class of options that don't work as late options?

1

2 Answers 2

4

A slightly different way is described in the following code. Note that you don't really need xcolor for this. Two tikz pictures are drawn, one using xcolor, the other using the basic commands in tikz. I drew the chain horizontally to save on space. I also added a macro that let's you change the number of nodes.

\documentclass{minimal}

\usepackage[rgb]{xcolor}
\usepackage{tikz}
\usetikzlibrary{chains}


\begin{document}

%with xcolor
\begin{tikzpicture}[start chain=chroma going right,
    node distance = 2mm,
    every node/.style ={shape=rectangle,minimum size =1cm,on chain}]

\pgfmathsetmacro{\nbnodes}{8}
\pgfmathsetmacro{\factor}{1/\nbnodes}

\foreach \n [evaluate=\n as \value using 1-\factor*\n] in {0,...,\nbnodes}{

    \pgfmathsetmacro{\bordershade}{ifthenelse(\n==0,100,0)}

    \definecolor{tmpc}{Hsb}{0,0,\value}
    \node[draw=black!\bordershade,fill=tmpc] {};
}
\end{tikzpicture}


%without xcolor
\begin{tikzpicture}[start chain=chroma going right,
    node distance = 2mm,
    every node/.style ={shape=rectangle,minimum size =1cm,on chain}]

\pgfmathsetmacro{\nbnodes}{8}
\pgfmathsetmacro{\factor}{100/\nbnodes}

\foreach \n [evaluate=\n as \shade using \factor*\n] in {0,...,\nbnodes}{

    \pgfmathsetmacro{\bordershade}{ifthenelse(\n==0,100,0)}

    \node[draw=black!\bordershade,fill=black!\shade] {};
}
\end{tikzpicture}

\end{document}

The output is

shading

1
  • Thanks for the pgfsetmacro example, this way I don't need two nearly equal node commands and don't need to draw a rectangle later. I'll stick with xcolor, though, because I want to specify colors in the Hsv model later.
    – Christoph
    May 20, 2011 at 16:30
4

I believe the draw option won't work as a late option: The pgfmanual says:

Most of these options will have no effect since you cannot change the appearance of the node

This means things like fill, draw, red, opacity etc. won't have an effect, while things like label, alias, on chain etc. will.

To achieve your desired result, I would just draw a rectangle around the node, instead of using the draw option:

\documentclass{article}
\usepackage[rgb]{xcolor}
\usepackage{tikz}
\usetikzlibrary{chains}
\begin{document}
  \begin{tikzpicture}[start chain=chroma going below,
              node distance=2mm,
              every node/.style={shape=rectangle,minimum size=1cm},
              ]
    \foreach \n [evaluate=\n as \value using 1-\n*0.125] in {0,...,8}
    {
      \definecolor{tmpc}{Hsb}{0,0,\value}
      \draw node[on chain,fill=tmpc] {}
      \ifnum\n=0
        (\tikzlastnode.north east) rectangle (\tikzlastnode.south west)
      \fi
      ; % ends the path
    }

  \end{tikzpicture}
\end{document}

coloured rectangles

2
  • 1
    +1 But you need to compensate for the outer sep I believe. The anchors do not lie on the normal node border but \pgfkeysvalueof{/pgf/outer xsep} or \pgfkeysvalueof{/pgf/outer ysep} away from them (usually .5\pgflinewidth) so that arrows to the node stop at the line not in the middle of the line. Setting outer sep=0pt for the node in the first place would make things much easier. May 20, 2011 at 14:28
  • 1
    Your reference to the manual is a good hint. However, I accepted Frédéric's answer, because it works on the node and does not add a rectangle later.
    – Christoph
    May 20, 2011 at 16:27

You must log in to answer this question.

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