在vue3中,如何優雅的使用echarts之實現大屏項目

前置知識?

效果圖

使用技術?

Vue3 + Echarts + Gasp

Gasp:是一個 JavaScript動畫庫,它支持快速開發高性能的 Web 動畫。在本項目中,主要是用于做軌跡運動

所需安裝的插件
npm i echarts
npm i countup.js 數字滾動特效
npm i gsap javascript動畫庫
npm i axios
npm i normalize.css 初始化樣式文件 
npm i lodash javascript工具函數庫    https://www.lodashjs.com/
npm i sass css預處理工具 

適配目標

1920*1080px 設計稿尺寸

目標設備:16:9

前期準備

封裝echarts

在大屏中,如果每個圖表都去單獨寫 init 以及進行resize監聽機會顯得很麻煩,這里我們可以將這些重復的步驟封裝成一個hooks,這樣在使用的時候就可以統一的進行初始化和進行resize監聽。

具體代碼如下:

src/hooks/useEcharts.js

import * as echarts from "echarts";
import { ref, onMounted, onUnmounted } from "vue";export default function useEchart(divEl) {// 參數一:DOM容器,參數二:主題色,參數三:渲染方式let echartInstance = echarts.init(divEl, null, { renderer: "svg" });onUnmounted(() => {// 銷毀實例echartInstance.dispose()})const setOption = (option) => {echartInstance.setOption(option)}const resizeEchart = () => {echartInstance.resize()}return {echartInstance,setOption,resizeEchart}
}

?

封裝sclae

這里我們可以新建一個 useScalePage hooks,目的在于隨著瀏覽器視口的變化是,大屏能夠隨之跟著變化,但是為了限制用戶在一定時間內去頻繁的改變瀏覽器視口,因此這里我們可以利用lodash的throttle節流閥進行限制

主要思路:

  • 根據當前設計稿的寬高以及寬高比,再獲取當前設備的即瀏覽器的寬高。
  • 通過當前設備的寬度比上當前設計稿的寬度,從而獲取到默認情況下的一個寬高比例
  • 再通過當前設備的寬度比上當前設備的高度,從而獲取到當前情況下的一個寬高比例

代碼入下:

useScalePage.js

