版本:V5.3.2
背景
ECharts底层渲染引擎为zrender。zrender
的默认渲染器为canvas
。但同时支持svg
渲染。本文通过一个简单的饼图示例来简单探究下echarts
或zrender
是如何实现同时支持canvas
和svg
渲染的。
饼图、折线图、柱状图、矩形树图等图表都可能采用标签来展示详细数据。但在大数据量下针对不同的图表可能存在(包含但不仅限)如下情况:
面对上述情况应该如何应对?我们尝试从ECharts的源码中来一探究竟。
饼图的label
防重大致步骤如下:
折线图与矩形树图则相对简单,只经过了对标签的简单布局以及LabelManager.ts中对仍重叠的标签的隐藏处理,即饼图防重中的步骤7。
静态图标主要用于传达信息、动效则赋予了它更多的功能。例如:引导用户进行下一步操作、将用户的目光聚焦到重要的信息上、使用户的操作得到更好的反馈、提升产品的品牌形象。
SVG
元素Path
标签的d
属性同样可以使用transition
来实现平滑过度、本文简单介绍如何使用transition
来平滑过度path
标签的路径,有那些限制,以及如何解决。
ECharts
在大规模数据渲染下性能表现优秀,基于现有的知识体系我们猜测可能应用了:
canvas
性能优化解决方案。ECharts
应用了哪些性能优化方案?如何去实现的?我们根据宿爽 - 16毫秒的挑战_图表库渲染优化尝试从ECharts的源码中来一探究竟。
使用ECharts
的lazyUpdate
模式多次执行setOption
,仅对最终的option
渲染一次。ECharts
是和React
一致自己单独实现了一套任务管理机制,还是基于setTimeout
或Promise
做的异步渲染?我们尝试从ECharts的源码中来一探究竟。
代码挺好跟,但涉及到Even loop
深入理解起来会相对困难。简单说明就是采用lazyUpdate
更新图表的话,图表会在下一个 animation frame
中更新而在下一个animation frame
之前执行的setOption
会根据notMerge
参数来判断是合并option
还是采用最后一次option
直接渲染。
Canvas
作为一个单独的DOM
元素,内部是用一维数组来存储的像素数据,也就意味着无法和HTML
一样直接对其内部的元素做事件绑定。如何去做Canvas
内部的事件响应以及,一旦Canvas
中的元素多起来如何去做性能优化。我们尝试从ECharts
的源码中来一探究竟。
这里放了一个具有一千个元素(扇形)的饼图,我们通过该示例来跟踪源码探究
ECharts
是如何实现的。
总体来说ZRender
对于Canvas
内部的事件判断的方式为单独构建了一套事件系统。对于每一个图形,ZRende
会检测一个事件的位置坐标(x, y)是否在图形的包络盒中,对于Path
类的图形ZRende
会在命中包围盒后多做两次判断是否命中多边形的边框或内部区域。ZRende
对于巨量元素的事件判断在性能上的优化方式为构建外围包围盒,在命中包围盒后再判断坐标是否再图形内部减少了大量计算。
这里记录一些基于type-challenges的一些挑战题目来学习的
typescript
type
笔记
1 | // 以下这三个类型均来源于 '@type-challenges/utils' 这些类型将会在接下来用于判断挑战的结果。这里简单介绍以下这三个类型 |