7

I'm trying to get TikZ to make a sort of experience bar command where I can just call it and enter a number out of say, 6, and it will return that many "filled" dots, and 6 minus that many "unfilled" dots. Problem is, something with the way the "foreach" command counts sizes makes it mess up, either by adding too many dots or not enough or not in the right spot or something (depending on what specifically I do with the index bounds)

For example:

\newcommand{\dotexp}[1]{
    \tikz{\foreach \x in {1,...,#1}
    \draw[cyan,fill=cyan] (\x/2.5,0) circle (.5ex);
    \ifnum#1<6 \foreach \y in {#1,...,6} \draw[lightgray,fill=lightgray] (\y/2.5,0) circle (.5 ex);\fi}
    }   

gives me

enter image description here

where each line is supposed to be a call for 0, 1, 2,....6 dots, in order.

Any suggestions for a fix? Maybe some way to pre-allocate the dot positioning but just change the color?

Cragfelt
  • 4,005
user151738
  • 71
  • 1

5 Answers5

12
\documentclass{article}
\usepackage{tikz}

\newcommand{\dotexp}[1]{%
  \edef\DEnum{\the#1}%
  \tikz{%
    \foreach \x in {1,...,6}{%
      \ifnum\x>\DEnum
        \edef\DEfill{lightgray}%
      \else
        \edef\DEfill{cyan}%
      \fi
      \draw[\DEfill,fill=\DEfill] (\x/2.5,0) circle (.5ex);%
    }%
  }%
}

\begin{document}
\newcount\x
\x=0
\loop
 \the\x\dotexp{\x}

 \advance \x by 1
 \ifnum\x<7
\repeat
\end{document}

enter image description here

9

Slightly different approach, with \foreach also to generate the seven variants. Output is the same as in Phelype's answer.

\documentclass{article}
\usepackage{tikz}
\newcommand{\dotexp}[1]{%
\begin{tikzpicture}
\foreach \tmpx in {0,...,5} {
  \ifnum \tmpx < #1
    \filldraw[cyan] (\tmpx/2.5,0) circle[radius=.5ex];
  \else
    \filldraw[lightgray] (\tmpx/2.5,0) circle[radius=.5ex];
  \fi
}
\end{tikzpicture}%
}
\begin{document}
\foreach \x in {0,...,6}
 { \x\ \dotexp{\x} \par }

\end{document}
Torbjørn T.
  • 206,688
7

A probably crude try with MetaPost and LuaLaTeX:

\documentclass{article}
\usepackage{luamplib}
    \everymplib{%
    input mpcolornames;
    verbatimtex \leavevmode etex;
    def dotexp(expr n, loc) =
        u := .4cm;
        label(textext(decimal n), loc);
        pickup pencircle scaled \mpdim{1ex};
        if n <= 6: 
            for i = 1 upto n: drawdot loc + (i*u, 0) withcolor Cyan; endfor;
            for i = n+1 upto 6: drawdot loc + (i*u, 0) withcolor LightGray; endfor; 
        fi
    enddef;
    beginfig(1);}
    \everyendmplib{endfig;}  
\begin{document}
\begin{mplibcode}
    for i= 0 upto 6:
        dotexp(i, (0, -i*\mpdim{\bigskipamount}));
    endfor;
\end{mplibcode}
\end{document}

enter image description here

Franck Pastor
  • 18,756
7

Without TikZ:

\documentclass[varwidth,border=5]{standalone}
\usepackage{xcolor}
\newdimen\dima\newdimen\dimb\newdimen\dimc
\def\expbar#1{%
  \dima=1.75ex\dimb=\dima\multiply\dimb 6\dimc=\dimb
  \hbox to\dimb{\dimb=\dima\multiply\dimb by#1
  \hbox to\dimb{\leaders\hbox to\dima{\textcolor{cyan}{$\bullet$}\hfil}\hfil}%
  \dimb=-\dimb\advance\dimb by\dimc
  \hbox to\dimb{\leaders\hbox to\dima{\textcolor{gray}{$\bullet$}\hfil}\hfil}%
}}
\begin{document}
0 \expbar{0} \\
1 \expbar{1} \\
2 \expbar{2} \\
3 \expbar{3} \\
4 \expbar{4} \\
5 \expbar{5} \\
6 \expbar{6}
\end{document}

enter image description here

Mark Wibrow
  • 70,437
4

Just for fun here is a tikz "style only" solution.

\documentclass[varwidth,border=7pt]{standalone}
\usepackage{tikz}
\tikzset{
  % one node insert
  insert circle/.style={insert path={++(1,0) node[#1,fill,circle]{}}},
  cyan circle/.style={insert circle=cyan},
  gray circle/.style={insert circle=lightgray},
  % the loops (the values 0 and 6 are particular cases with one empty loop)
  c0/.style={gray circle/.list={0,...,5}},
  c6/.style={cyan circle/.list={0,...,5}},
  c/.style={cyan circle/.list={1,...,#1},gray circle/.list={#1,...,5}},
}
\newcommand{\dotexp}[1]{\tikz\path[c#1/.try,c/.retry=#1];}
\begin{document}
  \dotexp{0}\\
  \dotexp{1}\\
  \dotexp{2}\\
  \dotexp{3}\\
  \dotexp{4}\\
  \dotexp{5}\\
  \dotexp{6}
\end{document}

enter image description here

Second solution: Here is a second solution that use the .is choice (without .try and .retry) and this answer.

\documentclass[varwidth,border=7pt]{standalone}
\usepackage{tikz}
\def\test{3}
\tikzset{
  % one node insert
  insert circle/.style={insert path={++(1,0) node[#1,fill,circle]{}}},
  cyan circle/.style={insert circle=cyan},
  gray circle/.style={insert circle=lightgray},
  % the loops (the values 0 and 6 are particular cases with one empty loop)
  c/.is choice,
  c/0/.style={gray circle/.list={0,...,5}},
  c/6/.style={cyan circle/.list={0,...,5}},
  c/.unknown/.style={cyan circle/.list={1,...,\pgfkeyscurrentchoice},gray circle/.list={\pgfkeyscurrentchoice,...,5}},
  c/.unknown/.prefix code={\edef\pgfkeyscurrentchoice{\pgfkeyscurrentname}}
}
\newcommand{\dotexp}[1]{\tikz\path[c=#1];}
\begin{document}
  \dotexp{0}\\
  \dotexp{1}\\
  \dotexp{2}\\
  \dotexp{3}\\
  \dotexp{4}\\
  \dotexp{5}\\
  \dotexp{6}
\end{document}  
Kpym
  • 23,002