Vue echarts封裝組件需求分析與實(shí)現(xiàn)
1.需求分析
本次需求是繪制多個(gè)折線圖描述服務(wù)器狀態(tài)信息。因此都是折線圖,樣式類似,因此考慮vue-echarts 進(jìn)行一個(gè)配置option多個(gè)圖表。
2.結(jié)構(gòu)
- 前端向后端請求數(shù)據(jù)(key,val)數(shù)組(分別對應(yīng)x軸、y軸),具體到代碼里就是結(jié)構(gòu)體obj的兩個(gè)屬性keys,vals
- 前端使用vue-echarts進(jìn)行option配置相關(guān)參數(shù),具體見代碼。
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() {
//啟動函數(shù)
//動態(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è)置的話會有小數(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 表示高度為屏幕可見的100% */
height: 600px;
margin-top: 30px;
}
.myBtn {
margin-top: 10px;
}
</style>4.結(jié)果

原生echarts
上文是基于vue-echarts 依賴的,在使用一段時(shí)間后,發(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"
>隨機(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ù)
//啟動函數(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è)置的話會有小數(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è)置的話會有小數(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);
//動態(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ù)可能是空得,這樣導(dǎo)出setup函數(shù)導(dǎo)出option就可能有問題。
3.結(jié)果

到此這篇關(guān)于Vue eharts封裝組件需求分析與實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Vue eharts封裝內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
如何通過Vue自定義指令實(shí)現(xiàn)前端埋點(diǎn)詳析
埋點(diǎn)分析是網(wǎng)站分析的一種常用的數(shù)據(jù)采集方法,下面這篇文章主要給大家介紹了關(guān)于如何通過Vue自定義指令實(shí)現(xiàn)前端埋點(diǎn)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07
vue實(shí)現(xiàn)element-ui對話框可拖拽功能
這篇文章主要介紹了vue實(shí)現(xiàn)element-ui對話框可拖拽功能,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-08-08
vue keep-alive列表頁緩存 詳情頁返回上一頁不刷新,定位到之前位置
這篇文章主要介紹了vue keep-alive列表頁緩存 詳情頁返回上一頁不刷新,定位到之前位置,本文通過實(shí)例代碼效果圖展示給大家介紹的非常詳細(xì),需要的朋友可以參考下2019-11-11
詳解vue-cli+element-ui樹形表格(多級表格折騰小計(jì))
這篇文章主要介紹了vue-cli + element-ui 樹形表格(多級表格折騰小計(jì)),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-04-04
解決Vue.js由于延時(shí)顯示了{(lán){message}}引用界面的問題
今天小編就為大家分享一篇解決Vue.js由于延時(shí)顯示了{(lán){message}}引用界面的問題,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-08-08

