Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

One thing annoying in sparklines is its verbosity and dependence on external arithmetics. For example, to depict a three bar graph of 16%, 53%, 31%, one has to write:

\begin{sparkline}{4}
  \sparkspike .166 .302
  \sparkspike .500 1
  \sparkspike .834 .585 
\end{sparkline}

I would prefer:

\threesparkline{0.16}{0.53}{0.31}

So my main question is can I do basic arithmetic in LaTeX, like dividing and multiplying numbers, finding the max among three parameters, etc?

Alternatively, is there a better way of using sparklines that I've missed?

UPDATE:

After the sugestion of using the calc package, I'm stuck with the following attempt which yields an error in \real and \ratio:

\newcommand{\threespike}[3]{
    \newcounter{max}\setcounter{max}{\maxof{\maxof{\real{#1}}{\real{#2}}}{\real{#3}}}
    \newcounter{a}\setcounter{a}{\ratio{\real{#1}}{max}}
    \newcounter{b}\setcounter{b}{\ratio{\real{#2}}{max}}
    \newcounter{c}\setcounter{c}{\ratio{\real{#3}}{max}}    
    \begin{sparkline}{4}
      \sparkspike .166 a
      \sparkspike .500 b
      \sparkspike .834 c 
    \end{sparkline}
}

UPDATE2:

I eventually got to make \ratio work directly like this:

\newcommand{\ratiofivespark}[7]{
    \begin{sparkline}{6}
      \sparkspike .1 \ratio{#2}{#1}
      \sparkspike .3 \ratio{#3}{#1}
      \sparkspike .5 \ratio{#4}{#1}
      \sparkspike .7 \ratio{#5}{#1}
      \sparkspike .9 \ratio{#6}{#1} 
    \end{sparkline}
}

Where the first parameter passed establishes the full height of a bar. See the accepted answer for more powerful LaTeX-Fu!

share|improve this question
    
How did you arrive at the numbers .166, .500, and .834? Why do you want the 53% to be the max height? Doesn't that make multiple bar graphs incomparable? Why do you want the 3 to be an optional argument? It seems like it would be required. –  TH. Aug 26 '10 at 23:02
    
(i) .166 .500 and .834 are the middle positions of a 5pt \sparkspikewidth with some padding (ii) in this particular case, the comparasion isn't among several bar graphs, but in the relative ratio among each bar (iii) true! 3 is a required argument. An even better solution would be \dosparkline{0.16, 0.53, 0.31}, but I believe latex doesn't support arrays? –  Hugo S Ferreira Aug 26 '10 at 23:31
1  
I guess what I was asking was what computation did you perform to arrive at those three numbers, but if you only ever want 3, then it's not really an issue. Counters only work with integers and I'm pretty sure that \ratio is expecting the ratio of two integers. You also need something like \arabic{foo} to use that counter, you can't just write foo. So, what you want requires a bit more work. As for arrays, there's no reason that that couldn't be parsed, but it'd require more work still. –  TH. Aug 27 '10 at 5:41
1  
Just an extremely minor and excessively picky point: having never heard of "sparklines", I misread the first sentence as "One thing annoying in sparkliness" and was wondering about why I'd never thought of LaTeX as being "sparkly" before! It's useful to make package names stand out in some way, often we do this by making them look like code: sparklines. –  Loop Space Aug 27 '10 at 8:24
    
I too read it as sparkliness to begin with. You have to admit, it's catchy. =) –  TH. Aug 27 '10 at 8:58
show 2 more comments

2 Answers

up vote 4 down vote accepted

You can certainly do basic arithmetic in LaTeX. You have several options. You can use the standard TeX \advance, \multiply, and \divide. You can use the calc package for a more natural way of doing arithmetic (although, I find I don't use it). You can also use the e-TeX extension \numexpr ... \relax.

Edit: Okay. I think I've got a solution for you.

\documentclass{article}
\usepackage{sparklines}
\usepackage{fp}
\newcount\slnum
\makeatletter
\newcommand\dosparkline[2][4]{%
        \FPset\slmax{0}%
        \FPset\slpos{0}%
        \slnum0
        \slparse#2,\relax
        \FPadd\sladvance{1}{\the\slnum}%
        \FPdiv\sladvance{1}\sladvance
        \count@\slnum
        \loop\ifnum\count@>0
                \advance\count@-1
                \FPdiv\sltemp{\csname sl@\the\count@\endcsname}\slmax
                \expandafter\let\csname sl@\the\count@\endcsname\sltemp
        \repeat
        \begin{sparkline}{#1}
                \count@0
                \loop\ifnum\count@<\slnum
                        \FPadd\slpos\slpos\sladvance
                        % The {} are necessary
                        \sparkspike \slpos{} \csname sl@\the\count@\endcsname{}
                        \advance\count@1
                \repeat
        \end{sparkline}
}
\def\slparse#1,#2\relax{%
        \FPset\sltemp{#1}%
        \FPmax\slmax\slmax\sltemp
        \expandafter\let\csname sl@\the\slnum\endcsname\sltemp
        \advance\slnum1
        \ifx\relax#2\relax\else
                \slparse#2\relax
        \fi
}
\makeatother
\begin{document}
\dosparkline[10]{16,53,31,25,10,45}

\dosparkline{.16,.53,.31}
\begin{sparkline}{4}
  \sparkspike .166 .302
  \sparkspike .500 1
  \sparkspike .834 .585 
\end{sparkline}

\end{document}

The first \dosparkline shows the optional argument which is the width (in ex of all things!). The second one shows what you asked for which you can compare without the output of yours. You'll note I didn't match your spacing. You can play around with that by changing how \sladvance is computed.

share|improve this answer
    
That was powerful! Have you considered contributing to the package? :-) –  Hugo S Ferreira Aug 27 '10 at 14:37
    
Contributing to sparklines? I'd never heard of it until I read this question. –  TH. Aug 27 '10 at 19:39
add comment

For calculations using real numbers, take a look at the fp package. If you are using LuaTeX then escaping to Lua is going to be the best approach.

share|improve this answer
    
Oh, that is really excellent. I've lamented TeX's lack of floating point calculations. –  TH. Aug 27 '10 at 5:58
    
I'm currently writing a module for LaTeX3 based on the fp package (but using floating points). This is an effort, so I too regard the lack of floating point arithmetic as a pain :-) –  Joseph Wright Aug 27 '10 at 7:08
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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