Global.js 9.1 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 13
    var SeriesModel = require('./Series');
    var ComponentModel = require('./Component');
L
lang 已提交
14

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

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

        constructor: GlobalModel,

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

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

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

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

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

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

L
lang 已提交
52 53 54 55
            /**
             * @type {Array.<module:echarts/model/Model}
             * @private
             */
L
lang 已提交
56 57
            this._series = [];

L
lang 已提交
58 59 60 61
            /**
             * @type {Object.<string, module:echarts/model/Model>}
             * @private
             */
L
lang 已提交
62 63
            this._seriesMap = {};

L
lang 已提交
64 65 66 67
            /**
             * @type {module:echarts/model/Model}
             * @private
             */
L
lang 已提交
68
            this._theme = new Model(theme);
L
lang 已提交
69

L
lang 已提交
70 71
            this._mergeTheme(option, theme);

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

L
lang 已提交
75 76 77
            this.mergeOption(option);
        },

L
lang 已提交
78 79 80 81 82 83 84 85
        /**
         * @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 已提交
86 87 88
                        option[name] = option[name]
                            ? zrUtil.clone(theme[name])
                            : zrUtil.merge(option[name], theme[name]);
L
lang 已提交
89 90 91 92 93 94 95 96 97 98 99
                    }
                    else {
                        option[name] = theme[name];
                    }
                }
            }
        },

        /**
         * @protected
         */
L
lang 已提交
100
        mergeOption: function (newOption) {
L
lang 已提交
101 102 103 104 105 106 107

            var option = this.option;

            zrUtil.each(newOption.series, function (series, idx) {
                var seriesName = series.name || (series.type + idx);
                var seriesMap = this._seriesMap;
                var seriesModel = seriesMap[seriesName];
L
lang 已提交
108
                if (seriesModel) {
L
lang 已提交
109
                    seriesModel.mergeOption(series, this);
L
lang 已提交
110 111
                }
                else {
L
lang 已提交
112 113 114
                    seriesModel = SeriesModel.create(series, this, idx);
                    seriesModel.name = seriesName;
                    seriesMap[seriesName] = seriesModel;
L
lang 已提交
115 116 117 118 119
                    this._series.push(seriesModel);
                }
            }, this);

            // 同步 Option
L
lang 已提交
120 121
            option.series = this._series.map(function (seriesModel) {
                return seriesModel.option;
L
lang 已提交
122 123
            });

L
lang 已提交
124
            var componentsMap = this._componentsMap;
L
lang 已提交
125
            var components = this._components;
P
pah100 已提交
126 127 128 129 130 131
            var modelNames = [];

            // 如果不存在对应的 component model 则直接 merge
            zrUtil.each(newOption, function (componentOption, name) {
                if (!ComponentModel.has(name)) {
                    if (componentOption && typeof componentOption === 'object') {
L
lang 已提交
132 133 134
                        option[name] = option[name] == null
                            ? zrUtil.clone(componentOption)
                            : zrUtil.merge(option[name], componentOption);
L
lang 已提交
135 136
                    }
                    else {
L
lang 已提交
137
                        option[name] = componentOption;
L
lang 已提交
138
                    }
L
lang 已提交
139 140
                }
                else {
P
pah100 已提交
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
                    modelNames.push(name);
                }
            });

            ComponentModel.topologicalTavel(modelNames, function (name, depends) {
                var componentOption = newOption[name];

                // Normalize
                if (!(componentOption instanceof Array)) {
                    componentOption = [componentOption];
                }
                if (!componentsMap[name]) {
                    componentsMap[name] = [];
                }

                for (var i = 0; i < componentOption.length; i++) {
                    var componentModel = componentsMap[name][i];
                    if (componentModel) {
                        componentModel.mergeOption(
                            componentOption[i], this
                        );
L
lang 已提交
162
                    }
P
pah100 已提交
163 164 165 166 167 168 169
                    else {
                        componentModel = ComponentModel.create(
                            name, componentOption[i], this,
                            this._getComponentsByTypes(depends)
                        );
                        componentsMap[name][i] = componentModel;
                        components.push(componentModel);
L
lang 已提交
170
                    }
P
pah100 已提交
171 172 173 174 175
                    if (componentModel) {
                        // 同步 Option
                        if (componentOption instanceof Array) {
                            option[name] = option[name] || [];
                            option[name][i] = componentModel.option;
L
lang 已提交
176 177
                        }
                        else {
P
pah100 已提交
178
                            option[name] = componentModel.option;
L
lang 已提交
179
                        }
L
lang 已提交
180 181
                    }
                }
P
pah100 已提交
182
            }, this);
L
lang 已提交
183 184
        },

