
highcharts: 问题案例
背景
在项目中使用highcharts是很容易的,移动端也适配的不错,按照官网教程即可。但是在移动端,由于手机端屏幕太小,需求方希望可以弄一个全屏图,把手机横过来观察曲线。
正常:
竖过来:
很容易想到的一种实现方法:设置曲线container的宽为屏幕的高,高为屏幕的宽,然后给曲线的container加一个transform:rotate(90deg),就能够实现竖屏了。
这样看起来没问题,但是当需要展现tooltip的时候,会发现tooltip不好使了。表现出来的现象是:当用户用手指延着曲线的x轴移动时,tooltip并不会跟着手指移动。
仔细观察会发现,tooltip的移动,还是根据手指在屏幕上移动时的【横坐标】来的。
开始尝试解决问题
经过查阅highcharts文档,发现chart.inverted可以实现x轴和y轴的反转。试了一下这个配置,发现并不是想象中那么理想,主要原因为:
1、y轴在屏幕下方,但我们需要的是y轴在屏幕上方。而y轴的位置不那么好调整。
2、tooltip也需要我们单独进行旋转。但是旋转后,手指touchmove时,tooltip适配会出问题,有时候会跑到曲线外面去,无法控制。并且由于是svg画图,tooltip本身的transform-origin的选择就是一个比较蛋疼的问题。
查阅了highcharts其他的api,并且上git搜了搜issue,但是并没有这个问题的解决方法。本来想放弃highcharts, 转投echarts的, 但在echarts的issue里发现很多人遇到了这个问题,但官方直接给列为了bug, 还不知道什么时候可以修复。最后还是考虑使用highcharts。
没办法,改源码吧
由于大概知道问题产生的原因:图表竖过来后,应该用触摸事件的纵坐标而不是横坐标来作为表格内的横坐标。改源码应该挺快的。
项目是用通过npm安装的highcharts, 首先根据highcharts的package.json可以看到,引用的入口文件为:highcharts.js
这个文件是压缩过的,它对应的源代码文件为:highcharts.src.js
结合源代码文件和浏览器调试,发现在用户滑动手指是,进入了下面的逻辑:
一切都在这个touch函数里。继续往下看:
这里的normalize比较关键,因为产生tooltip表现不符合预期的原因应该就是:旋转时,由于图被竖过来了,需要使用触摸事件的纵坐标来表示触摸的【横坐标】,但highcharts依然采用了事件的横坐标。继续看看normalize的内容。
按照这个思路,找到入口文件highcharts.js里对应部分的代码,进行修改。修改完成后,发现tooltip的表现符合预期了。
经过测试, 图表的其他基本功能正常。之前还担心这样会不会影响lengends的点击等。后来想了一下,由于是svg画图,所有点击事件应该都是直接绑定在元素上的,而不是像canvas一样强依赖坐标,所以不会影响。这也是为什么在echarts下进行rotate, lengends的交互也会受影响的原因。
由于highcharts的功能太多,这样的源码修改功能对其他的功能有无影响,还不能完全确定。待后续继续补充。
