ECharts的初始化
1、echarts.init
self.init = function (dom, theme) { var zrender = require('zrender'); if (zrender.version.replace('.', '') - 0 < self.dependencies.zrender.replace('.', '') - 0) { console.error('ZRender ' + zrender.version + ' is too old for ECharts ' + self.version + '. Current version need ZRender ' + self.dependencies.zrender + '+'); } dom = dom instanceof Array ? dom[0] : dom;//如果是一组id相同的,则会取第一个 var key = dom.getAttribute(DOM_ATTRIBUTE_KEY);//comment by danielinbiti这里可以看出,自己可以对dom节点增加属性,从而定义key。定义后这个key不能改,不然instances无法销毁 if (!key) { key = _idBase++; dom.setAttribute(DOM_ATTRIBUTE_KEY, key); } if (_instances[key]) { _instances[key].dispose(); } _instances[key] = new Echarts(dom);//这里做了事件监听,组件属性初始化,记录dom成全局变量。 _instances[key].id = key; _instances[key].canvasSupported = _canvasSupported; _instances[key].setTheme(theme); return _instances[key]; };
2、echarts.setOption: function (option, notMerge)
这是真正的图形初始化,其中option就是常见的参数和数据设置对象。notMerge是是否合并,如果是合并的,那option的信息会合并到原来的信息中。其中对于series要注意,如果是新的series,则数组纬度不能与原来的重叠,否则就认为合并了。比如旧的series:[{a},{b}],新的series:[{1}],那a和1就会合并属性,取并集。
3、核心的初始化方法就是_render
_render: function (magicOption) {//commend by danielinbiti this._mergeGlobalConifg(magicOption); if (this._noDataCheck(magicOption)) { return; } var bgColor = magicOption.backgroundColor; if (bgColor) {//设置底图背景色,也就是DOM节点的背景色 if (!_canvasSupported && bgColor.indexOf('rgba') != -1) { var cList = bgColor.split(','); this.dom.style.filter = 'alpha(opacity=' + cList[3].substring(0, cList[3].lastIndexOf(')')) * 100 + ')'; cList.length = 3; cList[0] = cList[0].replace('a', ''); this.dom.style.backgroundColor = cList.join(',') + ')'; } else { this.dom.style.backgroundColor = bgColor; } } this._zr.clearAnimation(); this._chartList = []; var chartLibrary = require('./chart'); var componentLibrary = require('./component'); if (magicOption.xAxis || magicOption.yAxis) { magicOption.grid = magicOption.grid || {};//有x和y轴的,需有grid,grid就是长方形网格 magicOption.dataZoom = magicOption.dataZoom || {}; } var componentList = [//所有的对象都在这里了。 'title', //标题 'legend', //图例 'tooltip', //提示 'dataRange', //数据区间 'roamController',//地图漫游组件 'grid', //grid网格 'dataZoom',//放大缩小 'xAxis', //x轴 'yAxis', //y轴 'polar'//雷达 ]; var ComponentClass; var componentType; var component; for (var i = 0, l = componentList.length; i < l; i++) {//根据上面定义,查找所有对象,放到this.component中,这在页面外面是能直接访问到的 componentType = componentList[i]; component = this.component[componentType]; if (magicOption[componentType]) { if (component) { component.refresh && component.refresh(magicOption); } else { ComponentClass = componentLibrary.get(/^[xy]Axis$/.test(componentType) ? 'axis' : componentType); component = new ComponentClass(this._themeConfig, this._messageCenter, this._zr, magicOption, this, componentType); this.component[componentType] = component; } this._chartList.push(component); } else if (component) { component.dispose(); this.component[componentType] = null; delete this.component[componentType]; } } var ChartClass; var chartType; var chart; var chartMap = {}; for (var i = 0, l = magicOption.series.length; i < l; i++) {//循环series,初始化图表,这段方法是核心 chartType = magicOption.series[i].type; if (!chartType) {//没有图标类型,就不初始化组件,但像图例之类的,在使用series数据时,不对这个进行判断,所以可以把一些额外属性单独一个series console.error('series[' + i + '] chart type has not been defined.'); continue; } if (!chartMap[chartType]) { chartMap[chartType] = true; ChartClass = chartLibrary.get(chartType);//获取图形类,比如bar if (ChartClass) { if (this.chart[chartType]) { chart = this.chart[chartType]; chart.refresh(magicOption); } else { chart = new ChartClass(this._themeConfig, this._messageCenter, this._zr, magicOption, this);//初始化,series都传了进去,内部又进行判断是否有多个bar或者line,所以也就是说this.chart中没中图形都只有一个对象。 } this._chartList.push(chart); this.chart[chartType] = chart; } else { console.error(chartType + ' has not been required.'); } } } for (chartType in this.chart) { if (chartType != ecConfig.CHART_TYPE_ISLAND && !chartMap[chartType]) { this.chart[chartType].dispose(); this.chart[chartType] = null; delete this.chart[chartType]; } } this.component.grid && this.component.grid.refixAxisShape(this.component); this._island.refresh(magicOption); this._toolbox.refresh(magicOption);//初始化tooltip magicOption.animation && !magicOption.renderAsImage ? this._zr.refresh() : this._zr.render(); var imgId = 'IMG' + this.id; var img = document.getElementById(imgId); if (magicOption.renderAsImage && _canvasSupported) { if (img) { img.src = this.getDataURL(magicOption.renderAsImage); } else { img = this.getImage(magicOption.renderAsImage); img.id = imgId; img.style.position = 'absolute'; img.style.left = 0; img.style.top = 0; this.dom.firstChild.appendChild(img); } this.un(); this._zr.un(); this._disposeChartList(); this._zr.clear(); } else if (img) { img.parentNode.removeChild(img); } img = null; this._option = magicOption; },总结:
上面3个方法是初始化的过程,大体就是先有画图,然后通过setOption再对图行进行初始化。所以参数的修改,也意味着是整个图形的刷新,而不是个别图形的刷新。另外很多属性设置都是支持三种方式的:字符串,函数,参数占位显示。这点还是很灵活的。