| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| /** |
| * Component model |
| * |
| * @module echarts/model/Component |
| */ |
| import * as zrUtil from 'zrender/src/core/util'; |
| import Model from './Model'; |
| import * as componentUtil from '../util/component'; |
| import { enableClassManagement, parseClassType } from '../util/clazz'; |
| import { makeInner } from '../util/model'; |
| import * as layout from '../util/layout'; |
| import boxLayoutMixin from './mixin/boxLayout'; |
| var inner = makeInner(); |
| /** |
| * @alias module:echarts/model/Component |
| * @constructor |
| * @param {Object} option |
| * @param {module:echarts/model/Model} parentModel |
| * @param {module:echarts/model/Model} ecModel |
| */ |
| |
| var ComponentModel = Model.extend({ |
| type: 'component', |
| |
| /** |
| * @readOnly |
| * @type {string} |
| */ |
| id: '', |
| |
| /** |
| * Because simplified concept is probably better, series.name (or component.name) |
| * has been having too many resposibilities: |
| * (1) Generating id (which requires name in option should not be modified). |
| * (2) As an index to mapping series when merging option or calling API (a name |
| * can refer to more then one components, which is convinient is some case). |
| * (3) Display. |
| * @readOnly |
| */ |
| name: '', |
| |
| /** |
| * @readOnly |
| * @type {string} |
| */ |
| mainType: '', |
| |
| /** |
| * @readOnly |
| * @type {string} |
| */ |
| subType: '', |
| |
| /** |
| * @readOnly |
| * @type {number} |
| */ |
| componentIndex: 0, |
| |
| /** |
| * @type {Object} |
| * @protected |
| */ |
| defaultOption: null, |
| |
| /** |
| * @type {module:echarts/model/Global} |
| * @readOnly |
| */ |
| ecModel: null, |
| |
| /** |
| * key: componentType |
| * value: Component model list, can not be null. |
| * @type {Object.<string, Array.<module:echarts/model/Model>>} |
| * @readOnly |
| */ |
| dependentModels: [], |
| |
| /** |
| * @type {string} |
| * @readOnly |
| */ |
| uid: null, |
| |
| /** |
| * Support merge layout params. |
| * Only support 'box' now (left/right/top/bottom/width/height). |
| * @type {string|Object} Object can be {ignoreSize: true} |
| * @readOnly |
| */ |
| layoutMode: null, |
| $constructor: function (option, parentModel, ecModel, extraOpt) { |
| Model.call(this, option, parentModel, ecModel, extraOpt); |
| this.uid = componentUtil.getUID('ec_cpt_model'); |
| }, |
| init: function (option, parentModel, ecModel, extraOpt) { |
| this.mergeDefaultAndTheme(option, ecModel); |
| }, |
| mergeDefaultAndTheme: function (option, ecModel) { |
| var layoutMode = this.layoutMode; |
| var inputPositionParams = layoutMode ? layout.getLayoutParams(option) : {}; |
| var themeModel = ecModel.getTheme(); |
| zrUtil.merge(option, themeModel.get(this.mainType)); |
| zrUtil.merge(option, this.getDefaultOption()); |
| |
| if (layoutMode) { |
| layout.mergeLayoutParam(option, inputPositionParams, layoutMode); |
| } |
| }, |
| mergeOption: function (option, extraOpt) { |
| zrUtil.merge(this.option, option, true); |
| var layoutMode = this.layoutMode; |
| |
| if (layoutMode) { |
| layout.mergeLayoutParam(this.option, option, layoutMode); |
| } |
| }, |
| // Hooker after init or mergeOption |
| optionUpdated: function (newCptOption, isInit) {}, |
| getDefaultOption: function () { |
| var fields = inner(this); |
| |
| if (!fields.defaultOption) { |
| var optList = []; |
| var Class = this.constructor; |
| |
| while (Class) { |
| var opt = Class.prototype.defaultOption; |
| opt && optList.push(opt); |
| Class = Class.superClass; |
| } |
| |
| var defaultOption = {}; |
| |
| for (var i = optList.length - 1; i >= 0; i--) { |
| defaultOption = zrUtil.merge(defaultOption, optList[i], true); |
| } |
| |
| fields.defaultOption = defaultOption; |
| } |
| |
| return fields.defaultOption; |
| }, |
| getReferringComponents: function (mainType) { |
| return this.ecModel.queryComponents({ |
| mainType: mainType, |
| index: this.get(mainType + 'Index', true), |
| id: this.get(mainType + 'Id', true) |
| }); |
| } |
| }); // Reset ComponentModel.extend, add preConstruct. |
| // clazzUtil.enableClassExtend( |
| // ComponentModel, |
| // function (option, parentModel, ecModel, extraOpt) { |
| // // Set dependentModels, componentIndex, name, id, mainType, subType. |
| // zrUtil.extend(this, extraOpt); |
| // this.uid = componentUtil.getUID('componentModel'); |
| // // this.setReadOnly([ |
| // // 'type', 'id', 'uid', 'name', 'mainType', 'subType', |
| // // 'dependentModels', 'componentIndex' |
| // // ]); |
| // } |
| // ); |
| // Add capability of registerClass, getClass, hasClass, registerSubTypeDefaulter and so on. |
| |
| enableClassManagement(ComponentModel, { |
| registerWhenExtend: true |
| }); |
| componentUtil.enableSubTypeDefaulter(ComponentModel); // Add capability of ComponentModel.topologicalTravel. |
| |
| componentUtil.enableTopologicalTravel(ComponentModel, getDependencies); |
| |
| function getDependencies(componentType) { |
| var deps = []; |
| zrUtil.each(ComponentModel.getClassesByMainType(componentType), function (Clazz) { |
| deps = deps.concat(Clazz.prototype.dependencies || []); |
| }); // Ensure main type. |
| |
| deps = zrUtil.map(deps, function (type) { |
| return parseClassType(type).main; |
| }); // Hack dataset for convenience. |
| |
| if (componentType !== 'dataset' && zrUtil.indexOf(deps, 'dataset') <= 0) { |
| deps.unshift('dataset'); |
| } |
| |
| return deps; |
| } |
| |
| zrUtil.mixin(ComponentModel, boxLayoutMixin); |
| export default ComponentModel; |