echarts封装折线图/柱状图 vue

267 阅读1分钟
  1. Charts组件封装
<template>
  <div :id="echartsId" :style="{ width: width, height: height }"></div>
</template>
<script>
import echarts from 'echarts';
require('echarts/theme/macarons');
export default {
  props: {
    // 折线图数据
    echartsData: {
      type: Object,
      default: {},
    },
    // 折线图标识
    echartsId: {
      type: String,
      default: '',
    },
    // 折线图高度 默认360px
    height: {
      type: String,
      default: '360px',
    },
    // 折线图宽度 默认页面的50%
    width: {
      type: String,
      default: '50%',
    },
    // 折线图标题
    title: {
      type: String,
      default: '',
    },
    // 图形类型
    chartsType: {
      chartsType: String,
      default: 'line',  // 如果是柱状图 type为bar
    }
  },
  // 监听数据改变的时候更新图表
  watch: {
    echartsData: {
      handler(newValue, oldValue) {
        // 拿到新数据更新图表数据重新绘制
        this.drawLine({
          xAxisData: this.echartsData.xAxisData,
          seriesData: this.echartsData.seriesData,
          areaFlag: this.echartsData.areaFlag,
          gridData: this.echartsData.gridData,
        });
      },
    },
  },
  data() {
    return {
      insuranceChart: null,
      insuranceOption: {},
    };
  },
  mounted() {
    // 初始化图表
    this.insuranceChart = echarts.init(document.getElementById(this.echartsId));
    // 监听窗口尺寸的改变,自适应
    window.addEventListener('resize', () => {
      this.insuranceChart.resize();
    });
    this.drawLine({
      // legendData: this.echartsData.legendData,
      xAxisData: this.echartsData.xAxisData,
      seriesData: this.echartsData.seriesData,
      areaFlag: this.echartsData.areaFlag,
      gridData: this.echartsData.gridData,
    });
  },
  methods: {
    drawLine(option) {
      this.$nextTick(function () {
        let that = this;
        this.insuranceChart = echarts.init(
            document.getElementById(this.echartsId)
        );
        this.insuranceOption = {
          // 图表标题
          title: {
            text: this.title,
            // 标题位置
            top: '0',
            left: 'center',
            // 标题样式
            textStyle: {
              fontsize: '12px'
            }
          },
          // 鼠标悬浮框
          tooltip: {
            trigger: 'axis',
          },
          // 图表背景颜色
          backgroundColor: '#fff',
          legend: {
            bottom: 20,
            itemWidth: 12,
            itemHeight: 4,
            // 设置legend名称用矩形还是圆形还是圆矩形
            icon: 'roundRect',
            // 占整体宽度
            width: '100%',
          },
          // 图表离上下左右的距离
          grid: {
            left: '7%',
            right: '3%',
            bottom: '25%',
            top: '18%',
            containLabel: false,
          },
          xAxis: {
            type: 'category',
            // x坐标轴两边留白
            boundaryGap: true,
            // 去除x轴的下划线
            axisLine: {
              show: false,
            },
            axisLabel: {
              // 设置x轴数据大于30的时候间隔几个展示
              interval: option.xAxisData.length > 30 ? 5 : 0,
            },
            // 是否显示坐标轴刻度 以及颜色设置 默认显示
            axisTick: {
              lineStyle: {
                color: 'rgba(224, 230, 241, 1)',
              },
            },
            // 遍历x轴的数据展示 设置字体大小
            data: (function () {
              return option.xAxisData.map(function (item, index) {
                return {
                  value: item,
                  textStyle: {
                    fontSize: (17 * that.width) / 720,
                  },
                };
              });
            })(),
          },
          yAxis: {
            type: 'value',
            // 是否显示y轴线条
            axisLine: {
              show: false,
            },
            // 是否显示y轴刻度线
            axisTick: {
              show: false,
            },
            // y轴分割线设置为虚线
            splitLine: {
              lineStyle: {
                type: 'dotted',
                color: 'rgba(224, 230, 241, 1)',
              },
            },
          },
          // 折线图线条预设颜色
          color: [
            '#FFFF00',
            '#FFCCFF',
            '#FF6666',
            '#66FF66',
            '#3399FF',
            '#330099',
            '#990066',
            '#FF6600',
            '#990000',
            '#CCFF99',
            '#663366',
            '#CC9900',
          ],
          // 动态获取折线图数据
          series: (function () {
            let series = [];
            // 遍历有多少条折线
            option.seriesData.map((item, index) => {
              let data = {
                name: item.name,
                type: that.chartsType, // 如果是柱状图 type为bar
                data: item.data,
                // 拐点圆的大小
                symbolSize: 6,
                // 圆是实心还是空心
                symbol: 'circle',
                // 是否是光滑的曲线 true是光滑
                smooth: false,
              };
              series.push(data);
            });
            return series;
          })(),
        };
        //设置滑动条 x轴数据大于10的时候显示滑动条
        if (option.xAxisData.length > 10) {
          this.insuranceOption.dataZoom = [
            {
              //Y轴固定,让内容滚动
              type: 'slider',
              show: false,
              xAxisIndex: [0],
              start: 0,
              end: 50, // 设置X轴刻度之间的间隔(根据数据量来调整)
              zoomLock: true, // 锁定区域禁止缩放(鼠标滚动会缩放 所以禁止)
            },
            {
              type: 'inside',
              xAxisIndex: [0],
              start: 0,
              end: 50,
              zoomLock: true, //锁定区域禁止缩放
            },
            {
              showDetail: false,
              left: '0', // 组件离容器左侧的距离,'left', 'center', 'right','20%'
              right: '0', // 组件离容器右侧的距离,'20%'
              bottom: '0',
              height: 10,
              fillerColor: '#ccc',
              backgroundColor: '#fff',
              dataBackground: {
                lineStyle: {
                  opacity: 0,
                },
                areaStyle: {
                  opacity: 0,
                },
              },
              // handleSize: "50%",
            },
          ];
        } else {
          this.insuranceOption.dataZoom = [];
        }
        this.insuranceChart.setOption(this.insuranceOption);
      });
    },
  },
};
</script>
  1. 使用
<template>
  <Charts :echartsData="echartsData" :echartsId="'测试图表'" :title="title" chartsType="line"> </Charts>
</template>
<script>
import Charts from "@/components/Charts";

export default {
  components: {
    Charts,
  },
  data() {
    return {
      echartsData: {},
      title: '测试图表名称'
    };
  },
  created() {
    this.getLineChart();
  },
  methods: {
    getLineChart() {
      this.echartsData = {
        // x轴标题数据
        xAxisData: ['1月', '2月', '3月', '4月', '5月', '6月', '7月'],
        seriesData: [
          {
            name: '测试1',
            data: [220, 192, 563, 234, 360, 730, 610],
          },
          {
            name: '测试2',
            data: [220, 182, 191, 234, 290, 330, 310],
          },
          {
            name: '测试3',
            data: [220, 232, 201, 154, 190, 330, 410],
          },
          {
            name: '测试4',
            data: [211, 432, 121, 231, 190, 330, 410],
          },
          {
            name: '测试5',
            data: [121, 90, 451, 211, 121, 221, 101],
          },
          {
            name: '测试6',
            data: [520, 377, 100, 420, 342, 520, 123],
          },
        ],
      };
    },
  },
};
</script>