echarts处理y轴最大小值根据数据动态处理、分割数和是否从0开始

方法

javascript 复制代码
/**
 * 取整
 * @param value 输入值
 * @param scale 保留位数 正数是整数位,负数是小数位
 * @param isUpper true 向上取整  false向下取整
 * @returns
 */
const numberFix = (value, scale, isUpper) => {
    const moreThanZero = value >= 0
    value = Math.abs(value)
    if (scale == 0) {
      return value
    }
    if (scale > 0) {
      scale -= 1
    }
    let result
    if (moreThanZero) {
      result =
        numberFloorOrCeil(value / Math.pow(10, scale), isUpper) *
        Math.pow(10, scale)
    } else {
      result =
        -1 *
        numberFloorOrCeil(value / Math.pow(10, scale), !isUpper) *
        Math.pow(10, scale)
    }
    if (scale < 0) {
      result =
        numberFloorOrCeil(result * Math.pow(10, -1 * scale), isUpper) /
        Math.pow(10, -1 * scale)
    }
    return result
  }
  
  const numberFloorOrCeil = (value, isUpper) => {
    if (isUpper) {
      return Math.ceil(value)
    } else {
      return Math.floor(value)
    }
  }
  
  /**
   * 得到数字的尺寸
   * 0=>1
   * 5=>1
   * 10=>2
   * 123=>3
   * 0.5=>-1
   * 0.003=>-3
   * @param value
   * @returns {number}
   */
  const getNumberMaxScale = value => {
    const moreThanZero = value >= 0
    let absValue = Math.abs(value)
    if (absValue >= 1) {
      const valueStr = absValue + ''
      return valueStr.split('.')[0].length
    } else if (absValue > 0) {
      let scale = 0
      while (absValue < 1) {
        absValue *= 10
        scale -= 1
      }
      return scale
    } else {
      // 为0
      return 1
    }
  }
  
  /**
   *
   * @param valueArr 对象数组
   * @param splitNum 分割线数量
   * @param fromZero 是否从0开始
   * @param splitSmallerScale 分割数取整减少位数
   * @param splitMinScale 1是个位 2是10位,-1表示0.1级别,-2表示0.01级别,-3表示0.001级别; null就是不启用这个功能
   * @returns {{min: number, max: number, interval: number}}
   */
  const echartsSplit = (
    valueArr,
    splitNum = 5,
    fromZero = true,
    splitSmallerScale = 0,
    splitMinScale = null
  ) => {
    valueArr = [...valueArr]
    if (fromZero) {
      valueArr.push(0)
    }
    let maxValue = Math.max(...valueArr)
    let minValue = Math.min(...valueArr)
  
    const maxMoreThanZero = maxValue >= 0
    const minMoreThanZero = minValue >= 0
    let totalDiff = maxValue - minValue
    let totalDiffScale = getNumberMaxScale(totalDiff / splitNum)
    let splitScale = totalDiffScale - splitSmallerScale
    if (splitMinScale != null && splitScale < splitMinScale) {
      splitScale = splitMinScale
    }
    splitScale = splitScale == 0 ? -1 : splitScale
    let minResult = numberFix(minValue, splitScale, false)
    let splitValue = (maxValue - minResult) / splitNum
    let splitResult = numberFix(splitValue, splitScale, true)
    // 如果所有数据值都一样的特殊情况处理
    if (splitResult == 0) {
      // 如果所有数据都一样且都为0,则最小值为0
      minResult = minResult == 0 ? 0 : minResult - 1
      splitResult = 1
    }
    let maxResult = minResult + splitResult * splitNum
  
    return {
      min: Math.round(minResult * 100000000) / 100000000,
      max: Math.round(maxResult * 100000000) / 100000000,
      interval: Math.round(splitResult * 100000000) / 100000000
    }
  }
  export default echartsSplit
  

使用

javascript 复制代码
import echartsSplit from '@/utils/echartsSplit'

setOptions(list) {
	  const wData = []
      const qData = []
      const drpData = []
      series.forEach((item) => {
        if (item.name.indexOf('流量') > -1) {
          qData.push(...item.data.filter((value) => value))
        } else if (item.name.indexOf('水位') > -1) {
          wData.push(...item.data.filter((value) => value))
        } else {
          drpData.push(...item.data.filter((value) => value))
        }
      })
      this.options.yAxis = yAxis.map((item, index) => {
        const data = index === 0 ? drpData : index === 1 ? wData : qData
        const obj = echartsSplit(data, 5, false)
        return {
          ...item,
          min: obj.min,
          max: obj.max,
          interval: obj.interval
        }
      })
      this.options = { ...this.options }
}

效果

相关推荐
daols881 小时前
vxe-table 渲染器教程一:实现金额输入控件
javascript·vue.js·vxe-table
触底反弹1 小时前
🔥 React 零基础入门(中):500 行屎山代码到组件化的蜕变
前端·javascript·react.js
张元清6 小时前
React useResizeObserver Hook:追踪元素尺寸变化(2026)
javascript·react.js
瑞瑞小同学8 小时前
处理echarts x轴内容过多,重叠问题
前端·javascript·echarts
像我这样帅的人丶你还9 小时前
MCP + npm:给五年前的老系统接上AI
前端·javascript·agent
一个写前端的11 小时前
基于 Vue 3 的大文件分片上传组件,支持断点续传、并发上传、失败重试等功能
前端·javascript·vue.js
猫头_11 小时前
AI 流式传输工程指南:有了 EventSource 为何还要 Fetch?
javascript·http·llm
良木林12 小时前
滑动窗口 - LeetCode hot 100
javascript·算法·leetcode·双指针·滑动窗口
不简说13 小时前
# JS 代码技巧 vol.7 — 20 个浏览器 API 实战,自带 API 能干的事别自己封装
前端·javascript·面试
Hilaku14 小时前
为什么 Cloudflare 能做到毫秒级冷启动,而其它云厂商却不行?
前端·javascript·程序员