自己项目Echarts的封装

394 阅读4分钟

我就用这篇文章来说说我是如何简单实现自己的Echarts的封装的吧

首先你得先去官网下载插件 我是根据npm install echarts --save 下载到我的项目的

1.然后自己封装代码

废话少说,上代码:

<template>
  <div>
    <div :style="styleE ? styleE : 'width:50%;height:200px;'" :ref="eRef"></div>
  </div>
</template>

<script>
import echarts from 'echarts';
export default {
  props: {
    styleE: {
      default: ''
    },
    chartData: {
      type: Object,
      default: () => {}
    },
    eRef: {
      default: ''
    },
    method: {
      // 自定义点击事件
      default: ''
    }
  },
  data() {
    return {
      count: 1,
      myChart: ''
    };
  },
  methods: {
    drawChart() {
      // 基于准备好的dom,初始化echarts实例
      this.myChart = echarts.init(this.$refs[this.eRef]);
      // 绘制图表
      this.myChart.setOption(this.chartData);
    },
    reloadEcharts(val) {
      this.myChart.setOption(val, true);
      this.myChart.on('click', this.method);
    }
  },
  mounted() {
    const vm = this;
    vm.$nextTick(() => {
      vm.drawChart();
    });
  },
  created: () => {}
};
</script>

<style scoped></style>
  • 这样我们的 echrats 算是单独封装成了一个组件~怎么样?简单吧?
  • 那么我么来第二步,引入到需要的文件中去

废话不多说,上代码~

<template>
  <div>
   <!-- echarts图表 -->
  	<my-echarts eRef="echarts"
                ref="barByYear1"
                :styleE="styleE"
                :chartData="chartDataByYear1"></my-echarts>
     <!-- 饼图 -->
      <div style="width:650px;height:650px;">
      	<my-echarts :styleE="stylePie"
                    eRef="pie2"
                    :method="clickProductLine1"
                    ref="pieByProductLine1"
                    :chartData="pieByProductLine1"></my-echarts>
      </div>
  </div>	
</template>

js部分做了引入的配置,所以分开来写:

2.编写对应的 js 逻辑

这里以年份的图表为例!!

上代码:

<script>
import myEcharts from '@/components/echarts'; // 引入自己封装echarts
import {
  echartsColor, //图表的颜色
  echartsFeature, //柱状图 堆叠柱状图 的数据视图
  echartsAxisLabel, //Y轴数据过大 转成k M B结尾
  pieTooltip, //饼状图的tooltip
  formatterThousands, //柱状图显示数据千分符格式
  grid, // 控制图的大小
  barsGrid, // 控制堆叠柱状图的大小
  labelFormatter, //饼状图 label formatter且保留一位小数
  formatterThousandsAndPercentage, // 柱状图tooltip 显示数据千分符格式和百分比格式
  formatterPercentage, //堆叠柱状图tooltip 显示数据百分比格式
  tableListByYearMonth, // 表格数据 tableListByYear
  tableListByCountry, // 表格数据 tableListByCountry
  getDataByYear, // 获取ByYear表格和柱状图的方法
  getDataByCountry, // 获取ByCountry表格和柱状图的方法
} from './common.js';
export default {
components: {
  myEcharts
},
 data () {
  return {
  // echarts配置
  // 年份图表
  chartDataByYear1: {
    color: echartsColor(),
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'cross',
        crossStyle: {
          color: '#999'
        }
      },
      formatter: formatterThousandsAndPercentage()
    },
    toolbox: {
      top: 45,
      show: true,
      feature: echartsFeature(this)
    },
    title: {
      // 图表标题
      show: true,
      text: '图表标题',
      textAlign: 'center',
      left: '50%',
      textStyle: {
        fontSize: 14,
        lineHeight: 20
      }
    },
    legend: {
      // 图表按钮
      data: [
        '图表按钮1',
        '图表按钮2',
        '图表按钮3',
        '图表按钮4'
      ],
      top: '25'
    },
    xAxis: [
      // x 轴
      {
        type: 'category',
        data: [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ], // 这里也可以不填
        nameLocation: 'start', //坐标轴名称显示位置。
        axisPointer: {
          type: 'shadow'
        }
      }
    ],
    yAxis: [
      // y 轴
      {
        type: 'value',
        axisLabel: echartsAxisLabel(),
        splitLine: {
          show: false
        }
      },
      {
        type: 'value',
        axisLabel: {
          show: true,
          interval: 'auto',
          formatter: '{value}%'
        },
        splitLine: {
          show: false
        },
        show: true
      }
    ],
    grid: grid(),
    series: [
      // 表格中点击按钮的地方
      {
        name: '图表按钮1',
        type: 'bar',
        data: [],
        label: {
          normal: {
            position: 'top',
            show: true,
            formatter: formatterThousands()
          }
        }
      },
      {
        name: '图表按钮2',
        type: 'bar',
        barGap: '0', //缩小柱子之间的缝隙 默认20%
        data: [],
        label: {
          normal: {
            position: 'top',
            show: true,
            formatter: formatterThousands()
          }
        }
      },
      {
        name: '图表按钮3',
        type: 'line',
        yAxisIndex: 1,
        data: [],
        label: {
          normal: {
            position: 'top',
            show: true,
            formatter: '{c}%'
          }
        }
      },
      {
        name: '图表按钮4',
        type: 'line',
        yAxisIndex: 1,
        data: [],
        label: {
          normal: {
            position: 'top',
            show: true,
            formatter: '{c}%'
          }
        }
      }
    ]
  },

// 饼图配置
pieByProductLine1: {
  title: {
    text: '饼图标题',
    subtext: '',
    left: 'center',
    textStyle: {
      fontSize: 14,
      lineHeight: 20
    }
  },
  tooltip: pieTooltip(),
  color: echartsColor(),
  series: [
    {
      name: '饼图附标题',
      type: 'pie',
      radius: '55%',
      center: [ '50%', '50%' ],
      data: [ 0 ],
      label: labelFormatter(),
      emphasis: {
        itemStyle: {
          shadowBlur: 10,
          shadowOffsetX: 0,
          shadowColor: 'rgba(0, 0, 0, 0.5)'
        }
      }
    }
  ]
},
  // 柱状图配置
  bars1: {
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        // 坐标轴指示器,坐标轴触发有效
        type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
      },
      formatter: formatterPercentage()
    },
    title: {
      show: true,
      text: '柱状图标题',
      subtext: '每月销量占比走势(金额维度)',
      textAlign: 'center',
      left: '50%',
      textStyle: {
        fontSize: 14,
        lineHeight: 20
      }
    },
    toolbox: {
      top: 50,
      show: true,
      feature: echartsFeature(this)
    },
    color: echartsColor(),
    legend: {
      // type: 'scroll',
      data: [],
      bottom: 0
    },
    xAxis: {
      type: 'category',
      data: [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ]
    },
    yAxis: [
      {
        type: 'value',
        axisLabel: {
          show: true,
          interval: 'auto',
          formatter: '{value}%'
        }
      }
    ],
    grid: barsGrid(),
    series: []
  },
 }
}
   </script>

