Bootstrap

el-progress进度条,format效果实现

需要实现如下效果图: 

 实现的需求是,取数组对象里面,amount最大的值作为100%,其余按照这个标准进行计算得到显示的进度条百分比

<template>
  <div class="app-container">  
     
    <div class="chart-container">
      <el-row :gutter="14">
         
        <el-col :span="12">
          <div
            v-loading="chartLoading"
            class="chart-wrapper"
            style="margin-bottom: 14px;"
          >
            <h3>近半年重量企业排名</h3>
            <div
              v-if="status3 === 'data'"
              class="rank_div"
            >
              <div
                v-for="(item, index) in leaseSortData"
                :key="index"
                class="rank_box"
              >
                <div
                  class="li_fl"
                  :style="{background: index == 0 ? '#fff1f1' : index == 1 ? '#fff5ee' : index == 2 ? '#fff8e6' : '#f4f4f4', color: index == 0 ? '#ff9292' : index == 1 ? '#ff9950' : index == 2 ? '#f7b500' : '#8b8b8b' }"
                >
                  <div>{{ index+1 }}</div>
                  <div>TOP</div>
                </div>
                <div class="li_fr">
                  <div class="name">
                    {{ item.name }}
                  </div>
                  <el-progress
                    :percentage="item.numPer"
                    :format="(p) => formatProgress(p, item)"
                    :stroke-width="8"
                    :title="item.tipTxt"
                  />
                </div>
              </div>
            </div>
            <emptyData
              :status="status3"
              height="202px"
            />
          </div>
        </el-col>
      </el-row>
    </div>
  </div>
</template>
  
<script>
import { divide, round } from '@/utils/digit'
import emptyData from '@/components/empty/index.vue' 
import {  fillAmountDeptStatistic } from '@/api/operationAnalysis/hydOper'

export default {
  components: { 
    emptyData
  },
  data() {
    return { 
      status3: 'empty', // 'loading': 正在加载中; 'empty': 数据为空; 'data': 存在数据
      chartLoading: false, 
      leaseSortData: [], // 排名数据  
    }
  },
  created() {  
    this.getFillAmountDeptStatistic() 
  },
  mounted() {
  },
  methods: { 
    formatProgress(percentage, item) {
      // console.log(percentage, item)
      return item.amount + "kg"
    },
    // 近半年 企业排名--bar横
    getFillAmountDeptStatistic() {
      this.status3 = 'loading'
      this.chartLoading = true
      this.leaseSortData = []
      fillAmountDeptStatistic()
        .then(response => {
          let resData = response.rows

          if (resData && resData.length) {
            // 求数组对象某个对象的最大值
            // 初始化最大值为第一个对象的属性值
            let arr = []
            let maxValue = resData[0].amount;
            // 遍历数组,比较每个对象的属性值
            for (let i = 1; i < resData.length; i++) {
              if (resData[i].amount > maxValue) {
                maxValue = resData[i].amount;
              }
            }
            // console.log(maxValue); // 输出: 20

            resData.map(v=>{
              let per = divide(v.amount, maxValue)  // 0.000567
              // console.log(per)
              arr.push({
                maxValue: maxValue,
                name: v.time,
                amount: v.amount,
                // amountInt: Math.round(v.amount),
                numPer: v.amount == maxValue ? 100 : round(per * 100, 2) ,
                tipTxt: v.time + ':' +  v.amount + 'kg'
              })
            })
            this.leaseSortData = arr
            // console.log(this.leaseSortData)
            this.status3 = 'data'
          } else {
            this.status3 = 'empty'
          }
          this.chartLoading = false
        })
        .catch(() => {
          this.chartLoading = false
          this.status3 = 'empty'
        })
    }, 
  },
}
</script>
  
<style lang="scss" rel="stylesheet/scss" scoped>
.app-container {
  background-color: #edf1f5;
  padding: 0; 
  .chart-container {
    height: calc(100vh - 200px);
    // overflow-y: auto;
    // padding: 20px;
    background: #edf1f5;
    border-radius: 4px;
    .el-row {
      height: 100%;
      // margin: 0 !important;
      .el-col {
        height: 100%;
        // padding: 0 !important;
      }
    }
    .chart-wrapper {
      height: calc(50% - 7px); 
      padding: 12px 16px 20px 16px;
      border-radius: 4px;
      // border: 1px solid #e6e6e6;
      background: #FFFFFF;
      h3 {
        margin: 0;
        font-size: 14px;
        font-weight: bold;
        color: rgba(0, 0, 0, 0.8);
        line-height: 20px;

        &::before {
          content: '';
          display: inline-block;
          width: 4px;
          height: 14px;
          background: #1F4A81;
          top: 3px;
          position: relative;
          margin-right: 6px;
        }
      }
    }
  }

  .rank_div {
    height: calc(100% - 50px); // 300px;
    max-height: calc(100% - 50px); // 300px;
    overflow: auto;
    margin-top: 20px;
    margin-bottom: 20px;
    padding-right: 10px;
    .rank_box:first-child {
      margin-top: 0;
    }
    .rank_box {
      display: flex;
      margin-top: 27px;
      .li_fl {
        width: 30px;
        // text-align: center;
        font-size: 10px;
        border-radius: 4px;
        margin-right: 10px;
        padding: 2px 4px;
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        justify-content: center;
      }
      .li_fr {
        flex: 1;
        .name {
          font-size: 12px;
          margin-bottom: 4px;
        }
      }
    }
  }
}
::v-deep {
  .el-progress-bar{
    padding-right: 0;
    position: relative;
  }
  .el-progress__text {
    position: absolute;
    right:0;
    font-size: 12px !important;
    top: -14px;
  }
}
</style>
  

 digit.js

// 高精度除法

export function divide(...nums) {

  if (nums.length > 2) {

    return iteratorOperation(nums, divide);

  }

  const [num1, num2] = nums;

  const num1Changed = float2Fixed(num1);

  const num2Changed = float2Fixed(num2);

  checkBoundary(num1Changed);

  checkBoundary(num2Changed);

  // 重要,这里必须用strip进行修正

  return times(num1Changed / num2Changed, strip(Math.pow(10, digitLength(num2) - digitLength(num1))));

}

// 四舍五入

export function round(num, ratio) {

  const base = Math.pow(10, ratio);

  let result = divide(Math.round(Math.abs(times(num, base))), base);

  if (num < 0 && result !== 0) {

    result = times(result, -1);

  }

  // 位数不足则补0

  return result;

}

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;