setOption - 图表配置变更

发布于: 5/16/2022 阅读大约需要2分钟

https://echarts.apache.org/zh/api.html#echartsInstance.setOption

代码解析

setOption<Opt extends ECBasicOption>(option: Opt, notMerge?: boolean, lazyUpdate?: boolean): void;
setOption<Opt extends ECBasicOption>(option: Opt, opts?: SetOptionOpts): void;
setOption<Opt extends ECBasicOption>(option: Opt, notMerge?: boolean | SetOptionOpts, lazyUpdate?: boolean): void;
setOption<Opt extends ECBasicOption>(option: Opt, notMerge?: boolean | SetOptionOpts, lazyUpdate?: boolean): void {
  // 是否是主线程
  if (this[IN_MAIN_PROCESS_KEY]) {
    if (__DEV__) {
      error('`setOption` should not be called during main process.');
    }
  return;
  }
  // 实例是否被销毁. 是否调用过 dispose()
  // https://echarts.apache.org/zh/api.html#echarts.dispose
  if (this._disposed) {
    disposedWarning(this.id);
    return;
  }

  let silent;
  let replaceMerge;
  let transitionOpt: SetOptionTransitionOpt;
  // 第二个参数是SetOptionOpts的情况, 读取参数
  if (isObject(notMerge)) {
    lazyUpdate = notMerge.lazyUpdate;
    silent = notMerge.silent;
    // 待替换模块
    replaceMerge = notMerge.replaceMerge;
    transitionOpt = notMerge.transition;
    // 将参数替换为option中的notMerge
    notMerge = notMerge.notMerge;
  }

  // 设置主线程flag为true
  // __flagInMainProcess
  this[IN_MAIN_PROCESS_KEY] = true;

  // 是否没有_model 或者 设置了notMerge
  if (!this._model || notMerge) {
    // option 管理器
    const optionManager = new OptionManager(this._api);
    const theme = this._theme;
    // 新实例化全局模型对象并赋值给 echarts 的 _model
    const ecModel = this._model = new GlobalModel();
    ecModel.scheduler = this._scheduler;
    ecModel.ssr = this._ssr;
    ecModel.init(null, null, null, theme, this._locale, optionManager);
  }
  // 全局模型设置option
  this._model.setOption(option as ECBasicOption, { replaceMerge }, optionPreprocessorFuncs);

  const updateParams = {
    seriesTransition: transitionOpt,
    optionChanged: true
  } as UpdateLifecycleParams;

  // 如果设置了lazyUpdate
  if (lazyUpdate) {
    // __pendingUpdate 存储参数
    this[PENDING_UPDATE] = {
      silent: silent,
      updateParams: updateParams
    };
    // __flagInMainProcess
    this[IN_MAIN_PROCESS_KEY] = false;
  
    // `setOption(option, {lazyMode: true})` may be called when zrender has been slept.
    // It should wake it up to make sure zrender start to render at the next frame.
    // 获取echarts实例的zrender实例, 并调用 wakeUp() 进行开始动画
    this.getZr().wakeUp();
  }
  else {
    // 普通情况, 非lazyUpdate
    try {
      prepare(this);
      updateMethods.update.call(this, null, updateParams);
    }
    catch (e) {
      // 还原字段
      this[PENDING_UPDATE] = null;
      this[IN_MAIN_PROCESS_KEY] = false;
    
      throw e;
    }
  
    // Ensure zr refresh sychronously, and then pixel in canvas can be
    // fetched after `setOption`.
    if (!this._ssr) {
      // not use flush when using ssr mode.
      // 立即触发zrender 的 refresh 和 refreshHover 所标记的重绘操作。不要在ssr模式使用。
      // https://ecomfe.github.io/zrender-doc/public/api.html#flush
      this._zr.flush();
    }
    // 还原字段
    this[PENDING_UPDATE] = null;
    this[IN_MAIN_PROCESS_KEY] = false;
  
    // 刷新等待队列 _pendingActions
    flushPendingActions.call(this, silent);
    // 调用更新事件, 即, 非silent情况下触发 'updated'
    triggerUpdatedEvent.call(this, silent);
  }
}

流程梳理

不能在主线程调用 echarts.__flagInMainProcess