echarts.js 12.0 KB
Newer Older
L
lang 已提交
1 2
/**
 * TODO processor的优先级
L
lang 已提交
3 4
 *      setTheme
 *      stack
5
 *      axis position 统一处理
L
lang 已提交
6
 */
L
lang 已提交
7 8
define(function (require) {

L
lang 已提交
9
    var GlobalModel = require('./model/Global');
L
lang 已提交
10
    var ExtensionAPI = require('./ExtensionAPI');
L
lang 已提交
11
    var CoordinateSystemManager = require('./CoordinateSystem');
L
lang 已提交
12

L
Update  
lang 已提交
13 14 15 16 17 18
    var ComponentModel = require('./model/Component');
    var SeriesModel = require('./model/Series');

    var ComponentView = require('./view/Component');
    var ChartView = require('./view/Chart');

L
lang 已提交
19
    var zrender = require('zrender');
L
lang 已提交
20
    var zrUtil = require('zrender/core/util');
L
lang 已提交
21

L
lang 已提交
22 23 24 25 26 27
    /**
     * @inner
     */
    function getSeriesId(series, seriesIndex) {
        return series.type + '_' + (series.name ||  seriesIndex);
    }
L
lang 已提交
28 29 30
    /**
     * @module echarts~ECharts
     */
L
lang 已提交
31 32
    var ECharts = function (dom, theme, opts) {
        opts = opts || {};
L
lang 已提交
33

L
lang 已提交
34 35 36 37
        /**
         * @type {module:zrender/ZRender}
         * @private
         */
L
lang 已提交
38 39 40
        this._zr = zrender.init(dom, {
            renderer: opts.renderer || 'canvas'
        });
L
lang 已提交
41

L
lang 已提交
42 43 44 45
        /**
         * @type {Object}
         * @private
         */
L
lang 已提交
46
        this._theme = zrUtil.clone(theme);
L
lang 已提交
47

L
lang 已提交
48 49 50 51
        /**
         * @type {Array.<module:echarts/view/Chart>}
         * @private
         */
L
lang 已提交
52
        this._chartsList = [];
L
lang 已提交
53 54 55 56 57

        /**
         * @type {Object.<string, module:echarts/view/Chart>}
         * @private
         */
L
lang 已提交
58 59
        this._chartsMap = {};

L
lang 已提交
60 61 62 63
        /**
         * @type {Array.<module:echarts/view/Component>}
         * @private
         */
L
lang 已提交
64
        this._componentsList = [];
L
lang 已提交
65 66 67 68 69

        /**
         * @type {Object.<string, module:echarts/view/Component>}
         * @private
         */
L
lang 已提交
70 71
        this._componentsMap = {};

L
lang 已提交
72
        /**
L
lang 已提交
73
         * @type {module:echarts/ExtensionAPI}
L
lang 已提交
74 75
         * @private
         */
L
lang 已提交
76
        this._extensionAPI = new ExtensionAPI(this);
L
lang 已提交
77

L
lang 已提交
78 79 80 81
        /**
         * @type {module:echarts/CoordinateSystem}
         * @private
         */
L
lang 已提交
82
        this._coordinateSystem = new CoordinateSystemManager();
L
lang 已提交
83

L
lang 已提交
84 85 86 87 88
        /**
         * Layout instances
         * @type {Array}
         * @private
         */
L
lang 已提交
89 90 91
        this._layouts = zrUtil.map(layoutClasses, function (Layout) {
            return new Layout();
        });
L
lang 已提交
92 93 94 95 96 97 98 99 100 101 102 103

        /**
         * @type {boolean}
         * @private
         */
        this._needsUpdate = false;

        this._zr.animation.on('frame', function () {
            if (this._needsUpdate) {
                this.updateImmediately();
            }
        }, this);
L
lang 已提交
104 105 106 107
    };

    ECharts.prototype = {

L
lang 已提交
108 109 110 111
        getZr: function () {
            return this._zr;
        },

L
lang 已提交
112
        setOption: function (option, notMerge) {
L
lang 已提交
113
            option = zrUtil.clone(option, true);
L
lang 已提交
114

L
lang 已提交
115 116 117 118 119 120 121 122
            var ecModel = this._model;
            if (! ecModel || notMerge) {
                ecModel = new GlobalModel(option, null, this._theme);
                this._model = ecModel;
            }
            else {
                ecModel.mergeOption(option);
            }
L
lang 已提交
123

L
lang 已提交
124
            this._prepareComponents(ecModel);
L
lang 已提交
125

L
lang 已提交
126
            this._prepareCharts(ecModel);
L
lang 已提交
127 128

            this.updateImmediately();
L
lang 已提交
129 130
        },

L
lang 已提交
131 132 133 134
        setTheme: function (theme) {

        },

L
lang 已提交
135 136 137 138
        getCoordinateSystem: function (type, idx) {
            return this._coordinateSystem.get(type, idx);
        },

L
lang 已提交
139 140 141
        /**
         * @return {number}
         */
L
lang 已提交
142 143 144
        getWidth: function () {
            return this._zr.getWidth();
        },
L
lang 已提交
145

L
lang 已提交
146 147 148
        /**
         * @return {number}
         */
L
lang 已提交
149 150 151 152 153
        getHeight: function () {
            return this._zr.getHeight();
        },

        update: function () {
L
lang 已提交
154
            this._needsUpdate = true;
L
lang 已提交
155 156
        },

L
lang 已提交
157
        updateImmediately: function () {
158 159
            // console.time('update');

L
lang 已提交
160 161 162
            var ecModel = this._model;

            ecModel.restore();
L
lang 已提交
163

L
lang 已提交
164 165
            ecModel.save();

L
lang 已提交
166
            this._processData(ecModel);
L
lang 已提交
167

L
lang 已提交
168
            this._coordinateSystem.update(ecModel, this._extensionAPI);
L
lang 已提交
169

L
lang 已提交
170 171
            this._doVisualCoding(ecModel);

L
lang 已提交
172 173 174
            this._doLayout(ecModel);

            this._doRender(ecModel);
L
lang 已提交
175 176

            this._needsUpdate = false;
177 178

            // console.timeEnd('update');
L
lang 已提交
179 180
        },

L
lang 已提交
181
        resize: function () {
L
lang 已提交
182
            // var ecModel = this._model;
L
lang 已提交
183

L
lang 已提交
184
            // this._coordinateSystem.resize(ecModel, this._extensionAPI);
L
lang 已提交
185

L
lang 已提交
186
            // this._doVisualCoding(ecModel);
L
lang 已提交
187

L
lang 已提交
188 189 190 191 192
            // this._doLayout(ecModel);

            // this._doRender(ecModel);

            this.updateImmediately();
L
lang 已提交
193 194
        },

L
lang 已提交
195
        _prepareCharts: function (ecModel) {
L
lang 已提交
196

L
lang 已提交
197 198 199 200 201 202 203 204 205 206 207
            var chartsList = this._chartsList;
            var chartsMap = this._chartsMap;

            for (var i = 0; i < chartsList.length; i++) {
                chartsList[i].__keepAlive = false;
            }

            ecModel.eachSeries(function (seriesModel, idx) {
                var id = getSeriesId(seriesModel.option, idx);

                var chart = chartsMap[id];
L
lang 已提交
208
                if (! chart) {
L
Update  
lang 已提交
209
                    chart = ChartView.create(seriesModel.type);
L
lang 已提交
210
                    if (chart) {
L
lang 已提交
211
                        chart.init(this._extensionAPI);
L
lang 已提交
212 213
                        chartsMap[id] = chart;
                        chartsList.push(chart);
L
lang 已提交
214 215 216 217 218 219
                    }
                    else {
                        // Error
                    }
                }

L
lang 已提交
220 221
                chart.__keepAlive = true;
                chart.__id = id;
L
lang 已提交
222 223
            }, this);

L
lang 已提交
224 225 226 227
            for (var i = 0; i < chartsList.length;) {
                var chart = chartsList[i];
                if (! chart.__keepAlive) {
                    this._zr.remove(chart.group);
L
lang 已提交
228
                    chart.dispose();
L
lang 已提交
229 230
                    chartsList.splice(i, 1);
                    delete chartsMap[chart.__id];
L
lang 已提交
231 232 233 234 235 236 237
                }
                else {
                    i++;
                }
            };
        },

L
lang 已提交
238
        _prepareComponents: function (ecModel) {
L
lang 已提交
239 240 241 242 243 244 245 246

            var componentsMap = this._componentsMap;
            var componentsList = this._componentsList;

            for (var i = 0; i < componentsList.length; i++) {
                componentsList[i].__keepAlive = true;
            }

L
Update  
lang 已提交
247
            ComponentView.eachAvailableComponent(function (componentType) {
L
lang 已提交
248

L
lang 已提交
249 250 251
                ecModel.eachComponent(componentType, function (componentModel, idx) {
                    var id = componentType + '_' + idx;
                    var component = componentsMap[id];
L
lang 已提交
252 253
                    if (! component) {
                        // Create and add component
L
Update  
lang 已提交
254
                        component = ComponentView.create(componentType, componentModel);
L
lang 已提交
255
                        component.init(this._extensionAPI);
L
lang 已提交
256
                        componentsMap[id] = component;
L
lang 已提交
257
                        componentsList.push(component);
L
lang 已提交
258 259

                        this._zr.add(component.group);
L
lang 已提交
260
                    }
L
lang 已提交
261 262 263 264 265 266 267 268 269 270 271 272 273 274
                    component.__id = id;
                    component.__keepAlive = true;
                    // Used in rendering
                    component.__model = componentModel;
                }, this);
            }, this);

            for (var i = 0; i < componentsList.length;) {
                var component = componentsList[i];
                if (! component.__keepAlive) {
                    this._zr.remove(component.group);
                    component.dispose();
                    componentsList.splice(i, 1);
                    delete componentsMap[component.__id];
L
lang 已提交
275 276
                }
                else {
L
lang 已提交
277
                    i++;
L
lang 已提交
278
                }
L
lang 已提交
279
            };
L
lang 已提交
280 281
        },

L
lang 已提交
282 283 284 285 286 287
        /**
         * Processor data in each series
         *
         * @param {module:echarts/model/Global} ecModel
         * @private
         */
L
lang 已提交
288
        _processData: function (ecModel) {
L
lang 已提交
289
            zrUtil.each(dataProcessorFuncs, function (processor) {
L
lang 已提交
290 291
                processor(ecModel);
            });
L
lang 已提交
292 293
        },

L
lang 已提交
294 295 296 297 298 299 300 301
        /**
         * Layout before each chart render there series after visual coding and data processing
         *
         * @param {module:echarts/model/Global} ecModel
         * @private
         */
        _doLayout: function (ecModel) {
            zrUtil.each(this._layouts, function (layout) {
302 303 304 305
                layout(ecModel);
            });
            zrUtil.each(layoutFuncs, function (layout) {
                layout(ecModel);
L
lang 已提交
306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323
            });
        },

        /**
         * Code visual infomation from data after data processing
         *
         * @param {module:echarts/model/Global} ecModel
         * @private
         */
        _doVisualCoding: function (ecModel) {
            zrUtil.each(visualCodingFuncs, function (visualCoding) {
                visualCoding(ecModel);
            });
        },

        /**
         * Render each chart and component
         */
L
lang 已提交
324
        _doRender: function (ecModel) {
L
lang 已提交
325
            var api = this._extensionAPI;
L
lang 已提交
326
            // Render all components
L
lang 已提交
327 328 329 330 331
            zrUtil.each(this._componentsList, function (component) {
                component.render(component.__model, ecModel, api);
            }, this);
            // Remove groups of charts
            zrUtil.each(this._chartsList, function (chart) {
332
                chart.__keepAlive = false;
L
lang 已提交
333
            }, this);
L
lang 已提交
334
            // Render all charts
L
lang 已提交
335 336
            ecModel.eachSeries(function (seriesModel, idx) {
                var id = getSeriesId(seriesModel.option, idx);
L
lang 已提交
337
                var chart = this._chartsMap[id];
338
                chart.__keepAlive = true;
L
lang 已提交
339
                chart.render(seriesModel, ecModel, api);
L
lang 已提交
340 341

                this._zr.add(chart.group);
L
lang 已提交
342
            }, this);
343 344 345 346 347 348 349
            // Remove groups of charts
            zrUtil.each(this._chartsList, function (chart) {
                if (!chart.__keepAlive) {
                    this._zr.remove(chart.group);
                    chart.remove();
                }
            }, this);
L
lang 已提交
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364
        },

        dispose: function () {
            zrUtil.each(this._components, function (component) {
                component.dispose();
            });
            zrUtil.each(this._charts, function (chart) {
                chart.dispose();
            });

            this.zr.dispose();
        }
    };


L
lang 已提交
365
    var dataProcessorFuncs = [];
L
lang 已提交
366 367 368

    var layoutClasses = [];

369 370
    var layoutFuncs = [];

L
lang 已提交
371 372
    var visualCodingFuncs = [];

L
lang 已提交
373 374 375 376 377
    /**
     * @module echarts
     */
    var echarts = {

L
lang 已提交
378 379
        init: function (dom, theme, opts) {
            return new ECharts(dom, theme, opts);
L
lang 已提交
380 381
        },

L
lang 已提交
382 383 384 385 386 387
        /**
         * @param {Function}
         */
        registerProcessor: function (processorFunc) {
            if (zrUtil.indexOf(dataProcessorFuncs, processorFunc) < 0) {
                dataProcessorFuncs.push(processorFunc);
L
lang 已提交
388
            }
L
lang 已提交
389 390
        },

L
lang 已提交
391 392 393 394
        /**
         * @param {string} type
         * @param {*} CoordinateSystem
         */
L
lang 已提交
395
        registerCoordinateSystem: function (type, CoordinateSystem) {
L
lang 已提交
396 397 398
            CoordinateSystemManager.register(type, CoordinateSystem);
        },

L
lang 已提交
399 400 401
        /**
         * @param {*} layout
         */
402 403 404 405 406 407 408 409 410 411
        registerLayout: function (layout, isFactory) {
            if (isFactory) {
                if (zrUtil.indexOf(layoutClasses, layout) < 0) {
                    layoutClasses.push(layout);
                }
            }
            else {
                if (zrUtil.indexOf(layoutFuncs, layout) < 0) {
                    layoutFuncs.push(layout);
                }
L
lang 已提交
412 413 414
            }
        },

L
lang 已提交
415 416
        registerVisualCoding: function (visualCodingFunc) {
            visualCodingFuncs.push(visualCodingFunc);
L
Update  
lang 已提交
417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444
        },

        /**
         * @param {Object} opts
         */
        extendSeriesModel: function (opts) {
            return SeriesModel.extend(opts);
        },

        /**
         * @param {Object} opts
         */
        extendChartView: function (opts) {
            return ChartView.extend(opts);
        },

        /**
         * @param {Object} opts
         */
        extendComponentModel: function (opts) {
            return ComponentModel.extend(opts);
        },

        /**
         * @param {Object} opts
         */
        extendComponentView: function (opts) {
            return ComponentView.extend(opts);
L
lang 已提交
445
        }
L
lang 已提交
446 447
    };

L
lang 已提交
448 449
    echarts.registerVisualCoding(require('./visual/defaultColor'));

L
lang 已提交
450 451
    return echarts;
});