vue 中实现 echarts 的全屏放大效果

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

该功能的实现是在vue+ECharts画图时的常用配置这篇文章的基础上做进一步的修改。 首先要实现图表的全屏放大效果,我总结了一下,共有2种方法可以实现:

  • 方法1:使用 Element.requestFullscreen() 实现
  • 方法2:使用弹窗全屏重新画图实现

方法1

1.自定义全屏工具 myFull

由于 echarts 官方并没有内置的全屏工具,但是支持自定义工具,所以我们可以自定义一个全屏放大的工具,我们只需要注意自定义的工具名字,以 my 开头就可以了,具体的配置如下:

       toolbox: {
          feature: {
            dataZoom: { yAxisIndex: 'none' }, // 数据区域缩放
            restore: { show: true }, // 重置
            saveAsImage: { show: true }, // 导出图片
            myFull: { // 全屏
              show: true,
              title: '全屏',
              icon: 'path://M432.45,595.444c0,2.177-4.661,6.82-11.305,6.82c-6.475,0-11.306-4.567-11.306-6.82s4.852-6.812,11.306-6.812C427.841,588.632,432.452,593.191,432.45,595.444L432.45,595.444z M421.155,589.876c-3.009,0-5.448,2.495-5.448,5.572s2.439,5.572,5.448,5.572c3.01,0,5.449-2.495,5.449-5.572C426.604,592.371,424.165,589.876,421.155,589.876L421.155,589.876z M421.146,591.891c-1.916,0-3.47,1.589-3.47,3.549c0,1.959,1.554,3.548,3.47,3.548s3.469-1.589,3.469-3.548C424.614,593.479,423.062,591.891,421.146,591.891L421.146,591.891zM421.146,591.891',
              onclick: (e) => {
                // 全屏查看
                if (domName.requestFullScreen) { // HTML W3C 提议
                  domName.requestFullScreen()
                } else if (domName.msRequestFullscreen) { // IE11
                  domName.msRequestFullScreen()
                } else if (domName.webkitRequestFullScreen) { // Webkit
                  domName.webkitRequestFullScreen()
                } else if (domName.mozRequestFullScreen) { // Firefox
                  domName.mozRequestFullScreen()
                }
                // 退出全屏
                if (domName.requestFullScreen) {
                  document.exitFullscreen()
                } else if (domName.msRequestFullScreen) {
                  document.msExitFullscreen()
                } else if (domName.webkitRequestFullScreen) {
                  document.webkitCancelFullScreen()
                } else if (domName.mozRequestFullScreen) {
                  document.mozCancelFullScreen()
                }
              }
            }
          }
        },
复制代码

2.存在的问题

浏览器效果如下: image.png

可以看见右上角多了几个小图标,最后一个就是全屏工具,点击后的效果如下: image.png

由上图可以看出,全屏展示的效果有了,但是仍然存在两个问题:

  1. 背景色是黑色的,我想要白色作为背景
  2. 图不是全屏自适应的,我想要全屏铺满自适应

3.问题解决

对于第一点,我偶然发现只需要更改图表容器的背景色就可以实现了,我给图表容器加了白色背景,代码如下:

<template>
  <div class="app-container">
    <div id="main" style="width:600px;height:600px;margin:0 auto;background-color:#fff;" />
  </div>
</template>
复制代码

浏览器效果如下: image.png

再次点击小眼睛图标,效果如下: image.png

由上图可知,全屏后的效果图,背景变成了白色。由此可以发现,只需要修改图表容器中渲染时的效果,那么全屏的效果也会跟着改变。

对于第二点,很显然是全屏展示后的图表没有自适应屏幕的大小,我们只需要加上自适应就可以了。首先需要引入自适应工具,代码如下:

import { EleResize } from '@/utils/esresize'// 图表自适应
复制代码

其次,在画图配置中使用自适应,代码如下:

// 图表自适应
const listener = function() {
    myChart.resize()
}
EleResize.on(domName, listener)
复制代码

点击全屏预览工具,效果如下: image.png

自适应实现的代码 esresize.js 在这篇文章vue中如何使用ECharts画图并实现自适应

4.最终效果展示

test1.gif

5.完整代码

<template>
  <div class="app-container">
    <!-- 初始图 -->
    <div id="main" style="width:600px;height:600px;margin:0 auto;background-color:#fff;" />
  </div>
