echarts在vue中如何使用

1,223 阅读3分钟

1.下载echarts

  • 使用npm或cnpm

npm install echarts --save

  • 引入echarts模块在main.js中

// 全量引入

  1. import echarts from 'echarts'
  2. // 按需引入
  3. // 引入 ECharts 主模块
  4. var echarts = require('echarts/lib/echarts');
  5. // 引入柱状图
  6. require('echarts/lib/chart/bar');
  7. // 引入提示框和标题组件
  8. require('echarts/lib/component/tooltip');
  9. require('echarts/lib/component/title');

2.新建charts.vue

demo.vue 调用echarts实例

  <div>
    <bar-chart :data="data" />
  </div>
</template>

<script>
import BarChart from './components/charts.vue'
export default {
  name: '',
  components: { BarChart },
  props: {},
  data() {
    return {
      data: {}
    }
  },
  computed: {},
  methods: {},
  mounted() {}
}
</script>

charts.vue 组件

<template>
  <div ref="chart"
       style="width:300px;height:300px"></div>
</template>

<script>
import echarts from 'echarts'
import resize from 'mixins/echartsResize'

import * as BARCONFIG from 'config/echarts'

export default {
  name: 'BarChart',
  props: {
    data: {
      type: Array,
      default() {
        return []
      }
    }
  },
  watch: {
    data: {
      handler() {
        this.initChart()
      },
      deep: true
    }
  },
  mixins: [resize],
  computed: {},
  methods: {
    initChart() {
      const that = this
      // 坐标轴配置
      const xyAxisConfig = {
        // 坐标轴轴线
        axisLine: {
          lineStyle: {
            color: '#98A9C4'
          }
        },
        // 坐标轴刻度
        axisTick: {
          lineStyle: {
            color: '#DEE6FD'
          }
        },
        // 坐标轴刻度标签
        axisLabel: {
          lineStyle: {
            color: '#DEE6FD'
          },
          interval: 0
          // rotate: 30
        },
        nameTextStyle: {
          color: '#98A9C4'
        }
      }
      const option = {
        // color: BARCONFIG.THEME,
        color: ['#ff0', 'f0f'],
        title: {
          text: '部门数据对比',
          // textStyle: BARCONFIG.TITLE
        },
        legend: {
          // data: ['过滤率', '成功发送率', '点击率', '转化率']
          data: [
            {
              name: '过滤率',
              icon: 'circle'
            },
            {
              name: '成功发送率',
              icon: 'circle'
            },
            {
              name: '点击率',
              icon: 'circle'
            },
            {
              name: '转化率',
              icon: 'circle'
            }
          ],
          top: 'top',
          left: 'right',
          textStyle: BARCONFIG.LEGEND
        },
        grid: {
          top: 60,
          left: 40,
          right: 20,
          bottom: 40
        },
        tooltip: {
          trigger: 'axis',
          ...BARCONFIG.TOOLTIP,
          // axisPointer: {
          //   type: 'shadow'
          // },
          formatter: function(params) {
            let str = `<div style="${BARCONFIG.TOOLTIP_BOXSHADOW}">`
            params.map(item => {
              str += `<div>${item.marker} ${item.seriesName}${
                item.value[item.seriesIndex + 1]
              }%</div>`
            })
            str += '</div>'
            return str
          }
        },
        dataset: {
          source: that.normalize()
        },
        xAxis: { type: 'category', ...xyAxisConfig },
        yAxis: {
          ...xyAxisConfig,
          name: '百分比',
          splitLine: {
            lineStyle: {
              color: '#F2F5FE'
            }
          }
        },
        series: [
          {
            type: 'bar',
            barCategoryGap: '60%',
            itemStyle: { barBorderRadius: [8, 8, 0, 0] }
          },
          {
            type: 'bar',
            barCategoryGap: '60%',
            itemStyle: { barBorderRadius: [8, 8, 0, 0] }
          },
          {
            type: 'bar',
            barCategoryGap: '60%',
            itemStyle: { barBorderRadius: [8, 8, 0, 0] }
          },
          {
            type: 'line',
            barCategoryGap: '60%',
            itemStyle: { barBorderRadius: [8, 8, 0, 0] }
          }
        ]
      }

      if (!this.echarts) {
        this.echarts = echarts.init(this.$refs.chart)
      }
      this.echarts.setOption(option)
    },
    normalize() {
      // [
      //   ['department', '过滤率', '成功发送率', '点击率', '转化率'],
      //   ['部门一', 43.3, 85.8, 93.7, 81.5],
      //   ['部门二', 83.1, 73.4, 55.1, 61.2],
      //   ['部门三', 86.4, 65.2, 82.5, 51.3],
      //   ['部门四', 72.4, 53.9, 39.1, 71.4],
      //   ['部门五', 62.4, 57.9, 69.1, 51.4]
      // ]
      let data = this.data.map(item => {
        return [
          item.name,
          item.filterRate,
          item.successCountRate,
          item.clickRate,
          item.successClickRate
        ]
      })
      data.unshift(['department', '过滤率', '成功发送率', '点击率', '转化率'])
      return data
    }
  },
  mounted() {
    this.initChart()
  }
}
</script>