完美~这样我们就引用好自己封装好的图表了

那么我们把图表文件配置项给配置一下:

  • 1.柱状图 堆叠柱状图 的数据视图
export function echartsFeature (that) {
  return {
    myFull: {
      show: true,
      title: '查看大图',
      icon: '你自己的icon图标',
      onclick (e) {
        that.dialogFullVisible = true
        let opts = e.getOption()
        opts.toolbox[0].feature.myFull.show = false
        setTimeout(() => {
          that.$refs.fullEchart.reloadEcharts(opts)
          window.onresize = that.$refs.fullEchart.myChart.resize()
        }, 1000)
      }
    },
    dataView: {
      readOnly: true,
      show: true,
      title: '数据视图',
      optionToContent (opt) {
        let axisData = opt.xAxis[0].data;
        let series = opt.series;
        let tdHeads = '<td  style="padding:0 10px;border:1px solid #ccc;">名称</td>';
        series.forEach(function (item) {
          tdHeads +=
            '<td style="padding: 0 10px;border:1px solid #ccc;">' + item.name + '</td>';
        });
        let table =
          '<table style="border:1px solid #ccc;margin-left:20px;border-collapse:collapse;font-size:14px;text-align:center"><tbody><tr>' +
          tdHeads +
          '</tr>';
        let tdBodys = '';
        for (let i = 0, l = axisData.length; i < l; i++) {
          for (let j = 0; j < series.length; j++) {
            tdBodys += '<td style="padding: 0 10px;border:1px solid #ccc;">' + series[j].data[i] + '</td>';
          }
          table += '<tr><td style="padding: 0 10px;border:1px solid #ccc;">' + axisData[i] + '</td>' + tdBodys + '</tr>';
          tdBodys = '';
        }
        table += '</tbody></table>';
        return table;
      }
    },
    mark: {
      show: true
    },
    magicType: {
      show: true,
      type: [ 'line', 'bar' ]
    },
    restore: {
      show: true
    },
    saveAsImage: {
      show: true
    }
  }
}
  • 2.图表的公共颜色
export function echartsColor () {
  return [ '#666666', '#003399', '#FFB6C1', '#77DDFF', '#66CC99', '#339999', '#006699', '#000066', '#999999', '#66CC66',
    '#009966', '#660066', '#330099', '#556B2F', '#778899', '#003377', '#6A5ACD', '#D8BFD8' ]
}
  • 3.Y轴数据过大 转成k M B结尾 (ps:这里完全看个人是否需求决定)
export function echartsAxisLabel () {
  return {
    margin: 2,
    formatter (value) {
      if (value >= 1000 && value < 1000000) {
        value = value / 1000 + 'K ';
      } else if (value >= 1000000 && value < 1000000000) {
        value = value / 1000000 + 'M ';
      } else if (value >= 1000000000) {
        value = value / 1000000000 + 'B ';
      }
      if (value > -1000000 && value <= -1000) {
        value = value / 1000 + 'K ';
      } else if (value > -1000000000 && value <= -1000000) {
        value = value / 1000000 + 'M ';
      } else if (value <= -1000000000) {
        value = value / 1000000000 + 'B ';
      }
      return '  ' + value + ' ';
    }
  }
}
  • 4.饼状图的tooltip
