You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							312 lines
						
					
					
						
							6.7 KiB
						
					
					
				
			
		
		
	
	
							312 lines
						
					
					
						
							6.7 KiB
						
					
					
				var zrUtil = require("../core/util"); | 
						|
 | 
						|
var Element = require("../Element"); | 
						|
 | 
						|
var BoundingRect = require("../core/BoundingRect"); | 
						|
 | 
						|
/** | 
						|
 * Group是一个容器,可以插入子节点,Group的变换也会被应用到子节点上 | 
						|
 * @module zrender/graphic/Group | 
						|
 * @example | 
						|
 *     var Group = require('zrender/container/Group'); | 
						|
 *     var Circle = require('zrender/graphic/shape/Circle'); | 
						|
 *     var g = new Group(); | 
						|
 *     g.position[0] = 100; | 
						|
 *     g.position[1] = 100; | 
						|
 *     g.add(new Circle({ | 
						|
 *         style: { | 
						|
 *             x: 100, | 
						|
 *             y: 100, | 
						|
 *             r: 20, | 
						|
 *         } | 
						|
 *     })); | 
						|
 *     zr.add(g); | 
						|
 */ | 
						|
 | 
						|
/** | 
						|
 * @alias module:zrender/graphic/Group | 
						|
 * @constructor | 
						|
 * @extends module:zrender/mixin/Transformable | 
						|
 * @extends module:zrender/mixin/Eventful | 
						|
 */ | 
						|
var Group = function (opts) { | 
						|
  opts = opts || {}; | 
						|
  Element.call(this, opts); | 
						|
 | 
						|
  for (var key in opts) { | 
						|
    if (opts.hasOwnProperty(key)) { | 
						|
      this[key] = opts[key]; | 
						|
    } | 
						|
  } | 
						|
 | 
						|
  this._children = []; | 
						|
  this.__storage = null; | 
						|
  this.__dirty = true; | 
						|
}; | 
						|
 | 
						|
