首页 > 其他分享 >echarts散点图数据相差巨大的解决方案

echarts散点图数据相差巨大的解决方案

时间:2023-11-03 15:25:21浏览次数:41  
标签:min 解决方案 散点图 item num let data echarts 255

1 这几天收到了一个新的需求,就是数据差距太大,导致页面很丑,让我优化一下,下面上图:

解决方案一:

将yAxis和xAxis的type设置为log,这个方式可以很好的解决这个问题,但是有一个前提就是你的数据不能为负数,如果为负数,则数据渲染会出错。那我们的y轴数据中假设就有负数咋办?那我们就用第二种方式解决。

解决方式二:

1、设置x轴 y轴间隔(这个间隔是初始间隔,你可以根据业务需求修改)

let InitialDataInterval = [0, 2, 5, 10, 50, 100, 200]//初始间隔X轴
let InitialDataIntervalY = [0, 5, 10, 15, 40, 80, 100]//初始间隔Y轴

2、根据原始数据修改上面的X轴和Y轴间隔

        因为你的X轴和Y轴数据可能不在上面设置的初始化间隔内,所以可以稍微修改一下X轴和Y轴间隔数据

   

//模拟数据
let swyl_data= [
        [16.91, 33.5],
        [3.06,6.23],
        [3.06,6.23],
        [862.79,12.22],
        [402.1,8.81],
        [59.83,6.32], 
        ]
    let  jcdl_data= [
          [2.74,5.1],
          [1.05,9.36],
          [97.30,18.0],
          [402.57,4.2],
          [0.770,13.8],
          [67.90,5.8],
        ]
    let rgzn_data = [
          [2.29,14.66],
          [392.19,0.61],
          [4.30,9.3],
          [ 6.920000,3.3] 
        ]
//----开始初始化间隔X---- InitialDataInterval  因为你的X轴数据可能不在上面设置的初始化间隔内
  let initData = getInitData(jcdl_data, rgzn_data, swyl_data, 0);
  let initDataY = getInitData(jcdl_data, rgzn_data, swyl_data, 1);
  function getInitData(arr1, arr2, arr3, index) {
    let arr = arr1
      .map((item) => item[index])
      .concat(arr2.map((item) => item[index]))
      .concat(arr3.map((item) => item[index]));
    return arr;
  }
  const dataInterval = parseInterval(initData, InitialDataInterval, 0);//X轴
  const dataIntervalY = parseInterval(initDataY, InitialDataIntervalY, 1); //Y轴
  function parseInterval(initData, myInterval, index) {
    const dataIntervals = [...myInterval];
    // 完善y轴的间隔
    let max_i = Math.max(...dataIntervals);
    let min_i = Math.min(...dataIntervals);
    let maxData = Math.max(...initData);
    let minData = Math.min(...initData);
    if (maxData > max_i) {
      dataIntervals.push(parseIntervalNum(maxData));
    }
    if (minData < min_i) {
      dataIntervals.unshift(parseIntervalNum(minData));
    }
    return dataIntervals;
  }
  function getPNum(num) {
    num = num.toString();
    let firstNumber = num.substr(0, 1);
    let endNumber = num.substr(1);
    return `${parseInt(firstNumber) + 1}${"0".repeat(endNumber.length)}`;
  }
  function parseIntervalNum(num) {
    // 记录前缀,主要为负数提供服务
    let prefix = "";
    if (num < 0) {
      prefix = "-";
    }
    // 将num转为正整数
    num = Math.abs(parseInt(num));
    let p_num = "";
    switch (num.toString().length) {
      case 1:
        p_num = 10;
        break;
      case 2:
        p_num = 100;
        break;
      case 3:
        p_num = 1000;
        break;
      case 4:
        p_num = 10000;
        break;
      case 5:
        p_num = getPNum(num);
        break;
      default:
        p_num = getPNum(num);
        break;
    }
    let finalNum = `${prefix}${p_num}`;
    return parseInt(finalNum);
  }
  // ----结束初始化间隔----

3、将原始数据做一些转换

let diff = Math.max(...initData) - Math.min(...initData) //以X轴数据为样本

// ---开始将原始数据做一些转换
  function echartsDataParse(data, mydataInterval, i, needParseY) {
    //needParseY 是否需要转换Y轴
      // 定义数据间隔 
    let echartsData = [];
    data.forEach((item, index) => {
      // 在数据间隔中查找小于当前项的最大值
      const min_v = Math.max(...mydataInterval.filter((v) => v <= item[0]));
      // 在数据间隔中查询大于当前项的最小值
      const max_v = Math.min(...mydataInterval.filter((v) => v > item[0]));
      // 寻找min_v所在下标
      const index_v = mydataInterval.findIndex((v) => v === min_v);
      // 计算该项在y轴上应该展示的位置
      let x_value = ((item[0] - min_v) / (max_v - min_v)) * 10 + index_v * 10;
      // 判断是否要Y轴转换
      if (needParseY) {
        const min_v_Y = Math.max(...dataIntervalY.filter((v) => v <= item[1]));
        // 在数据间隔中查询大于当前项的最小值
        const max_v_Y = Math.min(...dataIntervalY.filter((v) => v > item[1]));
        // 寻找min_v所在下标
        const index_v_Y = dataIntervalY.findIndex((v) => v === min_v_Y);
        // 计算该项在y轴上应该展示的位置
        let y_value =
          ((item[1] - min_v_Y) / (max_v_Y - min_v_Y)) * 10 + index_v_Y * 10;
        echartsData.push([x_value, y_value, item[0], item[1]]);
      } else {
        echartsData.push([x_value, item[1], item[0], item[1]]);
      }
    });
    return echartsData;
  }
  //  ----转换结束

 4、把转换后的数据挂到series上面

series: [
      {
        name: "商品1",
        type: "scatter",
        data:
          diff > 200? echartsDataParse(jcdl_data, dataInterval, 0, true): jcdl_data,
      },
      {
        name: "商品2",
        type: "scatter",
        data:
          diff > 200? echartsDataParse(swyl_data, dataInterval, 0, true): swyl_data,
      },
      {
        name: "商品3",
        type: "scatter",
        data:
          diff > 200? echartsDataParse(rgzn_data, dataInterval, 0, true): rgzn_data,
      },
    ]

5、修改xAxis和yAxis的axisLabel的formatter

xAxis: {
      type: "value",
      name: "",
      // type: "log", //使用对数
      // logBase: 10, // 底数
      // nameGap: 16,
      nameTextStyle: {
        color: "rgba(255, 255, 255, 0.4)",
        fontSize: 14,
      },
      splitLine: {
        show: true,
        lineStyle: {
          color: "rgba(255, 255, 255, 0.6)",
          width: 0.3,
        },
      },
      axisLine: {
        lineStyle: {
          color: "rgba(255, 255, 255, 0.4)",
        },
      },
      axisTick: {
        show: false, //隐藏X轴刻度
      },
      axisLabel: {
        show: true,
        // formatter: "{value}",
        formatter: (v, i) => {
          if (diff > 200) {
            return axisLabelFormat(v, i, " ", dataInterval);
          }
          return `${v}`;
        },
        textStyle: {
          color: "rgba(255,255,255,0.6)", //X轴文字颜色
          fontSize: 14,
        },
        color: "rgba(255,255,255,0.6)",
      },
    },
    yAxis: {
      type: "value",
      name: "",
      nameLocation: "end",
      // nameGap: 20,
      nameTextStyle: {
        color: "rgba(255, 255, 255, 0.4)",
        fontSize: 16,
      },
      axisLine: {
        lineStyle: {
          color: "rgba(255, 255, 255, 0.6)",
        },
      },
      axisTick: {
        lineStyle: {
          color: "rgba(255, 255, 255, 0.4)",
        },
      },
      splitLine: {
        lineStyle: {
          color: "rgba(255, 255, 255, 0.6)",
          width: 0.3,
        },
      },
      axisLabel: {
        formatter: (v, i) => {
          if (diff > 200) {
            return axisLabelFormat(v, i, "%", dataIntervalY);
          }
          return `${v}`;
        },
        textStyle: {
          color: "rgba(255, 255, 255, 0.4)",
        },
      },
    },
        
  //开始转换X 轴label
  function axisLabelFormat(v, i, suffix = "", dataInterval) {
    dataInterval.forEach((item, index) => {
      if (i == index) v = item + suffix;
    });
    return v;
  }

 6、修改tooltip

由于我们挂载到series的值是转换后的值,所以我们在这里的提示要改为原来的值

tooltip: {
      show: true,
      trigger: "item",
      backgroundColor: "rgba(54,55,65,0.4)",
      borderColor: "rgba(54,55,65,0.4)",
      textStyle: {
        color: "#fff",
      },
      formatter: function (params) {
        let str = "";
        if (params.componentType == "series") {
          str = `<div style="font-size:14px;">
					收入(元):${diff > 200 ? params.data[2] : params.data[0]}
					</div>
					<div style="font-size:14px;margin-top:10px">
					投入占收入百分比:${diff > 200 ? params.data[3] : params.data[1]}%
					</div>
					`;
        }
        return str;
      },
    },

 解决后的图

 

 

参考文章:https://blog.csdn.net/cai_niao5623/article/details/125394119(折线图的)

 

标签:min,解决方案,散点图,item,num,let,data,echarts,255
From: https://www.cnblogs.com/xuxuguaiguai/p/17807458.html

相关文章

  • echarts监听legend的点击事件
    1、echarts监听legend的点击事件myChart.on('legendselectchanged',function(params){console.log(params);});转自:echarts问题--点击legend不全部隐藏,监听最后一个legend点击事件_echarts点击图例不隐藏_哥要掉线了的博客-CSDN博客 ......
  • PLC 和Modbus/串口设备现场总线通信及短信报警解决方案
    在实现Modbus设备与PROFIBUSDP协议PLC通讯的同时可以在手机端实时的接收报警短信,使客户足不出户了解设备与PLC的状态,及时处理现场中的问题。系统组成Modbus转PROFIBUSDP网关PM-160V6.2具有两个串口,一个RS485,一个RS232,他们一个做通讯接口时,另一个就作为IOT接口,该......
  • 【zabbix】configure: error: Unable to use libevent (libevent check failed)解决方
    安装zabbix,在zabbix目录下执行编译命令时报错configure:error:Unabletouselibevent(libeventcheckfailed),如图:说明:新服务器,一般依赖不足,需要视情况安装依赖,问题解决。解决方案:yuminstalllibevent-devel-y......
  • 浅述青犀AI算法人体攀爬行为检测的应用场景及解决方案
    人体攀爬行为检测是指利用计算机视觉技术对人类攀爬物体的行为进行识别和分析。该技术主要依靠图像和视频数据进行分析,通过识别人类身体的各个部位,以及其在攀爬过程中的动作和姿态,实现对攀爬行为的检测和跟踪。该技术的场景应用比较广泛,今天我们来介绍一下TSINGSEE青犀AI边缘计算硬......
  • 数据分析和用户个性化体验:开发同城外卖APP的技术解决方案
    在数字化时代,外卖服务已经成为人们日常生活中不可或缺的一部分。无论是忙碌的白领、学生,还是家庭主妇,都倚赖同城外卖APP来方便地满足他们的饥饿需求。然而,随着竞争的激烈,外卖APP必须不断改进,以满足用户的期望,其中数据分析和用户个性化体验变得至关重要。一、数据分析的重要性1.1了......
  • 小程序引入echarts
    1、去官网资源地址下载https://github.com/ecomfe/echarts-for-weixin下载解压git项目,查看目录,将文件夹ec-canvas,复制到小程序内pages同级目录 注意事项:在ec-canvas文件夹内的echarts.js,不能超过500kb,否则警告,且无法渲染;通过https://echarts.apache.org/zh/builder.html,......
  • MQ【消息延迟解决方案】
    一、消息延迟如何监控    1、消息队列提供的工具,通过监控消息的堆积来完成。    2、通过生产监控消息对消息延时的监控。二、详情   /2.1、消息队列工具      以kafka为例。不用版本消费者的消费进度不一样。      在Kafka0.9之......
  • 真空充氮包装机远程监控运维平台解决方案
    真空充氮包装机是一种复合型的包装机械设备,用于包装食品、药品、化学品和其他物品。它通过将包装物品抽成真空,然后在其中注入氮气等方式,保护包装物品免受氧气、湿气和其他污染物的侵害,可以有效地延长包装物品的保质期,并提高它们的保存质量。 真空充氮包装机集制氮气、抽真空、充氮......
  • pytest + yaml 框架 -39.多账号操作解决方案
    前言最近有小伙伴提到,有写场景需要用到2个账号来回切换操作该如何解决。(备注:从v1.2.4以后新版本不再公开,新功能内部VIP学员可以使用,公开版本仅解决bug,不提供新功能了。)先获取账号token前面教程有讲到全局登录一次,后面所有的请求都会拿着全局登录的账号token去访问请求。......
  • javamail发送附件DataSource使用文件流解决方案
    问题:在使用james邮件服务器发送邮件时,附件是存储在华为云服务器上的,只能通过ApacheHttpClient去下载,存储在FTP上的文件同样会碰到这个问题。API上邮件添加附件的方法:/*************1.本地文件*************///将本地文件作为附件DataSourcedataSource=newFileDataSourc......