vue + element + ts + echarts 实现柱状图、折线图

1,737 阅读1分钟

vue + element + ts + echarts 实现柱状图、折线图、不废话直接上图,上代码.

柱状图.png

折线图.png

<template>
<!-- 写一个有宽高的div -->
  <div
    :id="id"
    :class="className"
  />
  <!--  :style="{height: height, width: width}" -->
</template>

<script lang="ts">
import echarts, { EChartOption } from 'echarts'
import { Component, Prop } from 'vue-property-decorator'
import { mixins } from 'vue-class-component'
import ResizeMixin from './mixins/resize'

@Component({
  name: 'MixedChart'
})
export default class extends mixins(ResizeMixin) {
  @Prop({ default: 'chart' }) private className!: string
  @Prop({ default: 'chart' }) private id!: string
  @Prop({ default: '100%' }) private width!: string
  @Prop({ default: '300px' }) private height!: string

  mounted() {
    this.$nextTick(() => {
      this.initChart()
    })
  }

  beforeDestroy() {
    if (!this.chart) {
      return
    }
    this.chart.dispose()
    this.chart = null
  }

  private initChart() {
    this.chart = echarts.init(document.getElementById(this.id) as HTMLDivElement)
    // //x轴显示的参数
    const xData = (function() {
      const data = [] // 月份
      for (let i = 1; i < 13; i++) {
        data.push(i + 'month')
      }
      return data
    }())
    this.chart.setOption({
      // backgroundColor: '#344b58', // 图标背景颜色
      // title: {
      //   text: 'statistics',
      //   top: '10',
      //   textStyle: {
      //     // title.textStyle. color 主标题文字的颜色
      //     color: '#fff',
      //     // title.textStyle. fontSize 主标题文字的字体大小。
      //     fontSize: 22
      //   },
      //   subtextStyle: {
      //     // title.subtextStyle. color 副标题文字的颜色
      //     color: '#90979c',
      //     // title.subtextStyle. fontSize 副标题文字的字体大小
      //     fontSize: 16
      //   }
      // },
       title: {
        text: '总薪资统计(单位:万元)',
    },
      tooltip: {
        // grid.tooltip.trigger 触发类型 'item'数据项图形触发,主要在散点图,饼图等无类目轴的图表中使用。
        // 'axis'坐标轴触发,主要在柱状图,折线图等会使用类目轴的图表中使用。
        // 'none' 什么都不触发。
        trigger: 'axis'
      },
      grid: {
        left: '5%', // grid 组件离容器左侧的距离。
        right: '5%',
        borderWidth: 0,
        top: 50, // grid 组件离容器上侧的距离。
        bottom: 50,
        textStyle: {
          //  grid.tooltip. textStyle  提示框浮层的文本样式。
          color: '#fff'
        }
      },
      // // 图例组件
      // legend: {
      //   x: '5%',
      //   top: '5%', // 图例组件离容器上侧的距离
      //   textStyle: {
      //     // legend. textStyle 图例的公用文本样式。
      //     //  legend.textStyle. color  文字的颜色。
      //     color: '#90979c'
      //   },
      //   data: ['粉色', 'male', 'average']
      // },
      // 直角坐标系 grid 中的 x 轴,一般情况下单个 grid 组件最多只能放上下两个 x 轴,
      // 多于两个 x 轴需要通过配置 offset 属性防止同个位置多个 x 轴的重叠。
      xAxis: [{
        type: 'category', // 'category' 类目轴  .'value' 数值轴,适用于连续数据 .'time' 时间轴,适用于连续的时序数据
        // 坐标轴轴线相关设置。
        axisLine: {
          lineStyle: {
            // 坐标轴线线的颜色。
            color: '#90979c'
          }
        },
        splitLine: {
          // 是否显示分隔线。默认数值轴显示,类目轴不显示。
          show: false
        },
        axisTick: {
          // 是否显示坐标轴刻度。
          show: false
        },
        splitArea: {
          // 是否显示分隔区域。
          show: false
        },
        axisLabel: {
          // 坐标轴刻度标签的显示间隔,在类目轴中有效
          interval: 0 // 设置成 0 强制显示所有标签。
          // 如果设置为 1,表示『隔一个标签显示一个标签』,如果值为 2,表示隔两个标签显示一个标签,以此类推。
        },
        data: xData //x轴显示的参数
      }],
      // 坐标轴类型。
      yAxis: [{
        // 'value' 数值轴,适用于连续数据. 'category' 类目轴,适用于离散的类目数据。 'time' 时间轴,适用于连续的时序数据
        type: 'value',
        splitLine: {
           // 是否显示分隔线。默认数值轴显示,类目轴不显示。
          show: false
        },
        // // 坐标轴轴线相关设置。
        axisLine: {
          // 
          lineStyle: {
             // 坐标轴线线的颜色。
            color: '#90979c'
          }
        },
        axisTick: {
           // 是否显示坐标轴刻度。
          show: true
        },
        axisLabel: {
           // 坐标轴刻度标签的显示间隔,在类目轴中有效.
          interval: 0 // 设置成 0 强制显示所有标签。
        },
        splitArea: {
            // 是否显示分隔区域。
          show: false
        }
      }],
      // 组件 用于区域缩放,从而能自由关注细节的数据信息,或者概览数据整体,或者去除离群点的影响。
      // dataZoom: [{
      //   show: true,
      //   xAxisIndex: [
      //     0
      //   ],
      //   bottom: 30,
      //   start: 10,
      //   end: 80,
      //   handleIcon: 'path://M306.1,413c0,2.2-1.8,4-4,4h-59.8c-2.2,0-4-1.8-4-4V200.8c0-2.2,1.8-4,4-4h59.8c2.2,0,4,1.8,4,4V413z',
      //   handleSize: '110%',
      //   handleStyle: {
      //     color: '#d3dee5'

      //   },
      //   textStyle: {
      //     color: '#fff'
      //   },
      //   borderColor: '#90979c'
      // }, {
      //   type: 'inside',
      //   show: true,
      //   start: 1,
      //   end: 35
      // }],
      series: [{
        name: '粉色', // 和图例组件绑定的数据
        type: 'bar', // bar
        stack: 'total', // series-bar. stack 数据堆叠,同个类目轴上系列配置相同的stack值可以堆叠放置。
        barMaxWidth: 35, // 柱条的最大宽度 比 barWidth 优先级高.可以是绝对值例如 40 或者百分数例如 '60%'。百分数基于自动计算出的每一类目的宽度。
        barGap: '10%', // 不同系列的柱间距离,为百分比(如 '30%',表示柱子宽度的 30%)
        //  // 图形样式。
        itemStyle: {
          // 柱条的颜色。  series-bar.itemStyle. color = 自适应 Color
          color: 'rgba(255,144,128,1)',
          label: {
            show: true,
            textStyle: {
              color: '#fff'
            },
            position: 'insideTop',
            // 文本标签文字的格式化器。
            formatter(p: any) {
              return p.value > 0 ? p.value : ''
            }
          }
        },
        data: [3709,1917,2455,2610,1719,1433,1544,3285,5208,3372,2484,7078,
          {
            value: 8000, // 某项需要突出单独处理的参数.
            itemStyle: {
                color: '#a90000'
            }
        },
        ]
      },

    // {
      //   name: 'male',
      //   type: 'bar',  // 柱状图
      //   stack: 'total',
      //   itemStyle: {
      //     color: 'rgba(0,191,183,1)',
      //     barBorderRadius: 0,
      //     label: {
      //       show: true,
      //       position: 'top',
      //       formatter(p: any) {
      //         return p.value > 0 ? p.value : ''
      //       }
      //     }
      //   },
      //   data: [
      //     327,
      //     1776,
      //     507,
      //     1200,
      //     800,
      //     482,
      //     204,
      //     1390,
      //     1001,
      //     951,
      //     381,
      //     220
      //   ]
      // },
      //  {
      //   name: 'average',
      //   type: 'line',  //折线图
      //   stack: 'total',
      //   symbolSize: 10,
      //   symbol: 'circle',
      //   itemStyle: {
      //     color: 'rgba(252,230,48,1)',
      //     barBorderRadius: 0,
      //     label: {
      //       show: true,
      //       position: 'top',
      //       formatter(p: any) {
      //         return p.value > 0 ? p.value : ''
      //       }
      //     }
      //   },
      //   data: [
      //     1036,
      //     3693,
      //     2962,
      //     3810,
      //     2519,
      //     1915,
      //     1748,
      //     4675,
      //     6209,
      //     4323,
      //     2865,
      //     4298
      //   ]
      // }
      ]
    } as EChartOption<EChartOption.SeriesLine | EChartOption.SeriesBar>)
  }
}
</script>
<style lang="scss"scoped>
div{
  height: 300px;
  width: 100%;
}
</style>