import { onMounted, onUnmounted } from 'vue';
import _ from 'lodash' /**大屏適配的 hooks*/
export default function useScalePage(option) {const resizeFunc = _.throttle(function() {triggerScale() // 動畫縮放網頁}, 100)onMounted(()=>{triggerScale()  // 動畫縮放網頁window.addEventListener('resize', resizeFunc)})// 釋放資源onUnmounted(()=>{window.removeEventListener('resize', resizeFunc) // 釋放})// 大屏的適配function triggerScale() {// 1.設計稿的尺寸let targetX = option.targetX ||  1920let targetY = option.targetY || 1080let targetRatio = option.targetRatio ||  16 / 9 // 寬高比率// 2.拿到當前設備(瀏覽器)的寬度let currentX = document.documentElement.clientWidth || document.body.clientWidthlet currentY = document.documentElement.clientHeight || document.body.clientHeight// 3.計算縮放比例let scaleRatio = currentX / targetX; // 參照寬度進行縮放 ( 默認情況 )let currentRatio = currentX / currentY // 寬高比率// 超寬屏if(currentRatio > targetRatio) {// 4.開始縮放網頁scaleRatio = currentY / targetY // 參照高度進行縮放document.body.style = `width:${targetX}px; height:${targetY}px;transform: scale(${scaleRatio}) translateX(-50%); left: 50%`} else {// 4.開始縮放網頁document.body.style = `width:${targetX}px; height:${targetY}px; transform: scale(${scaleRatio})`}}
}

?

請求方法封裝

services/request/config.js? 該文件的目的就是存放一些常量配置,比如:請求地址、超時時間等

export const BASE_URL = "http://123.207.32.32:9060/beike/api"
export const TIMEOUT = 10000

services/index.js

import axios from 'axios'
import { BASE_URL, TIMEOUT } from './config'
class LWJRequest {constructor(baseURL = BASE_URL, timeout= TIMEOUT) {this.instance = axios.create({baseURL,timeout})}request(config) {return new Promise((resolve, reject) => {this.instance.request(config).then(res => {resolve(res.data)}).catch(err => {reject(err)})})}get(config) {return this.request({ ...config, method: "get" })}post(config) {return this.request({ ...config, method: "post" })}
}
export default new LWJRequest()

?

圖表封裝?

這里封裝的組件放置在 components 里,具體代碼如下所示:

餅圖封裝

pie-echarts.vue

<template><div :style="{ width: width, height: height }" ref="divRef"></div>
</template><script setup>
import { ref, onMounted, watch } from "vue";
import useEchart from "@/hooks/useEchart";const props = defineProps({width: {type: String,default: "100%",},height: {type: String,default: "100%",},echartsChargingPileData: {type: Array,default: function () {return [];},},
});// 監聽 echartDatas 的變化
watch(() => props.echartsChargingPileData, (newV, oldV) => {setupEchart(newV);}
);// 獲取dom元素
let divRef = ref(null);
let myChart = null;onMounted(() => {setupEchart(props.echartsChargingPileData); // 第一次走這里
});function setupEchart(echartDatas = []) {if (!myChart) {myChart = useEchart(divRef.value);}let option = getOption(echartDatas); // 準備數據myChart.setOption(option);
}function getOption(pieDatas = []) {let colors = pieDatas.map((item) => {return item.color;});let data = pieDatas.map((item) => {return {value: item.value,name: item.name,};});let total = pieDatas.reduce((a, b) => {return a + b.value * 1;}, 0);const option = {colors: colors,title: {text: `{nameSty| 充電樁總數}\n{numberSty|${total}}`,top: "50%",left: "30%",textStyle: {rich: {nameSty: {fontSize: 19,color: "white",padding: [10, 0],},numberSty: {fontSize: 24,color: "white",padding: [4, 0, 0, 20],},},},},legend: {orient: "vertical",right: "10%",top: "18%",itemGap: 20,itemWidth: 16,itemHeigth: 16,icon: "rect",// 格式化圖例文本formatter: function (name) {var currentItem = pieDatas.find((item) => item.name === name);return ("{nameSty|" +currentItem.name +"}\n" +"{numberSty|" +currentItem.value +"個 }" +"{preSty|" +currentItem.percentage +"}");},textStyle: {rich: {nameSty: {fontSize: 12,color: "#FFFFFF",padding: [10, 14],},numberSty: {fontSize: 12,color: "#40E6ff",padding: [0, 0, 0, 14],},preSty: {fontSize: 12,color: "#40E6ff",},},},},series: [{type: "pie",center: ["40%", "57%"],radius: ["30%", "75%"],label: {show: false,},data: data,roseType: "area",},],};return option;
}
</script><style lang="scss" scoped></style>
折線圖

line-echarts.js

<template><div ref="divRef" :style="{ width: width, height: height }"></div>
</template><script setup>
import { ref, onMounted, watch } from "vue";
import useEchart from "@/hooks/useEchart";const props = defineProps({width: {type: String,default: "100%",},height: {type: String,default: "100%",},echartsPrecessMonitoringData: {type: Array,default: function () {return [];},},
});// 監聽 echartDatas 的變化
watch(() => props.echartsPrecessMonitoringData, (newV, oldV) => {setupEchart(newV);}
);// 獲取dom元素
let divRef = ref(null);
let myChart = null;onMounted(() => {setupEchart(props.echartsPrecessMonitoringData); // 第一次走這里
});function setupEchart(echartDatas = []) {if (!myChart) {myChart = useEchart(divRef.value);}let option = getOption(echartDatas); // 準備數據myChart.setOption(option);
}function getOption(echartDatas = []) {let option = {// backgroundColor: 'rbg(40,46,72)',grid: {left: "5%",right: "1%",top: "20%",bottom: "15%",containLabel: true, // grid 區域是否包含坐標軸的刻度標簽},legend: {right: "center",bottom: "5%",itemGap: 20,itemWidth: 13,itemHeigth: 12,textStyle: {color: "#64BCFF",},icon: "rect",},tooltip: {trigger: "axis",axisPointer: {type: "line",lineStyle: {color: "#20FF89",},},},xAxis: [{type: "category",axisLine: {show: false,},axisLabel: {color: "#64BCFF",},splitLine: {show: false,},axisTick: {show: false,},data: ["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月",],},],yAxis: [{type: "value",splitLine: {show: false,},axisLine: {show: false,},axisLabel: {show: true,color: "#64BCFF",},},],series: [{name: echartDatas[0].name,type: "line",smooth: true,stack: "總量",symbolSize: 5,showSymbol: false,itemStyle: {color: "#20FF89",lineStyle: {color: "#20FF89",width: 2,},},areaStyle: {color: {type: "linear",x: 0,y: 0,x2: 0,y2: 1,colorStops: [{offset: 0,color: "#20FF89",},{offset: 1,color: "rgba(255, 255, 255, 0)",},],},},data: echartDatas[0].data,},{name: echartDatas[1].name,type: "line",smooth: true,stack: "總量",symbolSize: 5,showSymbol: false,itemStyle: {color: "#EA9502",lineStyle: {color: "#EA9502",width: 2,},},areaStyle: {color: {type: "linear",x: 0,y: 0,x2: 0,y2: 1,colorStops: [{offset: 0,color: "#EA9502",},{offset: 1,color: "rgba(255, 255, 255, 0)",},],},},data:  echartDatas[1].data,},],};return option
}
</script><style lang="scss" scoped></style>

柱狀圖

bar-echarts.vue

<template><div ref="divRef" :style="{ width: width, height: height }"></div>
</template><script setup>
import { ref, onMounted, watch } from "vue";
import useEchart from "@/hooks/useEchart";const props = defineProps({width: {type: String,default: "100%",},height: {type: String,default: "100%",},echartsChargingStatisticsData: {type: Array,default: function () {return [];},},
});// 監聽 echartDatas 的變化
watch(() => props.echartsChargingStatisticsData,(newV, oldV) => {setupEchart(newV);}
);// 獲取dom元素
let divRef = ref(null);
let myChart = null;onMounted(() => {setupEchart(props.echartsChargingStatisticsData); // 第一次走這里
});function setupEchart(echartDatas = []) {if (!myChart) {myChart = useEchart(divRef.value);}let option = getOption(echartDatas); // 準備數據myChart.setOption(option);
}function getOption(echartDatas = []) {let category = echartDatas.map(item => item.name)let categoryData = echartDatas.map(item => item.value)const option = {// backgroundColor: 'rbg(40,46,72)',grid: {left: "5%",right: "5%",top: "30%",bottom: "5%",containLabel: true, // grid 區域是否包含坐標軸的刻度標簽},tooltip: {},xAxis: {axisLine: {show: true,lineStyle: {color: "#42A4FF",},},axisTick: {show: false,},axisLabel: {color: "white",},// data: ["一月", "二月", "三月", "四月", "五月", "六月", "七月"],data: category},yAxis: {name: "個",nameTextStyle: {color: "white",fontSize: 13,},axisLine: {show: true,lineStyle: {color: "#42A4FF",},},axisTick: {show: false,},splitLine: {show: true,lineStyle: {color: "#42A4FF",},},axisLabel: {color: "white",},},series: [{name: "銷量",type: "bar",barWidth: 17,itemStyle: {color: {type: "linear",x: 0,y: 0,x2: 0,y2: 1,colorStops: [{offset: 0,color: "#01B1FF", // 0% 處的顏色},{offset: 1,color: "#033BFF", // 100% 處的顏色},],global: false, // 缺省為 false},},// data: [500, 2000, 3600, 1000, 1000, 2000, 4000],data: categoryData},],};return option;
}
</script><style lang="scss" scoped></style>

其他區域封裝

center-svg.vue
<template><div class="center-svg"><svgid="dongxiao"data-name="dongxiao"xmlns="http://www.w3.org/2000/svg"xmlns:xlink="http://www.w3.org/1999/xlink"width="787.781"height="652"viewBox="0 0 787.781 652"><defs><linearGradientid="linear-gradient"x1="177.891"y1="126.344"x2="177.891"y2="51.375"gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#030000" /><stop offset="1" stop-color="#fff" /></linearGradient><linearGradientid="linear-gradient-2"x1="177.891"y1="110.344"x2="177.891"y2="44.719"xlink:href="#linear-gradient"/><linearGradientid="linear-gradient-3"x1="177.969"y1="90.719"x2="177.969"y2="-0.625"gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#26bbff" /><stop offset="1" stop-color="#26bbff" stop-opacity="0" /></linearGradient><linearGradientid="linear-gradient-4"x1="177.969"y1="91.219"x2="177.969"y2="46.875"gradientUnits="userSpaceOnUse"><stop offset="-0.055" stop-color="#26bbff" /><stop offset="1.044" stop-color="#26bbff" stop-opacity="0" /><stop offset="1.055" stop-color="#26bbff" /></linearGradient><linearGradientid="linear-gradient-5"x1="178.109"y1="87.563"x2="178.109"y2="38"gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#fff" /><stop offset="1" stop-color="#fff" stop-opacity="0" /></linearGradient><linearGradientid="linear-gradient-6"x1="718.89"y1="414.344"x2="718.89"y2="339.375"xlink:href="#linear-gradient"/><linearGradientid="linear-gradient-7"x1="718.89"y1="398.344"x2="718.89"y2="332.719"xlink:href="#linear-gradient"/><linearGradientid="linear-gradient-8"x1="718.969"y1="378.719"x2="718.969"y2="287.375"xlink:href="#linear-gradient-3"/><linearGradientid="linear-gradient-9"x1="718.968"y1="379.219"x2="718.968"y2="334.875"xlink:href="#linear-gradient-4"/><linearGradientid="linear-gradient-10"x1="719.109"y1="375.562"x2="719.109"y2="326"xlink:href="#linear-gradient-5"/><linearGradientid="linear-gradient-11"x1="67.891"y1="325.344"x2="67.891"y2="250.375"xlink:href="#linear-gradient"/><linearGradientid="linear-gradient-12"x1="67.891"y1="309.344"x2="67.891"y2="243.719"xlink:href="#linear-gradient"/><linearGradientid="linear-gradient-13"x1="67.969"y1="289.719"x2="67.969"y2="198.375"xlink:href="#linear-gradient-3"/><linearGradientid="linear-gradient-14"x1="67.969"y1="290.219"x2="67.969"y2="245.875"xlink:href="#linear-gradient-4"/><linearGradientid="linear-gradient-15"x1="68.109"y1="286.562"x2="68.109"y2="237"xlink:href="#linear-gradient-5"/><linearGradientid="linear-gradient-16"x1="159.891"y1="596.344"x2="159.891"y2="521.375"xlink:href="#linear-gradient"/><linearGradientid="linear-gradient-17"x1="159.891"y1="580.344"x2="159.891"y2="514.719"xlink:href="#linear-gradient"/><linearGradientid="linear-gradient-18"x1="159.969"y1="560.719"x2="159.969"y2="469.375"xlink:href="#linear-gradient-3"/><linearGradientid="linear-gradient-19"x1="159.969"y1="561.219"x2="159.969"y2="516.875"xlink:href="#linear-gradient-4"/><linearGradientid="linear-gradient-20"x1="160.109"y1="557.562"x2="160.109"y2="508"xlink:href="#linear-gradient-5"/><linearGradientid="linear-gradient-21"x1="581.89"y1="623.344"x2="581.89"y2="548.375"xlink:href="#linear-gradient"/><linearGradientid="linear-gradient-22"x1="581.89"y1="607.344"x2="581.89"y2="541.719"xlink:href="#linear-gradient"/><linearGradientid="linear-gradient-23"x1="581.969"y1="587.719"x2="581.969"y2="496.375"xlink:href="#linear-gradient-3"/><linearGradientid="linear-gradient-24"x1="581.968"y1="588.219"x2="581.968"y2="543.875"xlink:href="#linear-gradient-4"/><linearGradientid="linear-gradient-25"x1="582.109"y1="584.562"x2="582.109"y2="535"xlink:href="#linear-gradient-5"/><linearGradientid="linear-gradient-26"x1="633.89"y1="145.344"x2="633.89"y2="70.375"xlink:href="#linear-gradient"/><linearGradientid="linear-gradient-27"x1="633.89"y1="129.344"x2="633.89"y2="63.719"xlink:href="#linear-gradient"/><linearGradientid="linear-gradient-28"x1="633.969"y1="109.719"x2="633.969"y2="18.375"xlink:href="#linear-gradient-3"/><linearGradientid="linear-gradient-29"x1="633.968"y1="110.219"x2="633.968"y2="65.875"xlink:href="#linear-gradient-4"/><linearGradientid="linear-gradient-30"x1="634.109"y1="106.562"x2="634.109"y2="57"xlink:href="#linear-gradient-5"/><linearGradientid="linear-gradient-31"x1="273.219"y1="315.25"x2="524.25"y2="443.156"gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#fbab00" /><stop offset="0.342" stop-color="#f98100" /><stop offset="0.75" stop-color="#f86d00" stop-opacity="0" /><stop offset="1" stop-color="#f86000" /></linearGradient><linearGradientid="linear-gradient-32"x1="565.875"y1="379.485"x2="235.062"y2="379.485"gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#1b90ff" /><stop offset="0.745" stop-color="#0752ff" stop-opacity="0" /><stop offset="1" stop-color="#003dff" /></linearGradient><linearGradientid="linear-gradient-33"x1="628.344"y1="445.411"x2="169.406"y2="278.371"gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#fbab00" /><stop offset="0.342" stop-color="#f98100" /><stop offset="1" stop-color="#f86000" stop-opacity="0" /></linearGradient><filterid="filter"x="291"y="214"width="61"height="60"filterUnits="userSpaceOnUse"><feGaussianBlur result="blur" stdDeviation="6.667" in="SourceAlpha" /><feComposite result="composite" /><feComposite result="composite-2" /><feComposite result="composite-3" /><feFlood result="flood" flood-color="#1783ff" flood-opacity="0.9" /><feComposite result="composite-4" operator="in" in2="composite-3" /><feBlend result="blend" in2="SourceGraphic" /><feBlend result="blend-2" in="SourceGraphic" /></filter><filterid="filter-2"x="258"y="155"width="61"height="61"filterUnits="userSpaceOnUse"><feGaussianBlur result="blur" stdDeviation="6.667" in="SourceAlpha" /><feComposite result="composite" /><feComposite result="composite-2" /><feComposite result="composite-3" /><feFlood result="flood" flood-color="#1783ff" flood-opacity="0.9" /><feComposite result="composite-4" operator="in" in2="composite-3" /><feBlend result="blend" in2="SourceGraphic" /><feBlend result="blend-2" in="SourceGraphic" /></filter><!-- 藍色點濾鏡效果 --><filter id="blue-filter-2" filterUnits="userSpaceOnUse"><feGaussianBlur result="blur" stdDeviation="6.667" in="SourceAlpha" /><feComposite result="composite" /><feComposite result="composite-2" /><feComposite result="composite-3" /><feFlood result="flood" flood-color="#1783ff" flood-opacity="0.9" /><feComposite result="composite-4" operator="in" in2="composite-3" /><feBlend result="blend" in2="SourceGraphic" /><feBlend result="blend-2" in="SourceGraphic" /></filter><!-- 橙色點濾鏡特效 --><filter id="orange-filter-2" filterUnits="userSpaceOnUse"><feGaussianBlur result="blur" stdDeviation="6.667" in="SourceAlpha" /><feComposite result="composite" /><feComposite result="composite-2" /><feComposite result="composite-3" /><feFlood result="flood" flood-color="#f97a00" flood-opacity="0.9" /><feComposite result="composite-4" operator="in" in2="composite-3" /><feBlend result="blend" in2="SourceGraphic" /><feBlend result="blend-2" in="SourceGraphic" /></filter><filterid="filter-3"x="126"y="296"width="61"height="61"filterUnits="userSpaceOnUse"><feGaussianBlur result="blur" stdDeviation="6.667" in="SourceAlpha" /><feComposite result="composite" /><feComposite result="composite-2" /><feComposite result="composite-3" /><feFlood result="flood" flood-color="#1783ff" flood-opacity="0.9" /><feComposite result="composite-4" operator="in" in2="composite-3" /><feBlend result="blend" in2="SourceGraphic" /><feBlend result="blend-2" in="SourceGraphic" /></filter><filterid="filter-4"x="255"y="269"width="61"height="61"filterUnits="userSpaceOnUse"><feGaussianBlur result="blur" stdDeviation="6.667" in="SourceAlpha" /><feComposite result="composite" /><feComposite result="composite-2" /><feComposite result="composite-3" /><feFlood result="flood" flood-color="#1783ff" flood-opacity="0.9" /><feComposite result="composite-4" operator="in" in2="composite-3" /><feBlend result="blend" in2="SourceGraphic" /><feBlend result="blend-2" in="SourceGraphic" /></filter><filterid="filter-5"x="226"y="510"width="60"height="61"filterUnits="userSpaceOnUse"><feGaussianBlur result="blur" stdDeviation="6.667" in="SourceAlpha" /><feComposite result="composite" /><feComposite result="composite-2" /><feComposite result="composite-3" /><feFlood result="flood" flood-color="#1783ff" flood-opacity="0.9" /><feComposite result="composite-4" operator="in" in2="composite-3" /><feBlend result="blend" in2="SourceGraphic" /><feBlend result="blend-2" in="SourceGraphic" /></filter><filterid="filter-6"x="256"y="452"width="60"height="60"filterUnits="userSpaceOnUse"><feGaussianBlur result="blur" stdDeviation="6.667" in="SourceAlpha" /><feComposite result="composite" /><feComposite result="composite-2" /><feComposite result="composite-3" /><feFlood result="flood" flood-color="#1783ff" flood-opacity="0.9" /><feComposite result="composite-4" operator="in" in2="composite-3" /><feBlend result="blend" in2="SourceGraphic" /><feBlend result="blend-2" in="SourceGraphic" /></filter><filterid="filter-7"x="257"y="407"width="61"height="61"filterUnits="userSpaceOnUse"><feGaussianBlur result="blur" stdDeviation="6.667" in="SourceAlpha" /><feComposite result="composite" /><feComposite result="composite-2" /><feComposite result="composite-3" /><feFlood result="flood" flood-color="#1783ff" flood-opacity="0.9" /><feComposite result="composite-4" operator="in" in2="composite-3" /><feBlend result="blend" in2="SourceGraphic" /><feBlend result="blend-2" in="SourceGraphic" /></filter><filterid="filter-8"x="247"y="83"width="59"height="59"filterUnits="userSpaceOnUse"><feGaussianBlur result="blur" stdDeviation="6.667" in="SourceAlpha" /><feComposite result="composite" /><feComposite result="composite-2" /><feComposite result="composite-3" /><feFlood result="flood" flood-color="#1783ff" flood-opacity="0.9" /><feComposite result="composite-4" operator="in" in2="composite-3" /><feBlend result="blend" in2="SourceGraphic" /><feBlend result="blend-2" in="SourceGraphic" /></filter><filterid="filter-9"x="262"y="122"width="60"height="59"filterUnits="userSpaceOnUse"><feGaussianBlur result="blur" stdDeviation="6.667" in="SourceAlpha" /><feComposite result="composite" /><feComposite result="composite-2" /><feComposite result="composite-3" /><feFlood result="flood" flood-color="#1783ff" flood-opacity="0.9" /><feComposite result="composite-4" operator="in" in2="composite-3" /><feBlend result="blend" in2="SourceGraphic" /><feBlend result="blend-2" in="SourceGraphic" /></filter><filterid="filter-10"x="278"y="199"width="59"height="60"filterUnits="userSpaceOnUse"><feGaussianBlur result="blur" stdDeviation="6.667" in="SourceAlpha" /><feComposite result="composite" /><feComposite result="composite-2" /><feComposite result="composite-3" /><feFlood result="flood" flood-color="#1783ff" flood-opacity="0.9" /><feComposite result="composite-4" operator="in" in2="composite-3" /><feBlend result="blend" in2="SourceGraphic" /><feBlend result="blend-2" in="SourceGraphic" /></filter><filterid="filter-11"x="112"y="294"width="59"height="59"filterUnits="userSpaceOnUse"><feGaussianBlur result="blur" stdDeviation="6.667" in="SourceAlpha" /><feComposite result="composite" /><feComposite result="composite-2" /><feComposite result="composite-3" /><feFlood result="flood" flood-color="#1783ff" flood-opacity="0.9" /><feComposite result="composite-4" operator="in" in2="composite-3" /><feBlend result="blend" in2="SourceGraphic" /><feBlend result="blend-2" in="SourceGraphic" /></filter><filterid="filter-12"x="206"y="274"width="59"height="59"filterUnits="userSpaceOnUse"><feGaussianBlur result="blur" stdDeviation="6.667" in="SourceAlpha" /><feComposite result="composite" /><feComposite result="composite-2" /><feComposite result="composite-3" /><feFlood result="flood" flood-color="#1783ff" flood-opacity="0.9" /><feComposite result="composite-4" operator="in" in2="composite-3" /><feBlend result="blend" in2="SourceGraphic" /><feBlend result="blend-2" in="SourceGraphic" /></filter><filterid="filter-13"x="255"y="436"width="59"height="60"filterUnits="userSpaceOnUse"><feGaussianBlur result="blur" stdDeviation="6.667" in="SourceAlpha" /><feComposite result="composite" /><feComposite result="composite-2" /><feComposite result="composite-3" /><feFlood result="flood" flood-color="#1783ff" flood-opacity="0.9" /><feComposite result="composite-4" operator="in" in2="composite-3" /><feBlend result="blend" in2="SourceGraphic" /><feBlend result="blend-2" in="SourceGraphic" /></filter><filterid="filter-14"x="238"y="500"width="59"height="59"filterUnits="userSpaceOnUse"><feGaussianBlur result="blur" stdDeviation="6.667" in="SourceAlpha" /><feComposite result="composite" /><feComposite result="composite-2" /><feComposite result="composite-3" /><feFlood result="flood" flood-color="#1783ff" flood-opacity="0.9" /><feComposite result="composite-4" operator="in" in2="composite-3" /><feBlend result="blend" in2="SourceGraphic" /><feBlend result="blend-2" in="SourceGraphic" /></filter><filterid="filter-15"x="279"y="364"width="59"height="59"filterUnits="userSpaceOnUse"><feGaussianBlur result="blur" stdDeviation="6.667" in="SourceAlpha" /><feComposite result="composite" /><feComposite result="composite-2" /><feComposite result="composite-3" /><feFlood result="flood" flood-color="#1783ff" flood-opacity="0.9" /><feComposite result="composite-4" operator="in" in2="composite-3" /><feBlend result="blend" in2="SourceGraphic" /><feBlend result="blend-2" in="SourceGraphic" /></filter><imageid="image"width="23"height="23"xlink:href="../assets/images/center/image-1.png"/><imageid="image-2"width="15"height="15"xlink:href="../assets/images/center/image-2.png"/></defs><g id="dongxiao1"><g id="icon"><pathid="base_o"class="cls-1"d="M177.9,51.386c33.127,0,63.736,13.839,67.114,34,3.557,21.237-26.042,40.948-67.114,40.948s-70.671-19.711-67.113-40.948C114.162,65.225,144.771,51.386,177.9,51.386Z"/><pathid="base_t"class="cls-2"d="M177.9,44.728c33.127,0,63.736,12.114,67.114,29.76,3.557,18.59-26.042,35.844-67.114,35.844s-70.671-17.254-67.113-35.844C114.162,56.842,144.771,44.728,177.9,44.728Z"/><pathid="right_o"class="cls-3"d="M122.484-.626H233.455L208.447,90.7H147.491Z"/><pathid="right_t"class="cls-4"d="M112.064,46.866H243.875l-35.428,44.36H147.491Z"/><pathid="line"class="cls-5"d="M178.105,38c25.911,0,51.58,8.076,56.087,21.076,4.881,14.075-19.143,28.5-56.083,28.5s-60.966-14.426-56.087-28.5C126.527,46.072,152.194,38,178.105,38Z"/><imageid="icon_star_guangzhou"x="121"y="-3"width="112"height="112"xlink:href="../assets/images/center/star.png"/><pathid="base_o-2"data-name="base_o"class="cls-6"d="M718.9,339.386c33.127,0,63.736,13.839,67.114,34,3.557,21.237-26.042,40.948-67.114,40.948s-70.671-19.711-67.113-40.948C655.162,353.225,685.771,339.386,718.9,339.386Z"/><pathid="base_t-2"data-name="base_t"class="cls-7"d="M718.9,332.728c33.127,0,63.736,12.114,67.114,29.76,3.557,18.59-26.042,35.844-67.114,35.844s-70.671-17.254-67.113-35.844C655.162,344.842,685.771,332.728,718.9,332.728Z"/><pathid="right_o-2"data-name="right_o"class="cls-8"d="M663.484,287.374H774.455L749.447,378.7H688.491Z"/><pathid="right_t-2"data-name="right_t"class="cls-9"d="M653.064,334.866H784.875l-35.428,44.36H688.491Z"/><pathid="line-2"data-name="line"class="cls-10"d="M719.105,326c25.911,0,51.58,8.076,56.087,21.076,4.881,14.075-19.143,28.5-56.083,28.5s-60.966-14.426-56.087-28.5C667.527,334.072,693.194,326,719.105,326Z"/><imageid="icon_location_zhongshan"x="666"y="287"width="106"height="107"xlink:href="../assets/images/center/location.png"/><pathid="base_o-3"data-name="base_o"class="cls-11"d="M67.9,250.386c33.127,0,63.736,13.839,67.114,34,3.557,21.237-26.042,40.948-67.114,40.948S-2.773,305.62.785,284.383C4.162,264.225,34.771,250.386,67.9,250.386Z"/><pathid="base_t-3"data-name="base_t"class="cls-12"d="M67.9,243.728c33.127,0,63.736,12.114,67.114,29.76,3.557,18.59-26.042,35.844-67.114,35.844S-2.773,292.078.785,273.488C4.162,255.842,34.771,243.728,67.9,243.728Z"/><pathid="right_o-3"data-name="right_o"class="cls-13"d="M12.484,198.374H123.455L98.447,289.7H37.491Z"/><pathid="right_t-3"data-name="right_t"class="cls-14"d="M2.064,245.866H133.875l-35.428,44.36H37.491Z"/><pathid="line-3"data-name="line"class="cls-15"d="M68.105,237c25.911,0,51.58,8.076,56.087,21.076,4.881,14.075-19.143,28.5-56.083,28.5s-60.966-14.426-56.088-28.5C16.527,245.072,42.194,237,68.105,237Z"/><imageid="icon_pie_shenzhen"x="13"y="194"width="107"height="108"xlink:href="../assets/images/center/pie.png"/><pathid="base_o-4"data-name="base_o"class="cls-16"d="M159.9,521.386c33.127,0,63.736,13.839,67.114,34,3.557,21.237-26.042,40.948-67.114,40.948S89.227,576.62,92.785,555.383C96.162,535.225,126.771,521.386,159.9,521.386Z"/><pathid="base_t-4"data-name="base_t"class="cls-17"d="M159.9,514.728c33.127,0,63.736,12.114,67.114,29.76,3.557,18.59-26.042,35.844-67.114,35.844s-70.671-17.254-67.113-35.844C96.162,526.842,126.771,514.728,159.9,514.728Z"/><pathid="right_o-4"data-name="right_o"class="cls-18"d="M104.484,469.374H215.455L190.447,560.7H129.491Z"/><pathid="right_t-4"data-name="right_t"class="cls-19"d="M94.064,516.866H225.875l-35.428,44.36H129.491Z"/><pathid="line-4"data-name="line"class="cls-20"d="M160.1,508c25.911,0,51.58,8.076,56.087,21.076,4.881,14.075-19.143,28.5-56.083,28.5s-60.966-14.426-56.088-28.5C108.527,516.072,134.194,508,160.1,508Z"/><imageid="icon_earth_dongguan"x="106"y="460"width="111"height="112"xlink:href="../assets/images/center/earth.png"/><pathid="base_o-5"data-name="base_o"class="cls-21"d="M581.9,548.386c33.127,0,63.736,13.839,67.114,34,3.557,21.237-26.042,40.948-67.114,40.948s-70.671-19.711-67.113-40.948C518.162,562.225,548.771,548.386,581.9,548.386Z"/><pathid="base_t-5"data-name="base_t"class="cls-22"d="M581.9,541.728c33.127,0,63.736,12.114,67.114,29.76,3.557,18.59-26.042,35.844-67.114,35.844s-70.671-17.254-67.113-35.844C518.162,553.842,548.771,541.728,581.9,541.728Z"/><pathid="right_o-5"data-name="right_o"class="cls-23"d="M526.484,496.374H637.455L612.447,587.7H551.491Z"/><pathid="right_t-5"data-name="right_t"class="cls-24"d="M516.064,543.866H647.875l-35.428,44.36H551.491Z"/><pathid="line-5"data-name="line"class="cls-25"d="M582.105,535c25.911,0,51.58,8.076,56.087,21.076,4.881,14.075-19.143,28.5-56.083,28.5s-60.966-14.426-56.087-28.5C530.527,543.072,556.194,535,582.105,535Z"/><imageid="icon_hot_zhuhai"x="530"y="495"width="105"height="105"xlink:href="../assets/images/center/hot.png"/><pathid="base_o-6"data-name="base_o"class="cls-26"d="M633.9,70.386c33.127,0,63.737,13.839,67.114,34,3.557,21.237-26.042,40.948-67.114,40.948s-70.671-19.711-67.113-40.948C570.162,84.225,600.771,70.386,633.9,70.386Z"/><pathid="base_t-6"data-name="base_t"class="cls-27"d="M633.9,63.728c33.127,0,63.737,12.114,67.114,29.76,3.557,18.59-26.042,35.844-67.114,35.844s-70.671-17.254-67.113-35.844C570.162,75.842,600.771,63.728,633.9,63.728Z"/><pathid="right_o-6"data-name="right_o"class="cls-28"d="M578.484,18.374H689.455L664.447,109.7H603.491Z"/><pathid="right_t-6"data-name="right_t"class="cls-29"d="M568.064,65.866H699.875l-35.428,44.36H603.491Z"/><pathid="line-6"data-name="line"class="cls-30"d="M634.105,57c25.911,0,51.58,8.076,56.087,21.076,4.881,14.075-19.143,28.5-56.083,28.5s-60.966-14.426-56.087-28.5C582.527,65.072,608.194,57,634.105,57Z"/><imageid="icon_home_foshan"x="582"y="17"width="103"height="103"xlink:href="../assets/images/center/home.png"/></g><g id="circle"><pathid="white"class="cls-31"d="M414.057,225.629c96.638,0,183.089,41.729,194.7,100.322C621.763,391.613,533.734,450,417.167,450c-116.623,0-206.208-58.413-195.026-124.044C232.116,267.4,317.339,225.629,414.057,225.629Z"/><pathid="orange_2"class="cls-32"d="M397.666,306.9c63.817,0,120.7,28.166,126.181,67.065,5.811,41.258-50.026,77.528-124.026,77.528-74.041,0-130.915-36.294-126.336-77.528C277.8,335.086,333.819,306.9,397.666,306.9Z"/><pathid="blue"class="cls-33"d="M399.082,284.02c82.745,0,156.818,36,165.9,86.375,10,55.486-64.543,104.544-163.1,104.544-98.607,0-174.539-49.087-166.169-104.544C243.317,320.056,316.275,284.02,399.082,284.02Z"/><pathid="orange_1"class="cls-34"d="M396.909,228.952c111.911,0,212.629,47.606,229.169,115.472,19.27,79.068-85.494,150.425-225.217,150.425-139.785,0-246.6-71.391-229.688-150.425C185.681,276.624,284.878,228.952,396.909,228.952Z"/><imageid="light_o_3"x="520"y="324"width="72"height="92"xlink:href="../assets/images/center/light_0_3.png"/><imageid="light_o_2"x="141"y="261"width="99"height="137"xlink:href="../assets/images/center/light_0_2.png"/><imageid="light_o_1"x="436"y="385"width="99"height="66"xlink:href="../assets/images/center/light_0_1.png"/></g><imageid="center-houes"x="103"y="120"width="539"height="419"xlink:href="../assets/images/center/house.png"/><g id="right"><g id="組_380" data-name="組 380"><pathid="line_b_3"class="cls-35"d="M254.251,93.032s47.68,24.959,35.63,74.5,43.548,85.6,43.548,85.6"/><pathid="line_b_2"class="cls-35"d="M122.023,310.584s19.568,33.927,95.014-1.189,85.512,3.963,85.512,3.963"/><pathid="line_b_1"class="cls-35"d="M236.832,551.912s54.438-25.6,47.506-82.424,34.839-88.368,34.839-88.368"/><pathid="line_o_3"class="cls-36"d="M558.295,108.09s-49.1,12.55-54.633,70.932-39.193,77.669-39.193,77.669"/><pathid="line_o_2"class="cls-36"d="M653,387s-39.424,20.259-79-30-70.444-42.177-79-40"/><pathid="line_o_1"class="cls-36"d="M505,579s-31.47-27.546-17-86c12.415-50.151-42-83-42-83"/><g id="dots_b"><circleid="dots39"class="cls-37"cx="256.219"cy="94.234"r="2.781"/><pathid="dots38"class="cls-38"d="M331.062,248.777a2.766,2.766,0,1,1-2.765,2.766A2.766,2.766,0,0,1,331.062,248.777Z"/><pathid="dots37"class="cls-38"d="M120.828,306.621a2.781,2.781,0,1,1-2.781,2.781A2.781,2.781,0,0,1,120.828,306.621Z"/><circleid="dots36"class="cls-39"cx="300.938"cy="311.781"r="2.781"/><circleid="dots35"class="cls-37"cx="236.422"cy="552.313"r="2.766"/><pathid="dots34"class="cls-38"d="M318.391,380.34a2.766,2.766,0,1,1-2.782,2.765A2.773,2.773,0,0,1,318.391,380.34Z"/><imageid="dots28"x="255"y="91"width="22"height="23"xlink:href="../assets/images/center/dots28.png"/><circleid="dots27"class="cls-40"cx="321.25"cy="243.625"r="2.375"/><circleid="dots26"class="cls-41"cx="288"cy="184.969"r="2.375"/><circleid="dots25"class="cls-42"cx="155.766"cy="326.047"r="2.359"/><circleid="dots24"class="cls-43"cx="284.828"cy="298.703"r="2.359"/><pathid="dots23"class="cls-44"d="M255.547,537.652a2.375,2.375,0,1,1-2.375,2.375A2.375,2.375,0,0,1,255.547,537.652Z"/><pathid="dots22"class="cls-45"d="M285.641,479a2.375,2.375,0,1,1-2.375,2.375A2.375,2.375,0,0,1,285.641,479Z"/><circleid="dots21"class="cls-46"cx="286.813"cy="436.985"r="2.375"/><circleid="dots20"class="cls-47"cx="276.125"cy="112.078"r="1.594"/><pathid="dots19"class="cls-48"d="M291.578,149.308a1.579,1.579,0,1,1-1.594,1.578A1.587,1.587,0,0,1,291.578,149.308Z"/><pathid="dots18"class="cls-49"d="M306.625,226.965a1.594,1.594,0,1,1-1.578,1.593A1.585,1.585,0,0,1,306.625,226.965Z"/><circleid="dots17"class="cls-50"cx="140.734"cy="323.266"r="1.578"/><circleid="dots16"class="cls-51"cx="234.938"cy="302.672"r="1.594"/><circleid="dots15"class="cls-52"cx="284.422"cy="465.516"r="1.578"/><circleid="dots14"class="cls-53"cx="266.625"cy="528.938"r="1.594"/><circleid="dots13"class="cls-54"cx="307.797"cy="393.016"r="1.578"/></g><g id="dots_o"><pathid="dots33"class="cls-55"d="M555.906,103.715a2.766,2.766,0,1,1-2.765,2.765A2.765,2.765,0,0,1,555.906,103.715Z"/><pathid="dots32"class="cls-55"d="M466.437,252.34a2.766,2.766,0,1,1-2.765,2.765A2.765,2.765,0,0,1,466.437,252.34Z"/><circleid="dots31"class="cls-56"cx="652.093"cy="385.89"r="2.781"/><pathid="dots30"class="cls-55"d="M494.937,312.558a2.766,2.766,0,1,1-2.765,2.766A2.766,2.766,0,0,1,494.937,312.558Z"/><circleid="dots29"class="cls-56"cx="505.625"cy="576.485"r="2.781"/><circleid="dots29-2"data-name="dots29"class="cls-56"cx="446.25"cy="409.64"r="2.781"/><use id="dots12" x="516" y="118" xlink:href="#image" /><use id="dots11" x="505" y="304" xlink:href="#image" /><use id="dots10" x="572" y="353" xlink:href="#image" /><use id="dots09" x="486" y="555" xlink:href="#image" /><use id="dots08" x="479" y="465" xlink:href="#image" /><use id="dots07" x="499" y="158" xlink:href="#image-2" /><use id="dots06" x="483" y="221" xlink:href="#image-2" /><use id="dots05" x="470" y="239" xlink:href="#image-2" /><use id="dots04" x="632" y="383" xlink:href="#image-2" /><use id="dots03" x="564" y="346" xlink:href="#image-2" /><use id="dots02" x="455" y="415" xlink:href="#image-2" /><use id="dots01" x="482" y="455" xlink:href="#image-2" /></g><!-- 開始給點制作動畫特效 1個點--><!-- <circle cx="0" xy="0" r="3" class="cus-cls-blue"> --><!-- 做動畫 --><!-- <animateMotiondur="6s"begin="0s"repeatCount="indefinite"rotate="auto"> --><!-- 沿著哪條線/路徑進行 --><!-- <mpath href="#line_b_3"></mpath></animateMotion></circle> --><!-- n個點--左側 --><template v-for="item in [1, 2, 3]"><circle cx="0" xy="0" r="3" class="cus-cls-blue"><!-- 做動畫 --><animateMotiondur="6s"begin="0s"repeatCount="indefinite"rotate="auto"><!-- 沿著哪條線/路徑進行 --><mpath :href="`#line_b_${item}`"></mpath></animateMotion></circle><circle cx="0" xy="0" r="3" class="cus-cls-blue"><!-- 做動畫 --><animateMotiondur="6s"begin="-3s"repeatCount="indefinite"rotate="auto"><!-- 沿著哪條線/路徑進行 --><mpath :href="`#line_b_${item}`"></mpath></animateMotion></circle></template><!-- n個點--右側 --><template v-for="item in [1, 2, 3]"><circle cx="0" xy="0" r="3" class="cus-cls-orange"><!-- 做動畫 --><animateMotiondur="6s"begin="0s"repeatCount="indefinite"rotate="auto"><!-- 沿著哪條線/路徑進行 --><mpath :href="`#line_o_${item}`"></mpath></animateMotion></circle><circle cx="0" xy="0" r="3" class="cus-cls-orange"><!-- 做動畫 --><animateMotiondur="6s"begin="-3s"repeatCount="indefinite"rotate="auto"><!-- 沿著哪條線/路徑進行 --><mpath :href="`#line_o_${item}`"></mpath></animateMotion></circle></template></g></g><g id="text"><textid="text6"class="cls-57"transform="translate(179.049 154.026) scale(0.481 0.481)">廣州</text><textid="text5"class="cls-57"transform="translate(63.771 351.7) scale(0.481 0.481)">深圳</text><textid="text4"class="cls-57"transform="translate(161.75 622.618) scale(0.481 0.481)">東莞</text><textid="text3"class="cls-57"transform="translate(583.87 649.734) scale(0.481 0.481)">珠海</text><textid="text2"class="cls-57"transform="translate(719.835 441.012) scale(0.481 0.481)">中山</text><textid="text1"class="cls-57"transform="translate(637.843 173.315) scale(0.481 0.481)">佛山</text></g></g></svg><!-- 煙花特效 --><img class="lingxA" src="../assets/images/ling/lingxA.png" /><img class="lingxB" src="../assets/images/ling/lingxB.png" /><img class="lingxC" src="../assets/images/ling/lingxC.png" /><img class="lingxD" src="../assets/images/ling/lingxD.png" /><img class="lingxE" src="../assets/images/ling/lingxE.png" /><img class="lingxF" src="../assets/images/ling/lingxF.png" /></div>
</template><script setup>
import gsap from "gsap";
import { onMounted } from "vue";onMounted(() => {let timeline = gsap.timeline({});timeline.fromTo("#dongxiao",{duration: 1,scale: 0.8,y: 40,},{duration: 1,scale: 1,y: 0,}).fromTo(["#center-houes"],{duration: 1,opacity: 0.5,scale: 0.7,transformOrigin: "bottom",y: 20,},{duration: 1,opacity: 1,scale: 1,transformOrigin: "bottom",y: 0,},"-=1");
});
</script><style lang="scss" scoped>
.cls-1,
.cls-11,
.cls-12,
.cls-16,
.cls-17,
.cls-2,
.cls-21,
.cls-22,
.cls-26,
.cls-27,
.cls-31,
.cls-6,
.cls-7 {stroke: #fff;
}.cls-1,
.cls-10,
.cls-11,
.cls-12,
.cls-15,
.cls-16,
.cls-17,
.cls-2,
.cls-20,
.cls-21,
.cls-22,
.cls-25,
.cls-26,
.cls-27,
.cls-30,
.cls-31,
.cls-5,
.cls-6,
.cls-7 {stroke-width: 3px;
}.cls-1,
.cls-10,
.cls-11,
.cls-12,
.cls-13,
.cls-14,
.cls-15,
.cls-16,
.cls-17,
.cls-18,
.cls-19,
.cls-2,
.cls-20,
.cls-21,
.cls-22,
.cls-23,
.cls-24,
.cls-25,
.cls-26,
.cls-27,
.cls-28,
.cls-29,
.cls-3,
.cls-30,
.cls-31,
.cls-32,
.cls-33,
.cls-34,
.cls-35,
.cls-36,
.cls-38,
.cls-4,
.cls-44,
.cls-45,
.cls-48,
.cls-49,
.cls-5,
.cls-55,
.cls-6,
.cls-7,
.cls-8,
.cls-9 {fill-rule: evenodd;
}.cls-1,
.cls-11,
.cls-16,
.cls-21,
.cls-26,
.cls-6 {opacity: 0.15;
}.cls-1 {fill: url(#linear-gradient);
}.cls-12,
.cls-13,
.cls-14,
.cls-17,
.cls-18,
.cls-19,
.cls-2,
.cls-22,
.cls-23,
.cls-24,
.cls-27,
.cls-28,
.cls-29,
.cls-3,
.cls-4,
.cls-7,
.cls-8,
.cls-9 {opacity: 0.3;
}.cls-2 {fill: url(#linear-gradient-2);
}.cls-3 {fill: url(#linear-gradient-3);
}.cls-4 {fill: url(#linear-gradient-4);
}.cls-10,
.cls-15,
.cls-20,
.cls-25,
.cls-30,
.cls-31,
.cls-32,
.cls-33,
.cls-34,
.cls-35,
.cls-36,
.cls-5 {fill: none;
}.cls-10,
.cls-15,
.cls-20,
.cls-25,
.cls-30,
.cls-5 {stroke-dasharray: 12 12;opacity: 0.7;
}.cls-5 {stroke: url(#linear-gradient-5);
}.cls-6 {fill: url(#linear-gradient-6);
}.cls-7 {fill: url(#linear-gradient-7);
}.cls-8 {fill: url(#linear-gradient-8);
}.cls-9 {fill: url(#linear-gradient-9);
}.cls-10 {stroke: url(#linear-gradient-10);
}.cls-11 {fill: url(#linear-gradient-11);
}.cls-12 {fill: url(#linear-gradient-12);
}.cls-13 {fill: url(#linear-gradient-13);
}.cls-14 {fill: url(#linear-gradient-14);
}.cls-15 {stroke: url(#linear-gradient-15);
}.cls-16 {fill: url(#linear-gradient-16);
}.cls-17 {fill: url(#linear-gradient-17);
}.cls-18 {fill: url(#linear-gradient-18);
}.cls-19 {fill: url(#linear-gradient-19);
}.cls-20 {stroke: url(#linear-gradient-20);
}.cls-21 {fill: url(#linear-gradient-21);
}.cls-22 {fill: url(#linear-gradient-22);
}.cls-23 {fill: url(#linear-gradient-23);
}.cls-24 {fill: url(#linear-gradient-24);
}.cls-25 {stroke: url(#linear-gradient-25);
}.cls-26 {fill: url(#linear-gradient-26);
}.cls-27 {fill: url(#linear-gradient-27);
}.cls-28 {fill: url(#linear-gradient-28);
}.cls-29 {fill: url(#linear-gradient-29);
}.cls-30 {stroke: url(#linear-gradient-30);
}.cls-31 {opacity: 0.1;
}.cls-32,
.cls-33,
.cls-34 {stroke-width: 4px;
}.cls-32 {stroke: url(#linear-gradient-31);
}.cls-33 {stroke: url(#linear-gradient-32);
}.cls-34 {stroke: url(#linear-gradient-33);
}.cls-35 {stroke: #1374f1;
}.cls-35,
.cls-36 {stroke-width: 2px;opacity: 0.8;
}.cls-36 {stroke: #f97a00;
}.cls-37,
.cls-38,
.cls-39 {fill: #0e68ff;
}.cls-39 {opacity: 0.36;
}.cls-40,
.cls-41,
.cls-42,
.cls-43,
.cls-44,
.cls-45,
.cls-46,
.cls-47,
.cls-48,
.cls-49,
.cls-50,
.cls-51,
.cls-52,
.cls-53,
.cls-54 {fill: #fff;opacity: 0.9;
}/* 編寫點的樣式--藍色 */
.cus-cls-blue {fill: #fff;opacity: 0.9;filter: url(#blue-filter-2);/* 告訴瀏覽器該元素將會改變哪些屬性,讓瀏覽器提前做好優化的準備( 比較消耗內存 ) */will-change: opacity;
}
/* 編寫點的樣式--橙色 */
.cus-cls-orange {fill: #fff;opacity: 0.9;filter: url(#orange-filter-2);/* 告訴瀏覽器該元素將會改變哪些屬性,讓瀏覽器提前做好優化的準備( 比較消耗內存 ) */will-change: opacity;
}.cls-40 {filter: url(#filter);
}.cls-41 {filter: url(#filter-2);
}.cls-42 {filter: url(#filter-3);
}.cls-43 {filter: url(#filter-4);
}.cls-44 {filter: url(#filter-5);
}.cls-45 {filter: url(#filter-6);
}.cls-46 {filter: url(#filter-7);
}.cls-47 {filter: url(#filter-8);
}.cls-48 {filter: url(#filter-9);
}.cls-49 {filter: url(#filter-10);
}.cls-50 {filter: url(#filter-11);
}.cls-51 {filter: url(#filter-12);
}.cls-52 {filter: url(#filter-13);
}.cls-53 {filter: url(#filter-14);
}.cls-54 {filter: url(#filter-15);
}.cls-55,
.cls-56 {fill: #f97a00;
}.cls-57 {font-size: 41.603px;fill: #338ed5;text-anchor: middle;font-family: "Source Han Sans CN";
}/* ICON 懸浮動畫特效--開始 */
#icon_star_guangzhou {animation: updown 2.2s ease-in infinite;
}#icon_home_foshan {animation: updown 1.9s ease-in infinite;
}#icon_location_zhongshan {animation: updown 2s ease-in infinite;
}#icon_hot_zhuhai {animation: updown 2s ease-in infinite;
}#icon_earth_dongguan {animation: updown 1.7s ease-in infinite;
}#icon_pie_shenzhen {animation: updown 1.7s ease-in infinite;
}@keyframes updown {0%,100% {transform: translateY(0);}50% {transform: translateY(-10px);}
}
/* ICON 懸浮動畫特效--結束 *//*=======城市的燈光效果========*/
/* 廣州 */
.center .cls-3,
.center .cls-4,/* 佛山 */
.center .cls-28,
.center .cls-29,/* 中山 */
.center .cls-8,
.center .cls-9,/* 珠海 */
.center .cls-23,
.center .cls-24,/* 東莞 */
.center .cls-18,
.center .cls-19,/* 深圳 */
.center .cls-13,
.center .cls-14 {animation: light-beam 3s linear infinite;opacity: 0.2;
}@keyframes light-beam {0% {opacity: 0;}50% {opacity: 1;}100% {opacity: 0;}
}
/*=======城市的燈光效果========*//* 煙花特效--開始 */
.center-svg {position: relative;
}
.center-svg .lingxA {position: absolute;top: 30%;left: 47%;
}
.center-svg .lingxB {position: absolute;top: 35%;left: 58%;
}
.center-svg .lingxC {position: absolute;top: 40%;left: 40%;
}
.center-svg .lingxD {position: absolute;top: 28%;left: 41%;
}
.center-svg .lingxE {position: absolute;top: 28%;left: 54%;
}
.center-svg .lingxF {position: absolute;top: 40%;left: 53%;
}
.center-svg .lingxA {opacity: 0;animation: lingxA 2s linear infinite;
}
.center-svg .lingxB {opacity: 0;animation: lingxB 2.2s linear infinite;
}
.center-svg .lingxC {opacity: 0;animation: lingxC 1.7s linear infinite;
}
.center-svg .lingxD {opacity: 0;animation: lingxC 2.7s linear infinite;
}
.center-svg .lingxE {opacity: 0;animation: lingxB 1.2s linear infinite;
}
.center-svg .lingxF {opacity: 0;animation: lingxA 1.4s linear infinite;
}
/* 向上移動的煙花 */
@keyframes lingxA {from {transform: translateY(0px);opacity: 1;}60% {opacity: 1;}to {transform: translateY(-160px);opacity: 0;}
}@keyframes lingxB {from {transform: translateY(0px);opacity: 1;}40% {opacity: 1;}60%,to {transform: translateY(-120px);opacity: 0;}
}@keyframes lingxC {from {transform: translateY(0px);opacity: 1;}30% {opacity: 1;}50%,to {transform: translateY(-90px);opacity: 0;}
}
/* 煙花特效--結束 */
</style>

bottom-panle.vue
<template><div class="bottom-content"><template v-for="(item, index) in panelItems" :key="item"><div :class="['item', `panel${item.id}`]"><div class="pan-left"><div class="title">{{ item.title }}</div><!-- 數據動畫 --><span :id="`total-num-${item.id}`" class="number">{{item.totalNum}}</span><span class="unit">{{ item.unit }}</span></div><div class="pan-right"><span:class="['triangle', item.isUp ? 'up-triangle' : 'down-triangle']"></span><!-- 數據動畫 --><span :id="`percentage-num-${item.id}`" class="percentage">{{item.percentage}}</span></div></div></template></div>
</template><script setup>
import { watch, nextTick } from "vue";
import { CountUp } from "countup.js";const props = defineProps({panelItems: {type: Array,default: function () {return [];},},
});watch(() => props.panelItems, (newV, oldV) => {// 在下一次DOM更新完成之后會回調nextTick(() => {startAnimation(newV)})
})// 數字滾動動畫函數
function startAnimation(panelItems = []) {let option1 = {decimalPlaces: 1, // 保留兩位小數duration: 1.5, // 持續時長useGrouping: false,  // 是否需要分組}let option2 = {decimalPlaces: 1, // 保留兩位小數duration: 1.5, // 持續時長useGrouping: false,  // 是否需要分組suffix: '%', // 后綴}panelItems.forEach(item => {// 數據滾動:CountUp(id選擇器或元素對象,數字,配置){  }new CountUp(`total-num-${item.id}`, item.totalNum, option1).start()// 百分比滾動new CountUp(`percentage-num-${item.id}`, item.percentage, option2).start()})
}</script><style scoped lang="scss">
.bottom-content {width: 100%;height: 100%;display: flex;flex-direction: row;align-items: center;/* padding-top: 40px; */
}.bottom-content .item {display: flex;flex-direction: row;justify-content: space-between;align-items: center;margin-top: 60px;flex: 1;height: 100%;padding: 0 10px 0 35px;/* border: 1px solid red; */
}.bottom-content .pan-left {font-size: 16px;color: #ffffff;opacity: 0.8;
}
.bottom-content .pan-left .title {color: white;
}
.bottom-content .pan-left .number {font-size: 36px;font-weight: bold;color: #23aeff;line-height: 60px;
}.bottom-content .pan-left .unit {font-size: 18px;color: #23aeff;
}.bottom-content .pan-right {margin-top: 35px;
}.bottom-content .panel1 .pan-right .up-triangle {display: inline-block;margin-bottom: 4px;width: 0;height: 0;border-bottom: 8px solid #c70013;border-left: 8px solid transparent;border-right: 8px solid transparent;
}
.bottom .panel1 .pan-right .percentage {color: #c70013;
}
.bottom .panel2 .pan-right .up-triangle {display: inline-block;margin-bottom: 4px;width: 0;height: 0;border-bottom: 8px solid #c70013;border-left: 8px solid transparent;border-right: 8px solid transparent;
}
.bottom-content .panel2 .pan-right .percentage {color: #c70013;
}.bottom-content .panel3 .pan-right .down-triangle {display: inline-block;margin-bottom: 1px;width: 0;height: 0;border-top: 8px solid #37a73f;border-left: 8px solid transparent;border-right: 8px solid transparent;
}
.bottom-content .panel3 .pan-right .percentage {color: #37a73f;
}
</style>

water-ball.vue
<template><div class="water-ball"><!-- 波浪icon --><svgversion="1.1"xmlns="https://www.w3.org/2000/svg"xmlns:xlink="https://www.w3.org/1999/xlink"x="0px"y="0px"style="display: none"><symbol id="wave"><pathd="M420,20c21.5-0.4,38.8-2.5,51.1-4.5c13.4-2.2,26.5-5.2,27.3-5.4C514,6.5,518,4.7,528.5,2.7c7.1-1.3,17.9-2.8,31.5-2.7c0,0,0,0,0,0v20H420z"></path><pathd="M420,20c-21.5-0.4-38.8-2.5-51.1-4.5c-13.4-2.2-26.5-5.2-27.3-5.4C326,6.5,322,4.7,311.5,2.7C304.3,1.4,293.6-0.1,280,0c0,0,0,0,0,0v20H420z"></path><pathd="M140,20c21.5-0.4,38.8-2.5,51.1-4.5c13.4-2.2,26.5-5.2,27.3-5.4C234,6.5,238,4.7,248.5,2.7c7.1-1.3,17.9-2.8,31.5-2.7c0,0,0,0,0,0v20H140z"></path><pathd="M140,20c-21.5-0.4-38.8-2.5-51.1-4.5c-13.4-2.2-26.5-5.2-27.3-5.4C46,6.5,42,4.7,31.5,2.7C24.3,1.4,13.6-0.1,0,0c0,0,0,0,0,0l0,20H140z"></path></symbol></svg><!-- 水球 --><div class="box" :style="{ width: size, height: size }"><div class="percent" :style="{ fontSize: countSize }"><div class="percentNum" id="count" ref="countRef">0</div><div class="percentB">%</div></div><!-- 這個元素往上移 --><div id="water" class="water" ref="waterRef"><svg viewBox="0 0 560 20" class="water_wave water_wave_back"><use xlink:href="#wave"></use></svg><svg viewBox="0 0 560 20" class="water_wave water_wave_front"><use xlink:href="#wave"></use></svg></div></div></div>
</template><script setup>
import { ref, watch } from "vue";const props = defineProps({size: {type: String,default: "190px",},// 目標進度percentage: {type: Number,default: 0,},countSize: {type: String,default: "40px",},
});const countRef = ref(null);
const waterRef = ref(null);watch(() => props.percentage, (newV, oldV) => {startAnimation(newV)
});// 水球動畫函數
function startAnimation(percentage) {let countEl = countRef.value;let waterEl = waterRef.value;let percent = countEl.innerText; // 數據初始值 0let interval;// 1.定時更新數據interval = setInterval(function () {countEl.innerHTML = percent;if (percent <= 100) {// 2.超過100不能移動waterEl.style.transform = "translate(0" + "," + (100 - percent) + "%)";}// 3.停止定時if (percent >= percentage) {countEl.innerHTML = percentage;clearInterval(interval);}percent++;}, 60);
}
</script><style scoped>
.water-ball {position: relative;
}
.box {position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);border-radius: 100%;overflow: hidden;
}
.box .percent {position: absolute;left: 0;top: 0;z-index: 3;width: 100%;height: 100%;display: flex;align-items: center;justify-content: center;color: #fff;
}
.box .water {position: absolute;left: 0;top: 0;z-index: 2;width: 100%;height: 100%;transform: translate(0, 100%);background: #00c6ff;
}
/* 波浪定位 */
.box .water_wave {width: 200%;position: absolute;bottom: 100%;
}/* ============波浪動畫============ */
.box .water_wave_back {right: 0;fill: #c7eeff;animation: wave-back 1.4s infinite linear;
}
.box .water_wave_front {left: 0;fill: #00c6ff;margin-bottom: -1px;animation: wave-front 0.7s infinite linear;
}
@keyframes wave-front {100% {transform: translateX(-50%);}
}
@keyframes wave-back {100% {transform: translateX(50%);}
}
/* ============波浪動畫============ */
</style>

right-top-panle.vue
<template><div class="right-top-panel"><!-- 1. 水球 --><water-ball class="right-water-ball" :percentage="percentage"></water-ball><!-- 2. 圖例 --><div class="legend"><template v-for="item in panelItems" :key="item"><div class="leg-name"><span :class="['dot', `area${item.id}`]"></span><span class="name">{{ item.name }}</span><span class="percentage">{{ item.percentage }}</span></div></template></div></div>
</template><script setup>
import WaterBall from "./water-ball.vue";const props = defineProps({percentage: {type: Number,default: 0,},panelItems: {type: Array,default: function () {return [];},},
});
</script><style scoped>
.right-top-panel {width: 100%;height: 100%;display: flex;flex-direction: row;align-items: center;
}.right-top-panel .right-water-ball {width: 269px;height: 199px;margin-top: 50px;margin-left: 40px;
}.right-top-panel .legend {flex: 1;
}
.right-top-panel .leg-name {margin-top: 23px;margin-left: 40px;
}
.right-top-panel .leg-name span {display: inline-block;font-size: 20px;margin-right: 11px;
}
.right-top-panel .legend .dot {width: 17px;height: 17px;border-radius: 50%;
}
.right-top-panel .legend .area1 {background-color: #209393;
}
.right-top-panel .legend .area2 {background-color: #1a54a5;
}
.right-top-panel .legend .area3 {background-color: #85caf0;
}
.right-top-panel .legend .area4 {background-color: #f5b64a;
}
.right-top-panel .legend .area5 {background-color: #ee792e;
}
.right-top-panel .legend .name {color: white;
}
.right-top-panel .legend .percentage {color: #0cd2ea;
}
</style>

right-bottom.vue
<template><svgid="yichang"xmlns="http://www.w3.org/2000/svg"xmlns:xlink="http://www.w3.org/1999/xlink"width="456"height="127"viewBox="0 0 456 127"><defs><linearGradientid="lwj-linear-gradient"x1="432"y1="61.625"x2="2"y2="61.625"gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#26cadd" /><stop offset="0.301" stop-color="#26a3ff" /><stop offset="0.624" stop-color="#26cadd" /><stop offset="0.994" stop-color="#26a3ff" /><stop offset="1" stop-color="#26a3ff" /></linearGradient><linearGradientid="lwj-linear-gradient-2"x1="432"y1="61.625"x2="2"y2="61.625"gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#2b6bdc" /><stop offset="0.031" stop-color="#2b6bdc" /><stop offset="0.597" stop-color="#2bdcd2" /><stop offset="1" stop-color="#2b6bdc" /></linearGradient><filter id="lwj-filter" filterUnits="userSpaceOnUse"><feGaussianBlur result="blur" stdDeviation="6.667" in="SourceAlpha" /><feComposite result="composite" /><feComposite result="composite-2" /><feComposite result="composite-3" /><feFlood result="flood" flood-color="#f98800" flood-opacity="0.6" /><feComposite result="composite-4" operator="in" in2="composite-3" /><feBlend result="blend" in2="SourceGraphic" /><feBlend result="blend-2" in="SourceGraphic" /></filter><filterid="lwj-filter-2"x="67"y="-6"width="50"height="49"filterUnits="userSpaceOnUse"><feGaussianBlur result="blur" stdDeviation="6.667" in="SourceAlpha" /><feComposite result="composite" /><feComposite result="composite-2" /><feComposite result="composite-3" /><feFlood result="flood" flood-color="#f98800" flood-opacity="0.6" /><feComposite result="composite-4" operator="in" in2="composite-3" /><feBlend result="blend" in2="SourceGraphic" /><feBlend result="blend-2" in="SourceGraphic" /></filter></defs><pathid="curve_right"class="lwj-cls-1"d="M2.006,86.083H31.461l3.006-9.664,4.208,13.288,4.208-10.268,3.006,6.644H73.541l4.208-10.872L83.76,103l7.871-82.748,10.163,71.876,3.607-6.644h11.421l3.607,13.892L124.637,72.8l5.41,20.536,3.006-7.852h46.888l4.208-15.7,6.011,28.388,5.41-19.932,4.208,7.248h37.815L241,76l4,14,5-11,3,6h27l4-11,6,29,10-69,8,57,3-6h13l3,14,4-27,6,20,2-7h46l6-16,5,29,7-20,4,7h25"/><pathid="curve"class="lwj-cls-2"d="M2.006,86.083H31.461l3.006-9.664,4.208,13.288,4.208-10.268,3.006,6.644H73.541l4.208-10.872L83.76,103l7.871-82.748,10.163,71.876,3.607-6.644h11.421l3.607,13.892L124.637,72.8l5.41,20.536,3.006-7.852h46.888l4.208-15.7,6.011,28.388,5.41-19.932,4.208,7.248h37.815L241,76l4,14,5-11,3,6h27l4-11,6,29,10-69,8,57,3-6h13l3,14,4-27,6,20,2-7h46l6-16,5,29,7-20,4,7h25"/><!-- <circleid="curve_d_2"class="lwj-cls-3"cx="299.563"cy="34.734"r="4.813"/><ellipseid="curve_d_1"class="lwj-cls-4"cx="91.578"cy="17.844"rx="4.828"ry="4.844"/> --><!-- 只有一個點 --><!-- <circle  class="lwj-cls-3" cx="0" cy="0" r="5" fill="red"><animateMotiondur="10s"repeatCount="indefinite"rotate="auto"begin="0s"><mpath href="#curve"></mpath></animateMotion></circle> --><!-- n 個點 --><template v-for="(item, index) in dots" :key="item"><circle class="lwj-cls-3" cx="0" cy="0" :r="item.value"><animateMotion:dur="item.dur"repeatCount="indefinite"rotate="auto":begin="item.begin"><mpath href="#curve"></mpath></animateMotion></circle></template></svg>
</template><script setup>
const props = defineProps({dots: {type: Array,default: function () {return [];},},
});
</script><style scoped>
.lwj-cls-1,
.lwj-cls-2 {fill: none;stroke-linecap: round;stroke-linejoin: round;stroke-width: 4px;fill-rule: evenodd;
}.lwj-cls-1 {opacity: 0.8;stroke: url(#lwj-linear-gradient);
}.lwj-cls-2 {stroke: url(#lwj-linear-gradient-2);
}.lwj-cls-3,
.lwj-cls-4 {fill: #f98800;/* 告訴瀏覽器該元素將會改變哪些屬性,讓瀏覽器提前做好優化的準備( 比較消耗內存 ) */will-change: opacity;
}.lwj-cls-3 {filter: url(#lwj-filter);
}.lwj-cls-4 {filter: url(#lwj-filter-2);
}
</style>

在組件中使用

模擬數據

views/config/homeData.js? ?

// 充電樁數據
export const chargingPileData = [{// value: 100,value: 0,name: "廣州占比",// percentage: "5%",percentage: "0%",color: "#34D160",},{// value: 200,value: 0,name: "深圳占比",// percentage: "4%",percentage: "0%",color: "#027FF2",},{// value: 300,value: 0,name: "東莞占比",// percentage: "8%",percentage: "0%",color: "#8A00E1",},{// value: 400,value: 0,name: "佛山占比",// percentage: "10%",percentage: "0%",color: "#F19610",},{// value: 500,value: 0,name: "中山占比",// percentage: "20%",percentage: "0%",color: "#6054FF",},{// value: 600,value: 0,name: "珠海占比",// percentage: "40%",percentage: "0%",color: "#00C6FF",},
];// 流程監控數據
export const precessMonitoringData = [{name: "正常",data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],// data: [220, 182, 191, 234, 290, 330, 310, 201, 154, 190, 330, 410],},{name: "異常",data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],// data: [20, 12, 11, 24, 90, 330, 10, 1, 154, 90, 330, 10],},
];// 充電數據統計
export const chargingStatisticsData = [{name: "一月",value: 0,// value: 500},{name: "二月",value: 0,// value: 2000},{name: "三月",value: 0,// value:  3600},{name: "四月",value: 0,// value: 1000},{name: "五月",value: 0,// value: 1000},{name: "六月",value: 0,// value: 2000},{name: "七月",value: 0,// value: 4000},
];// 異常監控
export const exceptionMonitoringData = [// {//     "id": 1,//     "name": "異常1",//     "value": 5,//     "dur": "10s",//     "begin": "0s"// },// {//     "id": 2,//     "name": "異常2",//     "value": 3,//     "dur": "10s",//     "begin": "-3s"// },// {//     "id": 3,//     "name": "異常3",//     "value": 5,//     "dur": "10s",//     "begin": "-5s"// }
];// 充電樁數據分析
export const dataAnalysisData = [// {//   id: 1,//   title: "充電樁總數(個)",//   totalNum: 8579.9,//   unit: "萬",//   percentage: 79.5,//   isUp: true,// },// {//   id: 2,//   title: "年增長總數(個)",//   totalNum: 2856.6,//   unit: "萬",//   percentage: 88.9,//   isUp: true,// },// {//   id: 3,//   title: "月增長總數(個)",//   totalNum: 1189.3,//   unit: "萬",//   percentage: 62,//   isUp: false,// },{id: 1,title: "充電樁總數(個)",totalNum: 0,unit: "萬",percentage: 0,isUp: true,},{id: 2,title: "年增長總數(個)",totalNum: 0,unit: "萬",percentage: 0,isUp: true,},{id: 3,title: "月增長總數(個)",totalNum: 0,unit: "萬",percentage: 0,isUp: false,},
];// 充電樁Top4占比
export const chargingTop4Data = [{id: 1,name: "深圳",percentage: "0%",},{id: 2,name: "廣州",percentage: "0%",},{id: 3,name: "東莞",percentage: "0%",},{id: 4,name: "佛山",percentage: "0%",},{id: 5,name: "其它",percentage: "0%",},// {//   id: 1,//   name: "深圳",//   percentage: "30%",// },// {//   id: 2,//   name: "廣州",//   percentage: "20%",// },// {//   id: 3,//   name: "東莞",//   percentage: "10%",// },// {//   id: 4,//   name: "佛山",//   percentage: "10%",// },// {//   id: 5,//   name: "其它",//   percentage: "30%",// },
];

真實請求

views/powerView.vue

<template><main class="screen-bg"><div class="header"></div><div class="left-top"><PieEcharts :echartsChargingPileData="echartsChargingPileData" /></div><div class="left-bottom"><LineEcharts :echartsPrecessMonitoringData="echartsPrecessMonitoringData" /></div><div class="right-top"><RightTopPanel :panelItems="echartChargingTop4Data" :percentage="percentage" /></div><div class="right-center"><BarEchaarts :echartsChargingStatisticsData="echartsChargingStatisticsData" /></div><div class="right-bottom"><RightBottomSvg :dots="echartsExceptionMonitoringData" /></div><div class="center"><CenterSvg /></div><div class="bottom"><BottomPanel :panelItems="echartDataAnalysisData" /></div></main>
</template><script setup>
import PieEcharts from "@/components/pie-echarts.vue";
import LineEcharts from "@/components/line-echarts.vue";
import BarEchaarts from "@/components/bar-echarts.vue"
import {chargingPileData,precessMonitoringData,chargingStatisticsData,exceptionMonitoringData,dataAnalysisData,chargingTop4Data
} from '@/views/config/homeData'
import {getPowerScreenData} from '@/services'
import RightBottomSvg from '@/components/right-bottom-svg.vue'
import CenterSvg from '@/components/center-svg.vue'
import BottomPanel from '@/components/bottom-panel.vue'
import RightTopPanel from '@/components/right-top-panel.vue'import { ref } from "vue";// 充電樁飽和比例數據
let echartsChargingPileData = ref(chargingPileData);// 流程監控數據
let echartsPrecessMonitoringData = ref(precessMonitoringData)// 充電數據統計
let echartsChargingStatisticsData  = ref(chargingStatisticsData)// 異常監控
let echartsExceptionMonitoringData = ref(exceptionMonitoringData)// 充電樁數據分析
let echartDataAnalysisData = ref(dataAnalysisData)// 充電樁TOP4占比
let echartChargingTop4Data = ref(chargingTop4Data)
let percentage = ref(0) // 水球的百分比// 發送網絡請求獲取數據
getPowerScreenData().then(res => {echartsChargingPileData.value = res.data.chargingPile.dataechartsPrecessMonitoringData.value = res.data.processMonitoring.dataechartsChargingStatisticsData.value = res.data.chargingStatistics.dataechartsExceptionMonitoringData.value = res.data.exceptionMonitoring.dataechartDataAnalysisData.value = res.data.dataAnalysis.dataechartChargingTop4Data.value = res.data.chargingTop4.datapercentage.value = res.data.chargingTop4.totalPercentage
})
</script><style lang="scss" scoped>
.screen-bg {position: absolute;width: 100%;height: 100%;background-image: url(@/assets/images/bg.png);background-repeat: no-repeat;background-size: 100% 100%;background-color: #070a3c;.header {position: absolute;top: 21px;left: 0;right: 0;height: 56px;background-image: url(@/assets/images/bg_header.svg);}.left-top {position: absolute;top: 116px;left: 16px;width: 536px;height: 443px;background-image: url(@/assets/images/bg_left-top.svg);background-repeat: no-repeat;background-size: 100% 100%;}.left-bottom {position: absolute;bottom: 40px;left: 16px;width: 536px;height: 443px;background-image: url(@/assets/images/bg_left_bottom.svg);background-repeat: no-repeat;background-size: 100% 100%;}.right-top {position: absolute;right: 17px;top: 96px;width: 519px;height: 327px;background-image: url(@/assets/images/bg_right_top.svg);background-repeat: no-repeat;background-size: 100% 100%;}.right-center {position: absolute;right: 17px;top: 443px;width: 519px;height: 327px;background-image: url(@/assets/images/bg_right_center.svg);background-repeat: no-repeat;background-size: 100% 100%;}.right-bottom {position: absolute;right: 17px;bottom: 49px;width: 519px;height: 242px;display: flex;justify-content: center;align-items: center;background-image: url(@/assets/images/bg_right_bottom.svg);background-repeat: no-repeat;background-size: 100% 100%;}.center {position: absolute;right: 540px;bottom: 272px;width: 823px;height: 710px;/* border: 5px solid pink; */}.bottom {position: absolute;right: 540px;bottom: 49px;width: 823px;height: 209px;background-image: url(@/assets/images/bg_bottom.svg);background-repeat: no-repeat;background-size: 100% 100%;}
}
</style>

這里如果想進一步優化,比如如何按需引入echarts ,可參考:?vue3中如何更優雅的使用echarts?-CSDN博客 片文章

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/10882.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/10882.shtml
英文地址,請注明出處:http://en.pswp.cn/web/10882.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MogDBopenGauss查詢重寫規則lazyagg

在MogDB&openGauss中&#xff0c;參數rewrite_rule用于控制查詢重寫&#xff0c;本文介紹查詢重寫規則lazyagg 在未設置rewrite_rulelazyagg的情況下&#xff0c;子查詢中有GROUP BY會先進行GROUP BY lazyagg表示延遲聚合運算&#xff0c;目的是消除子查詢中的聚合運算&…

寶塔面板怎么解決nginx跨域問題

1.找到寶塔的nginx配置文件 寶塔有一點不同&#xff0c;nginx配置文件不在nginx的安裝目錄中&#xff0c;應當去/www/server/panel/vhost/nginx找到 2.添加你要跨域的地址 location /api {proxy_pass http://localhost:8080;proxy_set_header Host $host;proxy_set_header X-…

維護祖傳項目Tomcat部署war包

文章目錄 1. 安裝tomcat2. 解決Tomcat啟動日志亂碼3. idea配置啟動war包 1. 安裝tomcat 選擇免安裝版本&#xff0c;只需要在系統變量里面配置一下。 新增系統變量 CATALINA_HOME D:\Users\common\tomcat\apache-tomcat-8.5.97-windows-x64\apache-tomcat-8.5.97 編輯追加Path…

FPGA SDRAM讀寫控制器

感謝鄧堪文大佬 &#xff01; SDRAM 同步動態隨機存取內存&#xff08;synchronousdynamic randon-access menory&#xff0c;簡稱SDRAM&#xff09;是有一個同步接口的動態隨機存取內存&#xff08;DRAM&#xff09;。通常DRAM是有一個異步接口的&#xff0c;這樣它可以隨時響…

Node.js基礎:從入門到實戰

初識 Node.js 與內置模塊 &#xff08;初識&#xff09; 1、知道什么是node.js 2、知道node.js可以做什么 3、node.js 中js的組成部分 &#xff08;內置模塊&#xff09; 4、用 fs 模塊讀寫操作文件 5、使用 path 模塊處理路徑 6、使用http 模塊寫一個基本的web服務器 初識 N…

第1章 信息系統綜合知識 1.4 IT戰略

第1章 信息系統綜合知識 1.4 IT戰略 1.4.1 IT戰略的內涵 IT戰略&#xff0c;是在診斷和評估企業信息化現狀的基礎上&#xff0c;制定和調整企業信息化的指導綱領&#xff0c;爭取企業以最合適的成本&#xff0c;去做最合適的信息化工作。 IT戰略制定步驟: 定方向:明確遠景…

設計模式——模板設計模式(Template Method)

模板設計-base 什么是模板&#xff1f; 舉個簡單的例子&#xff0c;以AABB的格式&#xff0c;寫出一個詞語&#xff0c;你可能會想到&#xff0c;明明白白&#xff0c;干干凈凈等&#xff0c; 這個AABB就是一個模板&#xff0c;對模板心中有了一個清晰的概念之后&#xff0c;…

docker————docker的安裝

目錄 docker的安裝 1、安裝yum-utils工具 2、安裝yum倉庫 3、安裝docker引擎 4、設置開機啟動&#xff0c;并立即啟動 5、測試 docker的安裝 docker的官網Docker Docs 我才用的linux版本是rocky&#xff0c;使用的是最小安裝 1、安裝yum-utils工具 [rootbogon yum.rep…

環境變量(全)

概念 環境變量(environment variables)一般是指在操作系統中用來指定操作系統運行環境的一些參數 如&#xff1a;我們在編寫C/C代碼的時候&#xff0c;在鏈接的時候&#xff0c;從來不知道我們的所鏈接的動態靜態庫在哪里&#xff0c;但是照樣可以鏈接成功&#xff0c;生成可執…

今日arXiv最熱NLP大模型論文:揭露大語言模型短板,北京大學提出事件推理測試基準

人工智能領域又一里程碑時刻&#xff01;北京大學、北京智源人工智能研究院等機構聯合推出大型事件推理評測基準 。這是首個同時在知識和推理層面全面評估大模型事件推理能力的數據集。 總所周知&#xff0c;事件推理需要豐富的事件知識和強大的推理能力&#xff0c;涉及多種推…

consul啟動Error_server_rejoin_age_max (168h0m0s) - consider wiping your data dir

consul 啟動報錯&#xff1a; consul[11880]: 2024-05-12T08:37:51.095-0400 [ERROR] agent: startup error: error"refusing to rejoin cluster because server has been offline for more than the configured server_rejoin_age_max (168h0m0s) - consider wiping you…

【GD32】02-ADC模擬數字轉換器

ADC 在電子和通信技術中&#xff0c;ADC&#xff08;模擬數字轉換器&#xff09;是一種將模擬信號轉換為數字信號的電子設備。這種轉換是電子系統中非常關鍵的一個環節&#xff0c;因為數字信號更易于處理、存儲和傳輸。ADC的工作原理通常包括采樣、保持、量化和編碼等步驟。采…

http協議 tomcat如何訪問資源 servlet理論介紹

tomcat介紹 bin是啟動命令&#xff1b; conf是配置&#xff0c;可以修改端口號&#xff1b; lib是依賴的jar包&#xff1b; logs是日志 webapps是重點&#xff0c;在這里新建我們自己的javaWeb項目 tomcat如何訪問資源 tomcat通過統一資源定位符&#xff08;URL&#xff09;來…

鄉村振興與農村基礎設施建設:加大農村基礎設施建設投入,提升農村公共服務水平,改善農民生產生活條件,構建宜居宜業的美麗鄉村

一、引言 鄉村振興是我國現代化進程中的重要戰略&#xff0c;而農村基礎設施建設則是鄉村振興的基石。隨著城市化進程的加快&#xff0c;農村基礎設施建設滯后的問題日益凸顯&#xff0c;成為制約鄉村發展的瓶頸。因此&#xff0c;加大農村基礎設施建設投入&#xff0c;提升農…

打造一套在線教育系統,如何在教育這個慢行業打造品牌?

品牌對于教育行業非常重要&#xff0c;很多從事教育行業的朋友一直想塑造屬于自己的品牌形象&#xff0c;但做起來卻沒那么容易。因為教育行業相對來說是一個慢行業&#xff0c;用戶必須看到效果才會認可&#xff0c;而教育的效果往往需要經過長期的學習才能看到。 我覺得&…

AI大模型探索之路-訓練篇21:Llama2微調實戰-LoRA技術微調步驟詳解

系列篇章&#x1f4a5; AI大模型探索之路-訓練篇1&#xff1a;大語言模型微調基礎認知 AI大模型探索之路-訓練篇2&#xff1a;大語言模型預訓練基礎認知 AI大模型探索之路-訓練篇3&#xff1a;大語言模型全景解讀 AI大模型探索之路-訓練篇4&#xff1a;大語言模型訓練數據集概…

華為OD機試 - 執行任務賺積分 - 動態規劃(Java 2024 C卷 100分)

華為OD機試 2024C卷題庫瘋狂收錄中,刷題點這里 專欄導讀 本專欄收錄于《華為OD機試(JAVA)真題(A卷+B卷+C卷)》。 刷的越多,抽中的概率越大,每一題都有詳細的答題思路、詳細的代碼注釋、樣例測試,發現新題目,隨時更新,全天CSDN在線答疑。 一、題目描述 現有 N 個任…

Gradle基礎學習(六) 認識任務Task

理解Gradle中的任務 Gradle的構建過程基于任務&#xff08;Task&#xff09;的概念&#xff0c;而每個任務都可以包含一個或多個動作&#xff08;Action&#xff09;。 任務是構建中執行的一些獨立的工作單元&#xff0c;例如編譯類、創建JAR、生成Javadoc或將存檔發布到倉庫…

4.5網安學習第四階段第五周回顧(個人學習記錄使用)

本周重點 ①部署域環境&#xff08;Win2008&#xff09; ②域組策略 ③域內信息收集 ④(重點)哈希傳遞攻擊PTH ⑤MS14-068 提權漏洞 ⑥黃金票據偽造 ⑦白銀票據偽造 ⑧ZeroLogon (CVE-2020-1472) 漏洞復現 本周主要內容 ①部署域環境&#xff08;Win2008&#xff09;…

【算法】滑動窗口——串聯所有單詞的子串

今天來以“滑動窗口”的思想來詳解一道比較困難的題目——串聯所有單詞的子串&#xff0c;有需要借鑒即可。 目錄 1.題目2.下面是示例代碼3.總結 1.題目 題目鏈接&#xff1a;LINK 這道題如果把每個字符串看成一個字母&#xff0c;就是另外一道中等難度的題目&#xff0c;即&…