# Redistribute a range of percentages according to a minimum value, while keeping relative proportions

**FIDDLE HERE: http://jsfiddle.net/jakelauer/5S8t8/**

**What I need to do**

Loop through a range of percentages, which add up to 100%, and set any values that fall below a minimum threshold to a certain percentage, then redistribute the remaining percentages so that they are still the same relative to each other, so that the whole range still equals 100%.

**Why?**

I’m making a pie chart, and I need each value to show on the pie chart, even if it’s a zero-value, so that it’s still clickable. That means I need to set values below a certain threshold to a higher value, but I don’t want to lose the relative proportions of the higher values, and they can’t go over 100%

**Details**

Say I have a range of values:

```
var range = [190, 2453, 234, 14, 1244, 532, 0, 3, 1999];
```

and I convert these to percentage values, such that each value in the range becomes its percentage of the sum of the whole range, resulting in:

```
[0.02849002849002849, 0.36782126255810466, 0.03508771929824561, 0.002099265257159994, 0.18653471285050233, 0.07977207977207977, 0, 0.000449842555105713, 0.2997450892187734]
```

I want to loop through these percentages and set them to a minimum of `0.02`

, or 2%. Here is the code I have so far:

```
var range = [190, 2453, 234, 14, 1244, 532, 0, 3, 1999];
var minimumPercent = 0.02;
function distributeRangeGivenMinimum(range, min) {
var sum = 0;
for (var i = 0; i < range.length; i++) {
sum += range[i];
}
var percents = [];
for (var i = 0; i < range.length; i++) {
percents.push(range[i] / sum);
}
var amtToSubtract = 0;
var timesUnderMin = 0;
for (var i = 0; i < range.length; i++) {
if (percents[i] < min) {
amtToSubtract += (min - percents[i]);
timesUnderMin++;
percents[i] = min;
}
}
var timesOverMin = percents.length - timesUnderMin;
if (timesOverMin > 0) {
for (var i = 0; i < range.length; i++) {
if (percents[i] > min) {
percents[i] = percents[i] - (amtToSubtract / timesOverMin);
}
}
}
return percents;
}
```

The problem with the above function is that, while it does accomplish the redistribution, it fails if any of the values are *just* above the minimum (e.g. if one of the values is 0.0201 and the minimum is 0.02, or something), they end up below the minimum after the redistribution, and I’m not sure how to solve that.

### One Solution collect form web for “Redistribute a range of percentages according to a minimum value, while keeping relative proportions”

Try the following (new section is marked by comments):

```
var range = [190, 2453, 234, 14, 1244, 532, 0, 3, 1999];
var minimumPercent = 0.02;
function distributeRangeGivenMinimum(range, min) {
var sum = 0;
for (var i = 0; i < range.length; i++) {
sum += range[i];
}
var percents = [];
for (var i = 0; i < range.length; i++) {
percents.push(range[i] / sum);
}
var amtToSubtract = 0;
var timesUnderMin = 0;
for (var i = 0; i < range.length; i++) {
if (percents[i] < min) {
amtToSubtract += (min - percents[i]);
timesUnderMin++;
percents[i] = min;
}
}
var timesOverMin = percents.length - timesUnderMin;
// begin new section
do {
var prevTimesOverMin = timesOverMin;
var distSubAmt = amtToSubtract / timesOverMin;
for (var i = 0; i < range.length; i++) {
if (percents[i] > min && percents[i] - distSubAmt < min) {
amtToSubtract -= (percents[i] - min);
timesOverMin--;
percents[i] = min;
}
}
} while (timesOverMin != prevTimesOverMin);
// end new section
if (timesOverMin > 0) {
for (var i = 0; i < range.length; i++) {
if (percents[i] > min) {
percents[i] = percents[i] - (amtToSubtract / timesOverMin);
}
}
}
return percents;
}
```