vue+ECharts画图时的常用配置

3,358 阅读4分钟

「这是我参与2022首次更文挑战的第19天,活动详情查看:2022首次更文挑战」。

有时候,使用 ECharts 画图时,官方提供的一些基本配置并不能满足实际项目的需求,这时就需要我们自定义一些配置,这些配置包括以下几个方面。

1、多轴配置

根据官方文档所说的,先配置两个y轴如下:

  yAxis: [
      {
         type: 'value',
         name: '1111',
         position: 'left',
         axisLine: {
            show: true,
            lineStyle: {
              color: 'blue'
            }
         },
         axisLabel: {
            formatter: '{value}'
         }
      },
      {
         type: 'value',
         name: '2222',
         position: 'right',
         axisLine: {
           show: true,
           lineStyle: {
             color: '#91cc75'
         }
      },
      axisLabel: {
         formatter: '{value}'
      }
    }
]

下面重点是,当单个图表中存在多个y轴时,需要在 series 中使用 yAxisIndex 配置与之对应的y轴:

series: [
   {
       name: '销量1',
       type: 'bar',
       yAxisIndex: 0, // 指定第一个y轴
       data: [5, 20, 36, 10, 10, 20]
   },
   {
       name: '销量2',
       type: 'bar',
       yAxisIndex: 1, // 指定第二个y轴
       data: [150, 250, 400, 50, 150, 300]
   }
]

页面渲染如下图所示:

2、y轴坐标轴名称垂直显示处理

有时候,y轴坐标名称会很长,影响美观,特别是溢出以后,就会被隐藏,如下图所示:

这时候我们就希望竖着显示,可能效果更好,使用官方提供的方法,新增 nameLocation=“middle”,调整 nameTextStyle 样式即可实现,代码如下:

{
    type: 'value',
    name: '宇宙无敌第一大帅比就是我哈哈哈哈额!!!',
    nameLocation: 'middle',
    nameTextStyle: {
        lineHeight: 60
    },
    position: 'left',
    axisLine: {
        show: true,
        lineStyle: {
            color: 'blue'
        }
    },
    axisLabel: {
        formatter: '{value}'
    }
},
{
    type: 'value',
    name: '你们就承认我是宇宙无敌第一大帅比吧!!!',
    nameLocation: 'middle',
    nameTextStyle: {
       lineHeight: 60
    },
    position: 'right',
    axisLine: {
        show: true,
        lineStyle: {
            color: '#91cc75'
        }
    },
    axisLabel: {
        formatter: '{value}'
    }
}

效果如下:

这么倒着,看着感觉脑瓜疼,我想给它倒过来,看着更舒服,解决办法如下:

方法1、将坐标名称的每个字符用转义字符 “\n” 连接,设置 nameLocation=“left”,调整 nameTextStyle 样式即可实现,代码如下:

{
    type: 'value',
    name: '宇\n宙\n无\n敌\n第\n一\n大\n帅\n比\n就\n是\n我\n哈\n哈\n哈\n哈\n额\n!!!',
    nameLocation: 'left',
    nameTextStyle: {
       padding: [0, 80, 0, 0]
    },
    position: 'left',
    axisLine: {
        show: true,
        lineStyle: {
            color: 'blue'
        }
    },
    axisLabel: {
        formatter: '{value}'
    }
},
{
    type: 'value',
    name: '你\n们\n就\n承\n认\n我\n是\n宇\n宙\n无\n敌\n第\n一\n大\n帅\n比\n吧\n!!!',
    nameLocation: 'left',
    nameTextStyle: {
       padding: [0, 0, 0, 100]
    },
    position: 'right',
    axisLine: {
        show: true,
        lineStyle: {
            color: '#91cc75'
        }
    },
    axisLabel: {
        formatter: '{value}'
    }
}

效果如下:

方法2、将坐标名称的每个字符用转义字符 “\n” 连接,设置 nameLocation=“middle”,设置 nameRotate=0, ,调整 nameTextStyle 样式即可实现,代码如下:

{
    type: 'value',
    name: '宇\n宙\n无\n敌\n第\n一\n大\n帅\n比\n就\n是\n我\n哈\n哈\n哈\n哈\n额\n!!!',
    nameLocation: 'middle',
    nameRotate: 0,
    nameTextStyle: {
        padding: [0, 50, 0, 0],
        align: 'center'
    },
    position: 'left',
    axisLine: {
        show: true,
        lineStyle: {
            color: 'blue'
        }
    },
    axisLabel: {
        formatter: '{value}'
    }
},
{
    type: 'value',
    name: '你\n们\n就\n承\n认\n我\n是\n宇\n宙\n无\n敌\n第\n一\n大\n帅\n比\n吧\n!!!',
    nameLocation: 'middle',
    nameRotate: 0,
    nameTextStyle: {
        padding: [0, 0, 0, 60],
        align: 'center'
    },
    position: 'right',
    axisLine: {
        show: true,
        lineStyle: {
            color: '#91cc75'
        }
    },
    axisLabel: {
        formatter: '{value}'
    }
}

