Echarts实现折线图Y轴不等距百分比(最终解决方案)

Echarts实现折线图Y轴不等距百分比(最终解决方案-上集)

出现背景

  最近公司有一个需求,主要是想展示近7日产品的一个良品率(百分率制)。但是呢,基本上每天这个百分比率在90%~100%之间,很少有低于90%的。我就根据这个需求,很快就做出折线图表,图表右侧的Y轴是从0%-100%,并按20%间隔。

在这里插入图片描述

  给到产品后,TA说线上的数据基本上都是90%-100%,你这样的话就看不出太大的折线趋势,折线的起伏不是很明显,下面空白了一大片,着眼一看,确实不利于观测。

  后来,TA说因为数据比较固定,那么是否可以设置一个最低值呢?比如,在Y轴最低处设置一个60%,那整体不是就拉伸开了吗。后来我就尝试了一下,如下图所示:

在这里插入图片描述
  刚开始以为就这么简单搞定,当天测试工程师测试的时候,又发现一个问题。如果中间某一天没有生产,那么就没有数据,没有数据当时处理为0。不过图表它就不这样认为了,我偏要捣乱一下。当中间某一天没数据时,如下图所示:

在这里插入图片描述
  我勒个去,这是什么鬼,29日那天没数据默认为0,结果就飞到下面去了,显然不符合需求。那么就设置一个最低值为0,第二隔为60%,这样子总可以了嘛。来吧,如下图所示:

在这里插入图片描述
  到这里我觉得应该搞定了,给产品看了过后,TA觉得还行,那就这样吧。

  没过多久,突然出现某一天良率为80%,和Y轴的刻度对不上,然后检查后才发现全部的都没对应上Y轴。如下图所示:

在这里插入图片描述
  原因:虽然我们Y轴设置了不等距显示,但是实际上Y轴还是按照原来0-100%,来均匀分布,并没有实现不等距显示效果,想到这个问题很头疼。

  当天查了很多资料,都没有找到相应的解决办法。晚上回家也很想了很久,第二天上班突然灵机一动,可以根据Y轴比例和当前良率的值来设定它的对应位置,虽然麻烦点。

  ****以上就是我在开发过程中遇到的一个Echart折线图不等距百分比率问题,下面会跟大家讲一下我的思路和相关算法。

解决思路

  根据上面出现的问题,下面我们就开始解决。

  在开始之前先给大家看一个刻度对比图:

在这里插入图片描述
  所以根据这个比值我们得到一个简单比例公式,即:

  当百分比为0~60%时,对应真实值为20,比例为1/3
  当百分比为60~100%时,对应真实值为80,比例为2

所以咱们要做的就是,把坐标点的位置通过这个比例来进行分配,算法如下:

	 //折线图坐标点算法
    function initPointData(pointData) {
        var baseNum = 20;  //基础数 0~60%那一段的真实值
        var returnPosition = 0;  //初始化返回的值
        if (pointData <= 60) {  //判断当前真实百分比是否<=60%
        
            returnPosition = pointData / 3; 
             // 通过比例来算出它的位置,例如:30% ,30/3 =10,
             它就在真实值10的位置,对应折线30%,其他小于60的如此
        } else if (pointData > 60 && pointData <= 100) {
        
            returnPosition = (pointData % 60) * 2 + baseNum  
            // 重点:如果高于60%,那么就对当前这个
            百分比取60%的余,再乘以它的比例2,再加上基础值20,那么就是高于60%以上的位置。
            例如: 75%,75%60 =15,15*2=30,30+20=50,那么75%其实是对应Y轴真实值50,其他也如此
        } else {
            returnPosition = 0;  
        }
        return returnPosition
    }

  现在大家应该都知道这个算法,接下来咱们来看看其他部分怎么实现:

1、定义option中的yAxis

yAxis: [{
                type: 'value',
                name: '良率',
                splitLine: {
                    show: true,
                },
                position: 'right',
                min: 0,  //一定要设置最小刻度
                max: 100,  //一定要设置最大刻度
                minInterval: 20, //这个可自己设置刻度间隔
                axisLabel: {
                    formatter: function (value, index) {  //Y轴的自定义刻度值,对应上图
                        if (index == 0) {
                            value = 0
                        } else if (index == 1) {
                            value = 60
                        } else if (index == 2) {
                            value = 70
                        } else if (index == 3) {
                            value = 80
                        } else if (index == 4) {
                            value = 90
                        } else if (index == 5) {
                            value = 100
                        }
                        return value+'%';
                    }
                },
            }],

2、设置option中的series参数(动态生成)

var oneData = [89.25, 92.94, 70.001, 97.55, 97, 92.74, 94];
var allData = [78, 86.55, 80.56, 86, 89.02, 92, 97.56];
    
 myChart1.setOption({
            xAxis: [{
                data: ['26日', '27日', '28日', '29日', '1日', '2日', '3日'],
            }],
            series: initItem(oneData, allData)
        });
    
 //初始化折线图
 function initItem(oneData, allData) {
        var dataItem = [{
            name: '一次良率',
            data: getData(oneData)
        }, {
            name: '综合良率',
            data: getData(allData)
        }]
        return dataItem;
    }
        
function getData(temp) {
        var jsonString = [];
        for (var i = 0; i < temp.length; i++) {
            var json = {};
            json.name = temp[i] > 100 ? 0 : temp[i];
            json.value = initPointData(temp[i]);
            jsonString.push(json);
        }
        return jsonString;
    }
    
	//折线图坐标点算法
    function initPointData(pointData) {
        var baseNum = 20;
        var returnPosition = 0;
        if (pointData <= 60) {
            returnPosition = pointData / 3;
        } else if (pointData > 60 && pointData <= 100) {
            returnPosition = (pointData % 60) * 2 + baseNum
        } else {
            returnPosition = 0;
        }
        return returnPosition
    }

  以上代码就是生成每个折线点的方法,代码其实很简单,大家可以参考~
  其他属性就没全部贴出,大家看以上部分代码即可。

最终效果如下:
在这里插入图片描述
3、弹窗显示tooltip属性设置

  这个tooltip属性是鼠标放上去显示的详细数值,这个也需要自定义,不然不能显示。

  代码如下所示:

tooltip: {
                trigger: 'axis',
                formatter: function (params) {
                    var result = ''
                    var axisName = ''
                    params.forEach(function (item) {
                        axisName = item.axisValue
                        var itemValue = item.marker + item.seriesName + ": " + item.data.name + "%</br>"
                        result += itemValue
                    })
                    var allResult = axisName + "</br>" + result
                    return allResult
                }
            },

  需要注意的是,这个的itemValue取值不能取真实的值,只能取之前的折线图坐标值,也就是位置。

总结

  以上就是关于不等距的解决方法,如果有更好的方法也可以互相交流。初次写博客,如有不足之处敬请各位指出,有什么好的建议也可提出,共同学习共同进步!

附加

  一下节,我会在此问题基础上解决另外一个刻度问题,让Y轴最低刻度随数值动态变化。比如,取当前数组最小的值,向下取余整数,就为Y轴刻度的最低值。

来自一个被编程耽搁的健身教练编写于公元2020年3月25日

  • 12
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值