echarts 实现高亮渐变色图表

357 阅读2分钟

UI给了如下图的设计让用echarts实现,翻阅api和样例发现高亮配置无法实现渐变色 image.png

思路:

  1. 非高亮折线区域支持渐变色
  2. echarts 支持单独绘制竖线
  3. 折线、折线高亮区、渐变色遮盖单独绘制

最终用三种组合的形式实现了设计

/**
 * 允许传入参数
 * @param {Array} data 数据对象 [12,13,14] || [{value:12},{value:23}]
 */
export default {
  name: 'archive-graph',
  props: ['data'],
  data() {
    return {
      myChart: null
    }
  },
  mounted() {
    this.myChart = echarts.init(this.$el)
    this.initChart(this.data)
  },
  methods: {
    // 初始化折线图
    initChart(newVal) {
      // 转下数据
      let data = this.switchData(newVal)
      // 最后一组高亮显示
      let num = data[0].length - 2
      let result = {
        xAxis: {
          show: false,
          type: 'category',
          boundaryGap: 0
        },
        yAxis: {
          show: false,
          boundaryGap: 0
        },
        grid: {
          top: '20px',
          left: '8px',
          right: '8px',
          bottom: '1px'
        },
        visualMap: [
          // 折线颜色区分
          {
            type: 'piecewise',
            show: false,
            dimension: 0,
            seriesIndex: 0,
            pieces: [
              {
                lte: num,
                color: 'rgba(204,204,204)'
              },
              {
                gt: num,
                lte: num + 1,
                color: 'rgba(245,130,78)'
              }
            ]
          },
          // 面积颜色区分
          {
            type: 'piecewise',
            show: false,
            dimension: 0,
            seriesIndex: 1,
            pieces: [
              {
                lte: num,
                color: 'rgba(204,204,204,0.20)'
              },
              {
                gt: num,
                lte: num + 1,
                color: 'rgba(245,130,78,0.35)'
              }
            ]
          },
        ],
        series: [
          // 单独绘制线
          {
            type: 'line',
            smooth: true,
            showSymbol: true,
            z: 999,
            symbol: 'circle', // 设定为空心点
            symbolSize: 5, // 设定实心点的大小
            label: {
              fontFamily: '-apple-system, BlinkMacSystemFont, Helvetica Neue, Helvetica, Segoe UI, Arial, Roboto, PingFang SC, miui, Hiragino Sans GB, Microsoft Yahei, sans-serif',
              fontWeight: 600
            },
            itemStyle: {
              borderWidth: 2,
              lineStyle: {
                width: 2
              }
            },
            data: data[0],
            // 竖线
            markLine: {
              lineStyle: { type: 'solid', color: 'rgba(204,204,204,0.20)' },
              symbol: 'none', // 去掉箭头
              data: data[2]
            }
          },
          // 单独绘制区域
          {
            type: 'line',
            smooth: true,
            showSymbol: false,
            z: 1,
            lineStyle: {
              width: 0
            },
            symbol: 'none', // 设定为空心点
            areaStyle: {},
            data: data[1]
          },
          // 渐变色尝试
          {
            type: 'line',
            smooth: true,
            showSymbol: false,
            z: 9,
            lineStyle: {
              width: 0
            },
            symbol: 'none', // 设定为空心点
            areaStyle: {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                {
                  offset: 0,
                  color: 'rgba(255,255,255,0)'
                },
                {
                  offset: 1,
                  color: '#FFF'
                }
              ]),
              opacity: 1
            },
            data: data[1]
          },
        ]
      }
      this.myChart.setOption(result)
    },
    // 转换数据
    switchData(data) {
      // 为满足设计需求 线和区域单独渲染
      const arr1 = []
      const arr2 = []
      const arr3 = []
      // 最大值最小值
      let [min, max, minIndex, maxIndex] = [0, 0, 0, 0]
      let lastIndex = data.length - 1
      data.forEach((e, i) => {
        const value = e.value || e
        const O = {
          value,
          itemStyle: {
            borderColor: lastIndex === i ? '#F5824E' : '#ccc',
            color: '#fff'
          },
          label: { color: lastIndex === i ? '#F5824E' : '#CCC' }
        }
        arr1.push(O)
        arr2.push(value)
        // 最大值最小值
        if (!i) {
          [min, max] = [value, value]
        } else {
          // 最小值
          if(value < min){
            [min, minIndex] = [value, i]
          }
          // 最大值
          if(value > max){
            [max, maxIndex] = [value, i]
          } 
        }
        // 绘制竖线
        if (i && i < data.length - 1) {
          arr3.push([{ coord: [i, value] }, { coord: [i, 0] }])
        }
      })
      // 如果数据没有变化 取中间值
      if(max === min) {
        maxIndex = arr1.length - 1
        arr1[maxIndex].label.show = true
      }else{
        // 给最大值加 label
        arr1[maxIndex].label.show = true
        arr1[minIndex].label.show = true
      }
      return [arr1, arr2, arr3]
    }
  },
}