一:基本介绍
1、echarts 底层依赖 ZRender,一个轻量级的二维绘制库。
2、echarts 源码可以编译成三个版本,分别为完整版本、常用版本和精简版本,入口是下面三个文件。
????????
3、echarts 的基本使用:
/**
* 1、基于准备好的 dom,初始化 echarts 实例,参数分别是 dom、theme 和 opts。
* 1)、dom 是 echarts 挂载的容器。
* 2)、theme 是图表主题,可以在 主题下载 - Apache ECharts 下载或者定义自己的主题。
* ? 3)、opts 是一些基础配置项(宽高、渲染类型等)。
**/
let myChart = echarts.init(document.getElementById('main'));
// 2、构造自定义 option 对象,指定图表的配置项和数据
let option = {
title: {
text: '第一个 ECharts 实例'
},
tooltip: {},
legend: {
data: ['销量']
},
xAxis: {
data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"]
},
yAxis: {},
series: [{
name: '销量',
type: 'bar',
data: [5, 20, 36, 10, 10, 20]
}]
};
/**
* 3、设置 options 配置,参数分别是 option,notMerge, lazyUpdate
* 1)、option 是自定义的配置项
* 2)、notMerge 布尔值:是否合并配置项
* 3)、是否懒更新
**/
myChart.setOption(option);
二、深入源码
一些基本概念:
????????
????????
?源码 src 目录下:
????????
1、初始化的 init 方法:
/**
* @param opts.devicePixelRatio 设备像素比,默认值是 window.devicePixelRatio
* @param opts.renderer 渲染模式,支持 'canvas' 和 'svg'
* @param opts.width 宽度
* @param opts.height 高度
* @param opts.locale 使用的语言,内置 'ZH' 和 'EN' 两个语言,可以通过 echarts.registerLocale 注册语言包
* @param opts.useDirtyRect 是否开启脏矩形渲染,只有在 Canvas 渲染模式有效,默认为 false
*/
export function init(
dom: HTMLElement,
theme?: string | object,
opts?: EChartsInitOpts
): EChartsType {
// 已经初始化过的 echarts 实例,直接返回
const existInstance = getInstanceByDom(dom);
if (existInstance) {
return existInstance;
}
// 构造 echarts 实例
const chart = new ECharts(dom, theme, opts);
// 生成 id,把实例以 id 为 key 保存在 instances 变量里
chart.id = 'ec_' + idBase++;
instances[chart.id] = chart;
// 设置该 id 为 dom 的一个属性(dom.DOM_ATTRIBUTE_KEY = id)
modelUtil.setAttribute(dom, DOM_ATTRIBUTE_KEY, chart.id);
/**
* enableConnect 更新状态,三个状态:
* CONNECT_STATUS_PENDING
* CONNECT_STATUS_UPDATING
* CONNECT_STATUS_UPDATED
*/
enableConnect(chart);
// 触发生命周期函数 afterinit,用户绑定事件
lifecycle.trigger('afterinit', chart);
return chart;
}
1)、init 方法里构造 echarts 实例:
????????最重要的就是调用 zrender.init 方法,传入 dom 和 opts 里的配置进行初始化,返回 zrender 实例。(这部分需要看 zrender 的源码)
2、setOption 方法(参数:option,notMerge,lazyUpdate)
/**
* Usage:
* chart.setOption(option, notMerge, lazyUpdate);
* chart.setOption(option, {
* notMerge: ...,
* lazyUpdate: ...,
* silent: ...
* });
*
* @param opts opts or notMerge.
* @param opts.notMerge 是否不跟之前设置的 option 进行合并。默认为 false,使用普通合并。
* @param opts.lazyUpdate 设置完 option 后是否不立即更新图表,默认为 false。
* @param opts.silent 阻止调用 setOption 时抛出事件,默认为 false。
* @param opts.replaceMerge 指定的组件会进行替换合并,默认值为 undefined。
*/
setOption<Opt extends ECBasicOption>(option: Opt, notMerge?: boolean | SetOptionOpts, lazyUpdate?: boolean): void {
if (this._disposed) {
disposedWarning(this.id);
return;
}
let silent;
let replaceMerge;
let transitionOpt: SetOptionTransitionOpt;
if (isObject(notMerge)) {
lazyUpdate = notMerge.lazyUpdate;
silent = notMerge.silent;
replaceMerge = notMerge.replaceMerge;
transitionOpt = notMerge.transition;
notMerge = notMerge.notMerge;
}
this[IN_MAIN_PROCESS_KEY] = true;
// 第一次 setOption || 不和之前的 option 合并
if (!this._model || notMerge) {
// 构造 OptionManager 实例,进行 option 配置管理
const optionManager = new OptionManager(this._api);
const theme = this._theme;
// 构造 GlobalModel 实例,调用 init 方法进行初始化
const ecModel = this._model = new GlobalModel();
ecModel.scheduler = this._scheduler;
ecModel.init(null, null, null, theme, this._locale, optionManager);
}
// setOption 之前先执行的函数列表 optionPreprocessorFuncs
this._model.setOption(option as ECBasicOption, { replaceMerge }, optionPreprocessorFuncs);
const updateParams = {
seriesTransition: transitionOpt,
optionChanged: true
} as UpdateLifecycleParams;
// 延迟更新
if (lazyUpdate) {
this[PENDING_UPDATE] = {
silent: silent,
updateParams: updateParams
};
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.
this.getZr().wakeUp();
}
// 立刻更新
else {
// 准备更新
prepare(this);
// 进行更新
updateMethods.update.call(this, null, updateParams);
// Ensure zr refresh sychronously, and then pixel in canvas can be
// fetched after `setOption`.
this._zr.flush();
this[PENDING_UPDATE] = null;
this[IN_MAIN_PROCESS_KEY] = false;
// silent 为 false 的时候,触发 flushpengding 操作
flushPendingActions.call(this, silent);
// 触发 update 事件
triggerUpdatedEvent.call(this, silent);
}
}
|