2021SC@SDUSC
setOption调用后echarts操作流程
回归setOption方法的调用,echarts.js的setOption方法的主要代码如下:
echartsProto.setOption = function (option, notMerge, lazyUpdate) {
if (__DEV__) {
assert(!this[IN_MAIN_PROCESS], '`setOption` should not be called during main process.');
}
var silent;
if (isObject(notMerge)) {
lazyUpdate = notMerge.lazyUpdate;
silent = notMerge.silent;
notMerge = notMerge.notMerge;
}
this[IN_MAIN_PROCESS] = true;
if (!this._model || notMerge) {
var optionManager = new OptionManager(this._api);
var theme = this._theme;
// 初始化model
var ecModel = this._model = new GlobalModel(null, null, theme, optionManager);
ecModel.scheduler = this._scheduler;
ecModel.init(null, null, theme, optionManager);
}
// 调用GlobalModel中的setOption方法
this._model.setOption(option, optionPreprocessorFuncs);
if (lazyUpdate) {
this[OPTION_UPDATED] = {silent: silent};
this[IN_MAIN_PROCESS] = false;
}
else {
// 准备数据
prepare(this);
// 更新视图
updateMethods.update.call(this);
...
}
};
在调用globalModel.setOption方法之后,echarts通过调用
updateMethods.update.call(this);
进行视图更新。
update()方法中调用了render方法进行视图渲染,render方法主要代码如下:
function render(ecIns, ecModel, api, payload) {
renderComponents(ecIns, ecModel, api, payload);
each(ecIns._chartsViews, function (chart) {
chart.__alive = false;
});
renderSeries(ecIns, ecModel, api, payload);
// Remove groups of unrendered charts
each(ecIns._chartsViews, function (chart) {
if (!chart.__alive) {
chart.remove(ecModel, api);
}
});
}
render方法分为renderComponents(渲染Component)以及renderSeries(渲染series)两大部分,
renderComponents方法中通过each遍历调用component下的render方法
renderSeries方法在echarts3.0中也是通过each遍历调用series下的render方法,在4.0版本之后,便将控制渲染的逻辑交给了scheduler调度器进行处理,通过调用charts中的reset方法进而调用series下的render方法,主要代码如下:
function renderTaskReset(context) {
var seriesModel = context.model;
var ecModel = context.ecModel;
var api = context.api;
var payload = context.payload;
// ???! remove updateView updateVisual
var progressiveRender = seriesModel.pipelineContext.progressiveRender;
var view = context.view;
var updateMethod = payload && inner(payload).updateMethod;
var methodName = progressiveRender
? 'incrementalPrepareRender'
: (updateMethod && view[updateMethod])
? updateMethod
// `appendData` is also supported when data amount
// is less than progressive threshold.
: 'render';
if (methodName !== 'render') {
view[methodName](seriesModel, ecModel, api, payload);
}
return progressMethodMap[methodName];
}
var progressMethodMap = {
...
render: {
forceFirstProgress: true,
progress: function (params, context) {
context.view.render(
context.model, context.ecModel, context.api, context.payload
);
}
}
};