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