已解决:vue echart 动态获取数据且定时刷新

写在前面

我太难了,搞一个echart仪表盘,需求一步步分解:
①一开始是写死的假数据,图表成功显示在页面上;
②和后台约定数据类型格式,前台写好接口,请求后台数据,替换掉假数据给图表data赋值真实数据并成功渲染;
③我想每隔5秒调用一次请求获取数据,然后刷新图表,重新渲染出来。这里涉及到了timer定时器和watch监听数据变化的知识。
④终于在刚刚解决了。我草(一种植物)拟大爷…


需求①

先上代码:

<template>
  <div :class="className" :style="{height:height,width:width}" />
</template>

<script>
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'

export default {
  mixins: [resize],
  props: {
    className: {
      type: String,
      default: 'chart'
    },
    width: {
      type: String,
      default: '100%'
    },
    height: {
      type: String,
      default: '300px'
    },
    autoResize: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
    }
  },
  created () {
    this.$nextTick(() => {
      this.initChart()
    })
  },
  beforeDestroy() {
    if (!this.chart) {
      return
    }
    this.chart.dispose()
    this.chart = null
  },
  methods: {
    initChart () {
      // 基于准备好的dom,初始化echarts实例
      this.chart = echarts.init(this.$el, 'macarons')
      //绘制图表,option是图表数据
      this.chart.setOption({
        title: {
          text: 'CPU使用情况'
        },
        tooltip: {
          formatter: "{a} <br/>{b} : {c}%"
        },
        series: [
          {
            name: 'cpu仪表盘',
            type: 'gauge',
            min: 0,   // 最小值
            max: 100,  // 最大值
            precision: 0,  // 小数精度,默认为0,无小数点
            detail: {
              formatter: '{value}%'
            },
            data: [
              { value: 30, name: 'CPU占用率' }
            ],
          }
        ]
      })
    },
  }
}
</script>

再上图表:

在这里插入图片描述
到这里很简单,不用多说~


需求②

这里开始就遇到一堆问题了,总结几个问题如下:

问题① 和后台约定数据格式。 返回数据类型是什么? json对象?json字符串?
里面内容是什么,需要约定code请求码吗? (vue封装的request.js请求,判断返回成功必须有状态码,设置20000。所以得让后端返回数据内部加个code)

这里两处大的错误,随后解决。
传送门:① json解析数据问题
②数据未添加code状态码

问题② 前台写好接口,请求后台数据。 接口怎么写?如何能访问到后台?

不得不说菜的很,这里也搞了半天才成功访问到后台。
就拿我图表来说:
首先,我要在项目目录的api目录下,新建一个接口文件。比如cpu.js 具体代码如下:

import request from "@/utils/request"

// 这就是接口函数
export function getCpuData() {
  return request({
    url: '/cpu',   //这是自定义的前台url,随意
    method: 'get',   // 获取后台数据,  get请求
  })
}

其次,vue.config.js文件配置你当前url访问的后台url。很重要直接决定你访问后台成不成功。来看下面关键配置:

vue.config.js

