<template> <div class="chartBox" :id="id"></div> </template> <script setup name="pieRing"> import { guid } from '@/utils/ruoyi'; const { proxy } = getCurrentInstance(); const props = defineProps({ //刷新标志 refresh: { type: [String, Number], default: 1, }, //数据 echartData: { type: Object, default: {}, }, title: { type: String, default: '', }, }); // console.log('-------------------', props.title); const id = guid(); const myChart = shallowRef(''); let angle = 0; //角度,用来做简单的动画效果的 let pieValue = ref(80); let maxvalue = 100; let timerId = null; let option = ref({}); watch( () => props.refresh, value => { //先销毁实例 myChart.value && myChart.value.dispose(); intChart(); } ); //自适应 function resizeTheChart() { if (myChart.value) { myChart.value.resize(); } } //获取圆上面某点的坐标(x0,y0表示坐标,r半径,angle角度) function getCirlPoint(x0, y0, r, angle) { let x1 = x0 + r * Math.cos((angle * Math.PI) / 180); let y1 = y0 + r * Math.sin((angle * Math.PI) / 180); return { x: x1, y: y1, }; } function draw() { angle = angle + 10; myChart.value.setOption(option.value, true); //window.requestAnimationFrame(draw); } //初始化 function intChart() { pieValue.value = props.echartData?.data || 0; let percent = ((pieValue.value / maxvalue) * 100).toFixed(0); myChart.value = proxy.echarts.init(document.getElementById(id)); myChart.value.clear(); // 绘制图表 // if (!props.echartData.series.length) return; option.value = { // backgroundColor: '#000E1A', title: { text: '{a|' + percent + '} {c|分}', x: 'center', y: 'center', textStyle: { rich: { a: { fontSize: 32, color: 'rgba(28, 138, 255, 1)', // fontFamily: 'Din', // lineHeight: 40, // 调整行高以确保对齐 verticalAlign: 'bottom', // 底部对齐 }, c: { fontSize: 14, color: 'rgba(206, 246, 255, 1)', // fontFamily: 'SanFrancisco ', // lineHeight: 20, // 调整行高以确保对齐 // verticalAlign: 'bottom', // 底部对齐 }, }, }, }, polar: [ { // radius: ['33.5%', '45%'], radius: ['85%', '100%'], // radius: '100%', center: ['50%', '50%'], // startAngle: 180, // 从180度开始 // endAngle: 0, // 到0度结束 }, ], angleAxis: { max: maxvalue, show: false, inverse: false, clockwise: false, //角度轴的方向为逆时针方向。 }, radiusAxis: { type: 'category', show: true, axisLabel: { show: false, }, axisLine: { show: false, }, axisTick: { show: false, }, }, series: [ // 大弧线 { name: 'ring5', type: 'custom', coordinateSystem: 'none', renderItem: function (params, api) { return { type: 'arc', shape: { cx: api.getWidth() / 2, cy: api.getHeight() / 2, r: (Math.min(api.getWidth(), api.getHeight()) / 2.1) * 0.9, // r: (Math.min(api.getWidth(), api.getHeight()) / 2.3) * 0.6, // startAngle: (0+angle) * Math.PI / 180, // endAngle: (90+angle) * Math.PI / 180 startAngle: (0 * Math.PI) / 180, endAngle: (360 * Math.PI) / 180, }, style: { // stroke: 'rgb(53,53,53)', stroke: 'rgba(28, 138, 255,0.5)', fill: ' transparent', lineWidth: 5, }, silent: true, }; }, data: [0], }, // { // name: 'ring5', // type: 'custom', // coordinateSystem: 'none', // renderItem: function (params, api) { // // 定义线性渐变色 // // let gradient = proxy.echarts.graphic.RadialGradient( // // 0.5, // // 0.5, // 圆心位置,相对于容器的百分比 // // 0.5, // 半径,相对于容器的百分比 // // [ // // { offset: 0, color: 'rgba(62,255,203,0)' }, // 起始颜色 // // { offset: 1, color: '#3EFFCB' }, // 结束颜色 // // ] // // ); // return { // type: 'arc', // shape: { // cx: api.getWidth() / 2, // cy: api.getHeight() / 2, // r: (Math.min(api.getWidth(), api.getHeight()) / 2) * 0.6, // startAngle: ((0 + angle) * Math.PI) / 180, // endAngle: ((270 + angle) * Math.PI) / 180, // }, // style: { // stroke: '#3EFFCB', // // stroke: gradient, // fill: 'transparent', // lineWidth: 5, // }, // silent: true, // }; // }, // data: [0], // }, //极坐标柱状图 { name: '', type: 'bar', roundCap: true, barWidth: 10, showBackground: true, stack: 'a', backgroundStyle: { color: 'rgba(66, 66, 66, 0)', // borderWidth: 5, }, data: [pieValue.value, 0], coordinateSystem: 'polar', itemStyle: { normal: { color: proxy.echarts.graphic.LinearGradient(0, 1, 0, 0, [ { offset: 0, color: 'rgb(255,255,255,0.8)', }, { offset: 1, color: 'rgba(255,255,255,1)', }, ]), shadowBlur: 5, shadowColor: 'rgba(28, 138, 255,0.8)', }, }, }, ], }; myChart.value.setOption(option.value); } onMounted(() => { intChart(); window.addEventListener('resize', resizeTheChart); // timerId = setInterval(function () { // //用setInterval做动画感觉有问题 // draw(); // }, 100); }); onBeforeUnmount(() => { if (timerId) { clearInterval(timerId); } myChart.value && myChart.value.dispose(); window.removeEventListener('resize', resizeTheChart); }); </script> <style lang="scss" scoped> .chartBox { width: 100%; height: 100%; } </style>