效果如下:

3、图例名称过长时的换行处理

同样的,图例的名称有时候也会很长,这时也需要处理,处理办法如下:

legend: {
     data: ['销量1111111111111111111111', '销量22222222222222222222'],
     orient: 'vertical',
     'formatter': function(params) {
         if (params.length > 10) {
            var p1 = params.slice(0, 10)
            var p2 = params.slice(10)
            return p1 + '\n' + p2
         } else {
            return params
         }
     }
},

series 中的 name 要与 legend 中的 data 对应,否则不显示,效果如下:

4、坐标轴刻度标签名称过长时的换行处理

坐标轴刻度标签名称过长会导致标签显示不全,解决办法是进行换行或旋转,两者结合也可以,更改 xAxis 代码如下:

xAxis: {
      data: ['衬衫111111111', '羊毛衫1111111111111', '雪纺衫111111111', '裤子111111111', '高跟鞋11111111', '袜子1111111111'],
      axisLabel: { // 坐标轴标签
            interval: 0,
            // rotate: 45, // 倾斜度 -90 至 90 默认为0
            margin: 12,
            textStyle: {
              fontWeight: 'bolder',
              color: '#000000'
            },
            // 坐标轴刻度标签换行处理
            formatter: function(params) {
              var newParamsName = '' // 最终拼接成的字符串
              var paramsNameNumber = params.length // 实际标签的个数
              var provideNumber = 8 // 每行能显示的字的个数
              var rowNumber = Math.ceil(paramsNameNumber / provideNumber) // 换行的话,需要显示几行,向上取整
              /**
             * 判断标签的个数是否大于规定的个数, 如果大于,则进行换行处理 如果不大于,即等于或小于,就返回原标签
             */
              // 条件等同于rowNumber>1
              if (paramsNameNumber > provideNumber) {
                /** 循环每一行,p表示行 */
                for (var p = 0; p < rowNumber; p++) {
                  var tempStr = '' // 表示每一次截取的字符串
                  var start = p * provideNumber // 开始截取的位置
                  var end = start + provideNumber // 结束截取的位置
                  // 此处特殊处理最后一行的索引值
                  if (p === rowNumber - 1) {
                    // 最后一次不换行
                    tempStr = params.substring(start, paramsNameNumber)
                  } else {
                    // 每一次拼接字符串并换行
                    tempStr = params.substring(start, end) + '\n'
                  }
                  newParamsName += tempStr // 最终拼成的字符串
                }
              } else {
                // 将旧标签的值赋给新标签
                newParamsName = params
              }
              // 将最终的字符串返回
              return newParamsName
          }
     }
}

效果如下:

5、坐标轴标签大数值的科学计数法处理

当 y 轴的标签数据过大时

{
    name: '销量22222222222222222222',
    type: 'bar',
    yAxisIndex: 1, // 指定第二个y轴
    data: [15000, 25000, 40000, 50000, 150000, 300000]
}

我们可以使用科学计数法进行处理,具体做法是更改 axisLabel 代码如下:

	axisLabel: {
           formatter: function(value) { // 科学计数法显示标签
                var res = value.toString()
                var numN1 = 0
                var numN2 = 1
                var num1 = 0
                var num2 = 0
                var t1 = 1
                for (var k = 0; k < res.length; k++) {
                  if (res[k] === '.') { t1 = 0 }
                  if (t1) { num1++ } else { num2++ }
                }

                if (Math.abs(value) < 1 && res.length > 4) {
                  for (var i = 2; i < res.length; i++) {
                    if (res[i] === '0') {
                      numN2++
                    } else if (res[i] === '.') {
                      continue
                    } else {
                      break
                    }
                  }
                  var v = parseFloat(value)
                  v = v * Math.pow(10, numN2)
                  return v.toString() + 'e-' + numN2
                } else if (num1 > 4) {
                  if (res[0] === '-') {
                    numN1 = num1 - 2
                  } else {
                    numN1 = num1 - 1
                  }
                  v = parseFloat(value)
                  v = v / Math.pow(10, numN1)
                  if (num2 > 4) { v = v.toFixed(4) }
                  return v.toString() + 'e' + numN1
                } else {
                  return parseFloat(value)
                }
          }
     }

效果如下: