当前位置:   article > 正文

echarts 折线图y轴数据相差巨大的解决方案_折线图数据相差太大怎么办

折线图数据相差太大怎么办

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

有没有感觉巨丑,第一个百分比太大了,导致后面正常的百分比几乎都在下面了。于是我就翻看官网找到了第一个解决方案

解决方案一:

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

解决方式二:

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

注意:每个echarts对象的dataInterval可能都不一样,建议一个echarts对象一个dataInterval

dataInterval: [0,10, 30, 50, 100,150,200,10000]

2、根据原始数据修改上面的y轴间隔

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

  1. // 求得要处理的y轴数据的最大值和最小值
  2. const dataInterval = this.parseInterval([...actualAmountWithSamePeriodRateList,...amountRateList])
  3. getPNum(num) {
  4. num = num.toString();
  5. let firstNumber = num.substr(0,1);
  6. let endNumber = num.substr(1)
  7. return `${parseInt(firstNumber)+1}${'0'.repeat(endNumber.length)}`
  8. },
  9. parseIntervalNum(num) {
  10. // 记录前缀,主要为负数提供服务
  11. let prefix = '';
  12. if(num < 0) {
  13. prefix = '-'
  14. }
  15. // 将num转为正整数
  16. num = Math.abs(parseInt(num))
  17. let p_num = '';
  18. switch(num.toString().length) {
  19. case 1: p_num = 10;break;
  20. case 2: p_num = 100;break;
  21. case 3: p_num = 1000;break;
  22. case 4: p_num = this.getPNum(num);break;
  23. default: p_num = this.getPNum(num);break;
  24. }
  25. let finalNum = `${prefix}${p_num}`
  26. return parseInt(finalNum)
  27. },
  28. parseInterval(initData) {
  29. const dataInterval = [...this.dataInterval]
  30. // 完善y轴的间隔
  31. let max_i = Math.max(...dataInterval);
  32. let min_i = Math.min(...dataInterval);
  33. let maxData = Math.max(...initData);
  34. let minData = Math.min(...initData);
  35. if(maxData > max_i) {
  36. dataInterval.push(this.parseIntervalNum(maxData))
  37. }
  38. if(minData < min_i) {
  39. dataInterval.unshift(this.parseIntervalNum(minData))
  40. }
  41. return dataInterval
  42. },

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

  1. let diff = Math.max(...actualAmountWithSamePeriodRateList,...amountRateList) - Math.min(...actualAmountWithSamePeriodRateList,...amountRateList)
  2. let actualAmountWithSamePeriodRateList2 = this.echartsDataParse(actualAmountWithSamePeriodRateList,dataInterval);
  3. let amountRateList2 = this.echartsDataParse(amountRateList,dataInterval);
  4. echartsDataParse(data,dataInterval) {
  5. // 定义数据间隔
  6. let echartsData = []
  7. data.forEach((item, index) => {
  8. // 在数据间隔中查找小于当前项的最大值
  9. const min_v = Math.max(...dataInterval.filter(v => v <= item));
  10. // 在数据间隔中查询大于当前项的最小值
  11. const max_v = Math.min(...dataInterval.filter(v => v > item));
  12. // 寻找min_v所在下标
  13. const index_v = dataInterval.findIndex(v => v === min_v);
  14. // 计算该项在y轴上应该展示的位置
  15. let y_value = ((item - min_v) / (max_v - min_v)) * 10 + index_v * 10;
  16. // 这里处理一下极限值
  17. y_value = y_value > 75 ? 74.99 : y_value
  18. echartsData.push(y_value)
  19. })
  20. return echartsData;
  21. },

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

  1. series: [
  2. {
  3. name: '增长率1',
  4. type: 'line',
  5. data: diff > 200 ? amountRateList2 : amountRateList
  6. },
  7. {
  8. name: '增长率2',
  9. type: 'line',
  10. data: diff > 200 ? actualAmountWithSamePeriodRateList2 : actualAmountWithSamePeriodRateList
  11. }
  12. ],

5、修改yAxis的axisLabel的formatter

  1. yAxis: [
  2. {
  3. type: 'value',
  4. name: '百分比',
  5. axisLabel: {
  6. // formatter: '{value}%'
  7. formatter: (v,i) => {
  8. if(diff > 200) {
  9. return this.axisLabelFormat(v,i,'%',dataInterval)
  10. }
  11. return `${v}%`
  12. }
  13. },
  14. nameTextStyle: {
  15. fontSize: '16', //字体大小
  16. fontWeight: 700 //字体加粗
  17. },
  18. }
  19. ]
  20. axisLabelFormat(v,i,suffix="",dataInterval) {
  21. dataInterval.forEach((item,index) => {
  22. if(i == index) v = item+suffix
  23. })
  24. return v;
  25. /*
  26. if (i === 0) {
  27. v = '0';
  28. }
  29. if (i === 1) {
  30. v = '10';
  31. }
  32. if (i === 2) {
  33. v = '30';
  34. }
  35. if (i === 3) {
  36. v = '50';
  37. }
  38. if (i === 4) {
  39. v = '200';
  40. }
  41. if (i === 5) {
  42. v = '1000';
  43. }
  44. if (i === 6) {
  45. v = '5000';
  46. }
  47. if (i === 7) {
  48. v = '12000';
  49. }
  50. return v;
  51. */
  52. },

6、修改tooltip

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

  1. tooltip: {
  2. show: true,
  3. trigger: 'item',
  4. formatter: (params) => {
  5. if(params.componentSubType === 'line') {
  6. if(params.seriesName === '增长率2') {
  7. return `${params.seriesName} <br> ${params.marker}<span style="margin-left:5px;">${params.name}</span><span style="margin-left:15px;">${actualAmountWithSamePeriodRateList[params.dataIndex]}</span>%`
  8. }else if(params.seriesName === '增长率1') {
  9. return `${params.seriesName} <br> ${params.marker}<span style="margin-left:5px;">${params.name}</span><span style="margin-left:15px;">${amountRateList[params.dataIndex]}</span>%`
  10. }
  11. }else if(params.componentSubType === 'bar') {
  12. return `${params.seriesName} <br> ${params.marker}<span style="margin-left:5px;">${params.name}</span><span style="margin-left:15px;">${this.toInt(params.value)}</span>`
  13. }
  14. }
  15. },

至此这个问题就解决啦,下面上解决后的图

注意:这里需要优化一下,如果y轴的值相差在200以内,我们就不需要进行数据处理,只有大于200甚至更大的时候才进行处理,否则会造成数据渲染不正确。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/106621
推荐阅读