export function pieTooltip () {
  return {
    trigger: 'item',
    // formatter: '{a} <br/>{b} : {c} ({d}%)'
    formatter (data) {
      // console.log(data, 'data')
      return data.seriesName + '<br/>' + data.name + ' : ' + data.value + ' (' + data.percent.toFixed(2) + '%)';
    }
  }
}
  • 5.grid
export function grid () {
  return { // 控制图的大小,调整下面这些值就可以,
    // show:true,//是否显示直角坐标系网格。[ default: false ]
    left: '10%',//grid 组件离容器左侧的距离。
    right: '10%',
    // borderColor:"#c45455",//网格的边框颜色
    bottom: '25%', //
    top: '17%'
  }
}
export function barsGrid () {
  return { // 控制图的大小,调整下面这些值就可以,
    // show:true,//是否显示直角坐标系网格。[ default: false ]
    left: '10%',//grid 组件离容器左侧的距离。
    right: '10%',
    // borderColor:"#c45455",//网格的边框颜色
    bottom: '25%', //
    top: '17%'
  }
}
  • 6.柱状图显示数据千分符格式 (ps:这里完全看个人是否需求决定)
export function formatterThousands () {
  return function (a) {
    let value = []
    if (a.data > 0) {
      value = a.data
      if (value > 999) {
        // 数值加千分号
        let parts = value.toString().split('.')
        parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',')
        value = parts.join('.')
      }
    }
    return value
  }
}
  • 7.柱状图tooltip 显示数据千分符格式和百分比格式
export function formatterThousandsAndPercentage () {
  return function (params) {
    let html = params[0].name + '<br>';
    for (let i = 0; i < params.length; i++) {
      html += '<span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:' + params[i].color + ';"></span>'
      if (params[i].seriesName == 'Growth Rate Year-on-Year' || params[i].seriesName == 'Growth Rate Month-on-Month') {
        html += params[i].seriesName + ': ' + params[i].value + '%<br>';
      } else {
        html += params[i].seriesName + ': ' + Number(params[i].value).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',') + '<br>';
      }
    }
    return html;
  }
}
  • 8.饼状图 label formatter且保留一位小数( 一般我们的数值大道一定程度会用分隔符分开,这里也同一封装起来,还是看个人需求决定)
export function labelFormatter () {
  return {
    normal: {
      show: true,
      formatter (data) {
        return data.name + ' : ' + data.percent.toFixed(2) + '%';
      }
    }
  }
}

接下来就是划重点了!!!

我们接受参数来回显图表:

  • 表格数据 ByYear (获取年份 显示这个表格数据)
  • 这里举三个例子数据来演示
export function tableListByYearMonth () {
  return [
    {
      prop: '', // <String>  对应属性名1
      label: '', // <String>   表头标签
      label2: '', // <String>   表头标签
      width: 60
    },
    {
      prop: '', // <String>  对应属性名2
      label: '', // <String>   表头标签
      label2: '', // <String>   表头标签
      width: 70
    },
    {
      prop: '', // <String>  对应属性名3
      label: '', // <String>   表头标签
      label2: '', // <String>   表头标签
      width: 70
    },
  ]
}

最后这里获取传进来的数据

export function getDataByYear (that, params) {
  let monthList = [];
  let preYearSale = [];
  let curYearSale = [];
  let yearOnYear = [];
  let monthOnMonth = [];
  that.Loading = true;
  that.$store.dispatch('url', params).then((res) => {
    that.Loading = false;
    if (res && res.data && res.code == 200) {
      let dataList = res.data;
      if (dataList.length != 0) {
          dataList.map((item, index) => {
            item.id = index + 1
            monthList.push(item.month);
            preYearSale.push(item.参数1 ? item.参数1 : 0)
            curYearSale.push(item.参数2)
            yearOnYear.push(item.参数3 != null ? item.参数3 : '-')
            monthOnMonth.push(item.参数4 != null ? item.参数4 : '-')
        });
      // 填充数据
      that.chartDataByYear1.xAxis[0].data = monthList;
      that.chartDataByYear1.series[0].data = preYearSale;
      that.chartDataByYear1.series[1].data = curYearSale;
      that.chartDataByYear1.series[2].data = yearOnYear;
      that.chartDataByYear1.series[3].data = monthOnMonth;
      that.$refs.barByYear1.reloadEcharts(that.chartDataByYear1); // 渲染图像
    } else {
      that.timeOut = true;
      that.$message.closeAll();
    }

  })
    .catch(() => {
      that.Loading = false;
      that.timeOut = true;
    });
}

这样我们就完成了整个的渲染

喜欢的小伙伴请一件三联,关注支持博主,不定期更新,如果有不正确的地方,请多多指正....