echarts双Y轴,并实现图例等

一个Y轴时yAxis为对象

json 复制代码
yAxis: {
   type: 'value',
   name: '占比(%)'
},

两个Y轴时yAxis为数组

json 复制代码
 yAxis: [
          { // 左侧的
            type: 'value',
            name: '占比(%)',
            nameTextStyle: {
              padding: [0, 0, 10, -50]
            },
            min: 0,
            max: 100,
            splitNumber: this.splitNumber, // 设置坐标轴的分割段数
            interval: 20, // 标轴分割间隔
            axisLabel: {
              formatter: function(v) {
                return v.toFixed(0) + '%'
              },
              color: function(value, index) {
                return value >= 1000 ? 'red' : 'green'
              }
            }
          },
          { // 右侧的
            type: 'value',
            name: 'IPU',
            nameTextStyle: {
              padding: [0, 0, 10, 50]
            },
            min: minData2,
            max: maxData2,
            splitNumber: 5,
            interval: (maxData2 - minData2) / 5,
            axisLabel: {
              formatter: function(v) {
                return v.toFixed(2)
              }
            }
          }
]

双Y轴分割:

js 复制代码
 // 获取最大值
 const getMax = (arr)=> {
      var max = Math.max.apply(null, arr)
      var maxint = Math.ceil(max / 5)
      var maxval = maxint * 5 + 5
      return maxval
    }
 // 获取最小值
 const getMin= (arr)=> {
      var min = Math.min.apply(null, arr)
      var minint = Math.floor(min / 1)
      var minval = minint * 1 - 5
      return minval
}

/*
splitNumber:表示分割数
interval:计算轴分割间隔 ( (maxData2 - minData2) / 5 ),也可以写死
*/

series中使用:

js 复制代码
 series: [
          {
            name: '占比',
            type: 'bar',
            color: ['#eb9f0d'],
            symbol: 'none',
            smooth: true,
            data: dataBar
          },
          {
            name: 'IPU',
            type: 'line',
            color: ['#969ac7'],
            // symbol: 'none',
            // smooth: true,
            yAxisIndex: 1, // 在单个图表实例中存在多个y轴的时候有用
            data: dataLine
          }
]

案例图片:

案例源码

html 复制代码
<template>
  <div
    v-loading="loading"
    class="main-echart"
    element-loading-text="拼命加载中"
    element-loading-spinner="el-icon-loading"
    element-loading-background="rgba(0, 0, 0, 0.1)"
  >
    <div v-if="!loading" class="title">总IPU:1000 , 总占比98%</div>
    <div id="echartLineBar" />
  </div>
