Skip to content

前言

封装可以考虑多种的情况,是否是全局都有、还是一个模块下面有,可以封装一个vue组件、传入配置项来显示需要的图表,或者抽离配置项单独去定制

简单封装

场景是某个模块下需要 液位/流量、水质等配置图表,参数如下

悬浮框-->定制里面的属性展示(如果不抽离需要传更多的值)

图表缩放-->可以不用,直接在这写死,默认图表都是需要这个的

水平数据-->X轴的label展示

纵轴数据-->X轴值对应的Y轴数据

图表实例

另个垂直数据

js
// 液位/流量的配置项--------------------------------------------------------------------------------
export const liquidFlowOpt = (tooltip, dataZoom, curveHorizontal, liquidVerticalData, echarts, flowVerticalData) => {
  return {
    grid: {
      left: '7%',//图表距离左边
      right: '6%',
      containLabel: true//grid 区域是否包含坐标轴的刻度标签
    },
    legend: [     //图例组件展现了不同系列的标记(symbol),颜色和名字。可以通过点击图例控制哪些系列不显示。
      {
        data: [
          {
            name: '液位',
            icon: 'rect'    //长方形的
          }
        ],
        itemWidth: 11,    //宽
        itemHeight: 2,   //高
        top: '4%',      //距离上方
        left: '45%',    //距离左
        textStyle: {    //文字样式
          color: '#2C3542 ',
          // fontWeight: "normal",
          fontSize: 12,
          fontFamily: 'PingFang SC Arial, Helvetica, sans-serif' // 设置字体类型为 Arial、Helvetica 或 sans-serif 中的一种
        }
      },
      {
        data: [
          {
            name: '流量',
            icon: 'rect'
          }
        ],
        itemWidth: 11,
        itemHeight: 2,
        top: '4%',
        left: '55%',
        textStyle: {
          color: '#2C3542 ',
          // fontWeight: "normal",
          fontSize: 12,
          fontFamily: 'PingFang SC Arial, Helvetica, sans-serif' // 设置字体类型为 Arial、Helvetica 或 sans-serif 中的一种
        }
      }
    ],
    tooltip: tooltip,//悬浮提示
    dataZoom: dataZoom,  //缩放
    //x轴
    xAxis: {
      data: curveHorizontal,
      boundaryGap: false,
      axisLine: {
        lineStyle: {
          // 设置x轴颜色
          color: '#FFFFFF'
        }
      },
      axisLabel: {
        color: '#999999 ' //坐标轴的文本颜色
      }
    },
    //y轴没有显式设置,根据值自动生成y轴
    yAxis: [
      {
        name: '指标:液位(m)',
        nameGap: 25, // 设置纵轴名称距离轴线的距离为 25 像素
        min: function (v) {    //如果没数据时候默认展示的纵轴
          console.log(v);
          if (v.min == Infinity) {
            console.log(22222);
            return 0;
          }
          return v.min;
        },
        // offset: -30,
        max: function (v) {
          console.log(v);
          if (v.max == -Infinity) {
            console.log(1111);
            return 1.5;
          }
          return v.max;
        },
        type: 'value',
        position: 'left',
        axisTick: {
          show: false //坐标轴刻度|隐藏
        },
        // alignTicks: true,  //开启该配置项自动对齐刻度,刻度都隐藏了就没有必要了
        axisLine: {     //纵轴文字,就是0 3 6 9 12 14
          show: false,
          lineStyle: {
            color: '#999999'
          }
        },
        splitLine: {
          show: true, //隐藏纵轴的横线
          lineStyle: {
            color: '#DCDFE6 ',
            type: 'dashed'
          }
        },
        axisLabel: {
          formatter: '{value} '
        }
      },
      {
        name: '指标:流量(m³/s)',
        nameGap: 25, // 设置纵轴名称距离轴线的距离为 25 像素
        min: function (v) {
          console.log(v);
          if (v.min == Infinity) {
            return 0;
          }
          return v.min;
        },
        max: function (v) {
          console.log(v);
          if (v.max == -Infinity) {
            return 100;
          }
          return v.max;
        },
        // interval: 3,
        axisTick: {
          show: false // 设置 axisTick 的 show 属性为 false
        },
        type: 'value',
        position: 'right',
        // alignTicks: true,
        splitLine: {
          show: true, //隐藏纵轴的横线
          lineStyle: {
            color: '#DCDFE6',
            type: 'dashed'
          }
        },
        axisLine: {
          show: false,
          lineStyle: {
            color: '#999999'
          }
        },
        axisLabel: {
          formatter: '{value} '
        }
      }
    ],

    //数据-data是最终要显示的数据
    series: [
      {
        name: '液位',
        type: 'line',
        symbol: 'circle', // 默认是空心圆(中间是白色的),改成实心圆
        smooth: true,
        color: '#1d72f1',
        areaStyle: {
          normal: {
            //线性渐变,前4个参数分别是x0,y0,x2,y2(范围0~1);相当于图形包围盒中的百分比。如果最后一个参数是‘true’,则该四个值是绝对像素位置。
            color: new echarts.graphic.LinearGradient(
              0,
              0,
              0,
              1,
              [
                {
                  offset: 0,
                  color: '#e5f5fe'
                },
                {
                  offset: 0.6,
                  color: '#e0f4fe'
                },
                {
                  offset: 1,
                  color: '#dcf3fe'
                }
              ],
              false
            )
          }
        },
        data: liquidVerticalData,
        showSymbol: true,
        symbolSize: 6,
        lineStyle: {
          width: 3 // 设置线的粗细,这里设置为 3
        }
      },
      {
        name: '流量',
        type: 'line',
        symbol: 'circle', // 默认是空心圆(中间是白色的),改成实心圆
        smooth: true,
        yAxisIndex: 1,
        color: '#00dbd5',
        areaStyle: {
          normal: {
            //线性渐变,前4个参数分别是x0,y0,x2,y2(范围0~1);相当于图形包围盒中的百分比。如果最后一个参数是‘true’,则该四个值是绝对像素位置。
            color: new echarts.graphic.LinearGradient(
              0,
              0,
              0,
              1,
              [
                {
                  offset: 0,
                  color: '#fcfefe'
                },
                {
                  offset: 0.6,
                  color: '#d6f4fa'
                },
                {
                  offset: 1,
                  color: '#ccf7f6'
                }
              ],
              false
            )
          }
        },
        data: flowVerticalData,
        // showSymbol: flowVerticalData.length == 1 ? true : false,
        showSymbol: true,
        symbolSize: 6,
        lineStyle: {
          width: 3 // 设置线的粗细,这里设置为 3
        }
      }
    ]
  };
};

