Echarts 源码解读 一:zrender源码分析1var zr = zrender.init(document.getElementById(‘main‘));

2021SC@SDUSC

因为Echarts是基于zrender进行实现的,所以解读echarts源码前,首先要对zrender有基本的了解。

zrender是canvas的一个类库,zrender是基于canvas实现的。

目录


zrender的src文件夹

文件夹:

animation动画相关

contain包含判断

core核心代码,包含一些工具(util.js)、事件(event.js)、唯一ID(guid.js)、矩阵运算有关(matrix.js)等

dom dom事件有关

graphic 图形有关,shape文件夹下就是各个图形的js文件

mixin混入模式要混入的函数

tool工具函数,包括颜色工具(color.js)、path工具(path.js)和转换工具(transformPath.js)

vml IE中的画笔,vml解释

全局文件:

config.js配置文件

Element.js元素文件,作为zrender最基本的元素

Handle.js C层,控制层

Layer.js图层管理

Painter.js V层,视图层

Storage.js M层,数据管理层

zrender.js入口

zrender整体架构
zrender 采用MVC 封装

 

M为Model数据层,V为View视图层,C为Controller控制层:

Storage(M):Storage为zrender中的Model层,它主要进行图形数据的增删改查(CRUD)操作;
Painter(V):Painter为zrender中的View层,它主要对canvas元素的生命周期进行管理,渲染视图以及控制更新等。定义了addHover、setBackgroundColor等方法;
Handler(C):Handler为zrender中的Controller层,它主要实现事件交互处理,实现完整dom事件的模拟封装。
图形
处于graphic文件夹下,zrender定义了一系列图形,供外界调用,包括圆形、矩形、心形、扇形、多边形、折线等,echarts通过调用zrender定义好的图形,可以很便捷地完成图表渲染。

Displayable
Displayable.js为Path、Text等的基类,继承自Element,定义了setStyle、useStyle等方法

TEST
文本,继承自Displayable,调用了helper/text.js中的renderText方法进行绘制。主要代码如下:

export function renderText(hostEl, ctx, text, style, rect, prevEl) {
style.rich
? renderRichText(hostEl, ctx, text, style, rect, prevEl)
: renderPlainText(hostEl, ctx, text, style, rect, prevEl);
}
文本分为富文本以及普通文本进行分别渲染,它们均通过调用canvas的ctx.fillText或ctx.strokeText 等api进行文本渲染,具体实现可以查看helper/text.js文件。

Style
图形的样式文件,定义了基本的样式属性,以及样式set、clone以及判断等方法。

Path
path为图形的基类,继承自Displayable,定义了buildPath、getBoundingRect、setShape等方法,其包含this._style属性即为Style对象实例。

Shape
shape文件下存放着zrender定义的图形文件,扩展自Path。

Circle
圆形,通过调用Path.extend方法进行扩展,重写了buildPath方法,buildPath调用了canvas api:ctx.arc进行圆形的绘制,主要实现代码如下:

buildPath: function (ctx, shape, inBundle) {
if (inBundle) {
ctx.moveTo(shape.cx + shape.r, shape.cy);
}
ctx.arc(shape.cx, shape.cy, shape.r, 0, Math.PI * 2, true);
}
入口(zrender.js)
初始化
init调用:

var zr = zrender.init(document.getElementById('main'));
源码:进入init方法,A、初始化Zrender,B、将其存入Zrender实例map索引

zrender初始化,不让外部直接new是为了提供全局可控同时减少全局污染、降低命名冲突的风险

var instances = {}; // ZRender实例map索引
var zrender = {};
zrender.init = function(dom, opts) {
var zr = new ZRender(guid(), dom, opts);
instances[zr.id] = zr;
return zr;
};
构造函数
可以在构造函数中,看到MVC的管理机制

// zrender.js
/**
* ZRender接口类,对外可用的所有接口都在这里!!
* storage(M)、painter(V)、handler(C)为内部私有类,外部接口不可见
* 非get接口统一返回支持链式调用~
*
* @param {string} id 唯一标识
* @param {HTMLElement} dom dom对象,不帮你做document.getElementById
*
* @return {ZRender} ZRender实例
*/
function ZRender(id, dom) {
this.id = id;
this.env = require('./tool/env'); // 浏览器环境识别用
this.storage = new Storage(); //shape数据CURD管理
this.painter = new Painter(dom, this.storage); //canvase元素生命周期管理,视图渲染,绘画,更新控制
this.handler = new Handler(dom, this.storage, this.painter);//事件交互处理,实现完整dom事件模拟封装
// 动画控制
this.animatingShapes = [];
this.animation = new Animation({
stage : {
update : getAnimationUpdater(this)
}
});
this.animation.start();
}
每次绘图前,都清空画布

// zrender_demo.html
zr.clear();
zrender执行清空时,清空storage后,再执行painter的clear()方法

// zrender.js
/**
* 清除当前ZRender下所有类图的数据和显示,clear后MVC和已绑定事件均还存在在,ZRender可用
*/
ZRender.prototype.clear = function () {
this.storage.del();
this.painter.clear();
return this;
};

posted @ 2021-11-25 18:11  威武的大萝卜  阅读(392)  评论(0编辑  收藏  举报