</template>
<script>
import { EleResize } from '@/utils/esresize'// 图表自适应
export default {
  data() {
    return {
      dialogVisible: false
    }
  },
  mounted() {
    // 初始画图
    this.initChart(document.getElementById('main'))
  },
  methods: {
    initChart(domName) {
      var myChart = this.$echarts.init(domName)
      // 图表自适应
      const listener = function() {
        myChart.resize()
      }
      EleResize.on(domName, listener)
      var option = {
        title: {
          text: 'ECharts实例'
        },
        toolbox: {
          feature: {
            dataZoom: { yAxisIndex: 'none' }, // 数据区域缩放
            restore: { show: true }, // 重置
            saveAsImage: { show: true }, // 导出图片
            myFull: { // 全屏
              show: true,
              title: '全屏',
              icon: 'path://M432.45,595.444c0,2.177-4.661,6.82-11.305,6.82c-6.475,0-11.306-4.567-11.306-6.82s4.852-6.812,11.306-6.812C427.841,588.632,432.452,593.191,432.45,595.444L432.45,595.444z M421.155,589.876c-3.009,0-5.448,2.495-5.448,5.572s2.439,5.572,5.448,5.572c3.01,0,5.449-2.495,5.449-5.572C426.604,592.371,424.165,589.876,421.155,589.876L421.155,589.876z M421.146,591.891c-1.916,0-3.47,1.589-3.47,3.549c0,1.959,1.554,3.548,3.47,3.548s3.469-1.589,3.469-3.548C424.614,593.479,423.062,591.891,421.146,591.891L421.146,591.891zM421.146,591.891',
              onclick: (e) => {
                // 全屏查看
                if (domName.requestFullScreen) { // HTML W3C 提议
                  domName.requestFullScreen()
                } else if (domName.msRequestFullscreen) { // IE11
                  domName.msRequestFullScreen()
                } else if (domName.webkitRequestFullScreen) { // Webkit
                  domName.webkitRequestFullScreen()
                } else if (domName.mozRequestFullScreen) { // Firefox
                  domName.mozRequestFullScreen()
                }
                // 退出全屏
                if (domName.requestFullScreen) {
                  document.exitFullscreen()
                } else if (domName.msRequestFullScreen) {
                  document.msExitFullscreen()
                } else if (domName.webkitRequestFullScreen) {
                  document.webkitCancelFullScreen()
                } else if (domName.mozRequestFullScreen) {
                  document.mozCancelFullScreen()
                }
              }
            }
          }
        },
        legend: {
          data: ['销量1111111111111111111111', '销量22222222222222222222'],
          orient: 'horizontal',
          '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
            }
          }
        },
        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
            }
          }
        },
        yAxis: [
          {
            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: 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)
                }
              }
            }
          }
        ],
        series: [
          {
            name: '销量1111111111111111111111',
            type: 'bar',
            yAxisIndex: 0, // 指定第一个y轴
            data: [5, 20, 36, 10, 10, 20]
          },
          {
            name: '销量22222222222222222222',
            type: 'bar',
            yAxisIndex: 1, // 指定第二个y轴
            data: [15000, 25000, 40000, 50000, 150000, 300000]
          }
        ]
      }
      option && myChart.setOption(option)
    }
  }
}
</script>
复制代码

方法2

1.添加全屏画图弹框

:fullscreen="true" 为组件内置的全屏属性,screenHeight 为浏览器窗口的文档显示区的高度(为了实现图表的高度自适应),代码如下:

    <!-- 全屏弹框 -->
    <el-dialog
      title="全屏显示"
      :visible.sync="dialogVisible"
      :fullscreen="true"
      center
    >
      <div id="main1" ref="fullChart" :style="'width:100%;height:' + (screenHeight - 110) + 'px'" />
    </el-dialog>
复制代码
data() {
    return {
      dialogVisible: false,
      screenHeight: window.innerHeight
    }
},
复制代码

2.全屏图表高度自适应

图表高度自适应的实现,主要是监听 screenHeight 的变化来实现,代码如下:

// 监听screenHeight大小,从而改变全屏画图容器的大小
  watch: {
    screenHeight(val) {
      this.screenHeight = val
    }
  },
  mounted() {
    // 初始画图
    this.initChart(document.getElementById('main'))
    // 获取浏览器窗口大小
    window.onresize = () => {
      return (() => {
        window.screenHeight = window.innerHeight
        this.screenHeight = window.screenHeight
      })()
    }
  },
复制代码

