Use echarts in vue to realize dynamic chart multi-data display, with source code (x-axis dynamic time refresh, real-time update display data)

foreword

Before writing a project, I needed to write a chart to dynamically display the information of the current server. I found a lot of related articles on the Internet, but the content about the use of echarts dynamic charts in vue is relatively small. After I wrote it myself, I will record it here. I hope to be able to helpful to everyone

achieve effect

Let's first look at the effect:
dynamically display the current server memory usage, cpu usage, disk write volume and disk read volume (because the server has nothing, so the data is relatively flat), let's teach you how to write this dynamic chart
insert image description here

the content of the option

First of all, for such a dynamic chart, it looks very complicated, because I have four pieces of data here, you can write one piece of data first, run it, and it is easy to add data to the rest:
here is the option data, the points to pay attention to:

  1. xAxis stores the data of the abscissa. Here I display the current time in real time and refresh it. Give data:[ ] first, and then process it later.
  2. yAxis stores the ordinate data, which is hard-coded here, there should be no problem, the two objects correspond to the left and right ordinates
  3. The series stores the data of the current chart. The four pieces of data are four objects, and the data arrays are all empty, because dynamic rendering is performed here.
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: []
    }
  ]
}

Function content

Note: Because the application scenarios of actual development may be different, there are differences in methods. I am writing it as a component here, and the data is passed in from the parent component, but the main general idea is the same. If you understand what I say below, you can basically reproduce it yourself. now

The order I explain below is in the order of the page declaration cycle:

1.created()

In the page construction stage, in order to avoid the chart being created empty and without data, my processing here is: get the first 20 data at the current time, so that when the chart is refreshed, there is data in it, and then delete the data, add new data

So in created I wrote a function to get the first twenty data:

created () {
    
    
    this.getbefortime()
},

To get the first 20 data, the actual development has to find the back-end to write this interface, the front-end calls directly, and then I store the first 20 data in beforinfo

// 获取前20个数据
async getbefortime() {
    
    
  const {
    
     data: res } = await serverCpubefor()
 

  this.beforinfo = res
  // console.log('******', this.beforinfo)
},

After the first 20 data is obtained, then the first 20 times need to be obtained, that is, the abscissa: the idea here is that I refresh every 3s to obtain the current time, and then push back 20 3s, each data All are stored in the data of xAxis, and the first 20 data just obtained are also stored in the data corresponding to the series

//获取前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)
   }
  
 },

After created, we need to initialize the chart in mouted:
use myChart.showLoading() to achieve the effect of loading

mounted() {
    
    
    let myChart = echarts.init(document.getElementById("main2"))
    myChart.showLoading();
  },

2. Chart generation

We wrote the addbeforData() function above, so where to call it? Here we need to use watch to monitor, the initial value of this.beforinfo is empty, we store the value in this.beforinfo when we get the first 20 data, so as long as the beforinfo value changes, we can addbeforData( ) function and generate the graph:

//监听beforinfo值的变化
watch: {
    
    
    beforinfo(newVal,oldVal){
    
    
      this.addbeforData()
      this.initchart()
    }
  },

The initchart function is the function we use to generate the chart:
at this point, the chart data is explained and there is no problem, the chart can be displayed, myChart.hideLoading() closes the loaded animation

initchart(){
    
    
  let myChart = echarts.getInstanceByDom(document.getElementById("main2"));
  myChart.hideLoading();
  myChart.setOption(this.option);
  window.addEventListener('resize', function () {
    
    
    myChart.resize()
  })
}

3. Dynamic rendering of data

At the above step, the chart has been generated, but it shows the first 20 data of the current time. Then we need to move the chart. Next, we will perform dynamic rendering:
First, write a gettime() function to get the current data. time and return

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
},

Then we still use watch to monitor. The value here is passed by the parent component msg, so as long as the msg value changes, it means that there is new data, then new data must be added and old data deleted to achieve Dynamic effect:
don't forget to call this.initchart() again after deleting and adding data to refresh the chart

//在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()
},

Maybe you may have questions about dynamic data here, because the data I have here is passed from the parent component and is not written on this page. I will show you the key points of the implementation of the parent component:
Functions in the parent component:
1.getCputhings() gets the current data and stores it in this.serverInfo, which is to pass this value to the child component, which is the above chart
2. Use the setInterval timer in mounted, every other The data is requested once in a few seconds, so the child component can render the latest data as long as it listens to the change of the passed data
. 3. Delete this timer in beforeDestroy() to avoid entering other pages, and the timer is still working

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)
  }

At last

In this way, the dynamic rendering of the chart can be realized, which is mainly a process of monitoring the rendering. For the chart style, you can change the soup or not according to your own ideas.

insert image description here
If it is helpful to you, please like and follow to support it. If you have any questions, you can leave a message in the comment area~
If you need to leave a message in the comment area of ​​the complete code of the page, the main code is above, but it will not be included here due to space reasons.
insert image description here

Guess you like

Origin blog.csdn.net/weixin_45745641/article/details/123445762