vue中echarts使用

news/2024/7/10 0:45:44 标签: vue, es6, vue.js, javascript, node.js

前言

最近要在vue中使用echarts,觉得挺好玩的,这里记一下笔记。最终得到的是一个可自动刷新的可适应屏幕尺寸的图表,并可手动全屏

使用

安装echarts依赖
npm i echarts -s
main.js中配置echarts全局使用:

javascript">/*全局使用echarts*/
import Echarts from 'echarts'
Vue.prototype.$echarts = Echarts;

在子组件中使用:

javascript"><!--测试图表-->
<template>
  <div class="chart-default-size" ref="TestChart_ref"></div>
</template>

<script>
//导入主题,也可以不导入,使用默认的主题
  import 'echarts/theme/dark'

  export default {
    name: "TestChart",
    data() {
      return {
        chartInstance: null,
        allData: null, // 服务器返回的数据
        currentPage: 1,  // 当前显示的页数
        totalPage: 0, //共有多少页
        timerId: null //定时器标识
      }
    },
    created() {
    },
    mounted() {
      this.initChart()
      this.getData()
    },
    beforeDestroy() {
      clearInterval(this.timerId)
    },
    methods: {
      // 初始化echartInstance对象
      initChart() {
        this.chartInstance = this.$echarts.init(this.$refs.TestChart_ref, 'dark')
        // 对图表对象进行鼠标事件的监听
        this.chartInstance.on('mouseover', () => {
          clearInterval(this.timerId)
        })
        this.chartInstance.on('mouseout', () => {
          this.startInterval()
        })
      },
      // 获取服务器的数据
      async getData() {
        const {data: ret} = await this.$http.get('/pro/order')
        console.log(ret)
        this.allData = ret
        // 对数据进行排序
        this.allData.sort((a, b) => {
          return b.value - a.value    //从小到大排序
        })
        console.log(this.allData)
        console.log(ret)
        //每五个元素显示一次,总页数
        this.totalPage = this.allData.length % 5 === 0 ? this.allData.length / 5 : this.allData.length / 5 + 1

        this.updateChart()
        // 启动定时器
        this.startInterval()
      },
      // 更新图表
      updateChart() {
        const start = (this.currentPage - 1) * 5  //第一页0
        const end = this.currentPage * 5  //第一页5
        // slice包含start不包含end
        const showData = this.allData.slice(start, end)

        // 将获取的对象中的某一部分提取到数组中
        const sellerNames = showData.map((item) => {
          return item.name
        }).reverse() // 反转显示顺序

        const sellerValues = showData.map((item) => {
          return item.value
        }).reverse()  // 反转显示顺序

        const option = {
          title: {
            text: '| 商家销售统计',
            textStyle: {
              fontSize: 44,
            },
            left: 20,
            top: 20
          },
          grid: {
            top: '20%',
            left: '3%',
            right: '6%',
            bottom: '3%',
            // 位置调整包含坐标轴文字
            containLabel: true
          },
          xAxis: {
            type: 'value',

          },
          yAxis: {
            type: 'category',
            data: sellerNames
          },
          //文字提示
          tooltip:{
            trigger:'axis',
            axisPointer:{
              type:'line',
              z:0,
              lineStyle:{
                width:44,
                color:'#2D3443'
              }
            }
          },
          series: [
            {
              type: 'bar',
              data: sellerValues,
              barWidth: 44,  //柱宽度
              label: {   //指定标签
                show: true,  //文字展示
                position: 'right', //展示位置
                textStyle: {
                  color: 'white',   // 文字颜色
                }
              },
              itemStyle: {     //指定主要对象
                barBorderRadius: [0, 22, 22, 0],  //柱状圆角
                // 颜色渐变,通过调用echarts中的线性渐变实现
                // 对应参数:color:new this.$echarts.graphic.LinearGradient(x1,y1,x2,y2,[])
                // x1,y1,x2,y2参数指明方向
                // []中指明不同百分比之下颜色的值
                color:new this.$echarts.graphic.LinearGradient(0,0,1,0,[
                    // 百分之0状态之下的颜色值
                  {
                    offset:0,
                    color:'#5052EE'
                  },
                  // 百分之100状态之下的颜色值
                  {
                    offset:1,
                    color:'#AB6EE5'
                  }
                ])
              }
            }
          ]
        }
        this.chartInstance.setOption(option)
      },
      // 定时器切换
      startInterval() {
        // 查看是否已经有定时器
        if (this.timerId) {
          clearInterval(this.timerId)
        }
        this.timerId = setInterval(() => {
          this.currentPage++
          if (this.currentPage > this.totalPage) {
            this.currentPage = 1
          }
          this.updateChart()
        }, 3000)
      },
    }
  }
