只要使用过react-native绘制过图表的人都知道,react-native-cahrts-wrapper是github上chart方面非常棒的组件库,这这个组件库里面RN开发者可以很轻松的找到各种想要的图表,实乃居家旅行,rn开发的利器。
附上github地址:https://github.com/wuxudong/react-native-charts-wrapperhttps://github.com/wuxudong/react-native-charts-wrapper
问题背景:
首先,在项目中有一个起着关键功能的图表,这个图表是一个折线图,这个折线图的数据源是不断刷新的,但是刷新的频率不定,可能是1s刷新一个数据,也可能是两秒刷新一个点。那么折线图的样子应该很容易想象,就不截屏了,现在的问题是:我们的折线图一屏的起点默认就是第一个x轴坐标,这就很不好,因为在这个折线图中的数据在使用后期会形成一个堆积,导致最后的折线图完全不具备可读性,所以我第一个要解决的问题就是如何使得折线图能够滚动起来。
你可能会说,当一屏中的数据堆积起来后,可以直接通过手指对图表进行伸缩使得图表前后滑动,没必要再写什么解决方案了啊。
没错,react-native-charts-wrapper确实提供了通过手指对图表进行水平和竖直方向的伸缩,我在后面的解决方案中也使用了这个方法,那我们什么还要做这个?
要知道,当用户一开始怀着一定的需求进入你的APP,他一定是急切的想要找到他需求的解决方法,如果你能够妥善解决,才有可能让这个用户长期使用你的APP,如果的你操作过于冗余,我们很有可能会丧失这个用户,就拿这个问题做例子,我们为什么要做成一进入图表页面就直接默认滚动,而不是等着用户对这个他根本不知道怎么使用的APP中的图表进行手动伸缩,这是很简单的道理,市面上有这么多同款的APP,用户凭什么选择你的APP,具有图表的工具类APP就要有简单操作的觉悟,只要能留住用户,在后续的改版中,再对操作进行精细化处理也不晚。
第一个问题:如何使得图表能够自动滚动
首先,对于这个问题,我查阅了该组件库在github上面的说明文档,文档也不是很多,当然也不会很详细,一开始什么都没有看出来,直到我查看这个组件库的issues我看到了一个属性似乎可以解决我的问题:Zoom。
一开始当我把这个zoom属性写到我的Linechart中时,我发现,当scaleX、sacleY、xValue以及yValue不为默认值时,他们对图表会进行一个缩放,而且是既可以放大也可以缩小,这就给了我很大的启发:我是不是可以直接利用这个伸缩来实现跟手动滑动一样的效果,接着我发现这个操作是可以实现的,只不过当scaleY不为默认值后,伸缩到的y坐标值会不可见,所以我将scaleY设置为默认值,这样就可以只伸缩x轴以来达到间接性的自动水平滑动效果,做完这些我喜滋滋的以为我的任务完成了,但是事情并未简单的结束。
上面的上午做完的任务,下午我闲着没事我就打开项目调试,结果我发现,图表根本加载不出来,直接导致了软件宕机,只有重启软件才能重新回到页面。我心想,坏了。赶紧打开vscode调试代码,一调试不要紧,调试完我就傻了眼,我才知道了原因:
上午写代码进行调试时,我直接使用的是保存刷新,也就是局部刷新APP,而下午启动APP是刷新APP整体,上午写的那一行代码中的yValue导致了整个程序的崩溃,这是万万想不到的,而导致yValue不能使用的原因可能是我的图表x轴并非数字,而是进行了format处理的时间,反正不知道咋回事,yValue属性不能在刷新整个APP后第一次使用图表时出现在图表属性中,我心想,这还好,直接把这个属性去掉不就成了,结果出乎我的意料,当Linechart中不包含yValue属性后,图表不能跟上午一样进行伸缩了,这可就坏了,也引出了下一个问题。
第二个问题:如何能够在一开始不放入yValue属性的情况下,使得图表能够伸缩
其实,这个时候我就已经知道该怎么办了,不就是一开始不能放入yValue吗,我等着图表刷新一段时间后我在刷新Zoom属性不就可以解决这个问题了,嘿嘿,充分看完这个组件库issue的我,确实解决了这个问题。
其实在Zoom属性中,对于我们这个应用场景来说,只有scaleX这个属性的值是有意义的,而其他的属性虽然不需要变动,但是保持固定值是必要的,
zoom: {scaleX: 1, scaleY: 1, xValue: 2},
这是一开始没有yValue的zoom属性,这种写法是不能进行缩放的,
zoom :{scaleX: 1.2, scaleY: 1, xValue: 200, yValue: 500},
这是后来需要对图表进行缩放时,替换的zoom属性,200和500都是为了在放大后显示屏幕能够紧跟最新刷新的数据设置的,而scaleX等于1.2就使得图表在x轴方向成功伸展,可以达到预期的目标。
至于我是怎么在图表运行之后自动启用刷新zoom属性的这个方法,看下面代码:
if (
(secondall1 - secondall == 40 && minuteall1 == minuteall) ||
(minuteall1 - minuteall == 1 &&
secondall1 + 60 - secondall == 40) ||
(hourall1 - hourall == 1 && secondall1 + 60 - secondall == 40)
) {
//启用刷新zoom的函数
}
secondall和minuteall是图表启动的时间,secondall1和mintueall1是当前图表刷新周期中获取的时间,只要距离启动时间为40秒,就会启动刷新zoom的函数。
我本以为我可以再次高枕无忧了,现实却又一次打了我的脸。
我发现:如果我只让启动40s后刷新zoom以来达到滑动x轴的目的,确实在图表数据更新的前期可以达到我的目的,但是随着图表数据的不断刷新,可视一屏不断向后滚动,我吃惊的发现了一个大问题:到了后期,我原先设计的40s一屏就慢慢变成了50s甚至是60s,这可是一个大问题,刷新的并不均衡。
第三个问题:如何能够让图表保持40s一屏的方式进行滚动
为了解决这个问题,我观察了好久图表的滚动到底为什么到最后会成60s,在看了n次整个过程后,我发现,图表更新的那个方向没有问题,但是,不知道为什么,一屏中最左边的滚动却想比右边的刷新跨度要小一点,就小这么一点,就导致了当数据堆积,一屏中x轴的范围扩大了很多。
一开始,我对于这个问题的解决方案是,在图表启动40s,也就是数据刷新了40s之后,调用以下方法:
resetZoom=(scale_switch)=>{
this.setState({
zoom :{scaleX: this.state.scaleX, scaleY: 1, xValue: 200, yValue: 500},
});
this.state.scaleX=this.state.scaleX+scale_switch;
}
在确认达到40s的判断语句中,我这样写:
if (
(secondall1 - secondall == 40 && minuteall1 == minuteall) ||
(minuteall1 - minuteall == 1 &&
secondall1 + 60 - secondall == 40) ||
(hourall1 - hourall == 1 && secondall1 + 60 - secondall == 40)
) {
let scale1=setInterval()//什么一大堆
}
就是在40s的判断语句中,我们写一个定时器,这个定时器每隔一个周期,就会调用一次resetZoom方法,从而进行x轴的伸缩。
可能有朋友会问:你对x轴进行伸缩干嘛,你需要解决的是前后滚动速度的不一致问题。
我这样说吧,我们已知靠近y轴那边的数据滚动速度慢,而我们又通过设置zoom属性的200和500固定了我们默认视野是在最右方,那么能够抵消x轴缩放的只有扩展x轴,通过resetZoom属性我们就可以通过定时器来周期性的对x轴进行扩展,从而使得一屏保持只有40s。
除此之外我还发现,图表越滚动到后面,它x轴收缩的速度就越快,那么要保持40s我们只能相应的加快x轴的扩展速度,这也是我为什么要写resetZoom这个可以传参的函数。
这个问题就不单列出来了,多设置几个判断时间的语句就成,而且我们为了保证不同时出现多个定时器,我们从第二个时间节点开始,每进入一个if判断,我们就取消上一个时间节点的定时器。
到此为止,我们的滚动是实现了,虽然确实是40s一屏,但是图表总感觉是一卡一卡的,因为x轴扩展的太过于剧烈了,啥啥都是问题。
第四个问题:如何使得图表滚动时更加的自然,而不是一卡一卡的
一开始对于这个问题,我感觉还是很好解决的,我直接把每一个时间节点的定时器周期跳到0.1秒,企图让用户看不出来图表进行了扩展,但是事与愿违,这样写不但使得x轴的扩展更加的明显且别扭,而且由于定时器调用过于频繁,软件后期会直接卡死。
完美的解决方案是:将各个时间点的判断写到图表控制刷新的定时器中,不知道这一步的小伙伴记得看我上一篇关于图表解耦的blog,只要判断在定时器中,我们在对时间点的判断中就不用再写定时器,直接就可以调用相应x轴扩展范围的resetZoom函数。
对了,还记得我的数据时不定期刷新的吗,所以在对时间点的判断中还要加入对是否在这个图表更新周期中有数据刷新进行限制,只有进行数据刷新的定时器周期才能调用resetZoom函数进行x轴的扩展。
就这样,当每一秒有数据刷新的时候,我们靠近y轴的那一方的线就会神不知鬼不觉的扩展一下,以来抵消图表原有的缺陷。
这篇文章写到这里就结束了,写了4530字,纯手敲,纯原创,求个赞不过分吧