4

I trying to make a report containing colored spheres that should be wrapped in a command and updated dynamically. I have defined af colored sphere that receives a color, a value and a text. The color is determied from a value and I use a series of ifthens to make the selection. The problem is that the I cannot make the sphere accept the string with the color reference.

\documentclass[10pt]{article}
\usepackage[a4paper,margin=2.54cm,bmargin=2.04cm,headheight=2.54cm,headsep=0.5cm]{geometry}

\usepackage{tikz}
\usetikzlibrary{calc,shapes,positioning}
\usepackage{eso-pic}
\usepackage{xcolor}
\usepackage{calc}
\usepackage{ifthen}
\usepackage{xparse}
\usepackage{fp}
\usepackage{pgfplots}
\pgfplotsset{compat=newest,width=4cm}
\usepgfplotslibrary{patchplots,polar}
\usepackage[many]{tcolorbox}
\usepackage[absolute]{textpos}

\definecolor{newgreen}{RGB}{173,194,0}%
\definecolor{neworange}{RGB}{217,109,0}% 
\definecolor{newyellow}{RGB}{239,186,0}% 
\definecolor{newred}{RGB}{180,30,10}% 
\definecolor{newgrey}{RGB}{77,77,77}% 


\begin{document}

%%% Here we make colored sphere %%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newcommand{\gradientcircle}[3]{%
\pgfdeclareradialshading{ballshading}%
{\pgfpoint{-10bp}{10bp}}{%
    color(0bp)=(#1!45!white);% 
    color(9bp)=(#1!75!white);%
    color(18bp)=(#1!70!black);% 
    color(25bp)=(#1!50!black);%
    color(50bp)=(#1!15!black)}%
\begin{tikzpicture}%
\pgfpathcircle{\pgfpoint{0cm}{0cm}}{1.25cm}%
\pgfshadepath{ballshading}{280}%
\pgfusepath{}%
\node{\textbf{\textcolor{newgrey!5!white}{\Huge#2}}};%
\end{tikzpicture}\par\smallskip%
{\scriptsize #3}%
}%


%%% Here we make the color selection %%%%%%%%%%%%%%%%%%%%%%%

\def\thresholdi{50}
\def\thresholdii{75}
\def\thresholdiii{90}

\newcommand{\TestColor}[1]{%
\ifthenelse{\NOT#1=0}{%
    \ifthenelse{#1>\thresholdi}{%
        \ifthenelse{#1>\thresholdii}{%
            \ifthenelse{#1>\thresholdiii}{newgreen%
            }{newyellow}%
        }{neworange}%
    }{newred}%
}{newgrey}%
}   


%%% Here we define headers and more %%%%%%%%%%%%%%%%%%%%%%%%

\def\statusitext  {Text 1}
\def\statusiitext {Text 2}
\def\statusiiitext{Text 3}
\def\statusivtext {Text 4}
\def\statusvtext  {Text 5}


%%% Here we get the current KPI value %%%%%%%%%%%%%%%%%%%%%%

\def\testi{49}
\def\testii{74}
\def\testiii{85}
\def\testiv{96}
\def\testv{0}


%%% Here we make the reporting balls dynamics %%%%%%%%%%%%%%

\newcommand{\statusi}{\gradientcircle{blue}{\testi}{\statusitext}}
\newcommand{\statusii}{\gradientcircle{\TestColor{\testii}}{\testi}{\statusiitext}}

%\newcommand{\statusii} {\gradientcircle{\TestColor{\testii}}{\testii}{\statusiitext}}
%\newcommand{\statusiii}{\gradientcircle{\TestColor{\testiii}}{\testiii}{\statusiiitext}}
%\newcommand{\statusiv} {\gradientcircle{\TestColor{\testiv}}{\testiv}{\statusivtext}}
%\newcommand{\statusv}  {\gradientcircle{\TestColor{\testi}}{\testv}{\statusvtext}}


% Here we test the color selection %%%%%%%%%%%%%%%%%%%%%%%%%

\testi{} yields \TestColor{\testi} \par
\testii{} yields \TestColor{\testii} \par
\testiii{} yields \TestColor{\testiii} \par
\testiv{} yields \TestColor{\testiv} \par
\testv{} yields \TestColor{\testv} \par


% Here we test the colored spheres %%%%%%%%%%%%%%%%%%%%%%%%%

\vskip 24pt
Hard code color, value and text

\gradientcircle{black}{123}{Test}


\vskip 24pt
Hard code color, dynamic value and text

\statusi


% Here is the problem %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\vskip 24pt
Dynamic color, value and text

\statusii

\end{document}

1 Answer 1

1

I think the easiest way to do this is probably to define a colour newcol, say, which you then set appropriately. This avoids the problems caused by trying to deal with the colour setting while actually testing.

Minimising the example a bit:

\documentclass{article}
\usepackage{tikz}
\usepackage{ifthen}
\definecolor{newgreen}{RGB}{173,194,0}
\definecolor{neworange}{RGB}{217,109,0}
\definecolor{newyellow}{RGB}{239,186,0}
\definecolor{newred}{RGB}{180,30,10}
\definecolor{newgrey}{RGB}{77,77,77}
\colorlet{newcol}{black}
\begin{document}
%%% Here we make colored sphere %%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand{\gradientcircle}[3]{%
  \pgfdeclareradialshading{ballshading}%
  {\pgfpoint{-10bp}{10bp}}{%
    color(0bp)=(#1!45!white);%
    color(9bp)=(#1!75!white);%
    color(18bp)=(#1!70!black);%
    color(25bp)=(#1!50!black);%
    color(50bp)=(#1!15!black)}%
  \begin{tikzpicture}%
    \pgfpathcircle{\pgfpoint{0cm}{0cm}}{1.25cm}%
    \pgfshadepath{ballshading}{280}%
    \pgfusepath{}%
    \node{\textbf{\textcolor{newgrey!5!white}{\Huge#2}}};%
  \end{tikzpicture}\par\smallskip%
  {\scriptsize #3}%
}
\def\thresholdi{50}
\def\thresholdii{75}
\def\thresholdiii{90}
\newcommand{\TestColor}[1]{%
  \ifthenelse{\NOT#1=0}{%
    \ifthenelse{#1>\thresholdi}{%
      \ifthenelse{#1>\thresholdii}{%
        \ifthenelse{#1>\thresholdiii}{%
          \colorlet{newcol}{newgreen}%
        }{%
          \colorlet{newcol}{newyellow}%
        }%
      }{%
        \colorlet{newcol}{neworange}%
      }%
    }{%
      \colorlet{newcol}{newred}%
    }%
  }{%
    \colorlet{newcol}{newgrey}%
  }%
}
\def\statusitext  {Text 1}
\def\statusiitext {Text 2}
\def\testi{49}
\def\testii{74}
\def\testiii{85}
\def\testiv{96}
\def\testv{0}
\newcommand{\statusi}{\gradientcircle{blue}{\testi}{\statusitext}}
\newcommand{\statusii}{\TestColor{\testii}\gradientcircle{newcol}{\testi}{\statusiitext}}
\testi{} yields \TestColor{\testi} \par
\testii{} yields \TestColor{\testii} \par
\testiii{} yields \TestColor{\testiii} \par
\testiv{} yields \TestColor{\testiv} \par
\testv{} yields \TestColor{\testv} \par

\vskip 24pt
Hard code color, value and text

\gradientcircle{black}{123}{Test}

\vskip 24pt
Hard code color, dynamic value and text

\statusi

\vskip 24pt
Dynamic color, value and text

\statusii

\end{document}

colour selection

There are, however, easier ways to do the testing than using ifthen. You could, for example, use PGF/TikZ itself to handle this stuff since you are loading that anyway. (But I'd be more likely to use the TeX stuff, I guess. I've never liked the clumsiness of the LaTeX equivalents, although I guess they are safer.)

3
  • Thanks for the speedy response. It seems like a good solution. I have not had the chance to do a proper test yet so I will get back on that part. My main concern is to make a robust solution as I will be using colored figures at various places in my report. Also I have not found a good alternative to using the ifthen package, but it seems to be allright for this case. I think an alternative could be along the lines of a SQL "case when" structure.
    – Jesper
    May 13, 2016 at 5:32
  • 1
    @Jesper I don't think there's actually any reason not to use ifthen if it works for you. Sometimes people say it is deprecated or obsolete, but that isn't true as far as I can tell. There are just newer things people find easier to use.
    – cfr
    May 13, 2016 at 8:00
  • Sorry for the late response - I have been on vacation hence "off computer". I have now tested the solution that you suggest and it works fine for my report. Also, I will stick with the ifthen package, which yields the desired results.
    – Jesper
    May 17, 2016 at 12:59

You must log in to answer this question.

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