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