Vue echarts封裝組件需求分析與實(shí)現(xiàn)
1.需求分析
本次需求是繪制多個(gè)折線圖描述服務(wù)器狀態(tài)信息。因此都是折線圖,樣式類似,因此考慮vue-echarts 進(jìn)行一個(gè)配置option多個(gè)圖表。
2.結(jié)構(gòu)
- 前端向后端請(qǐng)求數(shù)據(jù)(key,val)數(shù)組(分別對(duì)應(yīng)x軸、y軸),具體到代碼里就是結(jié)構(gòu)體obj的兩個(gè)屬性keys,vals
- 前端使用vue-echarts進(jìn)行option配置相關(guān)參數(shù),具體見(jiàn)代碼。
3.代碼
<template> <v-chart class="chart" :option="option" /> <el-button class="myBtn" type="primary" @click="randomData" >隨機(jī)數(shù)據(jù)</el-button > </template> <script> // 導(dǎo)入相關(guān)組件 import { use } from "echarts/core"; import { CanvasRenderer } from "echarts/renderers"; import { LineChart } from "echarts/charts"; import { TitleComponent, TooltipComponent, LegendComponent, GridComponent, } from "echarts/components"; import VChart, { THEME_KEY } from "vue-echarts"; import { ref, defineComponent } from "vue"; import { reactive } from "vue"; import { ElButton } from "element-plus"; use([ GridComponent, CanvasRenderer, LineChart, TitleComponent, TooltipComponent, LegendComponent, ]); //從后端取出數(shù)據(jù) // import { getData } from "../utils/getChart"; // var obj = await getData(); // //console.log(obj); // let n = obj.keys.length; // var ans = Array(n); //作于 series.data // for (var i = 0; i < n; i++) { // ans[i] = new Array(2); // ans[i] = [obj.keys[i], obj.vals[i]]; // } var obj = { keys: ["10:09:03", "10:09:06", "10:09:09", "10:09:12", "10:09:15"], vals: [39.12, 23.76, 22.79, 30.57, 31.84], }; let n = 5; var ans = Array(n); for (var i = 0; i < n; i++) { ans[i] = new Array(2); ans[i] = [obj.keys[i], obj.vals[i]]; } export default defineComponent({ name: "ChartInfo", components: { //使用到的圖表組件 ElButton, VChart, }, provide: { [THEME_KEY]: "white", //設(shè)置主題 }, setup() { //啟動(dòng)函數(shù) //動(dòng)態(tài)生成數(shù)據(jù)ans,雙向綁定 const myData = reactive(ans); //隨機(jī)生成數(shù)據(jù) function randomData() { let mx = 30.0; let mn = 1.0; for (var i = 0; i < n; i++) { myData[i][1] = Math.random() * (mx - mn) + mn; } //console.log("random:", myData); } //配置option const option = ref({ //由grid控制各個(gè)圖表,x,y為與左上角頂點(diǎn)的距離,控制各個(gè)圖表的位置及大小 grid: [ { left: "10%", top: "6%", width: "80%", height: "20%" }, { left: "10%", top: "41%", width: "80%", height: "20%" }, { left: "10%", y: "76%", width: "80%", height: "20%" }, ], title: [ { text: "最近5個(gè)時(shí)刻的cpu使用率" }, { text: "最近5個(gè)時(shí)刻的mem使用率", top: "35%" }, { text: "最近5個(gè)時(shí)刻的load使用率", top: "70%" }, ], // tooltip: { // //提示框配置 // trigger: "axis", // formatter: "{a} <br/> : {c}", // }, // legend: { // //圖例組件 // orient: "vertical", // left: "left", // }, xAxis: [ { gridIndex: 0, data: obj.keys, }, { gridIndex: 1, data: obj.keys, }, { gridIndex: 2, data: obj.keys, }, ], // xAxis: { // type: "category", // data: obj.keys, //keys是x軸 // }, yAxis: [ //minInterval控制最小間隔,不設(shè)置的話會(huì)有小數(shù),同樣由gridIndex綁定各個(gè)圖表 { gridIndex: 0, minInterval: 1 }, { gridIndex: 1, minInterval: 1 }, { gridIndex: 2, minInterval: 1 }, ], series: [ //系列選擇pie,進(jìn)行相關(guān)數(shù)據(jù)配置 { xAxisIndex: 0, yAxisIndex: 0, name: "cpu使用率", type: "line", radius: "55%", center: ["50%", "60%"], data: myData, emphasis: { itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: "rgba(0, 0, 0, 0.5)", }, }, }, { xAxisIndex: 1, yAxisIndex: 1, name: "mem使用率", type: "line", radius: "55%", center: ["50%", "60%"], data: myData, emphasis: { itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: "rgba(0, 0, 0, 0.5)", }, }, }, { xAxisIndex: 2, yAxisIndex: 2, name: "load使用率", type: "line", radius: "55%", center: ["50%", "60%"], data: myData, emphasis: { itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: "rgba(0, 0, 0, 0.5)", }, }, }, ], }); return { option, randomData }; }, }); </script> <style scoped> .chart { /* 100vh 表示高度為屏幕可見(jiàn)的100% */ height: 600px; margin-top: 30px; } .myBtn { margin-top: 10px; } </style>
4.結(jié)果
原生echarts
上文是基于vue-echarts 依賴的,在使用一段時(shí)間后,發(fā)現(xiàn)該模塊對(duì)于異步請(qǐng)求數(shù)據(jù)不是很友好qwq,所以我換回了原生的echarts。
思路與前面完全一樣,只是模塊換成了原生的echarts。
1.代碼
<template> <div id="chart"></div> <!-- <v-chart class="chart" :option="option" /> --> <el-button class="myBtn" type="primary" @click="randomData" >隨機(jī)數(shù)據(jù)</el-button > </template> <script> import { ref, defineComponent, onMounted } from "vue"; import { reactive } from "vue"; import { ElButton } from "element-plus"; import { getData } from "../utils/getChart"; import * as echarts from "echarts"; export default defineComponent({ name: "ChartInfo", props: ["id"], components: { //使用到的圖表組件 ElButton, }, setup(props) { //props 為子組件介紹父組件的參數(shù),這里是路由props的參數(shù) //啟動(dòng)函數(shù) let obj = reactive({ cpu: [], mem: [], }); let ans_1 = reactive([]); let ans_2 = reactive([]); let option = reactive({}); function myformatter(value, index) { if (value) { let date = new Date(value * 1000); // 時(shí)間戳為秒:10位數(shù) //let date = new Date(value) // 時(shí)間戳為毫秒:13位數(shù) let year = date.getFullYear(); let month = date.getMonth() + 1 < 10 ? `0${date.getMonth() + 1}` : date.getMonth() + 1; let day = date.getDate() < 10 ? `0${date.getDate()}` : date.getDate(); let hour = date.getHours() < 10 ? `0${date.getHours()}` : date.getHours(); let minute = date.getMinutes() < 10 ? `0${date.getMinutes()}` : date.getMinutes(); let second = date.getSeconds() < 10 ? `0${date.getSeconds()}` : date.getSeconds(); return `${hour}:${minute}:${second}`; //return `${year}-${month}-${day} ${hour}:${minute}:${second}`; } else { return ""; } } onMounted(async () => { let obj = await getData(props.id).catch((err) => { console.log(err); }); console.log("res", obj); let x_arr = new Array(3); let res_arr = new Array(3); let n0 = obj.cpu.length; for (var i = 0; i < n0; i++) obj.cpu[i].key = myformatter(obj.cpu[i].key); x_arr[0] = new Array(n0); res_arr[0] = new Array(n0); for (var i = 0; i < n0; i++) { x_arr[0][i] = obj.cpu[i].key; res_arr[0][i] = [obj.cpu[i].key, obj.cpu[i].val]; } console.log(res_arr[0]); var n1 = obj.mem.length; for (var i = 0; i < n1; i++) obj.mem[i].key = myformatter(obj.mem[i].key); x_arr[1] = new Array(n1); res_arr[1] = new Array(n1); for (var i = 0; i < n1; i++) { x_arr[1][i] = obj.mem[i].key; res_arr[1][i] = [obj.mem[i].key, obj.mem[i].val]; } var n2 = obj.mem.length; x_arr[2] = new Array(n2); res_arr[2] = new Array(n2); for (var i = 0; i < n2; i++) { x_arr[2][i] = obj.mem[i].key; res_arr[2][i] = [obj.mem[i].key, obj.mem[i].val]; } ans_1.push(...x_arr); ans_2.push(...res_arr); var myChart = echarts.init(document.getElementById("chart")); option = reactive({ //由grid控制各個(gè)圖表,x,y為與左上角頂點(diǎn)的距離,控制各個(gè)圖表的位置及大小 grid: [ { left: "10%", top: "6%", width: "80%", height: "20%" }, { left: "10%", top: "41%", width: "80%", height: "20%" }, { left: "10%", y: "76%", width: "80%", height: "20%" }, ], title: [ { text: "最近5個(gè)時(shí)刻的cpu使用率" }, { text: "最近5個(gè)時(shí)刻的mem使用率", top: "35%" }, { text: "最近5個(gè)時(shí)刻的load使用率", top: "70%" }, ], // tooltip: { // //提示框配置 // trigger: "axis", // formatter: "{a} <br/> : {c}", // }, // legend: { // //圖例組件 // orient: "vertical", // left: "left", // }, xAxis: [ { gridIndex: 0, data: ans_1[0], }, { gridIndex: 1, data: ans_1[1], // axisLabel: { // formatter: myformatter, // }, }, { gridIndex: 2, data: ans_1[2], // axisLabel: { // formatter: myformatter, // }, }, ], // xAxis: { // type: "category", // data: obj.keys, //keys是x軸 // }, yAxis: [ //minInterval控制最小間隔,不設(shè)置的話會(huì)有小數(shù),同樣由gridIndex綁定各個(gè)圖表 { gridIndex: 0, minInterval: 1 }, { gridIndex: 1, minInterval: 1 }, { gridIndex: 2, minInterval: 1 }, ], series: [ //系列選擇pie,進(jìn)行相關(guān)數(shù)據(jù)配置 { xAxisIndex: 0, yAxisIndex: 0, name: "cpu使用率", type: "line", radius: "55%", center: ["50%", "60%"], data: ans_2[0], emphasis: { itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: "rgba(0, 0, 0, 0.5)", }, }, }, { xAxisIndex: 1, yAxisIndex: 1, name: "mem使用率", type: "line", radius: "55%", center: ["50%", "60%"], data: ans_2[1], emphasis: { itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: "rgba(0, 0, 0, 0.5)", }, }, }, { xAxisIndex: 2, yAxisIndex: 2, name: "load使用率", type: "line", radius: "55%", center: ["50%", "60%"], data: ans_2[2], emphasis: { itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: "rgba(0, 0, 0, 0.5)", }, }, }, ], }); myChart.setOption(option); }); //隨機(jī)生成數(shù)據(jù) function randomData() { // for (var i = 0; i < 3; i++) { // option.series[i].data = ans_2[i]; // option.xAxis[i].data = ans_1[i]; // } console.log("random test"); } //配置option // let option = reactive({ // //由grid控制各個(gè)圖表,x,y為與左上角頂點(diǎn)的距離,控制各個(gè)圖表的位置及大小 // grid: [ // { left: "10%", top: "6%", width: "80%", height: "20%" }, // { left: "10%", top: "41%", width: "80%", height: "20%" }, // { left: "10%", y: "76%", width: "80%", height: "20%" }, // ], // title: [ // { text: "最近5個(gè)時(shí)刻的cpu使用率" }, // { text: "最近5個(gè)時(shí)刻的mem使用率", top: "35%" }, // { text: "最近5個(gè)時(shí)刻的load使用率", top: "70%" }, // ], // // tooltip: { // // //提示框配置 // // trigger: "axis", // // formatter: "{a} <br/> : {c}", // // }, // // legend: { // // //圖例組件 // // orient: "vertical", // // left: "left", // // }, // xAxis: [ // { // gridIndex: 0, // data: ans_1[0], // }, // { // gridIndex: 1, // data: ans_1[1], // }, // { // gridIndex: 2, // data: ans_1[2], // }, // ], // // xAxis: { // // type: "category", // // data: obj.keys, //keys是x軸 // // }, // yAxis: [ // //minInterval控制最小間隔,不設(shè)置的話會(huì)有小數(shù),同樣由gridIndex綁定各個(gè)圖表 // { gridIndex: 0, minInterval: 1 }, // { gridIndex: 1, minInterval: 1 }, // { gridIndex: 2, minInterval: 1 }, // ], // series: [ // //系列選擇pie,進(jìn)行相關(guān)數(shù)據(jù)配置 // { // xAxisIndex: 0, // yAxisIndex: 0, // name: "cpu使用率", // type: "line", // radius: "55%", // center: ["50%", "60%"], // data: ans_2[0], // emphasis: { // itemStyle: { // shadowBlur: 10, // shadowOffsetX: 0, // shadowColor: "rgba(0, 0, 0, 0.5)", // }, // }, // }, // { // xAxisIndex: 1, // yAxisIndex: 1, // name: "mem使用率", // type: "line", // radius: "55%", // center: ["50%", "60%"], // data: ans_2[1], // emphasis: { // itemStyle: { // shadowBlur: 10, // shadowOffsetX: 0, // shadowColor: "rgba(0, 0, 0, 0.5)", // }, // }, // }, // { // xAxisIndex: 2, // yAxisIndex: 2, // name: "load使用率", // type: "line", // radius: "55%", // center: ["50%", "60%"], // data: ans_2[2], // emphasis: { // itemStyle: { // shadowBlur: 10, // shadowOffsetX: 0, // shadowColor: "rgba(0, 0, 0, 0.5)", // }, // }, // }, // ], // }); //console.log("dsda", obj); //動(dòng)態(tài)生成數(shù)據(jù)ans,雙向綁定 //console.log(option); //console("tep", tep); return { ans_1, ans_2, randomData }; }, }); </script> <style scoped> #chart { /* 100vh 表示高度為屏幕可見(jiàn)的100% */ height: 600px; margin-top: 30px; } .myBtn { margin-top: 10px; } </style>
2.區(qū)別
使用原生的echarts就可以在onMounted
鉤子函數(shù)中執(zhí)行異步請(qǐng)求,然后得到數(shù)據(jù),然后通過(guò)原生dom操作獲取圖表元素。然后配置option。
var myChart = echarts.init(document.getElementById("chart")); option = reactive({....}) myChart.setOption(option);
vue-echarts封裝后的option配置得先獲得數(shù)據(jù)就很蠢,在異步請(qǐng)求里獲得數(shù)據(jù)后,往下操作數(shù)據(jù)可能是空得,這樣導(dǎo)出setup函數(shù)導(dǎo)出option就可能有問(wèn)題。
3.結(jié)果
到此這篇關(guān)于Vue eharts封裝組件需求分析與實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Vue eharts封裝內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue3解決跨域問(wèn)題詳細(xì)代碼親測(cè)有效
跨域,跨的是不同域,也就是協(xié)議或主機(jī)或或端口號(hào)不同造成的現(xiàn)象,本文給大家分享vue3解決跨域問(wèn)題詳細(xì)代碼親測(cè)有效,感興趣的朋友跟隨小編一起看看吧2022-11-11Vue-cli3項(xiàng)目引入Typescript的實(shí)現(xiàn)方法
這篇文章主要介紹了Vue-cli3項(xiàng)目引入Typescript的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10詳解VUE 定義全局變量的幾種實(shí)現(xiàn)方式
本篇文章主要介紹了VUE 全局變量的幾種實(shí)現(xiàn)方式,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-06-06Vue 級(jí)聯(lián)下拉框的設(shè)計(jì)與實(shí)現(xiàn)
在前端開(kāi)發(fā)中,級(jí)聯(lián)選擇框是經(jīng)常用到的,這樣不僅可以增加用戶輸入的友好性,還能減少前后端交互的數(shù)據(jù)量。本文就介紹一下使用Vue實(shí)現(xiàn)級(jí)聯(lián)下拉框,感興趣的可以了解一下2021-07-07vue實(shí)現(xiàn)動(dòng)態(tài)面包屑導(dǎo)航
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)動(dòng)態(tài)面包屑導(dǎo)航的使用方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04Webpack+Vue如何導(dǎo)入Jquery和Jquery的第三方插件
本文主要介紹了Webpack+Vue導(dǎo)入Jquery和Jquery的第三方插件的方法,具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧2017-02-02Vue設(shè)置select下拉框的默認(rèn)選項(xiàng)詳解(select空白bug解決)
最近開(kāi)始學(xué)習(xí)vue,在學(xué)習(xí)的過(guò)程中遇到的問(wèn)題將記錄在這里,下面這篇文章主要給大家介紹了關(guān)于Vue設(shè)置select下拉框的默認(rèn)選項(xiàng)(select空白bug解決)的相關(guān)資料,需要的朋友可以參考下2022-12-12