赞
踩
这几天收到了一个新的需求,就是老大说我们y轴的数据差距太大,导致页面很丑,让我优化一下,下面上图:
有没有感觉巨丑,第一个百分比太大了,导致后面正常的百分比几乎都在下面了。于是我就翻看官网找到了第一个解决方案
将yAxis的type设置为log,这个方式可以很好的解决这个问题,但是有一个前提就是你的数据不能为负数,如果为负数,则数据渲染会出错。那我们的y轴数据中假设就有负数咋办?那我们就用第二种方式解决。
1、设置y轴间隔(这个间隔是初始间隔,你可以根据业务需求修改)
注意:每个echarts对象的dataInterval可能都不一样,建议一个echarts对象一个dataInterval
dataInterval: [0,10, 30, 50, 100,150,200,10000]
2、根据原始数据修改上面的y轴间隔
因为你的y轴数据可能不在上面设置的初始化间隔内,所以可以稍微修改一下y轴间隔数据
- // 求得要处理的y轴数据的最大值和最小值
- const dataInterval = this.parseInterval([...actualAmountWithSamePeriodRateList,...amountRateList])
-
- getPNum(num) {
- num = num.toString();
- let firstNumber = num.substr(0,1);
- let endNumber = num.substr(1)
- return `${parseInt(firstNumber)+1}${'0'.repeat(endNumber.length)}`
- },
- 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 = this.getPNum(num);break;
- default: p_num = this.getPNum(num);break;
- }
- let finalNum = `${prefix}${p_num}`
- return parseInt(finalNum)
- },
- parseInterval(initData) {
- const dataInterval = [...this.dataInterval]
- // 完善y轴的间隔
- let max_i = Math.max(...dataInterval);
- let min_i = Math.min(...dataInterval);
- let maxData = Math.max(...initData);
- let minData = Math.min(...initData);
- if(maxData > max_i) {
- dataInterval.push(this.parseIntervalNum(maxData))
- }
- if(minData < min_i) {
- dataInterval.unshift(this.parseIntervalNum(minData))
- }
- return dataInterval
- },

3、将原始数据做一些转换
- let diff = Math.max(...actualAmountWithSamePeriodRateList,...amountRateList) - Math.min(...actualAmountWithSamePeriodRateList,...amountRateList)
- let actualAmountWithSamePeriodRateList2 = this.echartsDataParse(actualAmountWithSamePeriodRateList,dataInterval);
- let amountRateList2 = this.echartsDataParse(amountRateList,dataInterval);
-
- echartsDataParse(data,dataInterval) {
- // 定义数据间隔
- let echartsData = []
- data.forEach((item, index) => {
- // 在数据间隔中查找小于当前项的最大值
- const min_v = Math.max(...dataInterval.filter(v => v <= item));
- // 在数据间隔中查询大于当前项的最小值
- const max_v = Math.min(...dataInterval.filter(v => v > item));
- // 寻找min_v所在下标
- const index_v = dataInterval.findIndex(v => v === min_v);
- // 计算该项在y轴上应该展示的位置
- let y_value = ((item - min_v) / (max_v - min_v)) * 10 + index_v * 10;
- // 这里处理一下极限值
- y_value = y_value > 75 ? 74.99 : y_value
- echartsData.push(y_value)
- })
- return echartsData;
- },

4、把转换后的数据挂到series上面
- series: [
- {
- name: '增长率1',
- type: 'line',
- data: diff > 200 ? amountRateList2 : amountRateList
- },
- {
- name: '增长率2',
- type: 'line',
- data: diff > 200 ? actualAmountWithSamePeriodRateList2 : actualAmountWithSamePeriodRateList
- }
- ],
5、修改yAxis的axisLabel的formatter
- yAxis: [
- {
- type: 'value',
- name: '百分比',
- axisLabel: {
- // formatter: '{value}%'
- formatter: (v,i) => {
- if(diff > 200) {
- return this.axisLabelFormat(v,i,'%',dataInterval)
- }
- return `${v}%`
- }
- },
- nameTextStyle: {
- fontSize: '16', //字体大小
- fontWeight: 700 //字体加粗
- },
- }
- ]
-
-
- axisLabelFormat(v,i,suffix="",dataInterval) {
- dataInterval.forEach((item,index) => {
- if(i == index) v = item+suffix
- })
- return v;
- /*
- if (i === 0) {
- v = '0';
- }
- if (i === 1) {
- v = '10';
- }
- if (i === 2) {
- v = '30';
- }
- if (i === 3) {
- v = '50';
- }
- if (i === 4) {
- v = '200';
- }
- if (i === 5) {
- v = '1000';
- }
- if (i === 6) {
- v = '5000';
- }
- if (i === 7) {
- v = '12000';
- }
- return v;
- */
- },

6、修改tooltip
由于我们挂载到series的值是转换后的值,所以我们在这里的提示要改为原来的值
- tooltip: {
- show: true,
- trigger: 'item',
- formatter: (params) => {
- if(params.componentSubType === 'line') {
- if(params.seriesName === '增长率2') {
- return `${params.seriesName} <br> ${params.marker}<span style="margin-left:5px;">${params.name}</span><span style="margin-left:15px;">${actualAmountWithSamePeriodRateList[params.dataIndex]}</span>%`
- }else if(params.seriesName === '增长率1') {
- return `${params.seriesName} <br> ${params.marker}<span style="margin-left:5px;">${params.name}</span><span style="margin-left:15px;">${amountRateList[params.dataIndex]}</span>%`
- }
- }else if(params.componentSubType === 'bar') {
- return `${params.seriesName} <br> ${params.marker}<span style="margin-left:5px;">${params.name}</span><span style="margin-left:15px;">${this.toInt(params.value)}</span>`
- }
- }
- },
至此这个问题就解决啦,下面上解决后的图
注意:这里需要优化一下,如果y轴的值相差在200以内,我们就不需要进行数据处理,只有大于200甚至更大的时候才进行处理,否则会造成数据渲染不正确。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。