| | |
| | | <template> |
| | | <div class="tech-chart-container"> |
| | | <Echart |
| | | :options="options" |
| | | :autoresize="true" |
| | | style="width: 100%; height: 100%" |
| | | /> |
| | | <div id="name" style="width: 100%; height: 100%"> |
| | | <!-- 渲æ ECharts é¥¼å¾ --> |
| | | <Echart :options="options" style="width: 100%; height: 100%"></Echart> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { currentGET } from "api/modules"; |
| | | import { GetCPLargeStockCount } from "@/api/http.js"; |
| | | import * as echarts from 'echarts'; |
| | | |
| | | export default { |
| | | data() { |
| | | return { |
| | | options: { |
| | | backgroundColor: 'transparent', |
| | | title: { |
| | | text: 'æå产ååºåæ»æ°', |
| | | subtext: 'å è½½ä¸...', |
| | | textStyle: { |
| | | color: '#00b5f3', |
| | | fontSize: 14, |
| | | }, |
| | | subtextStyle: { |
| | | align: 'center', |
| | | fontSize: 28, |
| | | color: '#4be1ff', |
| | | fontWeight: 'bold', |
| | | textShadow: '0 0 15px rgba(75, 225, 255, 0.7)' |
| | | }, |
| | | x: 'center', |
| | | y: 'center', |
| | | }, |
| | | tooltip: { |
| | | show: false // å®å
¨ç¦ç¨tooltip |
| | | }, |
| | | series: [ |
| | | { |
| | | name: 'åºåæ°é', |
| | | type: 'pie', |
| | | radius: ['65%', '85%'], |
| | | center: ['50%', '50%'], |
| | | hoverAnimation: false, // ç¦ç¨æ¬åå¨ç» |
| | | silent: true, // ç¦ç¨ææäº¤äº |
| | | label: { |
| | | show: false |
| | | }, |
| | | labelLine: { |
| | | show: false |
| | | }, |
| | | itemStyle: { |
| | | borderWidth: 0, |
| | | shadowBlur: 20, |
| | | shadowColor: 'rgba(0, 150, 255, 0.5)' |
| | | }, |
| | | data: [{ |
| | | value: 0, |
| | | name: '', |
| | | itemStyle: { |
| | | // éèè²å°èç½è²æ¸åï¼æ·»å å¨æææ |
| | | color: { |
| | | type: 'linear', |
| | | x: 0, |
| | | y: 0, |
| | | x2: 0, |
| | | y2: 1, |
| | | colorStops: [ |
| | | { offset: 0, color: '#00ffcc' }, |
| | | { offset: 0.5, color: '#00b4ff' }, |
| | | { offset: 1, color: '#0062ff' } |
| | | ], |
| | | global: false |
| | | } |
| | | } |
| | | }] |
| | | }, |
| | | // æ·»å å¤åå
åç¯ |
| | | { |
| | | type: 'pie', |
| | | radius: ['85%', '87%'], |
| | | center: ['50%', '50%'], |
| | | hoverAnimation: false, |
| | | silent: true, |
| | | label: { show: false }, |
| | | labelLine: { show: false }, |
| | | itemStyle: { |
| | | // éèè²å°èç½è²æ¸åï¼æ·»å å¨æææ |
| | | color: { |
| | | type: 'linear', |
| | | x: 0, |
| | | y: 0, |
| | | x2: 0, |
| | | y2: 1, |
| | | colorStops: [ |
| | | { offset: 0, color: '#00ffcc' }, |
| | | { offset: 0.5, color: '#00b4ff' }, |
| | | { offset: 1, color: '#0062ff' } |
| | | ], |
| | | global: false |
| | | } |
| | | }, |
| | | data: [{ |
| | | value: 1, |
| | | name: '' |
| | | }] |
| | | }, |
| | | // æ·»å å
åå
åç¯ |
| | | { |
| | | type: 'pie', |
| | | radius: ['63%', '65%'], |
| | | center: ['50%', '50%'], |
| | | hoverAnimation: false, |
| | | silent: true, |
| | | label: { show: false }, |
| | | labelLine: { show: false }, |
| | | itemStyle: { |
| | | // éèè²å°èç½è²æ¸åï¼æ·»å å¨æææ |
| | | color: { |
| | | type: 'linear', |
| | | x: 0, |
| | | y: 0, |
| | | x2: 0, |
| | | y2: 1, |
| | | colorStops: [ |
| | | { offset: 0, color: '#00ffcc' }, |
| | | { offset: 0.5, color: '#00b4ff' }, |
| | | { offset: 1, color: '#0062ff' } |
| | | ], |
| | | global: false |
| | | } |
| | | }, |
| | | data: [{ |
| | | value: 1, |
| | | name: '' |
| | | }] |
| | | }, |
| | | // æ·»å 卿ç²åææ |
| | | { |
| | | type: 'scatter', |
| | | coordinateSystem: 'none', |
| | | data: this.generateParticles(30), |
| | | symbolSize: (val) => { |
| | | return val[2] * 2; |
| | | }, |
| | | itemStyle: { |
| | | color: new echarts.graphic.RadialGradient(0.4, 0.3, 1, [ |
| | | { offset: 0, color: 'rgba(0, 255, 255, 0.8)' }, |
| | | { offset: 1, color: 'rgba(0, 255, 255, 0)' } |
| | | ]) |
| | | }, |
| | | // æ·»å ç²åéªçææ |
| | | effect: { |
| | | show: true, |
| | | period: 2, |
| | | trailLength: 0.1, |
| | | symbol: 'circle', |
| | | symbolSize: 0 |
| | | } |
| | | } |
| | | ] |
| | | }, |
| | | timer: null, |
| | | particleTimer: null, |
| | | gradientTimer: null |
| | | pageflag: true, |
| | | options: {}, // åå¨ ECharts é
ç½® |
| | | timer: null // 宿¶å¨æ è¯ |
| | | }; |
| | | }, |
| | | mounted() { |
| | | this.fetchData(); |
| | | this.startAutoRefresh(); |
| | | this.startParticleAnimation(); |
| | | this.startGradientAnimation(); |
| | | }, |
| | | beforeDestroy() { |
| | | this.stopAutoRefresh(); |
| | | this.stopParticleAnimation(); |
| | | this.stopGradientAnimation(); |
| | | created() { |
| | | this.getData(); |
| | | }, |
| | | methods: { |
| | | generateParticles(count) { |
| | | const particles = []; |
| | | for (let i = 0; i < count; i++) { |
| | | const angle = Math.random() * Math.PI * 2; |
| | | const radius = 0.7 + Math.random() * 0.2; |
| | | particles.push([ |
| | | Math.cos(angle) * radius, |
| | | Math.sin(angle) * radius, |
| | | Math.random() * 2 + 1 |
| | | ]); |
| | | } |
| | | return particles; |
| | | async getData() { |
| | | const rep = await GetCPLargeStockCount(); |
| | | // ç»è£
饼徿°æ®ï¼[{value: æ°é, name: 产åç¼ç }, ...] |
| | | const pieData = rep.map(item => ({ |
| | | value: item.qtys, |
| | | name: item.pCode |
| | | })); |
| | | // è®¡ç®æ»åï¼ç¨äºè®¡ç®ç¾åæ¯ |
| | | const total = pieData.reduce((acc, cur) => acc + cur.value, 0); |
| | | // é
ç½® ECharts é¥¼å¾ |
| | | this.options = { |
| | | backgroundColor: '#000', |
| | | tooltip: { |
| | | trigger: 'item', // é¼ æ æ¬æµ®æç¤ºï¼è§¦åæ¹å¼ä¸ºâitemâï¼é坹饼徿åºï¼ |
| | | }, |
| | | |
| | | series: [ |
| | | { |
| | | name: '客æ·ä»£ç ', |
| | | type: 'pie', |
| | | radius: ['40%', '70%'], // 饼å¾å
å¤åå¾ï¼å®ç°ç¯å½¢/æå½¢ææ |
| | | center: ['50%', '50%'], // 饼å¾å¨å®¹å¨ä¸çä¸å¿ä½ç½® |
| | | color: [ |
| | | 'rgba(135,183,255, 1)', // 对åºç¤ºä¾é¥¼å¾é¢è²ï¼å¯æéè°æ´ |
| | | 'rgba(248,195,248, 1)', |
| | | 'rgba(100,255,249, 1)', |
| | | 'rgba(100,255,249, 1)', |
| | | 'rgba(248,195,248, 1)' |
| | | ], |
| | | label: { |
| | | show: true, |
| | | position: 'outside', |
| | | textStyle: { |
| | | color: '#b3ccf8', |
| | | fontSize: 14, |
| | | fontFamily: 'PingFangSC-Regular' |
| | | }, |
| | | // æ ¼å¼åæ ç¾ï¼æ¾ç¤ºåç§°åç¾åæ¯ |
| | | formatter: (params) => { |
| | | const percent = ((params.value / total) * 100).toFixed(2) + '%'; |
| | | return `${params.name}\n${percent}`; |
| | | } |
| | | }, |
| | | data: pieData, |
| | | }, |
| | | ], |
| | | }; |
| | | }, |
| | | async fetchData() { |
| | | try { |
| | | const response = await GetCPLargeStockCount({}); |
| | | const stockCount = response.stockCount || 0; |
| | | this.updateChart(stockCount); |
| | | } catch (error) { |
| | | console.error('è·ååºåæ»æ°å¤±è´¥:', error); |
| | | this.options.title.subtext = 'æ°æ®å¼å¸¸'; |
| | | this.options.title.subtextStyle.color = '#ff4d4f'; |
| | | } |
| | | // è½®è¯¢ï¼æ¯éä¸å¤©è¯·æ±ä¸æ¬¡æ°æ®ï¼ |
| | | switper() { |
| | | if (this.timer) return; |
| | | // æ¯éä¸å¤©ï¼86400000 毫ç§ï¼æ§è¡ä¸æ¬¡ getData |
| | | this.timer = setInterval(() => { |
| | | this.getData(); |
| | | }, 86400000); |
| | | }, |
| | | updateChart(count) { |
| | | this.options.series[0].data[0].value = count; |
| | | this.options.title.subtext = count + 'ç§'; |
| | | this.options.title.subtextStyle.color = count > 0? '#4be1ff' : '#ff4d4f'; |
| | | }, |
| | | startAutoRefresh() { |
| | | this.stopAutoRefresh(); |
| | | this.timer = setInterval(() => { |
| | | this.fetchData(); |
| | | }, 3000); |
| | | }, |
| | | stopAutoRefresh() { |
| | | if (this.timer) clearInterval(this.timer); |
| | | }, |
| | | startParticleAnimation() { |
| | | this.stopParticleAnimation(); |
| | | this.particleTimer = setInterval(() => { |
| | | this.options.series[3].data = this.generateParticles(30); |
| | | this.options = {...this.options }; // 触åè§å¾æ´æ° |
| | | }, 2000); |
| | | }, |
| | | stopParticleAnimation() { |
| | | if (this.particleTimer) clearInterval(this.particleTimer); |
| | | }, |
| | | startGradientAnimation() { |
| | | this.stopGradientAnimation(); |
| | | this.gradientTimer = setInterval(() => { |
| | | const offset = Math.random(); |
| | | this.options.series.forEach(series => { |
| | | if (series.itemStyle.color.type === 'linear') { |
| | | series.itemStyle.color.colorStops.forEach(stop => { |
| | | stop.offset = (stop.offset + offset) % 1; |
| | | }); |
| | | } |
| | | }); |
| | | this.options = {...this.options }; // 触åè§å¾æ´æ° |
| | | }, 1000); |
| | | }, |
| | | stopGradientAnimation() { |
| | | if (this.gradientTimer) clearInterval(this.gradientTimer); |
| | | }, |
| | | beforeDestroy() { |
| | | // ç»ä»¶éæ¯æ¶æ¸
é¤å®æ¶å¨ |
| | | if (this.timer) { |
| | | clearInterval(this.timer); |
| | | this.timer = null; |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.switper(); // æè½½åå¯å¨å®æ¶å¨ |
| | | } |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .tech-chart-container { |
| | | width: 100%; |
| | | height: 100%; |
| | | position: relative; |
| | | background: radial-gradient(circle at center, #021228 0%, #000810 100%); |
| | | border-radius: 8px; |
| | | overflow: hidden; |
| | | box-shadow: 0 0 30px rgba(0, 100, 255, 0.2); |
| | | |
| | | &::before { |
| | | content: ''; |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | background: |
| | | radial-gradient(circle at 20% 30%, rgba(0, 150, 255, 0.1) 0%, transparent 50%), |
| | | radial-gradient(circle at 80% 70%, rgba(0, 200, 255, 0.1) 0%, transparent 50%); |
| | | z-index: 0; |
| | | animation: pulse 8s infinite alternate; |
| | | } |
| | | } |
| | | |
| | | @keyframes pulse { |
| | | 0% { |
| | | opacity: 0.3; |
| | | } |
| | | 100% { |
| | | opacity: 0.7; |
| | | } |
| | | } |
| | | |
| | | ::v-deep .echarts { |
| | | position: relative; |
| | | z-index: 1; |
| | | } |
| | | <style lang='scss' scoped> |
| | | /* è¥æ éç¹æ®æ ·å¼ï¼å¯ç®åæå é¤ */ |
| | | </style> |