Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Giving it 99 Percent!

DZone's Guide to

Giving it 99 Percent!

Think math is easy to nail down when using computers? This author built a dashboard and discovered, to his dismay, that the computational total and displayed information didn't coincide. This is a history of the three methods he tried to fix the problem.

· Web Dev Zone
Free Resource

Start coding today to experience the powerful engine that drives data application’s development, brought to you in partnership with Qlik.

When it comes to UI design, percentages can be a pain! At the convergence of UI/UX, mathematics, and computer mathematics it’s quite easy to find yourself in a situation as seen in this chart:

Claims progress

There is a problem with this chart? Can you spot it?

26 + 61 + 12 = 99

The percentages do not add up to 100. What’s going on? Is the data wrong? What follows is an explanation of the problem and a solution I implemented for use with Google Polymer applications.

Computation vs Display

When I ran into this issue my initial suspicion was that I’d simply made an error in the calculations; that my data was wrong. Unfortunately, the answer is not that simple. Take the classic example of adding thirds:

33.3333 + 33.3333 + 33.3333 = 99.9999

If the sum is rounded, the total will be 100. But the truth of the math doesn’t matter in a chart. The chart should convey the information in an easy-to-understand format. If I round these numbers for display, I would end up with a chart displaying “33” for each row.  The math isn’t wrong, but the visual representation is. As a user, I know the values are wrong, but I don’t know why.

I figured with the power of the internet it would be trivial to find a solution for this issue so I set about doing some research. I was surprised to find a wide variety of answers. One suggestion was to add a text explanation to the effect of “numbers may be wrong due to rounding.” Other systems simply don’t provide a solution. Another missed the mark, suggesting that the sum will be correct if you don’t round each number before summing. This is true, but misses the point. The fact is this is a problem without a “perfect” solution because rounding numbers introduces errors. I want to display rounded values for ease of use, but my computations need to be as accurate as possible.

Largest Remainder Method

I finally settled on using the largest remainder method as described in this Stack Overflow answer:

  1. For each item in the sum, get the floor value
  2. Sum the floored values
  3. Get the difference between this sum and 100
  4. Sort the floored values by their remainders
  5. Distribute the difference by adding 1 to each value and subtracting 1 from the difference until the difference is 0

Remember that no matter what, rounding introduces errors. Using the largest remainder method for the previous example, the values become [34, 33, 33]. However, I think for a dashboard-type chart this kind of error is acceptable. If the numbers need to be more mathematically accurate, it would be better to use a report of the data, rather than a chart.

Implementation

This implementation of the largest remainder method is available as a Polymer Web component and can be used like so:

<nuxeo-util-largest-remainder values-to-fix="[33.3, 33.3, 33.3]"
                              fixed-values="{{fixedValues}}">
 </nuxeo-util-largest-remainder>

You can find more information on the documentation page (with demo).

Create data driven applications in Qlik’s free and easy to use coding environment, brought to you in partnership with Qlik.

Topics:
google ,polymer ,stack ,component ,ui design

Published at DZone with permission of Josh Fletcher. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}