Vue echarts封裝組件需求分析與實現(xiàn)
1.需求分析
本次需求是繪制多個折線圖描述服務器狀態(tài)信息。因此都是折線圖,樣式類似,因此考慮vue-echarts 進行一個配置option多個圖表。
2.結(jié)構(gòu)
- 前端向后端請求數(shù)據(jù)(key,val)數(shù)組(分別對應x軸、y軸),具體到代碼里就是結(jié)構(gòu)體obj的兩個屬性keys,vals
- 前端使用vue-echarts進行option配置相關(guān)參數(shù),具體見代碼。
3.代碼
<template>
<v-chart class="chart" :option="option" />
<el-button class="myBtn" type="primary" @click="randomData"
>隨機數(shù)據(jù)</el-button
>
</template>
<script>
// 導入相關(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", //設置主題
},
setup() {
//啟動函數(shù)
//動態(tài)生成數(shù)據(jù)ans,雙向綁定
const myData = reactive(ans);
//隨機生成數(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控制各個圖表,x,y為與左上角頂點的距離,控制各個圖表的位置及大小
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個時刻的cpu使用率" },
{ text: "最近5個時刻的mem使用率", top: "35%" },
{ text: "最近5個時刻的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ù),同樣由gridIndex綁定各個圖表
{ gridIndex: 0, minInterval: 1 },
{ gridIndex: 1, minInterval: 1 },
{ gridIndex: 2, minInterval: 1 },
],
series: [
//系列選擇pie,進行相關(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 表示高度為屏幕可見的100% */
height: 600px;
margin-top: 30px;
}
.myBtn {
margin-top: 10px;
}
</style>4.結(jié)果

原生echarts
上文是基于vue-echarts 依賴的,在使用一段時間后,發(fā)現(xiàn)該模塊對于異步請求數(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"
>隨機數(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ù)
//啟動函數(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); // 時間戳為秒:10位數(shù)
//let date = new Date(value) // 時間戳為毫秒: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控制各個圖表,x,y為與左上角頂點的距離,控制各個圖表的位置及大小
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個時刻的cpu使用率" },
{ text: "最近5個時刻的mem使用率", top: "35%" },
{ text: "最近5個時刻的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ù),同樣由gridIndex綁定各個圖表
{ gridIndex: 0, minInterval: 1 },
{ gridIndex: 1, minInterval: 1 },
{ gridIndex: 2, minInterval: 1 },
],
series: [
//系列選擇pie,進行相關(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);
});
//隨機生成數(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控制各個圖表,x,y為與左上角頂點的距離,控制各個圖表的位置及大小
// 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個時刻的cpu使用率" },
// { text: "最近5個時刻的mem使用率", top: "35%" },
// { text: "最近5個時刻的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ù),同樣由gridIndex綁定各個圖表
// { gridIndex: 0, minInterval: 1 },
// { gridIndex: 1, minInterval: 1 },
// { gridIndex: 2, minInterval: 1 },
// ],
// series: [
// //系列選擇pie,進行相關(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);
//動態(tài)生成數(shù)據(jù)ans,雙向綁定
//console.log(option);
//console("tep", tep);
return { ans_1, ans_2, randomData };
},
});
</script>
<style scoped>
#chart {
/* 100vh 表示高度為屏幕可見的100% */
height: 600px;
margin-top: 30px;
}
.myBtn {
margin-top: 10px;
}
</style>2.區(qū)別
使用原生的echarts就可以在onMounted鉤子函數(shù)中執(zhí)行異步請求,然后得到數(shù)據(jù),然后通過原生dom操作獲取圖表元素。然后配置option。
var myChart = echarts.init(document.getElementById("chart"));
option = reactive({....})
myChart.setOption(option);
vue-echarts封裝后的option配置得先獲得數(shù)據(jù)就很蠢,在異步請求里獲得數(shù)據(jù)后,往下操作數(shù)據(jù)可能是空得,這樣導出setup函數(shù)導出option就可能有問題。
3.結(jié)果

到此這篇關(guān)于Vue eharts封裝組件需求分析與實現(xiàn)的文章就介紹到這了,更多相關(guān)Vue eharts封裝內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue-cli3項目引入Typescript的實現(xiàn)方法
這篇文章主要介紹了Vue-cli3項目引入Typescript的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-10-10
Webpack+Vue如何導入Jquery和Jquery的第三方插件
本文主要介紹了Webpack+Vue導入Jquery和Jquery的第三方插件的方法,具有很好的參考價值,下面跟著小編一起來看下吧2017-02-02
Vue設置select下拉框的默認選項詳解(select空白bug解決)
最近開始學習vue,在學習的過程中遇到的問題將記錄在這里,下面這篇文章主要給大家介紹了關(guān)于Vue設置select下拉框的默認選項(select空白bug解決)的相關(guān)資料,需要的朋友可以參考下2022-12-12

