FIDDLE HERE: http://jsfiddle.net/jakelauer/5S8t8/
我需要做什么
循环遍历百分比范围,加起来为 100%,并将低于最小阈值的任何值设置为某个百分比,然后重新分配剩余的百分比,使它们相对于彼此仍然相同,所以整个范围仍然等于 100%。
为什么?
我正在制作一个饼图,我需要每个值都显示在饼图上,即使它是零值,这样它仍然可以点击。这意味着我需要将低于某个阈值的值设置为更高的值,但我不想失去较高值的相对比例,并且它们不能超过 100%
详情
假设我有一系列值:
var range = [190, 2453, 234, 14, 1244, 532, 0, 3, 1999];
然后我将它们转换为百分比值,这样范围内的每个值都成为其占整个范围总和的百分比,结果是:
[0.02849002849002849, 0.36782126255810466, 0.03508771929824561, 0.002099265257159994, 0.18653471285050233, 0.07977207977207977, 0, 0.000449842555105713, 0.2997450892187734]
我想遍历这些百分比并将它们设置为最小值 0.02
,即 2%。这是我到目前为止的代码:
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;
}
上述函数的问题在于,虽然它确实完成了重新分配,但如果任何值刚好高于最小值(例如,如果其中一个值是 0.0201 并且最小值是 0.02 或其他),它们在重新分配后最终低于最小值,我不确定如何解决这个问题。
最佳答案
尝试以下操作(新部分用注释标记):
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;
}
关于javascript - 根据最小值重新分配百分比范围,同时保持相对比例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18238649/