import { ECharts } from 'echarts'
import { Component, Vue } from 'vue-property-decorator'

@Component({
  name: 'ResizeMixin'
})
export default class extends Vue {
  protected chart!: ECharts | null
  private sidebarElm?: Element

  mounted() {
    this.initResizeEvent()
    this.initSidebarResizeEvent()
  }

  beforeDestroy() {
    this.destroyResizeEvent()
    this.destroySidebarResizeEvent()
  }

  activated() {
    this.initResizeEvent()
    this.initSidebarResizeEvent()
  }

  deactivated() {
    this.destroyResizeEvent()
    this.destroySidebarResizeEvent()
  }

  private chartResizeHandler() {
    if (this.chart) {
      this.chart.resize()
    }
  }

  private sidebarResizeHandler(e: TransitionEvent) {
    if (e.propertyName === 'width') {
      this.chartResizeHandler()
    }
  }

  private initResizeEvent() {
    if (this.chartResizeHandler) {
      window.addEventListener('resize', this.chartResizeHandler)
    }
  }

  private destroyResizeEvent() {
    if (this.chartResizeHandler) {
      window.removeEventListener('resize', this.chartResizeHandler)
    }
  }

  private initSidebarResizeEvent() {
    this.sidebarElm = document.getElementsByClassName('sidebar-container')[0]
    if (this.sidebarElm) {
      this.sidebarElm.addEventListener('transitionend', this.sidebarResizeHandler as EventListener)
    }
  }

  private destroySidebarResizeEvent() {
    if (this.sidebarElm) {
      this.sidebarElm.removeEventListener('transitionend', this.sidebarResizeHandler as EventListener)
    }
  }
}

参考:https://echarts.apache.org/examples/zh/index.html#chart-type-bar