<style lang='stylus' scoped></style>

BARCONFIG.js 图表配置

// 主题样式 ( 可到官网定制主题,暂未定制 )
export const THEME = ['#3B98FF', '#00D2B3', '#FBA900', '#F96E5E', '#00C6FF']
export const MAP_THEME = ['#2F91FF', '#CCE6FE']

// 主内容 —— 黑色
export const BLACK = '#2D405E'
// 主内容 —— 灰色颜色
export const GRAY = '#98A9C4'
// 主内容 —— 白色
export const WHITE = '#ffffff'

// 字体大小
export const NORMAL = 16
export const SMALL = 14
export const THIN = 12

// 标题 样式
export const TITLE = {
  color: BLACK,
  fontSize: NORMAL
}
// 图例 样式
export const LEGEND = {
  color: GRAY,
  fontSize: THIN
}
// tooltip formater样式
export const TOOLTIP = {
  padding: 0,
  backgroundColor: WHITE,
  textStyle: {
    color: BLACK
  },
}
export const TOOLTIP_BOXSHADOW = 'box-shadow: 0px 0px 10px rgba(135,138,193,0.49);padding:5px;'

echartsResize.js 适配窗口大小变化

import { debounce } from 'utils/utils'

export default {
  mounted() {
    this.__resizeHandler = debounce(() => {
      if (this.echarts) {
        console.log('resize')
        this.echarts.resize()
      }
    }, 100)
    window.addEventListener('resize', this.__resizeHandler)
  },
  beforeDestroy() {
    if (!this.echarts) {
      return
    }
    window.removeEventListener('resize', this.__resizeHandler)
    this.echarts.dispose()
    this.echarts = null
  }
}

// 下面是 utils/utils 中 debounce 的相关代码
/**
 * @param {Function} func
 * @param {number} wait
 * @param {boolean} immediate
 * @return {*}
 */
export function debounce(func, wait, immediate) {
  let timeout, args, context, timestamp, result

  const later = function () {
    // 据上一次触发时间间隔
    const last = +new Date() - timestamp

    // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
    if (last < wait && last > 0) {
      timeout = setTimeout(later, wait - last)
    } else {
      timeout = null
      // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
      if (!immediate) {
        result = func.apply(context, args)
        if (!timeout) context = args = null
      }
    }
  }

  return function (...args) {
    context = this
    timestamp = +new Date()
    const callNow = immediate && !timeout
    // 如果延时不存在,重新设定延时
    if (!timeout) timeout = setTimeout(later, wait)
    if (callNow) {
      result = func.apply(context, args)
      context = args = null
    }

    return result
  }
}