1. 程式人生 > >echarts研究

echarts研究

研究 ive root 內容 spec tex array single truct

1.echarts是什麽?

關鍵字:data visualization,canvas,chart

Echarts是基於輕量級的canvas類庫,純javaScript實現,MVC封裝,數據驅動,一款直觀、生動,可交互,可個性化定制的數據圖表。

2.為什麽Echarts基於canvas類庫?

svg與canvas是兩個可以選擇的類庫之一,其中svg的交互性更好,性能較弱,不適用於移動端,在繪制數萬個點時會崩潰;而canvas的渲染速度和性能更好,echarts在canvas上構建一層MVC層使得它可以像svg一樣交互。

3.為什麽說Echarts是基於輕量級的類庫?

因為Echarts是純javaScript實現,所以它是一個輕量級的產品,侵入性較小,依賴的東西少,也就是說在換掉框架時對項目影響比較小。

4.什麽是數據驅動?

所謂數據驅動是指你只需做的是定義圖形數據,就可以實現繪圖。

5.Echarts的特點有哪些?

三個特點,重要性和優先級依次遞減。

設計效果必須直觀、生動;

能夠交互;

可個性化定制.

6.為什麽說Echarts是MVC封裝?

技術分享

Echarts總體結構是基於MVC架構的,各部分的主要作用是:

Storage(M):模型層,實現圖形數據的增刪改查(CURD)管理。

Painter(V):視圖層,實現canvas元素的生命周期管理,即視圖渲染、更新控制、繪圖。

Handler(C):控制層,事件交互處理,實現完整的dom事件模擬封裝。

從下面的代碼片段可知,Storage是一個類似數據的倉庫,提供各種數據的讀、寫、改、刪等操作。Painter持有了Storage對象,也就是說結構圖中視圖層與模型層存在R(read)關系,即Painter需要讀取Storage中的數據進行繪圖。Handler持有了Storage對象和Painter對象,也就是結構圖中控制層與模型層存在CURD關系,即Handler通過訪問Storage對象提供的數據增刪改查操作實現事件交互處理所需的數據部分;而結構圖中控制層與視圖層存在call關系,即Handler通過訪問Painter對象提供的視圖操作實現事件交互處理的視圖部分。

Storage :

/**

* 內容倉庫 (M)

* @alias module:zrender/Storage

* @constructor

*/

var Storage = function () {

this._roots = [];

this._displayList = [];

this._displayListLen = 0;

};

Painter :

/**

* @alias module:zrender/Painter

* @constructor

* @param {HTMLElement} root 繪圖容器

* @param {module:zrender/Storage} storage

* @param {Object} opts

*/

var Painter = function (root, storage, opts) {

// In node environment using node-canvas

var singleCanvas = !root.nodeName // In node ?

|| root.nodeName.toUpperCase() === ‘CANVAS‘;

this._opts = opts = util.extend({}, opts || {});

/**

* @type {number}

*/

this.dpr = opts.devicePixelRatio || config.devicePixelRatio;

/**

* @type {boolean}

* @private

*/

this._singleCanvas = singleCanvas;

/**

* 繪圖容器

* @type {HTMLElement}

*/

this.root = root;

var rootStyle = root.style;

if (rootStyle) {

rootStyle[‘-webkit-tap-highlight-color‘] = ‘transparent‘;

rootStyle[‘-webkit-user-select‘] =

rootStyle[‘user-select‘] =

rootStyle[‘-webkit-touch-callout‘] = ‘none‘;

root.innerHTML = ‘‘;

}

/**

* @type {module:zrender/Storage}

*/

this.storage = storage;

/**

* @type {Array.<number>}

* @private

*/

var zlevelList = this._zlevelList = [];

/**

* @type {Object.<string, module:zrender/Layer>}

* @private

*/

var layers = this._layers = {};

/**

* @type {Object.<string, Object>}

* @type {private}

*/

this._layerConfig = {};

if (!singleCanvas) {

this._width = this._getSize(0);

this._height = this._getSize(1);

var domRoot = this._domRoot = createRoot(

this._width, this._height

);

root.appendChild(domRoot);

}

else {

if (opts.width != null) {

root.width = opts.width;

}

if (opts.height != null) {

root.height = opts.height;

}

// Use canvas width and height directly

var width = root.width;

var height = root.height;

this._width = width;

this._height = height;

// Create layer if only one given canvas

// Device pixel ratio is fixed to 1 because given canvas has its specified width and height

var mainLayer = new Layer(root, this, 1);

mainLayer.initContext();

// FIXME Use canvas width and height

// mainLayer.resize(width, height);

layers[0] = mainLayer;

zlevelList.push(0);

this._domRoot = root;

}

// Layers for progressive rendering

this._progressiveLayers = [];

/**

* @type {module:zrender/Layer}

* @private

*/

this._hoverlayer;

this._hoverElements = [];

};

Handler :

/**

* @alias module:zrender/Handler

* @constructor

* @extends module:zrender/mixin/Eventful

* @param {module:zrender/Storage} storage Storage instance.

* @param {module:zrender/Painter} painter Painter instance.

* @param {module:zrender/dom/HandlerProxy} proxy HandlerProxy instance.

* @param {HTMLElement} painterRoot painter.root (not painter.getViewportRoot()).

*/

var Handler = function(storage, painter, proxy, painterRoot) {

Eventful.call(this);

this.storage = storage;

this.painter = painter;

this.painterRoot = painterRoot;

proxy = proxy || new EmptyProxy();

/**

* Proxy of event. can be Dom, WebGLSurface, etc.

*/

this.proxy = proxy;

// Attach handler

proxy.handler = this;

/**

* {target, topTarget}

* @private

* @type {Object}

*/

this._hovered = {};

/**

* @private

* @type {Date}

*/

this._lastTouchMoment;

/**

* @private

* @type {number}

*/

this._lastX;

/**

* @private

* @type {number}

*/

this._lastY;

Draggable.call(this);

util.each(handlerNames, function (name) {

proxy.on && proxy.on(name, this[name], this);

}, this);

};

相關連接:

1.http://www.cnblogs.com/hhstuhacker/p/zrender-source-advance-frame.html

2.zrender介紹: http://ecomfe.github.io/zrender/

3.大數據可視化應用:dataV, https://data.aliyun.com/visual/datav?spm=5176.8142029.388261.76.9CzYBB

4.echarts官網: http://echarts.baidu.com/index.html

echarts研究