echarts 算百分比与js toFixed算出来的百分比不一致的问题。
由图框选出来的地方可以看出不一致。
开始以为是js toFixed四舍五入的问题,材料提交计算出来的百分比值是60.824742268041234。toFixed(2)后得到60.82。
写了个递归如下,可以算出60.83
/** * 获取给定精度的数据 * @param {number} num 数字 * @param {number} n 精度 * @return {number} 百分数 */ NumberToFixed(num, n) { let arr = (num + '').split(''); let dian = arr.findIndex(r => r === '.'); let newArr = []; for (let i = 0; i < arr.length; i++) { if (i <= dian + n) { newArr.push(arr[i]); } else { if (arr[i] != 4) { newArr.push(arr[i]); break; } else { newArr.push(arr[i]); } } } // 先过滤数据,变成60.8247,再递归 return this.NumberToFixed2(newArr.join(''), n); }, NumberToFixed2(num, n) { let arr = (num + '').split(''); let dian = arr.findIndex(r => r === '.'); num = Number(num); if (arr.length <= dian + n + 2) { return num.toFixed(n); } else { let newNum = num.toFixed(arr.length - dian - 2); return this.NumberToFixed2(newNum, n); } },
后同事找到echarts算百分比的方法,发现并不是用四舍五入计算的。而是先算出百分比,再乘以10000,向下取整,再相加,总数不等于10000的话, 取出小数最大的索引对应的整数+1,然后将小数置0,将currentSum+1,,再循环 取出小数最大的索引对应的整数+1,然后将小数置0,将currentSum+1,,直到currentSum等于10000.
佩服大神写的代码,思路令人大开眼界。
具体方法如下(修改过)
/** * 获取给定精度的数据,确保valueList中的百分比之和为1 * 采用最大余数法 * @param {number[]} valueList 所有数据的列表 * @param {number} idx 数据的索引 * @param {number} precision 精度 * @return {number} 百分数 */ getPercentWithPrecision(valueList, idx, precision) { if (!valueList[idx]) { return 0; } var sum = valueList.reduce(function(acc, val) { return acc + (isNaN(val) ? 0 : val); }, 0); if (sum === 0) { return 0; } var digits = Math.pow(10, precision); var votesPerQuota = valueList.map(val => { return ((isNaN(val) ? 0 : val) / sum) * digits * 100; }); var targetSeats = digits * 100; var seats = votesPerQuota.map(votes => Math.floor(votes)); var currentSum = seats.reduce(function(acc, val) { return acc + val; }, 0); var remainder = votesPerQuota.map((votes, idx) => votes - seats[idx]); // Has remainding votes. while (currentSum < targetSeats) { // Find next largest remainder. var max = -Infinity; //Number.NEGATIVE_INFINITY; var maxId = null; for (var i = 0, len = remainder.length; i < len; ++i) { if (remainder[i] > max) { max = remainder[i]; maxId = i; } } // Add a vote to max remainder. ++seats[maxId]; remainder[maxId] = 0; ++currentSum; } return seats[idx] / digits; },
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)