首页 > 代码库 > echarts研究

echarts研究

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研究