首页 前端知识 vue自定义环形进度条

vue自定义环形进度条

2024-04-30 11:04:02 前端知识 前端哥 377 839 我要收藏

1. Elment ui 自定义环形进度条

自定义环形样式:

:stroke-width=“16”:定义环形粗细
circleCenter,circleBox:环形内百分比样式
el-progress-circle__track:改变环形图底色
el-progress内的color:环形图占比颜色

<div class="circleBox">
          <el-progress color="#6bbf69" type="circle" :show-text="false" :stroke-width="16" :percentage="typeof dashboardData.mem_usage !== 'undefined' && dashboardData.mem_usage !== null ? dashboardData.mem_usage : 0"></el-progress>
          <div class="circleCenter">
            <div style=" font-weight: bold; font-size: 18px;"> {{dashboardData.mem_usage}}%</div>
            <div style="  font-size: 10px;">使用率 </div>
          </div>
          <div> <span style=" ">内存:</span> <span style=" color: #32798b;  font-weight: bold;">{{dashboardData.mem_total}}</span>GB</div>
</div>

2. Echarts自定义环形进度条

实现思路是使用echarts的pie扇形图来绘制

主要是设置radius: [‘75%’, ‘90%’],来实现镂空效果

<!-- eslint-disable vue/multi-word-component-names -->
<template>
  <div
    class="percentloop"
    :style="{height: height + 'px',background: styles.compConfig.type === 'dark' ? '#2f3d65' : '#f5f5f5'}"
  >
    <div
      :id="forId(index)"
      :ref="forId(index)"
      :key="index"
      style="height: 140px;width: 140px"
      class="chart-box"
    />
    <div style="margin-top: 14px; display:flex; flex-wrap:wrap">
      <span
        v-show="showActual"
        style="font-weight: 500;margin-right: 10px"
      >
        实际: {{ actual }}
      </span>
      <span
        v-show="showObjective"
        style="font-weight: 500"
      >
        目标: {{ objective }}
      </span>
    </div>
  </div>
</template>
 
<script>
// import echarts from 'src/utils/echartsLoader.js'; 
import echarts from 'echarts';

export default {
  props: {
    data: {
      type: Object,
      default: () => {}
    },
    height: {
      type: [Number, String],
      default: 230
    },
    index: { // 使用时要保证index 唯一
      type: [String, Number],
      default: 0
    },
    percentage: { // 进度不必是0-100,值随意, 因为下面有处理
      type: [Number],
      default: 0
    },
    percent: { // 百分比
      type: [Number, String],
      default: 0
    },
    title: {
      type: String,
      default: ''
    },
    actual: { // 实际值
      type: String,
      default: ''
    },
    objective: { // 目标值
      type: String,
      default: ''
    },
    showActual: {
      type: Boolean,
      default: true
    },
    showObjective: {
      type: Boolean,
      default: true
    },
    color: {
      type: String,
      default: ''
    },
  },
  data () {
    return {
      styles: this.data.styles
    };
  },
  watch: {
    percent: { // 百分比变化重新绘制, 可根据业务自行修改要监听的数据
      handler() {
        this.$nextTick(() => {
          this.init();
        });
      }
    },
    color: { // 颜色变化重新绘制
      handler() {
        this.$nextTick(() => {
          this.init();
        });
      }
    },
  },
  mounted() {
    this.init(); // 渲染完成后绘制
  },
  methods: {
    handlerNumber(num) {  // 函数可处理带% 和千分位的数据, 转化成number给echarts使用, 因为echarts 只能接收number 类型的数据
      let strNum = JSON.parse(JSON.stringify(num));
      if (strNum.includes(',')) {
        strNum = strNum.split(',').reduce((pre, item) => {
          return pre += item;
        }, '');
      }
      if (strNum.includes('%')) {
        strNum = strNum.split('%')[0] / 100;
      }
      return +strNum;
    },
    init() {
      const actual = this.handlerNumber(this.actual);
      const objective = this.handlerNumber(this.objective);
      // console.log('还原的数', actual, objective);
      // const dom = this.$refs[this.forId(this.index)];
      const dom = document.getElementById(this.forId(this.index));
      const chart = echarts.init(dom);
      // 使用镂空饼图模拟进度条
      chart.setOption({
        color: [this.color, '#dbdbdb'],
        tooltip: {
          show: false,
          trigger: 'item',
          formatter: '{b} : {c} ({d}%)',
        },
        legend: {
          show: false,
        },
        series: [
          {
            name: '详情',
            type: 'pie',
            radius: ['75%', '90%'],
            hoverAnimation: false,
            label: {
              show: true,
              position: 'center',
              normal: {
                show: true,
                position: 'center',
                formatter: () => {
                  const str = `${this.percent}\n${this.title}`; // 图中间内容 \n 进行换行
                  return str;
                },
                rich: {
                  b: {
                    fontSize: 20,
                    color: 'green',
                    fontWeight: 'bold',
                  },
                  c: {
                    fontSize: 13,
                    color: 'skyblue',
                    lineHeight: 30,
                  },
                },
                textStyle: {
                  fontSize: 16,
                  fontWeight: 600,
                  color: '#000',
                },
              },
            },
            data: [
              {
                value: actual, // 实际值
              },
              {
                // 如果实际值为0 则直接用目标值的进度沾满整个进度条
                value: actual !== 0 ? objective - actual < 0 ? 0 : objective - actual : 100, // 目标值
              }
            ],
            silent: true,
            // emphasis: {
            //   itemStyle: {
            //     shadowBlur: 10,
            //     shadowOffsetX: 0,
            //     shadowColor: 'rgba(0, 0, 0, 0.5)',
            //   },
            // },
          },
        ],
      });

    },
    forId(index) { // 主要是为了创建唯一id, 可根据业务自行调整
      return this.data.i + index;
    },
  }
};
</script>
 
<style scoped lang="less">
.percentloop {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: #f5f5f5;
}
</style>

转载请注明出处或者链接地址:https://www.qianduange.cn//article/6691.html
标签
评论
会员中心 联系我 留言建议 回顶部
复制成功!