作者简介 Kid 蚂蚁金服·数据体验技术团队
本文介绍如何从头绘制一个业务图表以及对于通用性上的一些思考。代码在最后也会给出。
要画图,当然是先找找看有没有能够直接拿来用的。我需要绘制的是一个类甘特图。主要是为了做时间基线上的任务耗时管理,并且能够与过往耗时进行对比。与传统的甘特图定义有些区别。长相上与甘特图类似。
找了 AntV,echarts,和 D3。AntV 和 echarts 都没有直接的甘特图。D3 上有一些甘特图,但是和我想要的功能区别还是挺大的。基于他们修改的代价应该比自己画的代价高。那么挑哪种技术绘图呢,canvas,svg 和 div。我的业务场景绘制的点不算多,而且 canvas 对于事件挺难处理的。svg 毕竟有 DOM 元素,一些 hover 效果我可以直接借用 antd 来做。最后选择了 svg。(其实之前没画过图,用啥都得学~)
- 图表绘制
- 上下滚动
- 漫游器控制左右滚动以及缩放比例
- 节点 hover 显示细节
组件的设计就如上图所示了。图表与 Y 轴区域做成一个整体,让图表上下滚动。由于 windows 上左右滚动很不好用,所以水平方向上没有做滚动,而是设置了漫游器进行滚动以及缩放的功能。
组件的数据流向很简单,用户传入初始化配置以及真实数据。大部分组件只是单纯负责渲染,只有漫游器会修改图表位置以及缩放的比例。然后图表和 X 轴会相应的显示对应区域。
结构和数据流向设计好,编码开发其实很简单了,不详述,自己看 github 上的代码吧。然后就是一些细节的打磨。
自己从头写的好处就是一些小细节可以打磨的舒服些
超出一定的比例之后按单双数隐藏了 X 轴的部分显示。其实既可以选择隐藏,也可以旋转一定的角度,自己做,随便定~
antv 和 echart 漫游器都是会抖动的,而且可拖拽区域都是只在漫游器内部。虽然 echarts 做了动画的优化,其实还是不太舒服。截个 antv 的效果好了。
我把漫游器设计成百分比的,所以滑动顺滑,而且滑动的时候事件加到了 document 上,可拖拽区域就变成整个页面了。
编码做完了,细节也打磨的差不多了。对于产品的可用性已经可以交差了。也 get 了 svg 画图的技能,可是,沉淀下了啥呢……别人会需要绘制一模一样的图么?感觉不太可能。仔细一想,自己做的东西复用性太差。那么问题来了,复用性差跟白做了有什么区别..
很欣赏<黑客与画家>里的一句话,“编程就跟画油画一样,永远没有完工的那一天,你只是不再画下去了而已”
在工程方面,可能复用性是自己一直以来比较忽视的点。但是其实思考复用性方面的问题,既是对你的设计以及代码质量的考验,也能为后续的工作提高效率。还能培养你面对问题的直觉,思考复用性其实就是在思考问题的共性。这一个个共性就是一个个点,一个个的点多了,你的知识结构才能被串联起来,形成一张网。
如何提高复用性呢?首先明确定义业务使用场景:这个图是为了做时间基线上的任务耗时管理,并且能够与过往耗时进行对比。至少让别人在相同需求的时候能够复用,但是能重用的可能性太小了,不行。
要不我降低二次开发的门槛?如果别人就想改一点图表的渲染,我是不是该支持定制化渲染。仔细想想感觉不用。因为图形绘制都改了,那离重画一张图也没啥区别,毕竟技术难度也算很高。为了增加这一点灵活性,要给组件加太多的复杂度了,而且拍脑袋决定哪里开放绘制肯定做不好。毕竟灵活性和复杂度是成正比的。为了得到一些的灵活性而需要付出的代价是非常需要权衡的。二次开发这样的事情交给 antV 来做更好。
那怎么办?再看看能不能抽象出有一些复杂度的可重用的部分。重新审视整个设计,可用性较强的是漫游器组件。也就是下图内红色虚线框的位置:
共用性的理由也很充分,毕竟 windows 上左右拖拽不方便是事实,图表配上漫游器是正常的能力,而且 echarts 和 antv,漫游器都没有单独提供。
想明白了,做其实并不难。花些时间将漫游器的业务逻辑摘干净。将依赖全部以参数方式注入。然后定义好对外的接口,想想如何降低使用者的门槛。这个过程其实很能提高你的代码质量。你会抱怨自己为什么最开始写的时候没有解耦他们。可能更好的方式不应该是做完了之后进行抽象,而是设计阶段就能够意识到这是个通用能力而在设计层面就解耦掉。
具体的漫游器我也抽成了一个组件,如何使用可以参照我写在 github 上的 demo。我抽成了几个装饰器和一个组件,感觉已经无力再抽了,如果有好的思路能够把他们合到一起的话欢迎告知我。
文章主要是分享如何手工画一个自定义的图表,以及在这个过程中如何提高组件复用性来沉淀通用能力。更多的是分享下做业务组件应该去思考的角度,建议大家培养这样的习惯。毕竟习惯这种东西很可怕,我们可以先培养出一些习惯,然后等着习惯来推动你就好了。最后放上代码地址,图表地址和漫游器地址。