Echarts项目源代码分析

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
            );
        }
    }
};

上一篇:组件


下一篇:Oracle之资源正忙和标记要终止的会话