Global.js 8.9 KB
Newer Older
L
lang 已提交
1 2 3 4 5 6
/**
 * ECharts global model
 *
 * @module {echarts/model/Global}
 */

L
lang 已提交
7 8 9 10 11
define(function (require) {

    var zrUtil = require('zrender/core/util');
    var Model = require('./Model');

L
lang 已提交
12
    var ComponentModel = require('./Component');
L
lang 已提交
13

L
lang 已提交
14 15
    var globalDefault = require('./globalDefault');

L
lang 已提交
16 17
    /**
     * @alias module:echarts/model/Global
L
lang 已提交
18 19 20 21
     *
     * @param {Object} option
     * @param {module:echarts/model/Model} parentModel
     * @param {Object} theme
L
lang 已提交
22
     */
L
lang 已提交
23 24 25 26
    var GlobalModel = Model.extend({

        constructor: GlobalModel,

L
lang 已提交
27
        init: function (option, parentModel, theme) {
L
lang 已提交
28

L
lang 已提交
29 30
            theme = theme || {};

L
lang 已提交
31 32
            this.option = {};

L
lang 已提交
33 34 35 36 37 38 39 40 41 42 43 44
            /**
             * @type {Array}
             * @private
             */
            this._stack = [];

            /**
             * @type {Array.<module:echarts/model/Model}
             * @private
             */
            this._components = [];

L
lang 已提交
45 46 47 48
            /**
             * @type {Object.<string, module:echarts/model/Model>}
             * @private
             */
L
lang 已提交
49
            this._componentsMap = {};
L
lang 已提交
50

L
lang 已提交
51 52 53 54
            /**
             * @type {module:echarts/model/Model}
             * @private
             */
L
lang 已提交
55
            this._theme = new Model(theme);
L
lang 已提交
56

L
lang 已提交
57 58
            this._mergeTheme(option, theme);

L
lang 已提交
59
            // TODO Needs clone when merging to the unexisted property
L
lang 已提交
60 61
            zrUtil.merge(option, globalDefault, false);

L
lang 已提交
62 63 64
            this.mergeOption(option);
        },

L
lang 已提交
65 66 67 68 69 70 71 72
        /**
         * @private
         */
        _mergeTheme: function (option, theme) {
            for (var name in theme) {
                // 如果有 component model 则把具体的 merge 逻辑交给该 model 处理
                if (! ComponentModel.has[name]) {
                    if (typeof theme[name] === 'object') {
L
lang 已提交
73 74 75
                        option[name] = option[name]
                            ? zrUtil.clone(theme[name])
                            : zrUtil.merge(option[name], theme[name]);
L
lang 已提交
76 77 78 79 80 81 82 83 84 85 86
                    }
                    else {
                        option[name] = theme[name];
                    }
                }
            }
        },

        /**
         * @protected
         */
L
lang 已提交
87
        mergeOption: function (newOption) {
L
lang 已提交
88 89

            var option = this.option;
L
lang 已提交
90
            var componentsMap = this._componentsMap;
L
lang 已提交
91
            var components = this._components;
92
            var componentTypes = [];
P
pah100 已提交
93 94

            // 如果不存在对应的 component model 则直接 merge
95 96
            zrUtil.each(newOption, function (componentOption, componentType) {
                if (!ComponentModel.has(componentType)) {
P
pah100 已提交
97
                    if (componentOption && typeof componentOption === 'object') {
98
                        option[componentType] = option[componentType] == null
L
lang 已提交
99
                            ? zrUtil.clone(componentOption)
100
                            : zrUtil.merge(option[componentType], componentOption);
L
lang 已提交
101 102
                    }
                    else {
103
                        option[componentType] = componentOption;
L
lang 已提交
104
                    }
L
lang 已提交
105 106
                }
                else {
107
                    componentTypes.push(componentType);
P
pah100 已提交
108 109 110
                }
            });

111 112
            ComponentModel.topologicalTravel(componentTypes, function (componentType, dependencies) {
                var componentOption = newOption[componentType];
P
pah100 已提交
113 114

                // Normalize
115
                if (!(zrUtil.isArray(componentOption))) {
P
pah100 已提交
116 117
                    componentOption = [componentOption];
                }
118 119
                if (!componentsMap[componentType]) {
                    componentsMap[componentType] = [];
P
pah100 已提交
120 121 122
                }

                for (var i = 0; i < componentOption.length; i++) {
123 124 125 126 127 128 129
                    var componentModel = componentsMap[componentType][i];
                    var ComponentModelClass = ComponentModel.getComponentModelClass(
                        componentType, componentOption[i]
                    );

                    if (componentModel && componentModel instanceof ComponentModelClass) {
                        componentModel.mergeOption(componentOption[i], this);
L
lang 已提交
130
                    }
P
pah100 已提交
131
                    else {
132 133 134
                        componentModel = new ComponentModelClass(
                            componentOption[i], null, this,
                            this._getComponentsByTypes(dependencies), i
P
pah100 已提交
135
                        );
136
                        componentsMap[componentType][i] = componentModel;
P
pah100 已提交
137
                        components.push(componentModel);
L
lang 已提交
138
                    }
139

P
pah100 已提交
140 141
                    if (componentModel) {
                        // 同步 Option
142 143 144
                        if (zrUtil.isArray(componentOption)) {
                            option[componentType] = option[componentType] || [];
                            option[componentType][i] = componentModel.option;
L
lang 已提交
145 146
                        }
                        else {
147
                            option[componentType] = componentModel.option;
L
lang 已提交
148
                        }
L
lang 已提交
149 150
                    }
                }
P
pah100 已提交
151
            }, this);
L
lang 已提交
152 153
        },

L
lang 已提交
154 155 156
        /**
         * @return {module:echarts/model/Model}
         */
L
lang 已提交
157 158 159 160
        getTheme: function () {
            return this._theme;
        },

L
lang 已提交
161 162 163
        /**
         * @return {module:echarts/model/Component}
         */
L
lang 已提交
164
        getComponent: function (type, idx) {
L
lang 已提交
165
            var list = this._componentsMap[type];
L
lang 已提交
166 167 168 169 170
            if (list) {
                return list[idx || 0];
            }
        },

L
lang 已提交
171 172 173 174 175
        /**
         * @param {string} type
         * @param {Function} cb
         * @param {*} context
         */
L
lang 已提交
176
        eachComponent: function (type, cb, context) {
L
lang 已提交
177
            zrUtil.each(this._componentsMap[type], cb, context);
L
lang 已提交
178 179
        },

L
lang 已提交
180 181
        /**
         * @param {string} name
182
         * @return {module:echarts/model/Series}
L
lang 已提交
183
         */
L
lang 已提交
184
        getSeriesByName: function (name) {
185 186 187 188 189 190 191
            var series = this._componentsMap.series;
            for (var i = 0, len = series.length; i < len; i++) {
                // name should be unique.
                if (series[i].name === name) {
                    return series[i];
                }
            }
L
lang 已提交
192 193
        },

L
lang 已提交
194 195 196 197
        /**
         * @param {string} type
         * @return {Array.<module:echarts/model/Series>}
         */
L
lang 已提交
198
        getSeriesByType: function (type) {
199 200
            return zrUtil.filter(this._componentsMap.series, function (series) {
                return ComponentModel.parseComponentType(series.type).sub === type;
L
lang 已提交
201 202 203
            });
        },

L
lang 已提交
204 205 206 207 208
        /**
         * @param {number} seriesIndex
         * @return {module:echarts/model/Series}
         */
        getSeries: function (seriesIndex) {
209
            return this._componentsMap.series[seriesIndex];
L
lang 已提交
210 211
        },

L
lang 已提交
212 213 214 215
        /**
         * @return {Array.<module:echarts/model/Series>}
         */
        getSeriesAll: function () {
216
            return this._componentsMap.series.slice();
L
lang 已提交
217 218
        },

L
lang 已提交
219 220 221 222
        /**
         * @param {Function} cb
         * @param {*} context
         */
L
lang 已提交
223
        eachSeries: function (cb, context) {
224
            zrUtil.each(this._componentsMap.series, cb, context);
L
lang 已提交
225 226
        },

227 228 229 230
        eachSeriesByType: function (type, cb, context) {
            return zrUtil.each(this.getSeriesByType(type), cb, context);
        },

L
lang 已提交
231 232 233 234
        /**
         * @param {Function} cb
         * @param {*} context
         */
L
lang 已提交
235
        filterSeries: function (cb, context) {
236 237 238
            this._componentsMap.series = zrUtil.filter(
                this._componentsMap.series, cb, context
            );
L
lang 已提交
239 240 241
        },

        save: function () {
242
            var seriesList = this._componentsMap.series;
L
lang 已提交
243
            this._stack.push({
244
                series: seriesList.slice()
L
lang 已提交
245 246 247 248 249 250 251
            });

            var components = this._components;
            var i;
            for (i = 0; i < components.length; i++) {
                components[i].save();
            }
252 253
            for (i = 0; i < seriesList.length; i++) {
                seriesList[i].save();
L
lang 已提交
254 255 256 257 258
            }
        },

        restore: function () {
            if (this._stack.length) {
259
                this._componentsMap.series = this._stack.pop().series;
L
lang 已提交
260 261
            }

262
            var seriesList = this._componentsMap.series;
L
lang 已提交
263 264 265 266 267
            var components = this._components;
            var i;
            for (i = 0; i < components.length; i++) {
                components[i].restore();
            }
268 269
            for (i = 0; i < seriesList.length; i++) {
                seriesList[i].restore();
L
lang 已提交
270
            }
P
pah100 已提交
271 272 273 274 275 276 277 278
        },

        /**
         * @private
         * @param {Array.<string>|string} types model types
         * @return {Object} key: {string} type, value: {Array.<Object>} models
         */
        _getComponentsByTypes: function (types) {
279
            if (!zrUtil.isArray(types)) {
P
pah100 已提交
280 281 282 283 284 285 286 287 288
                types = types ? [types] : [];
            }

            var ret = {};
            zrUtil.each(types, function (type) {
                ret[type] = (this._componentsMap[type] || []).slice();
            }, this);

            return ret;
L
lang 已提交
289 290 291 292 293
        }
    });

    return GlobalModel;
});