</script>

<style lang="less" scoped>
.chart-default-size {
    height: 100%;
    width: 100%;
}
</style>

加圆角(整个图表四角)

javascript"> canvas{
    border-radius: 20px;
  }

展示

在这里插入图片描述

这个图表会循环展示

关于数据接口问题

get请求想得到的json数据为:

javascript">[{'name': '商家1', 'value': 50}, {'name': '商家2', 'value': 80}, {'name': '商家3', 'value': 90}, {'name': '商家4', 'value': 70}, {'name': '商家5', 'value': 100}, {'name': '商家6', 'value': 120}, {'name': '商家7', 'value': 50}, {'name': '商家8', 'value': 80}, {'name': '商家9', 'value': 110}, {'name': '商家10', 'value': 150}, {'name': '商家11', 'value': 180}]

可以修改getData()为:

javascript"> getData() {
        // const {data: ret} = await this.$http.get('/pro/order')
        // console.log(ret)
        let ret = [{'name': '商家1', 'value': 50}, {'name': '商家2', 'value': 80}, {'name': '商家3', 'value': 90}, {'name': '商家4', 'value': 70}, {'name': '商家5', 'value': 100}, {'name': '商家6', 'value': 120}, {'name': '商家7', 'value': 50}, {'name': '商家8', 'value': 80}, {'name': '商家9', 'value': 110}, {'name': '商家10', 'value': 150}, {'name': '商家11', 'value': 180}]

拆分图表配置项option并实现分辨率适配

首先我们需要知道,echarts的setOption是可以多次设置的,在这个过程中会整合配置,而不是重置,所以我们可以将配置option拆分为三部分:初始化配置initOption,数据配置dataOption,分辨率适配配置adapterOption。
从而可以在合适的地方针对性地更新配置
先将dataOption分离:

javascript">const dataOption = {
          yAxis: {
            data: sellerNames
          },
          series: [
            {
              data: sellerValues,
            }
          ]
        }
        this.chartInstance.setOption(dataOption)

再将分辨率适配部分配置:
这里我们先要得到容器的宽度,然后根据这个宽度去自适应

更新后代码:

javascript"><!--测试图表-->
<template>
  <div class="chart-default-size" ref="testchart_ref"></div>
</template>