</template>
<script>
import echarts from 'echarts'
export default {
  name: 'EchartLineBar',
  data() {
    return {
      splitNumber: 5,
      loading: true,
      dataBar: [
        { 'name': '1', 'value': 20 },
        { 'name': '2', 'value': 40 },
        { 'name': '3', 'value': 30 },
        { 'name': '4', 'value': 10 },
        { 'name': '5', 'value': 50 },
        { 'name': '6', 'value': 60 },
        { 'name': '7', 'value': 80 },
        { 'name': '8', 'value': 90 },
        { 'name': '9', 'value': 5 }
      ],
      dataLine: [
        { 'name': '1', 'value': 134 },
        { 'name': '2', 'value': 133 },
        { 'name': '3', 'value': 132 },
        { 'name': '4', 'value': 133 },
        { 'name': '5', 'value': 129 },
        { 'name': '6', 'value': 93 },
        { 'name': '7', 'value': 90 },
        { 'name': '8', 'value': 82 },
        { 'name': '9', 'value': 20 }
      ]
    }
  },
  mounted() {
    setTimeout(() => {
      this.initData(document.getElementById('echartLineBar'), {
        dataBar: this.dataBar, dataLine: this.dataLine
      })
    }, 1000)
  },
  methods: {
    initData(el, { dataBar = [], dataLine = [] }) {
      this.myChart = echarts.init(el)
      this.myChart.clear()
      // 调用方法,获取数据的最大值&最小值
      const dataLineArray = dataLine.map(n => n.value)
      var maxData2 = this.getMax(dataLineArray)
      var minData2 = this.getMin(dataLineArray)
      const option = {
        // 提示框
        tooltip: {
          trigger: 'axis',
          backgroundColor: '#ffffff',
          textStyle: {
            color: '#000000'
          },
          enterable: true, // 鼠标是否可以进入tooltip
          position: function(point, params, dom, rect, size) {
            // return [point[0] - dom.offsetWidth / 2, '50%']
            return [point[0] - dom.offsetWidth / 2, point[1] - dom.offsetHeight]
          },
          extraCssText: 'box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);',
          formatter: function(params) {
            // let str = params[0].name + '<br/>'
            let str = '<div style="min-width:200px">'
            params.forEach(item => {
              if (item.seriesName == '占比') {
                str += `<div class='tooltipTrigger'>${item.marker} ${item.seriesName}分布详情 <br/> 名称:${item.data.name} <br/>值:${item.data.value}% <br/><br/></div>`
              } else if (item.seriesName == 'IPU') {
                str += `<div class='tooltipTrigger'>${item.marker} ${item.seriesName}分布详情 <br/> 名称:${item.data.name} <br/>值:${item.data.value} <br/><br/></div>`
              }
            })
            str += `</div>`
            return str
          }
        },
        // 图例组件
        legend: [
          {
            bottom: '0%',
            left: '40%',
            textStyle: {
              fontSize: 12, // 字体大小
              color: '#000000' // 字体颜色(图例与图例文字配色保持一致)
            },
            data: [
              {
                name: '占比'
              }
            ]
          },
          {
            bottom: '0%',
            left: '50%',
            textStyle: {
              fontSize: 12, // 字体大小
              color: '#000000' // 字体颜色
            },
            data: [
              {
                name: 'IPU'
              }
            ]
          }
        ],
        // 直角坐标系内绘图网格
        grid: {
          show: true,
          x: 70,
          y: 50,
          x2: 70,
          y2: 50
        },
        xAxis: {
          name: '',
          type: 'category',
          data: ['10', '20', '30', '40', '50', '60', '70', '80', '90'],
          nameTextStyle: {
            padding: [0, 0, 50, 50]
          }
        },
        yAxis: [
          {
            type: 'value',
            name: '占比(%)',
            nameTextStyle: {
              padding: [0, 0, 10, -50]
            },
            min: 0,
            max: 100,
            splitNumber: this.splitNumber, // 设置坐标轴的分割段数
            interval: 20, // 标轴分割间隔
            axisLabel: {
              formatter: function(v) {
                return v.toFixed(0) + '%'
              },
              color: function(value, index) {
                return 'green'
              }
            }
          },
          {
            type: 'value',
            name: 'IPU',
            nameTextStyle: {
              padding: [0, 0, 10, 50]
            },
            min: minData2,
            max: maxData2,
            splitNumber: this.splitNumber,
            interval: (maxData2 - minData2) / this.splitNumber,
            axisLabel: {
              formatter: function(v) {
                return v.toFixed(2) // 0表示小数为0位,1表示1位小数,2表示2位小数
              }
            }
          }
        ],
        series: [
          {
            name: '占比',
            type: 'bar',
            color: ['#eb9f0d'],
            symbol: 'none',
            smooth: true,
            data: dataBar
          },
          {
            name: 'IPU',
            type: 'line',
            color: ['#969ac7'],
            // symbol: 'none',
            // smooth: true,
            yAxisIndex: 1, // 在单个图表实例中存在多个y轴的时候有用
            data: dataLine
          }
        ]
      }
      this.myChart.setOption(option)
      this.loading = false
      // 自适应布局
      const resizeFn = () => {
        this.myChart.resize()
      }
      window.removeEventListener('resize', resizeFn, false)
      window.addEventListener('resize', resizeFn, false)
    },
    getMax(arr) {
      var max = Math.max.apply(null, arr)
      var maxint = Math.ceil(max / 5)
      var maxval = maxint * 5 + 5
      return maxval
    },
    getMin(arr) {
      var min = Math.min.apply(null, arr)
      var minint = Math.floor(min / 1)
      var minval = minint * 1 - 5
      return minval
    }
  }
}
</script>
<style lang="scss" scoped>
.main-echart {
  width:100%;
  height: 550px;
  .title{
    margin-left: 20px;
    font-size: 14px;
  }
  #echartLineBar {
    width: 100%;
    height:500px;
  }
}
</style>
<style>
.tooltipTrigger{
  width: 100%;
  border-bottom: 2px dotted #999999;
  padding-top: 10px;
}
.tooltipTrigger:last-child{
  border: none;
}
</style>
相关推荐
new出一个对象13 分钟前
uniapp接入BMapGL百度地图
javascript·百度·uni-app
你挚爱的强哥1 小时前
✅✅✅【Vue.js】sd.js基于jQuery Ajax最新原生完整版for凯哥API版本
javascript·vue.js·jquery
y先森2 小时前
CSS3中的伸缩盒模型(弹性盒子、弹性布局)之伸缩容器、伸缩项目、主轴方向、主轴换行方式、复合属性flex-flow
前端·css·css3
前端Hardy2 小时前
纯HTML&CSS实现3D旋转地球
前端·javascript·css·3d·html
susu10830189112 小时前
vue3中父div设置display flex,2个子div重叠
前端·javascript·vue.js
IT女孩儿3 小时前
CSS查缺补漏(补充上一条)
前端·css
吃杠碰小鸡4 小时前
commitlint校验git提交信息
前端
虾球xz4 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇4 小时前
HTML常用表格与标签
前端·html
疯狂的沙粒5 小时前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript