initChart()

in src/common/Base.tsx [566:765]


  initChart() {
    // 合并默认配置项
    this.defaultConfig = this.getDefaultConfig();
    // 通过上下文传递的通用配置项 - 全局通用配置项
    const globalBaseConfig = this.context?.defaultConfig?.baseConfig;
    // 通过上下文传递的图表配置项 - 全局图表配置项
    const globalComsConfig = this.context?.defaultConfig?.[this.chartName.replace('G2', '')] ?? {};
    // 是否执行全局规则使用 - 默认为否(待规则完善后再默认开启)
    let globalRule = false;

    // 默认不传该配置项
    if (typeof this.props.force === undefined) {
      globalRule = !!this.context?.rule;
    } else if (typeof this.props.force === 'boolean') {
      // 属性优先级 > 上下文
      globalRule = this.props.force;
    } else if (typeof this.context?.rule === 'object' && typeof this.props.force === 'object') {
      globalRule = merge({}, this.context?.rule, this.props.force);
    }

    let currentProps: Props = {
      ...this.props,
      config: merge({}, this.defaultConfig, globalBaseConfig, globalComsConfig, this.props.config),
      force: globalRule,
    };

    // 开始初始化图表
    if (this.beforeInit) {
      currentProps = this.beforeInit(currentProps);
    }

    // 处理padding
    // todo: 加入规则体系中
    currentProps.config.padding = fixPadding(currentProps.padding || currentProps.config.padding);
    currentProps.config.appendPadding =
      currentProps.appendPadding || currentProps.config.appendPadding;

    // 颜色映射
    currentProps.config.colors = mapColors(currentProps.config.colors);

    // 用户自定义 > 图表 > 通用 > 默认
    this.mergeConfig = currentProps.config;

    const {
      width,
      height,
      data: initData,
      // padding,
      // forceFit,
      event,
      interaction,
      animate,
      force,
      chartLifecycle,
      localRefresh = false,
      ...otherProps
    } = currentProps;
    let { config } = currentProps;

    // 预处理数据
    let data =
      this.convertData && config.dataType !== 'g2'
        ? highchartsDataToG2Data(initData, config)
        : initData;
    this.rawData = initData;

    // 初始化规则
    const { data: specialData, config: specialConfig } = runInitRule(this, config, data);
    data = specialData ?? data;
    config = specialConfig ?? config;

    // 后置配置项处理
    config = processFinalConfig(this, config);

    // 后置数据处理
    const { data: finalData, config: finalConfig } = processFinalData(this, data, config);
    data = finalData;
    config = finalConfig;

    // 特殊配置项检测
    // 目前仅对线图、线点图与散点图微调x轴range
    // todo: 加入规则体系
    // const extraConfig = checkSpecialConfig(this.chartName, config, force);
    // config = merge({}, config, extraConfig);

    // 检测饼图、多重饼图、多重圆环是否有chilren
    // if (['G2Pie', 'G2MultiPie', 'G2MultiCircle'].includes(this.chartName) && this.props.children) {
    //   // @ts-ignore
    //   if (this.props.config?.innerContent) {
    //     warn(`W${this.chartName.slice(2)}`, '图表的中心内容innerContent配置项会被chilren覆盖,建议删除chilren');
    //   } else {
    //     warn(`W${this.chartName.slice(2)}`, '推荐通过innerContent配置项设置中心内容');
    //   }
    // }

    // 生成图表实例
    const chart = new Chart({
      container: this.chartDom,
      width: this.size[0],
      height: this.size[1] || 200,
      padding: config.padding,
      appendPadding: config.appendPadding,
      localRefresh: localRefresh,
      limitInPlot: false,
      // forceFit: forceFit || false,
      // auto-padding 时自带的内边距
      // autoPaddingAppend: 3,
      ...otherProps,
    });

    this.chart = chart;

    // 绑定上下文
    // @ts-ignore
    this.chart.widgetsCtx = this;

    // 上下文的主题配置, 优先级高于全局变量 | 全局事件
    if (this.context?.theme) {
      this.chart.theme(getG2theme(convertThemeKey(this.context.theme)));
    }

    // todo: 加入规则体系
    // 检测颜色规则
    checkColor(config, this.chartName, chart);
    // 检测间距
    checkPadding(config, this.chartName, chart);
    // 检测尺寸
    checkSizeConfig(this.chartName, config, this.size[0], this.size[1] || 200);

    if (animate !== undefined) {
      warn('animate', '请使用 config.animate 设置动画开关。');
      // 将 props.animate 传入 config.animate
      if (config.animate === undefined) {
        config.animate = animate;
      }
    }

    this.emitWidgetsEvent(event, 'beforeWidgetsInit', config, data);

    // 绘制逻辑
    chart && this.init(chart, config, data);

    this.emitWidgetsEvent(event, 'afterWidgetsInit', config, data);

    // 全局动画设置
    if (typeof config.animate === 'boolean') {
      chart.animate(config.animate);
    }

    // 绑定事件,这里透传了G2的所有事件,暂时不做额外封装
    if (chart && event) {
      Object.keys(event).forEach((eventKey) => {
        chart.on(fixEventName(eventKey), event[eventKey]);
      });
    }

    // 绑定交互
    if (chart && interaction) {
      Object.keys(interaction).forEach((interactionName) => {
        chart.interaction(interactionName, interaction[interactionName]);
      });
    }

    if (typeof currentProps.getChartInstance === 'function') {
      currentProps.getChartInstance(chart);
    }

    // 渲染前规则
    runBeforePaintRule(this, config, data);

    // 后置检测
    chart.on('afterpaint', () => {
      // todo: 加入规则体系
      // 检测图形尺寸与间距,目前仅检测柱状图的柱宽与间距
      checkSize(this.chartName, this.chart);
    });

    const startTime = new Date().getTime();
    chartLifecycle?.renderStart?.();

    // 开始渲染
    chart.render();

    const endTime = new Date().getTime();
    chartLifecycle?.renderEnd?.();

    chartLog(this.chartName, 'renderTime', {
      chartId: this.chartId,
      chartName: this.chartName,
      renderTime: endTime - startTime,
    });

    // this.handleAfterRender(config);

    // 绑定ref
    this.ref.current = chartRefs(this, config);
    if (this.props.chartRef) {
      this.props.chartRef.current = this.ref.current;
    }
  }