测试!你是真会给前端找事呀!!!

63 阅读3分钟

背景:

测试:你这柱形图做出来咋都成这样了,两侧刻度都没对齐,恭喜你,功德-1,bug+1。

前端:汗流浃背了,小黑子。 image.png

echart 双柱状图-技术篇

双柱+折线双y轴刻度对齐

在最近的项目中用到双刻度的柱状图,但是没有优化,导致上了测试环境就产生了这样的问题。

应届小老弟:(火急火燎)哥!这东西真恶心呀,顶不住啦

我:干!

配置项:

pieConf: {
        tooltip: {
          trigger: 'axis',
          backgroundColor: '#fff',
          textStyle: {
            color: '#48505B',
          },
          axisPointer: {
            type: 'cross',
            crossStyle: {
              color: '#999',
            },
          },
        },
        xAxis: [
          {
            type: 'category',
            triggerEvent: true,
            data: [],
            axisLabel: {
              fontSize: 12,
              interval: 0,
              rotate: 30,
              formatter: function (value) {
                if (value !== undefined) {
                  if (value.length > 5) {
                    // 超出6个字符显示省略号
                    return `${value.slice(0, 6)}...`
                  }
                  return value
                }
              },
            },
            axisPointer: {
              type: 'shadow',
            },
          },
        ],
        yAxis: [
          {
            type: 'value',
            name: '使用项目数(个)',
            min: 0,
            axisLabel: {
              formatter: '{value}',
            },
            // //网格线
            splitLine: {
              show: true,
              lineStyle: {
                type: 'solid', //y轴分割线类型
                color: ['rgba(227, 229, 232, 0.5)'],
                width: 1,
              },
            },
          },
          {
            type: 'value',
            name: '使用率(%)',
            min: 0,
            axisLabel: {
              formatter: '{value} %',
            },
            // //网格线
            splitLine: {
              show: true,
              lineStyle: {
                type: 'solid', //y轴分割线类型
                color: ['rgba(227, 229, 232, 0.5)'],
                width: 1,
              },
            },
          },
        ],
        series: [
          {
            name: '使用项目数(个)',
            type: 'bar',
            color: '#1AB394',
            tooltip: {
              valueFormatter: function (value) {
                console.log(value)
                return value
              },
            },
            data: [],
          },
          {
            name: '未使用项目数(个)',
            type: 'bar',
            color: '#0081CC',
            tooltip: {
              valueFormatter: function (value) {
                return value
              },
            },
            data: [],
          },
          {
            name: '使用率(%)',
            type: 'line',
            color: '#FF9900',
            yAxisIndex: 1,
            tooltip: {
              valueFormatter: function (value) {
                return value
              },
            },
            data: [],
          },
        ],
      }

后端获取数据:

    qualityCheckUseRate() {
      let params = this.queryParams
      qualityCheckUseRate(params).then((res) => {
        let data = res.data || []
        if (data.length) {
          this.hasData = true
          let xData = data.map((it) => it.orgName)
          this.pieConf.xAxis[0].data = xData

          let y1Data = data.map((it) => it.useCount)
          let y2Data = data.map((it) => it.notUseCount)
          let rateDate = data.map((it) => it.useRate)

          this.pieConf.series[0].data = y1Data
          this.pieConf.series[1].data = y2Data
          this.pieConf.series[2].data = rateDate

          let y1max = Math.max(...y1Data)
          let y2Max = Math.max(...y2Data)

          let yMax1 = y1max > y2Max ? y1max : y2Max
          let yMax2 = Math.max(...rateDate)

          var divisor = 5
          var lcmVal = this.chartlcm(yMax1, yMax2) //获取两条y轴的最大公约数
          var Ymaxval_interval = this.YmaxvalAndinterval(
            yMax1,
            yMax2,
            lcmVal,
            divisor
          ) //计算y轴最大值和间隔值

          this.pieConf.yAxis[0].max = Ymaxval_interval.max1|| 5 //确保最小项目数量为5,不会出现小数
          this.pieConf.yAxis[0].interval = Ymaxval_interval.interval1 || 1 //刚好五等分

          this.pieConf.yAxis[1].max = Ymaxval_interval.max2 || 100  //没有值就设置最大值为100
          this.pieConf.yAxis[1].interval = Ymaxval_interval.interval2 || 20  //间隔为20,刚好 100/20 五等分

         this.initPieEchart(data)
        } else {
          this.hasData = false
          this.rateChart && this.rateChart.dispose()
        }
      })
    },
    initPieEchart(data) {
      this.rateChart = echarts.init(document.querySelector('.useRate-chart')) //对应的echart dom节点
      this.rateChart.setOption(this.pieConf)
    },

之后就是比较重要的两个方法:

最好是单独封装然后拿过来用,我这里直接用混入,其他组件需要就直接导入即可

//echarts专用求最大公约数 不含小数
    chartlcm(a, b) {
      var result = 1
      for (var i = 1; i <= a && i <= b; i++) {
        if (a % i == 0 && b % i == 0) {
          result = i
        }
        if (result > 1 && i >= 10)
          //公约数大于10的时候 直接跳出 避免y轴刻度太多  (如果不介意刻度太多可以把这一段去掉)
          break
      }
      return result
    },
    //获取echarts  多Y轴的最大值和间隔值 lcmval 最大公约数   divisor 间隔数量
    YmaxvalAndinterval(m, n, lcmval, divisor) {
      var interval1 = Math.ceil(m / lcmval)
      var interval2 = Math.ceil(n / lcmval)

      if (lcmval != 1 && lcmval != 0 && lcmval <= 10) {
        return { max1: m, max2: n, interval1: interval1, interval2: interval2 }
      }

      if (divisor == undefined || divisor == null) divisor = 5
      
      m = Math.ceil(m / divisor) * divisor

      n = Math.ceil(n / divisor) * divisor

      interval1 = Math.ceil(m / divisor)

      interval2 = Math.ceil(n / divisor)

      return { max1: m, max2: n, interval1: interval1, interval2: interval2 }
    },

上菜:

image.png 完美实现刻度对齐。

应届生老弟:家人们谁懂啊!!大哥功德+1.

image.png