常用场景
- 用于动态计算页面元素的百分比占比
- 可视化中扇形统计图的显示数值修正
代码
/**
* 计算数组中各项的占比,保证百分比和等于1
* @param arr 需要计算百分比的数组,传入时必须降序排序
* @param precision 精度 比如 4 0.34567 =》 34.56
*
* arr降序排序,避免较小的值因为顺位补值导致大于原本比他大的值,
* 至于原本相等的值因为顺位补值变得不相等则不考虑,
* 比如[33,33,33] => [34,33,33],将数值精确后势必三个百分比会不相等,
* 【总和等于1】与【相等的值百分比也相等】在这里只保证第一种情况,
* 毕竟百分比是看的与1的关系
*
* padEnd 属于es6 可能需要自己改写 '0'.padEnd(3,'-') => '0--'
*/
function getPercent(arr, precision) {
let total = 1,//总和
percentArr,//每个模块的宽度百分比数组 精确到.00
percentTotal = 0,//第一次计算百分比后,百分比总和
dif,//第一次计算百分比总和后与实际和的差值,因为第一次计算百比试向下精确,所以和总会比实际和小
len = arr.length,
i = 0,
result;
//计算总和
total = arr.reduce(function (a, b) {
return a + b;
});
//简单过滤总和为零的情况
if(total == 0){
return
}
//计算百分比数组
percentArr = arr.map(function (d, index) {
let r = (d / total + '').substring(2, 2 + precision);//0.23456 => 2345
r = +r.padEnd(precision, '0');//0.23 => 2300
percentTotal += r;//累计百分比
return +r;// 2345
});
//计算差值
dif = Math.pow(10, precision) - percentTotal;
//分配差值
while (dif-- > 0) {
percentArr[i++] += 1;
i = i % len;
}
//转换为百分比字符串
result = percentArr.map(function (per) {
per += '';
per=per.padStart(precision, '0');
return parseFloat(per.replace(/(\d{2})/, '$1.')) + '%'
});
return result
}
console.log(getPercent([33, 33, 33], 4));