调用

js
	  var that = this;
      let dataZoom = deepClone(this.echartOptions.dataZoom);
      //Todo 液位/流量图表的Tooltip 有时间可以再封装
      let liquidFlowTooltip = {
        trigger: 'axis',
        backgroundColor: 'rgba(0, 0, 0, 0.75)',
        confine: true,
        formatter: function (params) {
          // console.log(params);
          var relVal = '';
          var time = '';
          let qId = '';
          for (var i = 0, l = params.length; i < l; i++) {
            if (i === 0) {
              relVal += '<span style="display:inline-block;margin-right:5px;width:1px;"></span>' + that.chartShowTime[params[i].dataIndex] + '<br/>';
              time = that.curveDateTime[params[i].dataIndex];
              qId = that.curveIdList[params[i].dataIndex];
            }
            relVal +=
              '<span style="display:inline-block;padding-bottom:20px;width:1px;"></span> <span style="display:inline-block;margin-right:5px;margin-bottom:4px;border-radius:10px;width:13px;height:3px;background-color:' +
              params[i].color +
              '"></span>' +
              params[i].seriesName +
              ':' +
              (params[i].value || '-') +
              getUnit(params[i].seriesName, params[i].value) +
              '<br/>';
          }
          that.queryTime = time;
          that.queryID = qId;
          return relVal;
        },
        // 添加以下样式
        textStyle: {
          fontSize: 14,
          color: '#FFFFFF ',
          margin: 20
        },
        extraCssText: 'max-width: 300px; padding: 12px;'
      };
      var option1 = liquidFlowOpt(liquidFlowTooltip, dataZoom, this.curveHorizontal, this.liquidVerticalData, this.$echarts, this.flowVerticalData);

      //初始化ehcharts实例
      let charts = document.getElementById('line_charts');
      this.myChart = this.$echarts.init(charts);//这是全局注册了
	  this.myChart.setOption(option1);

组件抽离

图表组件

vue
<template>
  <div ref="chart" />
</template>

<script>
export default {
  name: 'EChartsChart',
  props: {
    option: {
      type: Object,
      required: true
    }
  },
  mounted() {
    this.initChart()
  },
  beforeDestroy() {
    // 在组件销毁前销毁图表实例,释放资源
    if (this.chart) {
      this.chart.dispose()
      this.chart = null
    }
  },
  methods: {
    initChart() {
      // 在mounted钩子函数中初始化图表
      this.chart = this.$echarts.init(this.$refs.chart)
      this.chart.setOption(this.option)
    }
  }
}
</script>

配置项抽离,应该要类似简单封装那配置项用方法导出,更智能

