需求分析
需要实现记录宝宝生长状况的功能,本次的成长曲线即用户记录的数据可视化,包括:身高-年龄、体重-年龄、睡眠时长-日期、睡眠规律-日期四条曲线,3张折线图 + 1张自定义(Echarts的学名)
睡眠规律视觉稿与UI大致样式
其中身高与体重的折线图需要有参考线,参考线的数据来源是产品提供的excel
参考线间的区域需要有颜色填充
初步调研
参考资料
- echarts for weixin(附带小程序体验)
- echarts官方文档
- echarts官方实例
- 医生端小程序
官方有一个自定义实例与本次实现目标很像,乍一看x/y轴倒一下即可,好像不难
初步调研后难点list:
- 图表拖动的交互实现
- 折线间区域的颜色填充
- 图表UI细节涉及的配置项过多
- 数据处理的工作量较大
技术方案选择
- 小程序
- H5
觉得在医生端小程序上跑的效果还不错,试着跑了几个demo,发现效果还可以,滑动交互都有现成案例,决定用小程序原生开发。
开发历程
首先是杂七杂八的顶部tab与无数据,页面跳转等乱七八糟东西弄好,最后开始画图
0.后端同学先开发,约定数据结构
- 对图表研究的还不够彻底,我自己还没有搞清楚最后需要的是什么样的数据格式
- 管理后台基于antd pro,使用另一套图表库,相同的呈现,数据格式可能不同
最终约定了“人可读”的数据结构,并自己处理参考线的数据。
1.把图大概样子画出来
参考echarts for weixin的实例,将引用的库copy到项目中,开发工具上正常,过不了编译,微信有包体积大小限制(目前是2MB),将echarts压缩过之后,正常编译。
上线之前,可以按需定制一个echarts的生产版本,官方的下载地址
图出来了,真机预览页面滑动的时候,内容会与图表有重叠,原因是这里的布局顶部fix,图表包含在scroll-view中,小程序的canvas文档提到这一点。
2.图表初始化
组件
<ec-canvas wx:if="{{!isDisposed}}" id="mychart-dom-bar" canvas-id="mychart-bar" ec="{{ ec }}"></ec-canvas>
官方的图表初始化,在init的时候就传入配置,对于异步获取的,通过lazyload选项,来初始化,医生端小程序则是自己实现了一个发布订阅。
3.数据映射到视图
配置项,坐标轴的type
这里重点说一下value轴和category轴的区别
如何理解value轴是连续数据,category是离散的类目数据这句话?
就拿数学中常见的直角坐标x轴来举例子
比如说图上蓝色的标记代表了1.5, 3.3两个点,连续数据可以理解为数学中的坐标轴,(-∞,+∞)之间的任何值都可以放在轴上
类目轴的区别在于限制了坐标轴的值,只能出现限定的几个值。
这是官方的一个折线图实例,x轴上只有['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
这七个值,一旦限制好了这些category,就一定只会出现这些category,Mon与Tue之间想要有值插进来是不可能的。
轴的选择非常关键,直接决定了配置项的数据结构。
来看身高的折线图,除了用户记录的成长曲线外还有四条参考线,参考线的数据是以月为单位,而记录的时间是天为单位。
这里的实现思路是将天转化成月,比如说15天在轴上对应的就是0.5个月,使用dayjs
来处理日期的计算。
4.自定义图表
官方针对自定义有专门教程,大概就是渲染函数自己去写,数据->像素由开发者来控制,一些细节处的坐标计算不是很好理解,可以自己去量,将加减关系试出来
function renderSleepLawItem(params, api) {
const start = api.coord([api.value(0), api.value(1)]);
const end = api.coord([api.value(0), api.value(2)]);
const width = api.size([0, 1])[0] * 0.2;
const rectShape = echarts.graphic.clipRectByRect({
x: end[0] - (width / 2),
y: end[1],
width: width,
height: start[1] - end[1]
}, {
x: params.coordSys.x,
y: params.coordSys.y,
width: params.coordSys.width,
height: params.coordSys.height
});
return rectShape && {
type: 'rect',
shape: rectShape,
style: api.style()
};
}
5.画图流程抽象与优化项
- 画图流程的抽象
- echarts单例切换配置
- 配置缓存
- 按需创建
- 卸载(review时候提出来的,一开始并没有考虑到)
6.图表切换的问题
- 上一张图的东西还保留在图上,调用echarts实例的clear方法,再重新传入配置
- 带上tooltip时候,切换内部报错,采用多实例实现
- 多实例切换又出现新的问题,卸载不了,模板代码通过循环的方式去写就报错,需要将代码重复多次
7.关于折线间颜色填充的补充
只有当设置了stack即数据堆叠的时候才能有这种效果
经验与感想
- 微信小程序的分包
- 微信小程序原生组件的限制
- 真机看效果
- echarts可以在官网按需定制
- 折线图轴的选择(非常重要!!!)
- 乱七八糟配置项不要研究,扫一眼,去看社区图例,针对问题搜索
- 不建议用原生小程序实现复杂度过高的图表
感想
- 分清主次,先把主体功能实现
- 复杂case的初次开发也存在迭代的,将复杂任务拆解,细化,一步一步的去做优化与抽象
- 沉淀到文档,代码注释要有补充