原生 JS+CSS+HTML 实现时序图的方法

2020-04-24 19:26:51易采站长站整理

之前本人使用React + AntDesign 实现了一个简单的时序图,但是后来有了更复杂的需求,并且要求同时展示2000个任务的展示,这就涉及到了性能问题,本人先使用React+antd+ts实现了一个基本满足下面需求的demo,但是react的渲染机制造成了较大的性能问题,利用chrome自带的Performance,测试发现demo的首次渲染高达10s以上,并且后续的操作也会使整个页面非常卡。经过思索后决定使用原声js+css+html去实现,因为原声js下性能是最优的。下面先来说说新版本的需求:

左侧以树形结构展示任务,可折叠
右侧展示任务运行所耗时间的长度
需要用线条链接任务之间的关系
右侧可缩放查看详细的任务状态
缩放时图形保持以鼠标为中心向两端成一定比例放大,放大时里面的文字描述不受影响
图形缩放时表示任务耗时的时间以及坐标需要跟随图像放大的比例进行相应变化
鼠标在时序图上移动时出现一根线条提示当前的时间以及信息

效果图

图一:


 

图二:

实现难点

鼠标缩放,x轴的缩放方式

鼠标缩放产生时序图X轴的缩放。时序图的缩放,在这里提供三种思路:

做数据截取,按照一定的算法截取前后的数据,然后重新渲染整个页面
利用css3的scaleX对时序图的dom做缩放
实际改变时序图dom的width,里面的任务运行的长度,连接线条的长度,任务运行预计需要的时长都以百分比显示。

三种思路的优缺点:

优点:不需要去操作dom的css属性,之间重新渲染,比较方便。缺点:对于使用dom重绘,耗费性能严重,大量任务渲染时性能很慢。
优点:只需改变dom的css,加载快,较流程。缺点:计算麻烦,使用过scaleX的小伙伴会发现当我X轴放大时垂直连接线会变宽,字体会横向拉伸,都需要去反向缩小。
优点:加载快,很流畅,一次计算好元素所占宽度的占百分比,后面的操作都不需要去计算。缺点:使用百分比计算会有一定误差,放大到一定程度会看的出来。(综合考虑,本人采用的是第三种)


// 计算宽度百分比的函数
// endTime: 任务的结束时间
// startTime: 任务的开始时间
// maxTime: 所有任务结束时间最大的值
// minTime: 所有任务开始时间最小的值
// time: 所有任务开始时间与结束时间的排序 升序
// task_width: 任务的长度、水平连接线的长度、垂直连接线的left值