<script>
  import 'echarts/theme/dark'

  export default {
    name: "TestChart",
    data() {
      return {
        chartInstance: null,
        allData: null, // 服务器返回的数据
        currentPage: 1,  // 当前显示的页数
        totalPage: 0, //共有多少页
        timerId: null //定时器标识
      }
    },
    created() {
    },
    mounted() {
      this.initChart()
      this.getData()
      // 给浏览器窗口添加一个监听事件
      window.addEventListener('resize',this.screenAdapter)
      // 在界面加载完成时,主动进行屏幕适配
      this.screenAdapter()
    },
    // 组件销毁时
    beforeDestroy() {
      // 清除定时器循环
      clearInterval(this.timerId)
      // 移除监听事件
      window.removeEventListener('resize',this.screenAdapter)
    },
    methods: {
      // 初始化echartInstance对象
      initChart() {
        this.chartInstance = this.$echarts.init(this.$refs.testchart_ref, 'dark')
        // 对图表初始化配置的控制
        const initOption ={
          title: {
            text: '| 商家销售统计',
            textStyle: {
              fontSize: 44,
            },
            left: 20,
            top: 20
          },
          grid: {
            top: '20%',
            left: '3%',
            right: '6%',
            bottom: '3%',
            // 位置调整包含坐标轴文字
            containLabel: true
          },
          xAxis: {
            type: 'value',

          },
          yAxis: {
            type: 'category',

          },
          //文字提示
          tooltip:{
            trigger:'axis',
            axisPointer:{
              type:'line',
              z:0,
              lineStyle:{
                width:44,
                color:'#2D3443'
              }
            }
          },
          series: [
            {
              type: 'bar',

              barWidth: 44,  //柱宽度
              label: {   //指定标签
                show: true,  //文字展示
                position: 'right', //展示位置
                textStyle: {
                  color: 'white',   // 文字颜色
                }
              },
              itemStyle: {     //指定主要对象
                barBorderRadius: [0, 22, 22, 0],  //柱状圆角
                // 颜色渐变,通过调用echarts中的线性渐变实现
                // 对应参数:color:new this.$echarts.graphic.LinearGradient(x1,y1,x2,y2,[])
                // x1,y1,x2,y2参数指明方向
                // []中指明不同百分比之下颜色的值
                color:new this.$echarts.graphic.LinearGradient(0,0,1,0,[
                  // 百分之0状态之下的颜色值
                  {
                    offset:0,
                    color:'#5052EE'
                  },
                  // 百分之100状态之下的颜色值
                  {
                    offset:1,
                    color:'#AB6EE5'
                  }
                ])
              }
            }
          ]
        }
        this.chartInstance.setOption(initOption)
        // 对图表对象进行鼠标事件的监听
        this.chartInstance.on('mouseover', () => {
          clearInterval(this.timerId)
        })
        this.chartInstance.on('mouseout', () => {
          this.startInterval()
        })
      },
      // 获取服务器的数据
      async getData() {
        const {data: ret} = await this.$http.get('/pro/order')
        console.log(ret)
        this.allData = ret
        // 对数据进行排序
        this.allData.sort((a, b) => {
          return b.value - a.value    //从小到大排序
        })
        console.log(this.allData)
        console.log(ret)
        //每五个元素显示一次,总页数
        this.totalPage = this.allData.length % 5 === 0 ? this.allData.length / 5 : this.allData.length / 5 + 1

        this.updateChart()
        // 启动定时器
        this.startInterval()
      },
      // 更新图表
      updateChart() {
        const start = (this.currentPage - 1) * 5  //第一页0
        const end = this.currentPage * 5  //第一页5
        // slice包含start不包含end
        const showData = this.allData.slice(start, end)

        // 将获取的对象中的某一部分提取到数组中
        const sellerNames = showData.map((item) => {
          return item.name
        }).reverse() // 反转显示顺序

        const sellerValues = showData.map((item) => {
          return item.value
        }).reverse()  // 反转显示顺序

        const dataOption = {
          yAxis: {
            data: sellerNames
          },
          series: [
            {
              data: sellerValues,
            }
          ]
        }
        this.chartInstance.setOption(dataOption)
      },
      // 定时器切换
      startInterval() {
        // 查看是否已经有定时器
        if (this.timerId) {
          clearInterval(this.timerId)
        }
        this.timerId = setInterval(() => {
          this.currentPage++
          if (this.currentPage > this.totalPage) {
            this.currentPage = 1
          }
          this.updateChart()
        }, 3000)
      },
      //当浏览器窗口大小发生变化的时候,会调用的方法,来完成屏幕的适配
      screenAdapter(){
        // console.log(this.$refs.testchart_ref.offsetWidth);
        const titleFontSize = this.$refs.testchart_ref.offsetWidth / 100 * 3.6
        // 和分辨率大小相关的配置项
        const adapterOption = {
          title: {
            textStyle: {
              fontSize: titleFontSize,
            },
          },
          //文字提示
          tooltip:{
            axisPointer:{
              lineStyle:{
                width:titleFontSize,
              }
            }
          },
          series: [
            {
              barWidth: titleFontSize,  //柱宽度
              itemStyle: {     //指定主要对象
                barBorderRadius: [0, titleFontSize / 2, titleFontSize / 2, 0],  //柱状圆角
              }
            }
          ]
        }
        this.chartInstance.setOption(adapterOption)
        // 手动的调用图表对象的resize才能产生效果
        this.chartInstance.resize()
      },
    }
  }
</script>

<style lang="less" scoped>

</style>

此时已经拆分了echarts的配置项,并且已经可以根据浏览器宽度进行适配了

实现全屏切换

既然以及实现了分辨率适配,那么实现全屏就很简单了,只需加一个点击事件,改变样式即可
父组件中:

javascript"><template>
  <div style="width: 100%;height: 100%">
    <!--多个类绑定-->
    <div :class="['test',test ? 'fullscreen' : '']" >
      <test-chart ref="test"></test-chart>
      <div class="resize">
        <span @click="changeSize('test')" :class="[test ? 'el-icon-bottom-left' : 'el-icon-top-right']"></span>
      </div>
    </div>
  </div>

</template>

