微信小程序使用echarts图表时遇到的一些问题

798 阅读5分钟

最近做了一个微信小程序项目,项目中需要用到echarts的折线图来显示数据变化趋势,可选择7日或30日的数据,当选择30日时,可左右滑动查看图表数据。

针对左右滑动这个功能,首先想到的是将echarts放入scroll-view中,这样超出屏幕宽度的图表便可左右滑动查看了,然而事实并不是像你想象的那样美好,遇到了如下几个问题(这两问题目前只在ios系统有,Android正常,具体为啥呢,咱也没细研究):

1.iOS环境下,echarts图表不显示,显示空白

2.iOS环境下,echarts图表超出屏幕宽度时,无法左右滑动

3.折线图为双x轴,其中一个x轴为自定义轴,默认显示天气图表显示在图表上方,当设置图表左右滑动时,自定义x轴不会跟随图表滑动,导致x轴数据与图表数据对应不起来

首先对于第一个问题,在Android机上显示正常,所以找了很多办法解决。开始想的是渲染图表的时机问题,有可能是图表先渲染然后dom结构还未加载完成导致渲染图表失败所造成的。后来查看代码发现并不是这个问题,然后用手机真机调试发现,echarts图表的宽度超出其规定宽度导致了报错(报错截图暂且就不放了),后来修改echarts的宽度才重新渲染出来。

对于第二个问题,很多人第一反应是放在scroll-view里,在开发者工具上是可以实现滑动的,但是在真机上面发现不能滑动,发现官方早已说明

image.png 由于canvas是由客户端创建的原生组件,原生组件的层级是最高的,所以页面中的其他组件无论设置 z-index 为多少,都无法盖在原生组件上,无法进行遮挡实现一些特定的效果。 所以当你左右滑动时,scroll-view监测不到滑动事件,图表不会滑动。

针对这一问题,放弃了使用scroll-view来滑动图表的这一想法,转而用正常的view来显示图表,然后想到的是监听view的滑动事件,通过touchstart、touchmove和touchend事件,获取滑动的距离,来动态设置view的css来实现滑动的效果,但是这种方法需要判断边界,否则就会一直向一个方向滑动,从而影响使用体验,但是边界的判断不是那么很准确,所以也放弃了这种方法。

最后想起echarts图表里有dataZoom这一配置项可以设置内置滑块来实现图表的滑动

dataZoom: [{
                type: 'inside',
                show: true, // flase直接隐藏图形
                xAxisIndex: 0,
                left: '15%', // 滚动条靠左侧的百分比
                bottom: 'auto',
                startValue: 0,
                endValue: 7,
                throttle: 100, // 设置触发视图刷新的频率
                zoomLock: true,
                zoomOnMouseWheel: false, // 是否启用鼠标滚轮缩放
                moveOnMouseWheel: false, // 鼠标滚轮不能触发平移
                preventDefaultMouseMove: false // 是否阻止 mousemove 事件的默认行为
            }],

此种方法解决了图表无法滑动的问题

然后紧接着又遇到了第三个问题,其中一个需要滑动的图表为双x轴折线图,该折线图已在上面描述,达到的效果类似于如下这种方式

08b963a08eec63757a6d10261ce59352.gif

上方的天气图标为通过rich自定义的x轴,下方显示另一个日期轴。当滑动时,下方日期轴可以正常跟随图表滑动且数据可以与图表数据对应起来,但是上方自定义的x轴不会跟随图表滑动。

针对这个,首先想到的是dataZoom属性配置有问题,如果想要图表滑动关联多个x轴,dataZoom的xAxisIndex属性应为一个数组

dataZoom: [{
                type: 'inside',
                show: true, // flase直接隐藏图形
                xAxisIndex: [0, 1],
                // start: 0,
                // end: 22,
                startValue: 0,
                // 数据窗口范围的结束数值(一页显示多少条数据)
                endValue: 6,
            }],

但是设置完之后发现还是不能跟随滑动,后来才知道,你在滑动图表时,自定义x轴所自定义的index也会变化,需要重新设置自定义的x轴所展示的图片,具体代码为

   xAxis: [{
                    type: 'category',
                    boundaryGap: false,
                    triggerEvent: true,
                    axisLine: {
                        show: false,
                    },
                    axisTick: {
                        show: false
                    },
                    data: ["8-16", "8-17", "8-18", "8-19", "8-20", "8-21", "8-22"]
                },
                {
                    type: 'category',
                    boundaryGap: false,
                    triggerEvent: true,
                    position: 'top',
                    offset: -40,
                    axisLine: {
                        show: false
                    },
                    axisTick: {
                        show: false
                    },
                    axisLabel: {
                        interval: 0,
                        formatter: (value, index) => {
                            let distacne
                            weatherXdata.forEach((item, slot) => {
                                if (item == value) {
                                    distacne = slot - index
                                }
                            })
                            let richIndex = index + distacne
                            return '{' + richIndex + '| }'
                        },
                        rich: {
                            0: {
                                backgroundColor: {
                                      image:'https://mtoss.zhiquyun.cn/miniapp/images/common/晴.png'
                                },
                                height: 32,
                                width: 32
                            },
                            1: {
                                backgroundColor: {
                                    // image: 'https://d.scggqx.com/forecast/img/小雨.png'
                                    image: 'https://mtoss.zhiquyun.cn/miniapp/images/common/晴.png'
                                },
                                height: 32,
                                width: 32
                            },
                            2: {
                                backgroundColor: {
                                    image: 'https://mtoss.zhiquyun.cn/miniapp/images/common/雷雨.png'
                                },
                                height: 32,
                                width: 32
                            }
                        }
                    },
                    axisPointer: {
                        show: true, // 初始状态不显示

                    },
                    
                     data: ["8-16", "8-17", "8-18", "8-19", "8-20", "8-21", "8-22"]
                },
            ],

当然这里只是列举了两条数据作为展示格式,正常开发的时候,rich里的值需要根据需要接口里的数据动态赋值。

重点的是formatter里,当图表滑动时,对应的x轴的index会变化,例如当data数据为["8-16", "8-17", "8-18", "8-19", "8-20", "8-21", "8-22"],图表也是按照这个数据显示的,此时,“8-16”的index为0,“8-17”的index为1,“8-18”的index为2,... 以此类推。

当图表向左滑动一格时,此时图表显示的是[ "8-17", "8-18", "8-19", "8-20", "8-21", "8-22"],而此时此时,“8-17”的index变为0,“8-18”的index为1,... 以此类推,与rich中的图表对应不起来,所以需要动态更改日期所对应的index,按照如上formatter里的更改可正确使得日期与天气图标对应起来,实现整个图表左右滑动的效果。

至此所有的问题都已解决,新手小白遇到的一些问题以及解决办法,所以想记录一下以便能更好的提升自己,或许能够给遇到同样问题的同学们提供一种思考的方向和方法-_-.