封装一个仪表盘组件 发表于 2024-07-13 最近因为工作需要,封装了一个仪表盘组件。 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446<template> <div ref="guageChart" id="charts"></div></template><script> import * as echarts from 'echarts' import { deepMerge } from '@/utils/index' export default { name: 'CgGuageChart', data() { return { level: '一级', color: '#eee305', defaultOptions: {}, chartInstance: null, value: 0, } }, props: { chartOptions: { type: Object, default: () => ({}), }, }, methods: { // 更新颜色 updateColor(value) { if (value >= 0 && value <= 33) { this.color = '#eee305' this.level = '一级' } else if (value > 33 && value <= 66) { this.color = '#f68d06' this.level = '二级' } else if (value > 66 && value <= 100) { this.color = '#ff2023' this.level = '三级' } }, // 浏览器窗口发生变化的回调 handleResize() { if (this.chartInstance) { this.chartInstance.resize() } }, // 初始化echarts initChart() { const chartContainer = this.$refs.guageChart this.chartInstance = echarts.init(chartContainer) this.updateChart() }, // 生成配置项 generateChartOption() { // 定义渐变色 const colorList = [ new echarts.graphic.LinearGradient(0, 0, 0, 1, [ { offset: 0, color: 'red' }, { offset: 1, color: 'blue' }, ]), ] this.defaultOptions = { title: { text: '风险等级', // 标题文本 left: 'center', // 标题水平位置,可选值有 'left'、'center' 或 'right',或具体的像素值 bottom: '10%', // 标题垂直位置,可选值有 'top'、'middle' 或 'bottom',也可以是具体的像素值 textStyle: { // 标题文本样式 color: '#fff', // 文本颜色 fontSize: 18, // 字体大小 }, }, grid: { top: 20, left: 20, right: 20, bottom: 20, }, series: [ // 最外侧的仪表盘 { type: 'gauge', center: ['50%', '50%'], radius: '94%', startAngle: 230, endAngle: -50, axisLabel: { show: false, }, pointer: { show: false, }, axisLine: { lineStyle: { color: [ [0.08, '#2a7099'], [0.16, '#002342'], [0.2, '#2a7099'], [0.33, '#002342'], [0.46, '#2a7099'], [0.56, '#002342'], [0.66, '#2a7099'], [0.8, '#002342'], [0.88, '#2a7099'], [0.94, '#002342'], [1, '#2a7099'], ], width: 2, }, }, splitLine: { show: false, length: 30, distance: -30, lineStyle: { width: 5, color: '#01033a', }, }, detail: false, axisTick: { show: false, }, data: [ { value: this.chartOptions.value || this.value, }, ], }, { // 第二个仪表盘 type: 'gauge', center: ['50%', '50%'], radius: '86%', startAngle: 230, endAngle: -50, axisLabel: { show: false, }, pointer: { show: false, }, axisLine: { lineStyle: { color: [ [0.08, '#2a7099'], [0.16, '#002342'], [0.2, '#2a7099'], [0.33, '#002342'], [0.46, '#2a7099'], [0.56, '#002342'], [0.66, '#2a7099'], [0.8, '#002342'], [0.88, '#2a7099'], [0.94, '#002342'], [1, '#2a7099'], ], width: 2, }, }, splitLine: { show: false, length: 30, distance: -30, lineStyle: { width: 5, color: '#01033a', }, }, detail: false, axisTick: { show: false, }, data: [ { value: this.chartOptions.value || this.value, }, ], }, // 第三个仪表盘 { type: 'gauge', center: ['50%', '50%'], radius: '80%', startAngle: 230, endAngle: -50, min: 0, max: 100, pointer: { show: true, icon: 'pin', length: 32, width: 20, itemStyle: { color: this.color, }, }, markPoint: { symbol: 'circle', symbolSize: 70, data: [ //跟你的仪表盘的中心位置对应上,颜色可以和画板底色一样 { value: this.level, x: 'center', y: 'center', itemStyle: { color: this.color, shadowColor: this.color, shadowBlur: 150, shadowOffsetX: 0, shadowOffsetY: 0, }, }, ], label: { show: true, color: '#FFF', //气泡中字体颜色 fontSize: 20, }, }, axisLabel: { show: false, }, axisLine: { lineStyle: { color: [ [0.12, '#eee305'], [0.33, '#eee305'], [0.54, '#f68d06'], [0.66, '#f68d06'], [0.9, '#ff2023'], [1, '#ff2023'], ], width: 30, }, }, detail: false, axisTick: { show: false, }, splitLine: { show: true, length: 30, distance: -30, lineStyle: { width: 5, color: '#01033a', }, }, splitNumber: 6, data: [ { value: this.chartOptions.value || this.value, }, ], }, // 内侧圆形 { name: '数量', type: 'pie', hoverAnimation: false, clockwise: false, radius: ['35%', '35%'], center: ['50%', '50%'], data: [10], itemStyle: { normal: { borderWidth: 1, borderType: 'dotted', //dotted 虚线 borderColor: this.color, // 虚线颜色 opacity: 0.4, }, }, label: { normal: { show: false, }, emphasis: { show: false, textStyle: { fontSize: '14', }, }, }, labelLine: { normal: { show: false, }, }, }, // 内侧圆形 { name: '数量', type: 'pie', hoverAnimation: false, clockwise: false, radius: ['36%', '36%'], center: ['50%', '50%'], data: [10], itemStyle: { normal: { borderWidth: 1, borderType: 'dotted', //dotted 虚线 borderColor: this.color, // 虚线颜色 opacity: 0.4, }, }, label: { normal: { show: false, }, emphasis: { show: false, textStyle: { fontSize: '14', }, }, }, labelLine: { normal: { show: false, }, }, }, // 内侧圆形 { name: '数量', type: 'pie', hoverAnimation: false, clockwise: false, radius: ['30%', '30%'], center: ['50%', '50%'], data: [10], itemStyle: { normal: { borderWidth: 1, borderType: 'dotted', //dotted 虚线 borderColor: this.color, // 虚线颜色 opacity: 0.4, }, }, label: { normal: { show: false, }, emphasis: { show: false, textStyle: { fontSize: '14', }, }, }, labelLine: { normal: { show: false, }, }, }, // 内侧圆形 { name: '数量', type: 'pie', hoverAnimation: false, clockwise: false, radius: ['32%', '32%'], center: ['50%', '50%'], data: [10], itemStyle: { normal: { borderWidth: 1, borderType: 'dotted', //dotted 虚线 borderColor: this.color, // 虚线颜色 opacity: 0.4, }, }, label: { normal: { show: false, }, emphasis: { show: false, textStyle: { fontSize: '14', }, }, }, labelLine: { normal: { show: false, }, }, }, ], } const mergedOptions = deepMerge({}, this.defaultOptions) const res = deepMerge( mergedOptions, this.chartOptions.echartOptions || {} ) return res }, // 更新图表 updateChart() { const option = this.generateChartOption() if (this.chartInstance) { this.chartInstance.setOption(option, true) } else { console.warn('ECharts instance is not initialized yet.') } }, }, mounted() { window.addEventListener('resize', this.handleResize) this.initChart() }, beforeDestroy() { window.removeEventListener('resize', this.handleResize) if (this.chartInstance) { this.chartInstance.dispose() } }, watch: { 'chartOptions.value': { handler(newValue) { this.updateColor(newValue) this.updateChart() }, immediate: true, }, chartOptions: { deep: true, handler() { this.updateChart() }, }, }, }</script><!-- Add "scoped" attribute to limit CSS to this component only --><style lang="scss" scoped> #charts { width: 100%; height: 100%; }</style>