devServer: {
    port: port,
    open: true,
    overlay: {
      warnings: false,
      errors: true
    },
    //before: require('./mock/mock-server.js'), /*注释掉这行代码*/
    proxy: {
      '/cpu' : {
        target: 'xxx',  // 你的后台接口url地址
        changeOrigin: true,  // 跨域
        pathRewrite: {
          '^/cpu': '/cpu'
        }
      },
    },

这里也容易有问题,比如后台提供你的是 127.0.0.1:8081/cpu 。那在代理转发target处要写成 ‘127.0.0.1:8080/’ 语法规则会默认将 开头的 '/cpu’和target合并的。我之前就是直接写的接口地址。结果访问不到。注意一下。

第三步, 修改图表,将假数据变成调用接口获取真实数据。
直接上图表代码:

<template>
  <div :class="className" :style="{height:height,width:width}" />
</template>

<script>
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'
import { getCpuData } from "@/api/cpu"

export default {
  mixins: [resize],
  props: {
    className: {
      type: String,
      default: 'chart'
    },
    width: {
      type: String,
      default: '100%'
    },
    height: {
      type: String,
      default: '200px'
    },
    autoResize: {
      type: Boolean,
      default: true
    }
  },
  data () {
    return {                                                  // 改动一
      option: {
        title: {
          text: 'CPU使用情况'
        },
        tooltip: {
          formatter: "{a} <br/>{b} : {c}%"
        },
        series: [
          {
            name: 'cpu仪表盘',
            type: 'gauge',
            min: 0,   // 最小值
            max: 100,  // 最大值
            precision: 0,  // 小数精度,默认为0,无小数点
            detail: {
              formatter: '{value}%'
            },
            data: [],                        
          }
        ]
      },
    }
  },
  mounted () {
    this.$nextTick(() => {
      this.initChart()
    })
  },
  methods: {
    // 初始化图表
    initChart () {
      // 基于准备好的dom,初始化echarts实例
      this.chart = echarts.init(this.$el, 'macarons')
      //绘制图表,option是图表数据                        // 改动二
      // let option = {
      //   title: {
      //     text: 'CPU使用情况'
      //   },
      //   tooltip: {
      //     formatter: "{a} <br/>{b} : {c}%"
      //   },
      //   series: [
      //     {
      //       name: 'cpu仪表盘',
      //       type: 'gauge',
      //       min: 0,   // 最小值
      //       max: 100,  // 最大值
      //       precision: 0,  // 小数精度,默认为0,无小数点
      //       detail: {
      //         formatter: '{value}%'
      //       },
      //       data: [
      //         { value: this.cpuData * 100, name: 'CPU占用率' }
      //       ],
      //     }
      //   ]
      // }
      this.drawData()                                     // 改动三
      //this.chart.setOption(this.option, true)
    },
    // 获取后台数据                                   // 最重要的改动四
    drawData () {
      getCpuData().then(res => {
        let code = res["code"]
        if (code == 20000) {
          console.log(res)
          this.cpuData = res["cpu"]["pct"];
          // 赋值给图表data
          this.option.series[0].data.push({
            name: 'CPU占用率',
            value: Math.round(this.cpuData * 100)
          });
          this.chart.setOption(this.option, true)
        } else {
          alert("get failed")
        }
        console.log(this.cpuData)
      })
    },
  }
}
</script>

以上,跟第一版图表代码比较,里面有几处大的改动。
一. 将绘制图表的option数据从methods里拿出来放到了data()中;
二. 添加接口回调函数,绘制图表数据函数setOption放在了接口回调函数内部。

关键点:

①约定状态码,确认收到数据;
②数据格式确认,我的例子此处是json对象,故直接以数组形式就可直接赋值给临时变量;
③将临时变量的值添加到option的对应位置处。
④调用setOption绘制图表。

现在,你可以看到你的图标数据渲染就是你后台获得的真实数据
看图:
在这里插入图片描述


需求③

现在我们要每隔5秒向后台拿一次数据,然后前台重新渲染一遍。这里涉及到了定时器、watch监听、图表渲染清除上一次数据几个关键点。
查了数不清的资料一遍一遍尝试终于可以了。想流泪~~~

直接上高速:

<template>
  <div :class="className" :style="{height:height,width:width}" />
</template>

<script>
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'
import { getCpuData } from "@/api/cpu"

export default {
  mixins: [resize],
  props: {
    className: {
      type: String,
      default: 'chart'
    },
    width: {
      type: String,
      default: '100%'
    },
    height: {
      type: String,
      default: '200px'
    },
    autoResize: {
      type: Boolean,
      default: true
    }
  },
  data () {
    return {
      option: {
        title: {
          text: 'CPU使用情况'
        },
        tooltip: {
          formatter: "{a} <br/>{b} : {c}%"
        },
        series: [
          {
            name: 'cpu仪表盘',
            type: 'gauge',
            min: 0,   // 最小值
            max: 100,  // 最大值
            precision: 0,  // 小数精度,默认为0,无小数点
            detail: {
              formatter: '{value}%'
            },
            data: [],
          }
        ]
      },
    }
  },
  watch: {
    // 观察cpu_option的变化
    option: {
      handler(newVal, oldVal) {
        this.timer()
        this.destroyed()
      },
      deep: true   //对象内部属性的监听
    },
  },
  mounted () {
    this.$nextTick(() => {
      this.initChart()
    })
  },
  methods: {
    // 初始化图表
    initChart () {
      // 基于准备好的dom,初始化echarts实例
      this.chart = echarts.init(this.$el, 'macarons')
      this.drawData()
    },
    // 获取后台数据
    drawData () {
      getCpuData().then(res => {
        let code = res["code"]
        if (code == 20000) {
          console.log(res)
          this.option.series[0].data = []         // 这里涉及致命问题,下面解释
          this.cpuData = res["cpu"]["pct"];
          // 赋值给图表data
          this.option.series[0].data.push({
            name: 'CPU占用率',
            value: Math.round(this.cpuData * 100)
          });
		//绘制图表数据
          this.chart.setOption(this.option, true)
        } else {
          alert("get failed")
        }
        console.log(this.cpuData)
      })
    },
    //这是一个定时
    timer () {
      return setTimeout(() => {
        this.drawData()
      }, 5000)
    },
    // 销毁定时器
    destroyed () {
      clearTimeout(this.timer())
    }
  }
}
</script>

我直接说如何每次刷新图表都清除上一次渲染的数据。

无效的解决办法1:
this.chart.setOption(option,true)  无效
无效的解决办法2
this.chart.clear()   无效
有效的解决办法
this.option.series[0].data = []

即在下一次获取数据渲染图表前先将上一次赋的数据清空!!!!!

否则,你会看到,一个仪表盘百分比一直保持第一次获取数据不变,而指针每5秒增加一个,最后成了千手观音,那画面简直太美。。。


以上就是我所一路坎坷总结。如有不成熟的地方还请谅解。如有更好的解决办法还请不吝赐教。我虚心好学~

  • 11
    点赞
  • 72
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值