vue3之仪表盘

vue3之仪表盘

效果:

版本

"echarts": "^5.5.1"

核心代码:

javascript 复制代码
<!--
 * @Description: 圆环组件封装
 * @Version: 1.0
 * @Autor: qh
-->

<template>
  <div ref="chartRef" class="circle"></div>
</template>

<script lang="ts" setup>
import { ref, onMounted } from 'vue';
import * as echarts from 'echarts';

const props = defineProps({
  percent: {
    type: Number,
    default: 0,
  },
});

const chartRef = ref(null);
let chart: any = null;

const rich = {
  bule: {
    fontSize: 22,
    fontFamily: 'DINPro',
    color: '#fff',
    padding: [6, 0, 0, 0],
  },
  white: {
    fontSize: 12,
    color: '#fff',
    padding: [10, 0, 0, 0],
  },
};

const topChartOptions = (value: number) => {
  return {
    tooltip: {
      show: false,
      formatter: '{a} <br/>{b} : {c} ({d}%)',
    },
    series: [
      {
        name: 'S',
        z: 3,
        type: 'gauge', // 仪表盘
        center: ['49.5%', '58%'],
        radius: '95%',
        detail: {
          formatter: (value: any) => {
            return '{bule|' + value + '}{white|%}';
          },
          rich,
          offsetCenter: ['0%', '0%'],
        },
        title: {
          show: false,
        },
        data: [
          {
            value,
            name: 'Percent',
          },
        ],
        axisLine: {
          show: true,
          lineStyle: {
            roundCap: true,
            width: 7,
            color: [
              [
                value / 100,
                new echarts.graphic.LinearGradient(0, 0, 1, 0, [
                  {
                    offset: 0,
                    color: 'rgba(0, 255, 231, 0.5)',
                  },
                  {
                    offset: 0.5,
                    color: 'rgba(0, 255, 231, 0.8)', // 100% 处的颜色
                  },
                  {
                    offset: 1,
                    color: 'rgba(0, 255, 231, 0.5)', // 100% 处的颜色
                  },
                ]),
              ],
              [1, 'rgba(4, 211, 251, 0)'],
            ],
          },
        },
        axisTick: {
          show: false,
        },
        axisLabel: {
          show: false,
        },
        splitLine: {
          show: false,
        },
        pointer: {
          length: '14%',
          width: 2,
          icon: 'rect',
          offsetCenter: [0, '-87%'],
          itemStyle: {
            color: 'rgba(0, 255, 231, 1)',
          },
        },
      },
      {
        name: 'T',
        z: 2,
        type: 'gauge', // 仪表盘
        center: ['49.5%', '58%'],
        radius: '96%',
        detail: {
          show: false,
        },
        title: {
          show: false,
        },
        data: [
          {
            value: 100,
            name: 'Percent',
          },
        ],
        axisLine: {
          show: true,
          lineStyle: {
            roundCap: true,
            width: 8,
            color: [
              [
                1,
                new echarts.graphic.LinearGradient(0, 0, 1, 0, [
                  {
                    offset: 0,
                    color: 'rgba(150, 179, 180, 1)',
                  },
                  {
                    offset: value / 100,
                    color: 'rgba(150, 179, 180, 0.5)',
                  },
                  {
                    offset: 1,
                    color: 'rgba(150, 179, 180, 1)', // 100% 处的颜色
                  },
                ]),
              ],
              [1, 'rgba(255, 192, 1, 0)'],
            ],
          },
        },
        axisTick: {
          show: false,
        },
        axisLabel: {
          show: false,
        },
        splitLine: {
          show: false,
        },
        pointer: {
          show: false,
        },
      },
    ],
  };
};

const initChart = () => {
  if (!chart) chart = echarts.init(chartRef.value);
  chart.setOption(topChartOptions(props.percent));
};

onMounted(() => {
  initChart();
});

onBeforeUnmount(() => {
  if (chart) {
    chart.clear();
    chart.dispose();
    chart = null;
  }
});
</script>

<style scoped lang="scss">
.circle {
  width: 132px;
  height: 113px;
  // 根据实际情况加背景图
  background: url('@/assets/img/inspection/overview-bg.png') no-repeat;
}
</style>
相关推荐
nvd11几秒前
深入现代 Web 鉴权架构:网关统一代理 (Forward-Auth) vs 前端持有 JWT 的终极选型与边缘同域实践
前端·架构·状态模式
leoZ23123 分钟前
2026-09-09-springboot-cloud-deploy-pitfalls
java·前端·javascript·vue.js·人工智能·spring boot·后端
YWL29 分钟前
OpenLayers弹窗Overlay深度实战
前端·vue·openlayers
YWL1 小时前
OpenLayers+ECharts联动:地图点击联动图表,数据可视化大屏方案
前端·信息可视化·vue·echarts·openlayers
芭拉拉小魔仙1 小时前
Vue 2 门诊收费系统中的医保结算流程设计与实践
前端·javascript·vue.js
moonrailgun1 小时前
用 Node.js 复刻 Codex Astra 的终端星光
前端·javascript·算法
海上彼尚2 小时前
Cursor 模型的强度实测排行
前端·人工智能·后端
默_笙2 小时前
💫 给金鱼建图书馆(下):Milvus 向量数据库,让 AI 拥有长期记忆
前端·javascript
liangshanbo12152 小时前
手写 Function.prototype.call 与 Function.prototype.apply 面试题满分答案
开发语言·javascript·原型模式
EatFan2 小时前
HTML前端利用flex解决input定位的问题
前端·css·html·css3