前言
之前写项目,需要写一个图表动态展示出当前服务器的信息,在网上找了很多相关的文章,但是关于vue中使用echarts动态图表的内容比较少,自己写过之后就在这里记录一下,希望能够对大家有所帮助
实现效果
先来看下效果:
动态展现当前服务器 内存占用率,cpu占用率,磁盘写入量和磁盘读取量(因为服务器没上东西,所以数据相对比较平缓),下面教大家怎么写出这种动态图表
option的内容
首先对于这样一个动态图表,看起来很复杂,因为我这里有四条数据,大家可以先写一条数据,把他跑起来,其余再加数据是很容易的:
这里option的数据,要注意的点:
- xAxis存放横坐标的数据,我这里是实时展示当前时间刷新出来,先给data:[ ],后面再处理
- yAxis存放纵坐标数据,这里是写死的,应该没啥问题,两个对象对应左右两个纵坐标
- series存放当前图表的数据,四条数据所以是四个对象,data数组都给空,因为这里进行动态渲染
option: {
tooltip: {
trigger: 'axis',
axisPointer: { type: 'cross' }
},
legend: {
},
xAxis: [
{
type: 'category',
axisTick: {
alignWithLabel: true,
show: false
},
data: []
}
],
yAxis: [
{
type: 'value',
name: '磁盘使用量',
min: 0,
max: 1000,
position: 'right',
axisLabel: {
formatter: '{value} GB'
}
},
{
type: 'value',
name: '占用百分比',
min: 0,
max: 100,
position: 'left',
axisLabel: {
formatter: '{value} %'
}
}
],
series: [
{
name: '内存占用率',
yAxisIndex: 1,
type: 'bar',
data: [],
itemStyle: {
barBorderRadius: 5,
borderWidth: 1,
borderType: 'solid',
borderColor: '#73c0de',
shadowColor: '#5470c6',
shadowBlur: 1
}
},
{
name: 'CPU占用率',
yAxisIndex: 1,
type: 'bar',
data: [],
itemStyle: {
barBorderRadius: 5,
borderWidth: 1,
borderType: 'solid',
borderColor: '#73c0de',
shadowColor: '#5470c6',
shadowBlur: 1
}
},
{
name: '磁盘写入量',
yAxisIndex: 0,
type: 'line',
data: []
},
{
name: '磁盘读取量',
yAxisIndex: 0,
type: 'line',
data: []
}
]
}
函数内容
说明:因为实际开发的运用场景可能不同,所以方法上存在差异,我这里是写成一个组件,数据由父组件传入,不过主要的大致思路相同,看懂下面我讲的,基本你自己能够复现
下面我讲解的顺序,按照页面声明周期的顺序走:
1.created()
页面穿建阶段,为了避免图表创建出来是空的,没有数据,所以我这里的处理是:获取当前时间前20个数据,这样图表刷新出来的时候,里面是有数据的,然后再删数据,加新数据
所以created中我写了获取前二十个数据的函数:
created () {
this.getbefortime()
},
获取前20个数据,实际开发就得找后端写这个接口,前端直接调用,然后我将前20个数据存入beforinfo中
// 获取前20个数据
async getbefortime() {
const { data: res } = await serverCpubefor()
this.beforinfo = res
// console.log('******', this.beforinfo)
},
前20个数据获取好了,那就还需要获取前二十个时间,也就是横坐标:这里思路就是我每隔3s刷新一次,就获取当前时间,然后往后推20个3s,每个数据都存入到xAxis的data中,并且也把刚刚获取的前20个数据存入series对应的data中
//获取前20个时间,并把前20个时间,和前20个数据存入对应的xAxis和series的data中,这样图表生成就有数据
addbeforData() {
var hh = new Date().getHours();
var mf = new Date().getMinutes()<10 ? '0'+new Date().getMinutes() : new Date().getMinutes();
var ss = new Date().getSeconds()<10 ? '0'+new Date().getSeconds() : new Date().getSeconds();
for(var i=0;i<=19;i++){
if(ss>12){
ss=ss-3
}else if(12<=ss>=3){
ss='0'+(ss-3)
}else{
if(mf>=11){
mf=mf-1
ss=60-3
}else{
mf='0'+(mf-1)
ss=60-3
}
}
var befortime = [hh, mf, ss].join(":");
// console.log('---***---',befortime )
// console.log('---***---',this.beforinfo.数据[i].CPU占用率[0] )
this.option.xAxis[0].data.unshift(befortime);
// 添加初始cpu占用率数据
this.option.series[1].data.unshift(this.beforinfo.数据[i].CPU占用率[0]);
// 添加初始内存占用率数据
this.option.series[0].data.unshift(this.beforinfo.数据[i].内存占用率[0]);
// 添加初始磁盘写入量数据
this.option.series[2].data.unshift(this.beforinfo.数据[i].硬盘写入量[0]);
// 添加初始磁盘读取量数据
this.option.series[3].data.unshift(this.beforinfo.数据[i].硬盘读取量[0]);
//console.log(befortime)
}
},
created后我们需要在mouted中初始化图表:
使用myChart.showLoading()实现加载的效果
mounted() {
let myChart = echarts.init(document.getElementById("main2"))
myChart.showLoading();
},
2.图表生成
上面我们写了addbeforData()函数,那么在哪里调用呢?这里就要用到watch进行监听,this.beforinfo初始值为空,我们在获取到前20个数据的时候将值存入了this.beforinfo中,所以只要beforinfo值发生了改变,就可以进行addbeforData()函数和生成图表了:
//监听beforinfo值的变化
watch: {
beforinfo(newVal,oldVal){
this.addbeforData()
this.initchart()
}
},
initchart函数就是我们生成图表的函数:
到这一步说明图表数据以及没问题了,可以展示图表了,myChart.hideLoading()关闭加载的动画
initchart(){
let myChart = echarts.getInstanceByDom(document.getElementById("main2"));
myChart.hideLoading();
myChart.setOption(this.option);
window.addEventListener('resize', function () {
myChart.resize()
})
}
3.数据的动态渲染
到上面一步,图表就已经生成了,只不过里面展示的是当前时间的前20个数据,那么我们还需要图动起来,下面就来进行动态渲染:
首先写一个gettime()函数来获取当前的时间并返回
gettime(){
var hh = new Date().getHours();
var mf = new Date().getMinutes()<10 ? '0'+new Date().getMinutes() : new Date().getMinutes();
var ss = new Date().getSeconds()<10 ? '0'+new Date().getSeconds() : new Date().getSeconds();
var nowtime = [hh, mf, ss].join(":");
return nowtime
},
然后我们还是使用watch进行监听,我这里的值是由父组件msg传过来的,所以只要msg值发生改变就说明有新的数据,那么就要进行新数据的加入和旧数据的删除,从而实现动态效果:
别忘了删除和添加数据之后要重新调用this.initchart()实现图表的刷新
//在watch中监听msg数据
msg(val) {
this.serverInfo = val
if(this.option.series[1].data.length == '20' ) {
// 删除头部数据
this.option.xAxis[0].data.shift();
this.option.series[1].data.shift();
this.option.series[0].data.shift();
this.option.series[2].data.shift();
this.option.series[3].data.shift();
// 队尾添加数据
this.option.xAxis[0].data.push(this.gettime());
this.option.series[1].data.push(this.serverInfo.数据.CPU占用率[0]);
this.option.series[0].data.push(this.serverInfo.数据.内存占用率[0]);
this.option.series[2].data.push(this.serverInfo.数据.硬盘写入量[0]);
this.option.series[3].data.push(this.serverInfo.数据.硬盘读取量[0]);
}
this.initchart()
},
==可能对于动态数据这里大家可能有疑问,因为我这里数据是从父组件传过来的,没有写在这个页面,我把父组件的实现关键点给大家看看:==
父组件中的函数:
1.getCputhings()获取到当前的数据,存入到this.serverInfo中,这就是把这个值传给子组件也就是上面图表
2.在mounted中使用setInterval定时器,每隔几秒就请求一次数据,所以子组件只要监听到传过去的数据改变就能渲染最新的数据
3.beforeDestroy()中删除掉这个定时器,避免进入其它页面,定时器依旧在工作
methods: {
async getCputhings() {
const { data: res} = await serverCpu()
this.serverInfo = res
},
},
created() {
this.getCputhings()
},
mounted() {
this.timer = window.setInterval(() => {
setTimeout(()=>{
this.getCputhings()
})
}, 2000)
},
beforeDestroy() {
clearInterval(this.timer)
}
最后
这样一套下来,就能实现出图表的动态渲染,主要是这样一个监听渲染的过程,对于图表样式可以根据自己的想法来,换汤不换药罢了
如果对你有帮助,点赞 点个关注支持一下,有问题可以在评论区留言~
如果需要页面完整代码的评论区留言,主要代码上面都有,因为篇幅原因这里就不放了