You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

如何将数值映射至0-1区间?适配ProgressBar进度条库实践

嘿,我来帮你搞定这个进度值映射和代码修改的问题!

核心逻辑:数值映射到0-1区间

根据你的需求,我们需要把delivered - pending的结果映射到0-1的范围,规则是:

  • pending=0时,delivered - pending = delivered,此时映射为1(100%进度)
  • 其他情况,用计算出的进度值除以delivered(也就是最大可能的进度值),得到0-1之间的小数

公式如下:

// 先计算原始进度值
const rawProgress = delivered - pending;
// 处理delivered为0的边界情况,避免除以0
const normalizedProgress = delivered === 0 ? 0 : rawProgress / delivered;
// 确保数值不会超出0-1范围(比如rawProgress可能为负或者超过delivered的情况)
const clampedProgress = Math.max(0, Math.min(1, normalizedProgress));
代码修改要点

你的代码目前有两个关键问题:

  1. 异步执行顺序问题fetch是异步操作,你现在在fetch外面创建进度条并调用bar.animate,这时候progress还没从API获取到值,会使用未定义的变量。
  2. 硬编码替换:需要把进度条的文本值和动画参数替换为计算后的归一化进度值。

修改后的完整代码如下:

完整HTML+JS+CSS代码

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8" />
 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 <title>Document</title>
 <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous" ></script>
 <script src="https://cdn.tutorialjinni.com/progressbar.js/1.1.0/progressbar.js"></script>
 <style>
 #progreso {
 margin: 20px;
 width: 150px;
 height: 150px;
 }
 </style>
</head>
<body>
 <div id="progreso"></div>
 <script>
 let delivered, pending, cumplidas;

 fetch("http://157.230.190.251/api/v1/cmodels/secure/dashboard")
  .then(function(response) { return response.json(); })
  .then(function(json) {
    console.log(json);
    cumplidas = json.kpis[0];
    delivered = cumplidas.entregadas;
    pending = cumplidas.pendientes;

    // 计算归一化的进度值和百分比文本
    const rawProgress = delivered - pending;
    const normalizedProgress = delivered === 0 ? 0 : rawProgress / delivered;
    const clampedProgress = Math.max(0, Math.min(1, normalizedProgress));
    const progressText = Math.round(clampedProgress * 100).toString();

    // 创建进度条并执行动画(放到异步回调里,确保拿到数据后再执行)
    var bar = new ProgressBar.Circle(progreso, {
      strokeWidth: 6,
      easing: 'easeInOut',
      duration: 1400,
      color: '#FFEA82',
      trailColor: '#eee',
      trailWidth: .6,
      svgStyle: { display: 'block', width: '100%' },
      text: {
        value: progressText, // 替换为计算后的百分比文本
        style: {
          color: '#f00',
          position: 'absolute',
          left: '50%',
          top: '50%',
          padding: 0,
          margin: 0,
          transform: { prefix: true, value: 'translate(-50%, -50%)' }
        }
      }
    });

    bar.animate(clampedProgress); // 替换为归一化后的进度值
  })
  .catch(function(error) {
    // 处理API请求失败的情况,默认显示0%
    console.error('Failed to fetch data:', error);
    var bar = new ProgressBar.Circle(progreso, {
      strokeWidth: 6,
      easing: 'easeInOut',
      duration: 1400,
      color: '#FFEA82',
      trailColor: '#eee',
      trailWidth: .6,
      svgStyle: { display: 'block', width: '100%' },
      text: {
        value: '0',
        style: {
          color: '#f00',
          position: 'absolute',
          left: '50%',
          top: '50%',
          padding: 0,
          margin: 0,
          transform: { prefix: true, value: 'translate(-50%, -50%)' }
        }
      }
    });
    bar.animate(0);
  });
 </script>
</body>
</html>
额外说明
  • 边界处理:加入了delivered=0的判断,避免除以0的错误;同时用Math.maxMath.min确保进度值始终在0-1之间,防止异常数据导致进度条显示异常。
  • 异步处理:把进度条的创建和动画触发放到fetchthen回调里,确保只有当API数据成功返回后才会渲染进度条,避免使用未定义的变量。
  • 错误处理:加入了catch回调,当API请求失败时,进度条会显示0%,提升用户体验。

内容的提问来源于stack exchange,提问作者Julio Rodriguez

火山引擎 最新活动