L
lang 已提交
185 186 187
        /**
         * @return {module:echarts/model/Model}
         */
L
lang 已提交
188 189 190 191
        getTheme: function () {
            return this._theme;
        },

L
lang 已提交
192 193 194
        /**
         * @return {module:echarts/model/Component}
         */
L
lang 已提交
195
        getComponent: function (type, idx) {
L
lang 已提交
196
            var list = this._componentsMap[type];
L
lang 已提交
197 198 199 200 201
            if (list) {
                return list[idx || 0];
            }
        },

L
lang 已提交
202 203 204 205 206
        /**
         * @param {string} type
         * @param {Function} cb
         * @param {*} context
         */
L
lang 已提交
207
        eachComponent: function (type, cb, context) {
L
lang 已提交
208
            zrUtil.each(this._componentsMap[type], cb, context);
L
lang 已提交
209 210
        },

L
lang 已提交
211 212 213 214
        /**
         * @param {string} name
         * @return {Array.<module:echarts/model/Series>}
         */
L
lang 已提交
215 216 217 218
        getSeriesByName: function (name) {
            return this._seriesMap[name];
        },

L
lang 已提交
219 220 221 222
        /**
         * @param {string} type
         * @return {Array.<module:echarts/model/Series>}
         */
L
lang 已提交
223 224 225 226 227 228
        getSeriesByType: function (type) {
            return zrUtil.filter(this._series, function (series) {
                return series.type === type;
            });
        },

L
lang 已提交
229 230 231 232 233
        /**
         * @param {number} seriesIndex
         * @return {module:echarts/model/Series}
         */
        getSeries: function (seriesIndex) {
L
lang 已提交
234 235 236
            return this._series[seriesIndex];
        },

L
lang 已提交
237 238 239 240
        /**
         * @return {Array.<module:echarts/model/Series>}
         */
        getSeriesAll: function () {
L
lang 已提交
241
            return this._series.slice();
L
lang 已提交
242 243
        },

L
lang 已提交
244 245 246 247
        /**
         * @param {Function} cb
         * @param {*} context
         */
L
lang 已提交
248 249 250 251
        eachSeries: function (cb, context) {
            zrUtil.each(this._series, cb, context);
        },

L
lang 已提交
252 253 254 255
        /**
         * @param {Function} cb
         * @param {*} context
         */
L
lang 已提交
256 257
        filterSeries: function (cb, context) {
            this._series = zrUtil.filter(this._series, cb, context);
L
lang 已提交
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289
        },

        save: function () {
            this._stack.push({
                series: this._series.slice()
            });

            var components = this._components;
            var series = this._series;
            var i;
            for (i = 0; i < components.length; i++) {
                components[i].save();
            }
            for (i = 0; i < series.length; i++) {
                series[i].save();
            }
        },

        restore: function () {
            if (this._stack.length) {
                this._series = this._stack.pop().series;
            }

            var components = this._components;
            var series = this._series;
            var i;
            for (i = 0; i < components.length; i++) {
                components[i].restore();
            }
            for (i = 0; i < series.length; i++) {
                series[i].restore();
            }
P
pah100 已提交
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307
        },

        /**
         * @private
         * @param {Array.<string>|string} types model types
         * @return {Object} key: {string} type, value: {Array.<Object>} models
         */
        _getComponentsByTypes: function (types) {
            if (!(types instanceof Array)) {
                types = types ? [types] : [];
            }

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

            return ret;
L
lang 已提交
308 309 310 311 312
        }
    });

    return GlobalModel;
});