Group.prototype = { | 
						|
  constructor: Group, | 
						|
  isGroup: true, | 
						|
 | 
						|
  /** | 
						|
   * @type {string} | 
						|
   */ | 
						|
  type: 'group', | 
						|
 | 
						|
  /** | 
						|
   * 所有子孙元素是否响应鼠标事件 | 
						|
   * @name module:/zrender/container/Group#silent | 
						|
   * @type {boolean} | 
						|
   * @default false | 
						|
   */ | 
						|
  silent: false, | 
						|
 | 
						|
  /** | 
						|
   * @return {Array.<module:zrender/Element>} | 
						|
   */ | 
						|
  children: function () { | 
						|
    return this._children.slice(); | 
						|
  }, | 
						|
 | 
						|
  /** | 
						|
   * 获取指定 index 的儿子节点 | 
						|
   * @param  {number} idx | 
						|
   * @return {module:zrender/Element} | 
						|
   */ | 
						|
  childAt: function (idx) { | 
						|
    return this._children[idx]; | 
						|
  }, | 
						|
 | 
						|
  /** | 
						|
   * 获取指定名字的儿子节点 | 
						|
   * @param  {string} name | 
						|
   * @return {module:zrender/Element} | 
						|
   */ | 
						|
  childOfName: function (name) { | 
						|
    var children = this._children; | 
						|
 | 
						|
    for (var i = 0; i < children.length; i++) { | 
						|
      if (children[i].name === name) { | 
						|
        return children[i]; | 
						|
      } | 
						|
    } | 
						|
  }, | 
						|
 | 
						|
  /** | 
						|
   * @return {number} | 
						|
   */ | 
						|
  childCount: function () { | 
						|
    return this._children.length; | 
						|
  }, | 
						|
 | 
						|
  /** | 
						|
   * 添加子节点到最后 | 
						|
   * @param {module:zrender/Element} child | 
						|
   */ | 
						|
  add: function (child) { | 
						|
    if (child && child !== this && child.parent !== this) { | 
						|
      this._children.push(child); | 
						|
 | 
						|
      this._doAdd(child); | 
						|
    } | 
						|
 | 
						|
    return this; | 
						|
  }, | 
						|
 | 
						|
  /** | 
						|
   * 添加子节点在 nextSibling 之前 | 
						|
   * @param {module:zrender/Element} child | 
						|
   * @param {module:zrender/Element} nextSibling | 
						|
   */ | 
						|
  addBefore: function (child, nextSibling) { | 
						|
    if (child && child !== this && child.parent !== this && nextSibling && nextSibling.parent === this) { | 
						|
      var children = this._children; | 
						|
      var idx = children.indexOf(nextSibling); | 
						|
 | 
						|
      if (idx >= 0) { | 
						|
        children.splice(idx, 0, child); | 
						|
 | 
						|
        this._doAdd(child); | 
						|
      } | 
						|
    } | 
						|
 | 
						|
    return this; | 
						|
  }, | 
						|
  _doAdd: function (child) { | 
						|
    if (child.parent) { | 
						|
      child.parent.remove(child); | 
						|
    } | 
						|
 | 
						|
    child.parent = this; | 
						|
    var storage = this.__storage; | 
						|
    var zr = this.__zr; | 
						|
 | 
						|
    if (storage && storage !== child.__storage) { | 
						|
      storage.addToStorage(child); | 
						|
 | 
						|
      if (child instanceof Group) { | 
						|
        child.addChildrenToStorage(storage); | 
						|
      } | 
						|
    } | 
						|
 | 
						|
    zr && zr.refresh(); | 
						|
  }, | 
						|
 | 
						|
  /** | 
						|
   * 移除子节点 | 
						|
   * @param {module:zrender/Element} child | 
						|
   */ | 
						|
  remove: function (child) { | 
						|
    var zr = this.__zr; | 
						|
    var storage = this.__storage; | 
						|
    var children = this._children; | 
						|
    var idx = zrUtil.indexOf(children, child); | 
						|
 | 
						|
    if (idx < 0) { | 
						|
      return this; | 
						|
    } | 
						|
 | 
						|
    children.splice(idx, 1); | 
						|
    child.parent = null; | 
						|
 | 
						|
    if (storage) { | 
						|
      storage.delFromStorage(child); | 
						|
 | 
						|
      if (child instanceof Group) { | 
						|
        child.delChildrenFromStorage(storage); | 
						|
      } | 
						|
    } | 
						|
 | 
						|
    zr && zr.refresh(); | 
						|
    return this; | 
						|
  }, | 
						|
 | 
						|
  /** | 
						|
   * 移除所有子节点 | 
						|
   */ | 
						|
  removeAll: function () { | 
						|
    var children = this._children; | 
						|
    var storage = this.__storage; | 
						|
    var child; | 
						|
    var i; | 
						|
 | 
						|
    for (i = 0; i < children.length; i++) { | 
						|
      child = children[i]; | 
						|
 | 
						|
      if (storage) { | 
						|
        storage.delFromStorage(child); | 
						|
 | 
						|
        if (child instanceof Group) { | 
						|
          child.delChildrenFromStorage(storage); | 
						|
        } | 
						|
      } | 
						|
 | 
						|
      child.parent = null; | 
						|
    } | 
						|
 | 
						|
    children.length = 0; | 
						|
    return this; | 
						|
  }, | 
						|
 | 
						|
  /** | 
						|
   * 遍历所有子节点 | 
						|
   * @param  {Function} cb | 
						|
   * @param  {}   context | 
						|
   */ | 
						|
  eachChild: function (cb, context) { | 
						|
    var children = this._children; | 
						|
 | 
						|
    for (var i = 0; i < children.length; i++) { | 
						|
      var child = children[i]; | 
						|
      cb.call(context, child, i); | 
						|
    } | 
						|
 | 
						|
    return this; | 
						|
  }, | 
						|
 | 
						|
  /** | 
						|
   * 深度优先遍历所有子孙节点 | 
						|
   * @param  {Function} cb | 
						|
   * @param  {}   context | 
						|
   */ | 
						|
  traverse: function (cb, context) { | 
						|
    for (var i = 0; i < this._children.length; i++) { | 
						|
      var child = this._children[i]; | 
						|
      cb.call(context, child); | 
						|
 | 
						|
      if (child.type === 'group') { | 
						|
        child.traverse(cb, context); | 
						|
      } | 
						|
    } | 
						|
 | 
						|
    return this; | 
						|
  }, | 
						|
  addChildrenToStorage: function (storage) { | 
						|
    for (var i = 0; i < this._children.length; i++) { | 
						|
      var child = this._children[i]; | 
						|
      storage.addToStorage(child); | 
						|
 | 
						|
      if (child instanceof Group) { | 
						|
        child.addChildrenToStorage(storage); | 
						|
      } | 
						|
    } | 
						|
  }, | 
						|
  delChildrenFromStorage: function (storage) { | 
						|
    for (var i = 0; i < this._children.length; i++) { | 
						|
      var child = this._children[i]; | 
						|
      storage.delFromStorage(child); | 
						|
 | 
						|
      if (child instanceof Group) { | 
						|
        child.delChildrenFromStorage(storage); | 
						|
      } | 
						|
    } | 
						|
  }, | 
						|
  dirty: function () { | 
						|
    this.__dirty = true; | 
						|
    this.__zr && this.__zr.refresh(); | 
						|
    return this; | 
						|
  }, | 
						|
 | 
						|
  /** | 
						|
   * @return {module:zrender/core/BoundingRect} | 
						|
   */ | 
						|
  getBoundingRect: function (includeChildren) { | 
						|
    // TODO Caching | 
						|
    var rect = null; | 
						|
    var tmpRect = new BoundingRect(0, 0, 0, 0); | 
						|
    var children = includeChildren || this._children; | 
						|
    var tmpMat = []; | 
						|
 | 
						|
    for (var i = 0; i < children.length; i++) { | 
						|
      var child = children[i]; | 
						|
 | 
						|
      if (child.ignore || child.invisible) { | 
						|
        continue; | 
						|
      } | 
						|
 | 
						|
      var childRect = child.getBoundingRect(); | 
						|
      var transform = child.getLocalTransform(tmpMat); // TODO | 
						|
      // The boundingRect cacluated by transforming original | 
						|
      // rect may be bigger than the actual bundingRect when rotation | 
						|
      // is used. (Consider a circle rotated aginst its center, where | 
						|
      // the actual boundingRect should be the same as that not be | 
						|
      // rotated.) But we can not find better approach to calculate | 
						|
      // actual boundingRect yet, considering performance. | 
						|
 | 
						|
      if (transform) { | 
						|
        tmpRect.copy(childRect); | 
						|
        tmpRect.applyTransform(transform); | 
						|
        rect = rect || tmpRect.clone(); | 
						|
        rect.union(tmpRect); | 
						|
      } else { | 
						|
        rect = rect || childRect.clone(); | 
						|
        rect.union(childRect); | 
						|
      } | 
						|
    } | 
						|
 | 
						|
    return rect || tmpRect; | 
						|
  } | 
						|
}; | 
						|
zrUtil.inherits(Group, Element); | 
						|
var _default = Group; | 
						|
module.exports = _default; |