js
export const option7 = {
  color: ['#ff2600', '#ffc000', '#00ad4e', '#0073c2', '#165868', '#e76f00', '#316194', '#723761', '#00b2f1', '#4d6022', '#4b83bf', '#f9c813', '#0176c0'], // 柱状图颜色列表
  tooltip: {
    // 鼠标悬浮时的提示框配置
    trigger: 'axis', // 触发类型为坐标轴
    transitionDuration: 0, // 提示框动画过渡时间
    // backgroundColor: 'rgba(83,93,105,0.8)', // 提示框背景颜色
    // borderColor: '#535b69', // 提示框边框颜色
    // borderRadius: 8, // 提示框圆角半径
    // borderWidth: 2, // 提示框边框宽度
    // padding: [5, 10], // 提示框内边距
    formatter: function (params, ticket, callback) {
      // 提示框内容格式化函数
      var res = ''
      for (var i = 0, l = params.length; i < l; i++) {
        res += '' + params[i].seriesName + ' : ' + params[i].value + '<br>' // 拼接系列名称和对应的数值
      }
      return res
    },
    axisPointer: {
      type: 'line',
      lineStyle: {
        type: 'dashed',
        color: '#ffff00',
      },
    },
  },
  toolbox: {
    show: true, // 显示工具栏
    feature: {
      mark: {
        show: true,
      },
    },
  },
  grid: {
    borderWidth: 0, // 网格边框宽度
    top: '40', // 上边距
    left: '30', // 左边距
    right: '10', // 右边距
    bottom: '40', // 下边距

    color: '#fff', // 文字颜色
  },
  xAxis: [
    {
      type: 'category', // 类目轴
      axisTick: {
        show: false, // 不显示刻度线
      },
      axisLine: {
        show: false, // 不显示轴线
        lineStyle: {
          color: '#868c96', // 轴线颜色
        },
      },
      axisLabel: {
        interval: 0, // 强制显示所有类目
        fontSize: 14, // 字体大小
        formatter: function (value) {
          var ret = '' // 拼接加\n返回的类目项
          var maxLength = 2 // 每项显示文字个数
          var valLength = value.length // X轴类目项的文字个数
          var rowN = Math.ceil(valLength / maxLength) // 类目项需要换行的行数
          if (rowN > 1) {
            // 如果类目项的文字大于3,
            for (var i = 0; i < rowN; i++) {
              var temp = '' // 每次截取的字符串
              var start = i * maxLength // 开始截取的位置
              var end = start + maxLength // 结束截取的位置
              // 这里也可以加一个是否是最后一行的判断,但是不加也没有影响,那就不加吧
              temp = value.substring(start, end) + '\n'
              ret += temp // 凭借最终的字符串
            }
            return ret
          } else {
            return value
          }
        },
      },
      splitArea: {
        show: false,
      },
      data: ['电力部门', '水利部门', '海外部门', '物联网', '消防部门', '平台研发', '其他'], // X轴数据
      splitLine: {
        show: false,
      },
    },
  ],
  yAxis: [
    {
      type: 'value', // 数值轴
      offset: -14, // 偏移量
      splitLine: {
        show: false, // 不显示分隔线
      },
      axisLine: {
        show: false, // 不显示轴线
        lineStyle: {
          color: '#868c96', // 轴线颜色
        },
      },
      axisTick: {
        show: false, // 不显示刻度线
      },
      axisLabel: {
        interval: 0, // 强制显示所有标签
        fontSize: 14, // 字体大小
      },
      splitArea: {
        show: false,
      },
    },
  ],
  series: [
    {
      name: '共享次数', // 系列名称
      type: 'bar', // 柱状图
      data: [2912, 3991, 4621, 3941, 3313, 6631, 5543, 4463, 6541, 3381], // 数据
      itemStyle: {
        color: function (params) {
          // 柱状图颜色
          var colorList = ['#ff2600', '#ffc000', '#00ad4e', '#0073c2', '#165868', '#e76f00', '#316194', '#723761', '#00b2f1', '#4d6022', '#4b83bf', '#f9c813', '#0176c0']
          return colorList[params.dataIndex]
        },
      },
      barWidth: 14, // 柱状图宽度
      label: {
        show: true, // 显示标签
        position: 'top', // 标签位置

        color: '#ffc72b', // 标签文字颜色
        fontSize: 10, // 标签文字大小
      },
    },
    {
      name: '折线', // 系列名称
      type: 'line', // 折线图
      itemStyle: {
        color: '#d3d5fd', // 折线颜色
      },
      data: [2912, 3991, 4621, 3941, 3313, 6631, 5543, 4463, 6541, 3381], // 数据
    },
  ],
}

调用

js

       <EChartsChart :option="option7" style="width: 100%; height: 300px" />
           
       import { option7 } from '@/components/echarts/option7.js'
	   import EChartsChart from '@/components/echarts/EChartsChart.vue'

 	   components: {EChartsChart },//data同级
 	   created() {
   			 this.option7 = option7
		}