<script>
  import TestChart from "../../../components/charts/TestChart";
  export default {,
    components:{
      TestChart
    },
    data(){
      return {
        chartId:'testChart',
        //定义全屏状态
        test:false,
      }
    },
    methods:{
  
      changeSize(chartName){
        // 1.改变test的数据
        this.test = !this.test
        // 2.需要调用每一个图表组件的screenAdapter的方法
        // Vue中DOM更新是异步的
        // 数据变动后不会即时更新完成,需要调用$nextTick当数据更新完成,下一次组件更新的时候调用方法
        this.$nextTick(()=>{
          this.$refs[chartName].screenAdapter()
        })
      }
    }
  }
</script>

<style lang="less" scoped>
  .test{
    width: 50%;
    height: 50%;
    position: relative;
    .resize{
      position: absolute;
      right: 20px;
      top:20px;
      cursor: pointer;
      color: white;
    }
  }
  .fullscreen{
    position: fixed!important;
    top:0!important;
    left: 0!important;
    width: 100%!important;
    height: 100%!important;
    margin: 0!important;
    z-index: 100;
  }
</style>

初始状态:
在这里插入图片描述点击右上角后全屏:
在这里插入图片描述ok,开发完成


http://www.niftyadmin.cn/n/1799011.html

相关文章

【观察者模式】 ——每天一点小知识

&#x1f4a7; 观察者模式 \color{#FF1493}{观察者模式} 观察者模式&#x1f4a7; &#x1f337; 仰望天空&#xff0c;妳我亦是行人.✨ &#x1f984; 个人主页——微风撞见云的博客&#x1f390; &#x1f433; 《数据结构与算法》专栏的文章图文并茂&#x1f995;…

MySql,Sqlserver,Oracle数据的分页语句

在实际项目中分页是常见的不能再说了&#xff0c;这里我总结了MySql&#xff0c;SqlServer&#xff0c;Oracle这三个数据库的sql分页语句在这三个数据库中&#xff0c;个人觉得MySql的分页语句是最简单的&#xff0c;只用一个limit关键字就能完成MySql数据库&#xff1a;select…

Centos下Gitee+Typora+PicGo存储云端笔记实操记录

前言 一直以来都没有将笔记存储在一个固定位置&#xff0c;这里一点那里一点&#xff0c;不利于知识体系化。 最近了解到GiteeTypora存储笔记挺好用的&#xff0c;遂来试着使用。加入PicGo的话&#xff0c;它的主要作用是生成图片外链&#xff0c;如果需要的话可以装&#xff…

spring整合hibernate,配置datasource,No suitable driver

我是利用读取外部文件来配置spring的datasource。 hibernate.Properties jdbc.driverClassNamecom.mysql.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/hibernatespring?useUnicodetrue&amp;characterEncodingutf-8 jdbc.usernameroot jdbc.passwordmysql 而spring.x…

windows上安装python并配置源

前言 经常在不同电脑安装 python 环境&#xff0c;不能每次都去搜&#xff0c;这里记录一下 开始 安装包下载 直接进入官网&#xff0c;先选择系统版本&#xff0c;然后从上一个个找&#xff0c;他这个排列顺序不是根据 3.9 &#xff0c;3.8 …来的&#xff0c;而是发布日期…

九月十月百度人搜,阿里巴巴,腾讯华为笔试面试八十题(第331-410题)

2019独角兽企业重金招聘Python工程师标准>>> 九月十月百度人搜&#xff0c;阿里巴巴&#xff0c;腾讯华为小米搜狗笔试面试八十题 引言 自发表上一篇文章至今&#xff08;事实上&#xff0c;上篇文章更新了近3个月之久&#xff09;&#xff0c;blog已经停了3个多月&…

Centos离线服务器安装包文件---非常简单的方法,不需要去一个个手动下了

前言 前面文章中我们已经将centos的iso文件里的package作为yum源&#xff0c; 大部分的软件都可直接安装&#xff0c;但是还是有一部分没有。 开始 如果是之前的话&#xff0c;我会选择一个rpm包网站&#xff0c;将安装包一个个下好然后拿过来安装&#xff0c;不过自从使用过…

windows下Kettle9.1连接oracle数据库报错

因为此时 kettle 的版本是最新的&#xff0c;所以理所应当要跟oracle的最新版 ojdbc.jar包配合使用。 步骤&#xff1a;oracle官网下载最新版 instantclient-basic-windows.x64-19.9.0.0.0dbru.zip &#xff0c;解压得到 ojdbc8.jar&#xff0c;放到 kettle 的 data-integrati…