经历过H5接入echart 的需求后,同时小程序端使用
taro
开发,本以为小程序接入图表不是很难的事,结果硬生生躺了一次坑,上线之后决定总结一次,记录开发期间遇到的各种问题以及解决办法,方便自己后续迭代并帮助后来者避开风险。只有在面临bug和上线的一番对抗和内心挣扎之后,才会理解经验是多么宝贵。
本地下载 ec-canvas
文件过大(超过500k),微信开发者工具无法编译上传的问题
按照官网的指示,下载 ec-canvas
包引入工程目录,github版本的 echart.js 文件大小为 700k,虽然本地可以成功引入并绘制,但最后一步上传却让人大失所望,超过微信单个文件大小限制500k。
此时官网按照指示,在线定制 echart.js 内容
定制好后,成功将文件大小控制在363k,导入工程目录替换原文件。然而经过taro编译压缩过后,原来的图表变成一片空白,内心崩溃。
经过几番折腾过后,终于找到了解决办法: 在官网定制时不能勾选代码压缩,下载源文件后去专业的压缩网站压缩代码,再导入工程目录
此时上传问题迎刃而解。出现这个问题的原因在于,taro在编译 echart.js 时会将部分注释的内容进行编译导致代码报错,报错截图为证:
微信原生 canvas 层级最高问题,遮挡底部悬浮菜单和弹窗
在经过一番挣扎过后,终于可以画出满意的折线图了,微信开发者工具中一切风平浪静,上传到体验版后,傻眼了,弹窗和底部悬浮 button 都被图标盖住了,这下改动就大了。于是傻乎乎的把底部button和弹窗的容器改成了 cover-view,再到真机上,渲染一个列表就卡的不行,更不谈样式的各种不兼容。看来cover-view 虽然强大可也不能滥用啊!
经过一番思索,决定在渲染完成后,启用 echart 的保存图片功能,将绘制完成的 canvas 保存成图片。
const ecComponent = this.$scope.selectComponent('#deal-chart-dom-area');
if (!ecComponent) {
return;
}
ecComponent.canvasToTempFilePath({
success: res => {
this.setState({ img: res.tempFilePath });
},
fail: res => console.error('canvasToTempFilePath', res)
});
可问题是,图片虽然可以解决层级问题,但失去了图表的可交互性,无法两全其美,如果能在初始状态echart渲染图表,渲染完成后将canvas转换成图片保存下来,在有弹框时将 canvas 切换成图片,就可以解决这个问题。实际效果看上去还可以接受,剩下的问题就是控制图片和图表的切换,工作量应该会大幅减少。
安卓真机上无法保存图片的问题
生产环境中,在部分安卓手机上保存图片会失败,查找原因,将下部分代码
ctx.draw(true, () => {
wx.canvasToTempFilePath(opt, this);
});
加100ms延时,改成
ctx.draw(true, setTimeout(() => {
wx.canvasToTempFilePath(opt, this);
}, 100));
重新编译,图片就能正常保存啦!
总结来看,微信小程序做图表不是一个很好的方式,从长期看,建议使用h5承载图表业务,代码的健壮性和扩展性能更加可控。
以上是开发过程的不完全记录,也是个人的解决办法,可能有不妥之处。如果有更好的微信图表方案,欢迎留言探讨!