vue使用Echarts定制散点图及mock数据的使用实践

17 篇文章 0 订阅

项目数据分析需要用散点图,但是在官网展示的案例中没有产品想要的效果,所以花了一点时间定制散点图,另外由于散点图的数据要多一些才比较直观,所以使用了mock生成假数据
在这里插入图片描述

为了方便后面与后台对接,首先确定了数据结构(可以按照自己喜欢的结构自行构建)
[
  {
    time: 6,
    rate: 90,
    name: 'Mick'
  }
  ...
]
定制1:tooltip展示除散点标记数值之外的数据。
tooltip: {
  trigger: 'item',
  formatter: (params)=> {
  	// params为当前item的能被Echarts使用的数据
    const {value=[]} = params
    if (value.length > 1) {
      // 使用formatter格式化tooltip
      return `${value[2]}:<br/>作业用时:${value[1]}分钟<br/>正确率:${value[0]}%`
    }
  }
}
定制2:展示平均值标线
// 在series里面添加markLine注意默认展示valueIndex为1的标线,添加多条标线需在data里面添加配置,并制定valueIndex,label可凭产品喜好自行添加。
markLine : {
  silent: true, // 标线点击是静默
  symbol: ['none','none'], // 标线样式
  data : [
    {
      type: 'average', 
      name: '平均值',
      label:{
        position: 'insideEndTop',
        formatter:'班级平均值线:{c}%'
      }
    },
    {
      valueIndex: 0,
      type: 'average', 
      name: '平均值',
      label:{
        position: 'end',
        formatter:'班级平均值线:{c}分钟' //{c}为平均值
      }
    }
  ],
},
定制3:正确率平均值以上的item显示绿色,正确率平均值以下的显示黄色
itemStyle: {
  normal: {
    shadowBlur: 10,
    shadowColor: 'rgba(120, 36, 50, 0.5)',
    shadowOffsetY: 5,
    color: (e)=>{
      const {data=[]} = e
      if(data[1] >= this.avageRightRate){ // avageRightRate是自行求出来的
        return '#52c41a'
      }else{
        return '#faad14'
      }
    }
  }
},
mock数据的简单使用
  1. 安装: npm install mockjs --s
  2. 在src下创建mock文件夹,添加index.js,chart.js
    在这里插入图片描述
  3. 修改chart.js及index.js文件
// chart.js
import Mock from 'mockjs'
const code = 200 // 状态码 项目同一
export default {
  getScatterChartData() {
    let data = Mock.mock({
      'list|30': [{
        'time|1-30': 8,
        'rate|1-100': 50,
        'name': '@name',
      }]
    })
    return {
      code,
      data
    }
  }
}
//index.js
import mockjs from 'mockjs';
import ChartApi from './chart.js'
const Mock = require('mockjs') // 使用拦截规则拦截命中的请求
Mock.mock('api/getChartData', ChartApi.getChartData());
export default mockjs
  1. 在main.js中引入mock文件夹下的index.js
  2. 在页面使用
import axios from 'axios'
methods: {
  getdata(){
    axios.get('api/getChartData').then(response => {
      let {list} = response.data.data; // mock生成的假数据
      this.data = list
      this.$nextTick(()=>{
        this.echartInit() //获取到接口数据实例化Echarts组件
      })
    })
  }
}

注意,接口请求到的数据结构不一定是Echarts希望得到的数据,因此常常需要对接口请求到的数据进行组装,至于数据结构可以与后台商量。另外mock数据也可以根据自己需要来造。可自行学习mockjs官网

补充

以上mock数据生成之后除非刷新网页才会生成新的数据,若是需要异步刷新数据需要稍微修改一下mock文件夹下的chart.js,及index.js

// chart.js
import { Random } from 'mockjs'
const code = 200
export default {
  getScatterChartData() {
    let list = []
    for (let i = 0; i < 30; i++) {
      let item = {}
      item['time'] = Random.integer(0, 30)
      item['rate'] = Random.integer(0, 100)
      item['name'] = Random.name()
      list.push(item)
    }
    return {
      code,
      data: { list }
    }
  }
}
// index.js
import mockjs from 'mockjs';
import ChartApi from './chart.js'
const Mock = require('mockjs')
Mock.mock('api/getChartData', () => {
  return ChartApi.getScatterChartData()
});
export default mockjs
完整代码:
<template>
  <div class="chart-container" ref="chart-container"></div>
</template>

<script>
import axios from 'axios'
import 'zrender/lib/svg/svg';
let echarts = require('echarts/lib/echarts');
require('echarts/lib/component/grid');
require('echarts/lib/chart/scatter');
export default {
  props: {
    
  },
  data(){
    return{
      chartDom: null,
      data:[]
    }
  },
  mounted() {
    window.addEventListener('resize',()=>{this.chartDom.resize()},false)
    this.getdata()
  },
  destroyed() {
    window.removeEventListener('resize',()=>{})
  },
  computed:{
    dataList(){
      const handleList = this.data.map(item=>{
        return Object.values(item)
      })
      return handleList
    },
    avageRightRate(){
      const rateArray = this.dataList.map(item=>item[1])
      return window._.round(window._.mean([...rateArray]),1) // lodash方法求平均值
    }
  },
  methods: {
    getdata(){
      axios.get('api/getChartData').then(response => {
        let {list} = response.data.data;
        this.data = list
        this.$nextTick(()=>{
          this.echartInit()
        })
      })
    },
    echartInit(){
      this.chartDom = echarts.init(this.$refs['chart-container'],null,{renderer: 'svg'})
      this.chartDom.setOption({
        xAxis: {
          max: 30,
          splitNumber: 15,
          name: '用时(分钟)',
        },
        yAxis: {
          max: 100,
          name: '正确率',
          nameTextStyle:{
            align: 'right',
          },
          minorTick:{
            show: true,
            splitNumber: 2
          },
          splitNumber: 10
        },
        tooltip: {
          trigger: 'item',
          formatter: function(params){
            const {value=[]} = params
            if (value.length > 1) {
              return `${value[2]}:<br/>作业用时:${value[1]}分钟<br/>正确率:${value[0]}%`
            }
          }
        },
        series: [{
          symbolSize: 16,
          markLine : {
            silent: true,
            symbol: ['none','none'],
            precision: 1,
            data : [
              {
                type: 'average', 
                name: '平均值',
                label:{
                  position: 'insideEndTop',
                  formatter:'班级平均值线:{c}%'
                }
              },
              {
                valueIndex: 0,
                type: 'average', 
                name: '平均值',
                label:{
                  position: 'end',
                  formatter:'班级平均值线:{c}分钟'
                }
              }
            ],
          },
          itemStyle: {
            normal: {
              shadowBlur: 10,
              shadowColor: 'rgba(120, 36, 50, 0.5)',
              shadowOffsetY: 5,
              color: (e)=>{
                const {data=[]} = e
                if(data[1] >= this.avageRightRate){
                  return '#52c41a'
                }else{
                  return '#faad14'
                }
              }
            }
          },
          data: this.dataList,
          type: 'scatter'
        }]
      })
    }
  }
}
</script>

<style lang="scss" scoped>
 .chart-container{
   width: 100%;
   height: 100%;
 }
</style>
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值