3.echarts 自定义工具配置

        toolbox: {
          feature: {
            dataZoom: { yAxisIndex: 'none' }, // 数据区域缩放
            restore: { show: true }, // 重置
            saveAsImage: { show: true }, // 导出图片
            myFull: { // 全屏
              show: true,
              title: '全屏',
              icon: 'path://M432.45,595.444c0,2.177-4.661,6.82-11.305,6.82c-6.475,0-11.306-4.567-11.306-6.82s4.852-6.812,11.306-6.812C427.841,588.632,432.452,593.191,432.45,595.444L432.45,595.444z M421.155,589.876c-3.009,0-5.448,2.495-5.448,5.572s2.439,5.572,5.448,5.572c3.01,0,5.449-2.495,5.449-5.572C426.604,592.371,424.165,589.876,421.155,589.876L421.155,589.876z M421.146,591.891c-1.916,0-3.47,1.589-3.47,3.549c0,1.959,1.554,3.548,3.47,3.548s3.469-1.589,3.469-3.548C424.614,593.479,423.062,591.891,421.146,591.891L421.146,591.891zM421.146,591.891',
              onclick: () => {
                // 全屏查看
                this.dialogVisible = true// 打开弹窗
                this.$nextTick(() => {
                  const chartFul = this.$refs.fullChart
                  if (chartFul) {
                    this.initChart(document.getElementById('main1'))// 画图
                  }
                })
              }
            }
          }
        },
复制代码

4.效果展示

test2.gif

5.完整代码

<template>
  <div class="app-container">
    <!-- 初始图 -->
    <div id="main" style="width:600px;height:600px;margin:0 auto;background-color:#fff;" />
    <!-- 全屏弹框 -->
    <el-dialog
      title="全屏显示"
      :visible.sync="dialogVisible"
      :fullscreen="true"
      center
    >
      <div id="main1" ref="fullChart" :style="'width:100%;height:' + (screenHeight - 110) + 'px'" />
    </el-dialog>
  </div>
</template>
<script>
import { EleResize } from '@/utils/esresize'// 图表自适应
export default {
  data() {
    return {
      dialogVisible: false,
      screenHeight: window.innerHeight
    }
  },
  // 监听screenHeight大小,从而改变全屏画图容器的大小
  watch: {
    screenHeight(val) {
      this.screenHeight = val
    }
  },
  mounted() {
    // 初始画图
    this.initChart(document.getElementById('main'))
    // 获取浏览器窗口大小
    window.onresize = () => {
      return (() => {
        window.screenHeight = window.innerHeight
        this.screenHeight = window.screenHeight
      })()
    }
  },
  methods: {
    initChart(domName) {
      var myChart = this.$echarts.init(domName)
      // 图表自适应
      const listener = function() {
        myChart.resize()
      }
      EleResize.on(domName, listener)
      var option = {
        title: {
          text: 'ECharts实例'
        },
        toolbox: {
          feature: {
            dataZoom: { yAxisIndex: 'none' }, // 数据区域缩放
            restore: { show: true }, // 重置
            saveAsImage: { show: true }, // 导出图片
            myFull: { // 全屏
              show: true,
              title: '全屏',
              icon: 'path://M432.45,595.444c0,2.177-4.661,6.82-11.305,6.82c-6.475,0-11.306-4.567-11.306-6.82s4.852-6.812,11.306-6.812C427.841,588.632,432.452,593.191,432.45,595.444L432.45,595.444z M421.155,589.876c-3.009,0-5.448,2.495-5.448,5.572s2.439,5.572,5.448,5.572c3.01,0,5.449-2.495,5.449-5.572C426.604,592.371,424.165,589.876,421.155,589.876L421.155,589.876z M421.146,591.891c-1.916,0-3.47,1.589-3.47,3.549c0,1.959,1.554,3.548,3.47,3.548s3.469-1.589,3.469-3.548C424.614,593.479,423.062,591.891,421.146,591.891L421.146,591.891zM421.146,591.891',
              onclick: () => {
                // 全屏查看
                this.dialogVisible = true// 打开弹窗
                this.$nextTick(() => {
                  const chartFul = this.$refs.fullChart
                  if (chartFul) {
                    this.initChart(document.getElementById('main1'))// 画图
                  }
                })
              }
            }
          }
        },
        legend: {
          data: ['销量1111111111111111111111', '销量22222222222222222222'],
          orient: 'horizontal',
          '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
            }
          }
        },
        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
            }
          }
        },
        yAxis: [
          {
            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: 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)
                }
              }
            }
          }
        ],
        series: [
          {
            name: '销量1111111111111111111111',
            type: 'bar',
            yAxisIndex: 0, // 指定第一个y轴
            data: [5, 20, 36, 10, 10, 20]
          },
          {
            name: '销量22222222222222222222',
            type: 'bar',
            yAxisIndex: 1, // 指定第二个y轴
            data: [15000, 25000, 40000, 50000, 150000, 300000]
          }
        ]
      }
      option && myChart.setOption(option)
    }
  }
}
</script>
复制代码

