echarts.js 11.9 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) {
209 210 211
                    chart = ChartView.create(
                        ComponentModel.parseComponentType(seriesModel.type).sub
                    );
L
lang 已提交
212
                    if (chart) {
L
lang 已提交
213
                        chart.init(this._extensionAPI);
L
lang 已提交
214 215
                        chartsMap[id] = chart;
                        chartsList.push(chart);
L
lang 已提交
216 217 218 219 220 221
                    }
                    else {
                        // Error
                    }
                }

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

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

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

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

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

L
Update  
lang 已提交
249
            ComponentView.eachAvailableComponent(function (componentType) {
L
lang 已提交
250

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

                        this._zr.add(component.group);
L
lang 已提交
262
                    }
L
lang 已提交
263 264 265 266 267 268 269 270 271 272 273 274 275 276
                    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 已提交
277 278
                }
                else {
L
lang 已提交
279
                    i++;
L
lang 已提交
280
                }
281
            }
L
lang 已提交
282 283
        },

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

L
lang 已提交
296 297 298 299 300 301 302 303
        /**
         * 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) {
304 305 306 307
                layout(ecModel);
            });
            zrUtil.each(layoutFuncs, function (layout) {
                layout(ecModel);
L
lang 已提交
308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
            });
        },

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

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

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

            this.zr.dispose();
        }
    };


L
lang 已提交
367
    var dataProcessorFuncs = [];
L
lang 已提交
368 369 370

    var layoutClasses = [];

371 372
    var layoutFuncs = [];

L
lang 已提交
373 374
    var visualCodingFuncs = [];

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

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

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

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

L
lang 已提交
401 402 403
        /**
         * @param {*} layout
         */
404 405 406 407 408 409 410 411 412 413
        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 已提交
414 415 416
            }
        },

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

        /**
         * @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 已提交
440
        }
L
lang 已提交
441 442
    };

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

L
lang 已提交
445 446
    return echarts;
});