echarts双Y轴,并实现图例等

一个Y轴时yAxis为对象

yAxis: {
   type: 'value',
   name: '占比(%)'
},

两个Y轴时yAxis为数组

 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轴分割:

 // 获取最大值
 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中使用:

 series: [
          {
            name: '占比',
            type: 'bar',
            color: ['#eb9f0d'],
            symbol: 'none',
            smooth: true,
            data: dataBar,
             itemStyle: {
              normal: {
                label: {
                  show: true, // 开启显示
                  position: 'top', // 在上方显示
                  textStyle: { // 数值样式
                    color: '#999999',
                    fontSize: 12
                  },
                  formatter: function(res) {
                    if (res.value > 0) {
                      return res.value 
                    }
                    return ''
                  }
                }
              }
            }
          },
          {
            name: 'IPU',
            type: 'line',
            color: ['#969ac7'],
            // symbol: 'none',
            // smooth: true,
            yAxisIndex: 1, // 在单个图表实例中存在多个y轴的时候有用
            data: dataLine
          }
]

案例图片:

在这里插入图片描述

案例源码

<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'
import Vue from 'vue'
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 == '折线图') {
                str += `<div class='tooltipTrigger'>${item.marker} ${item.seriesName}分布详情 <br/> 名称:${item.data.name} <br/>值:${item.data.value} <br/><br/></div>`
              }
            })
            str += `</div>`
            return str
          }
        },
        /*
        // echarts 5.0才可以返回 string | HTMLElement | HTMLElement[]
        // 可以使用其他组件
        formatter: function(params, ticket, callback) {
            const component = new Vue({
              render: (h) => {
                return (<div style='min-width:200px'>
                  {
                    params.map(item => {
                      return (
                        <div class='tooltipTrigger'>
                          {item.marker} {item.seriesName}分布详情 <br/> 名称:{item.data.name} <br/>值:{item.data.value}% <br/><br/>
                          <ElTooltip effect='dark' content='ElementUI组件提示' placement='top'><i style='font-size:14px;color:rgb(64, 158, 255);cursor: pointer;margin-left:5px' class='el-icon-question' ></i></ElTooltip>
                        </div>
                      )
                    })
                  }
                </div>)
              }
            })
            component.$nextTick(() => {
              callback(ticket, component.$el)
            })
            return 'Loading'
          }
        },
        */
        // 图例组件
         legend: [
          {
            bottom: '0%',
            left: '35%',
            textStyle: {
              fontSize: 12, // 字体大小
              color: '#000000' // 字体颜色(图例与图例文字配色保持一致)
            },
            data: [
              {
                name: '柱状图'
                //icon: 'circle',
              }
            ],
            formatter: function(name) {
              return name //这里可以对图例显示的文字进行操作
            }
          },
          {
            bottom: '0%',
            left: '52%',
            textStyle: {
              fontSize: 12, // 字体大小
              color: '#000000' // 字体颜色
            },
            data: [
              {
                name: '折线图'
              }
            ],
            formatter: function(name) {
              return name //这里可以对图例显示的文字进行操作
            }
          }
        ],
        // 直角坐标系内绘图网格
        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'],
          axisLabel: {
            interval: 0,
            rotate: 0 // 值>0向右倾斜,值<0则向左倾斜
          },
          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位小数
              }
            }
          }
        ],
        color: ['#eb9f0d', '#969ac7'], // 颜色
        series: [
          {
            name: '柱状图',
            type: 'bar',
            barWidth: '50%', // 宽度
            // color: ['#eb9f0d'],
            symbol: 'none',
            smooth: true,
            data: dataBar,
             itemStyle: {
              normal: {
                label: {
                  show: true, // 开启显示
                  position: 'top', // 在上方显示
                  textStyle: { // 数值样式
                    color: '#999999',
                    fontSize: 12
                  },
                  formatter: function(res) {
                    if (res.value > 0) {
                      return res.value
                    }
                    return ''
                  }
                }
              }
            }
          },
          {
            name: '折线图',
            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>

  • 20
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值