方法3

1.添加全屏按钮

添加一个 icon 按钮,绑定一个点击事件 fullSc(),代码如下:

<i
   class="el-icon-rank"
   style="font-size: 22px;
      transform: rotate(45deg);
      color:rgb(135 135 135);
      cursor: pointer;
      position: absolute;
      top: 5px;
      right: 105px;
      z-index: 5;"
   title="全屏"
   @click="fullSc()"
/>
复制代码

2.点击画图

    // 点击全屏图标按钮弹框画图
    fullSc() {
      this.dialogVisible = true
      this.$nextTick(() => {
        const chartFul = this.$refs.fullChart
        if (chartFul) {
          this.initChart(document.getElementById('main1'))// 画图
        }
      })
    }
复制代码

3.渲染效果

image.png

4.全屏效果展示

image.png

5.完整代码

<template>
  <div class="app-container">
    <div style="width:600px;height:600px;margin:0 auto;background-color:#fff;position:relative">
      <!-- 全屏图标按钮 -->
      <i
        class="el-icon-rank"
        style="font-size: 22px;
      transform: rotate(45deg);
      color:rgb(135 135 135);
      cursor: pointer;
      position: absolute;
      top: 5px;
      right: 105px;
      z-index: 5;"
        title="全屏"
        @click="fullSc()"
      />
      <!-- 图表容器 -->
      <div id="main" style="width:100%;height:100%;" />
    </div>
    <!-- 全屏弹框 -->
    <el-dialog
      title="全屏显示"
      :visible.sync="dialogVisible"
      :fullscreen="true"
      center
    >
      <div id="main1" ref="fullChart" :style="'width:100%;height:' + (screenHeight - 110) + 'px'" />
    </el-dialog>
  </div>
</template>
<script>
import { EleResize } from '@/utils/esresize'// 图表自适应
export default {
  data() {
    return {
      dialogVisible: false,
      screenHeight: window.innerHeight
    }
  },
  // 监听screenHeight大小,从而改变全屏画图容器的大小
  watch: {
    screenHeight(val) {
      this.screenHeight = val
    }
  },
  mounted() {
    // 初始画图
    this.initChart(document.getElementById('main'))
    // 获取浏览器窗口大小
    window.onresize = () => {
      return (() => {
        window.screenHeight = window.innerHeight
        this.screenHeight = window.screenHeight
      })()
    }
  },
  methods: {
    // 初始画图
    initChart(domName) {
      var myChart = this.$echarts.init(domName)
      // 图表自适应
      const listener = function() {
        myChart.resize()
      }
      EleResize.on(domName, listener)
      var option = {
        title: {
          text: 'ECharts实例'
        },
        toolbox: {
          feature: {
            dataZoom: { yAxisIndex: 'none' }, // 数据区域缩放
            restore: { show: true }, // 重置
            saveAsImage: { show: true } // 导出图片
          }
        },
        legend: {
          data: ['销量1111111111111111111111', '销量22222222222222222222'],
          orient: 'horizontal',
          '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
            }
          }
        },
        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
            }
          }
        },
        yAxis: [
          {
            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: 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)
                }
              }
            }
          }
        ],
        series: [
          {
            name: '销量1111111111111111111111',
            type: 'bar',
            yAxisIndex: 0, // 指定第一个y轴
            data: [5, 20, 36, 10, 10, 20]
          },
          {
            name: '销量22222222222222222222',
            type: 'bar',
            yAxisIndex: 1, // 指定第二个y轴
            data: [15000, 25000, 40000, 50000, 150000, 300000]
          }
        ]
      }
      option && myChart.setOption(option)
    },
    // 点击全屏图标按钮弹框画图
    fullSc() {
      this.dialogVisible = true
      this.$nextTick(() => {
        const chartFul = this.$refs.fullChart
        if (chartFul) {
          this.initChart(document.getElementById('main1'))// 画图
        }
      })
    }
  }
}
</script>
复制代码

总结

总结以上三种方法: 如果我们只预览图表,只在图表容器渲染出来的图上做操作的话,推荐使用方法一;

如果我们不仅要在表容器渲染出来的图上做操作,还要进行其他操作(比如下拉框啥的),比如下图这样: image.png

这两个下拉框是不属于图表容器里的东西,全屏显示时,是不显示的。

对于这种情况,推荐使用方法二和方法三,但是方法二中用不了 this,所以我觉得用方法三,最终效果如下: image.png

猜你喜欢

转载自juejin.im/post/7077751650365997070