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.
		
		
		
		
			
				
					905 lines
				
				26 KiB
			
		
		
			
		
	
	
					905 lines
				
				26 KiB
			| 
								 
											4 years ago
										 
									 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								* 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.
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var _config = require("../../config");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var __DEV__ = _config.__DEV__;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var zrUtil = require("zrender/lib/core/util");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var Eventful = require("zrender/lib/mixin/Eventful");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var graphic = require("../../util/graphic");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var interactionMutex = require("./interactionMutex");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var DataDiffer = require("../../data/DataDiffer");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								* 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.
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								var curry = zrUtil.curry;
							 | 
						||
| 
								 | 
							
								var each = zrUtil.each;
							 | 
						||
| 
								 | 
							
								var map = zrUtil.map;
							 | 
						||
| 
								 | 
							
								var mathMin = Math.min;
							 | 
						||
| 
								 | 
							
								var mathMax = Math.max;
							 | 
						||
| 
								 | 
							
								var mathPow = Math.pow;
							 | 
						||
| 
								 | 
							
								var COVER_Z = 10000;
							 | 
						||
| 
								 | 
							
								var UNSELECT_THRESHOLD = 6;
							 | 
						||
| 
								 | 
							
								var MIN_RESIZE_LINE_WIDTH = 6;
							 | 
						||
| 
								 | 
							
								var MUTEX_RESOURCE_KEY = 'globalPan';
							 | 
						||
| 
								 | 
							
								var DIRECTION_MAP = {
							 | 
						||
| 
								 | 
							
								  w: [0, 0],
							 | 
						||
| 
								 | 
							
								  e: [0, 1],
							 | 
						||
| 
								 | 
							
								  n: [1, 0],
							 | 
						||
| 
								 | 
							
								  s: [1, 1]
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								var CURSOR_MAP = {
							 | 
						||
| 
								 | 
							
								  w: 'ew',
							 | 
						||
| 
								 | 
							
								  e: 'ew',
							 | 
						||
| 
								 | 
							
								  n: 'ns',
							 | 
						||
| 
								 | 
							
								  s: 'ns',
							 | 
						||
| 
								 | 
							
								  ne: 'nesw',
							 | 
						||
| 
								 | 
							
								  sw: 'nesw',
							 | 
						||
| 
								 | 
							
								  nw: 'nwse',
							 | 
						||
| 
								 | 
							
								  se: 'nwse'
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								var DEFAULT_BRUSH_OPT = {
							 | 
						||
| 
								 | 
							
								  brushStyle: {
							 | 
						||
| 
								 | 
							
								    lineWidth: 2,
							 | 
						||
| 
								 | 
							
								    stroke: 'rgba(0,0,0,0.3)',
							 | 
						||
| 
								 | 
							
								    fill: 'rgba(0,0,0,0.1)'
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  transformable: true,
							 | 
						||
| 
								 | 
							
								  brushMode: 'single',
							 | 
						||
| 
								 | 
							
								  removeOnClick: false
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								var baseUID = 0;
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @alias module:echarts/component/helper/BrushController
							 | 
						||
| 
								 | 
							
								 * @constructor
							 | 
						||
| 
								 | 
							
								 * @mixin {module:zrender/mixin/Eventful}
							 | 
						||
| 
								 | 
							
								 * @event module:echarts/component/helper/BrushController#brush
							 | 
						||
| 
								 | 
							
								 *        params:
							 | 
						||
| 
								 | 
							
								 *            areas: Array.<Array>, coord relates to container group,
							 | 
						||
| 
								 | 
							
								 *                                    If no container specified, to global.
							 | 
						||
| 
								 | 
							
								 *            opt {
							 | 
						||
| 
								 | 
							
								 *                isEnd: boolean,
							 | 
						||
| 
								 | 
							
								 *                removeOnClick: boolean
							 | 
						||
| 
								 | 
							
								 *            }
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param {module:zrender/zrender~ZRender} zr
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function BrushController(zr) {
							 | 
						||
| 
								 | 
							
								  Eventful.call(this);
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * @type {module:zrender/zrender~ZRender}
							 | 
						||
| 
								 | 
							
								   * @private
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this._zr = zr;
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * @type {module:zrender/container/Group}
							 | 
						||
| 
								 | 
							
								   * @readOnly
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this.group = new graphic.Group();
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * Only for drawing (after enabledBrush).
							 | 
						||
| 
								 | 
							
								   *     'line', 'rect', 'polygon' or false
							 | 
						||
| 
								 | 
							
								   *     If passing false/null/undefined, disable brush.
							 | 
						||
| 
								 | 
							
								   *     If passing 'auto', determined by panel.defaultBrushType
							 | 
						||
| 
								 | 
							
								   * @private
							 | 
						||
| 
								 | 
							
								   * @type {string}
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this._brushType;
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * Only for drawing (after enabledBrush).
							 | 
						||
| 
								 | 
							
								   *
							 | 
						||
| 
								 | 
							
								   * @private
							 | 
						||
| 
								 | 
							
								   * @type {Object}
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this._brushOption;
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * @private
							 | 
						||
| 
								 | 
							
								   * @type {Object}
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this._panels;
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * @private
							 | 
						||
| 
								 | 
							
								   * @type {Array.<nubmer>}
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this._track = [];
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * @private
							 | 
						||
| 
								 | 
							
								   * @type {boolean}
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this._dragging;
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * @private
							 | 
						||
| 
								 | 
							
								   * @type {Array}
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this._covers = [];
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * @private
							 | 
						||
| 
								 | 
							
								   * @type {moudule:zrender/container/Group}
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this._creatingCover;
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * `true` means global panel
							 | 
						||
| 
								 | 
							
								   * @private
							 | 
						||
| 
								 | 
							
								   * @type {module:zrender/container/Group|boolean}
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this._creatingPanel;
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * @private
							 | 
						||
| 
								 | 
							
								   * @type {boolean}
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this._enableGlobalPan;
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * @private
							 | 
						||
| 
								 | 
							
								   * @type {boolean}
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * @private
							 | 
						||
| 
								 | 
							
								   * @type {string}
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								  this._uid = 'brushController_' + baseUID++;
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * @private
							 | 
						||
| 
								 | 
							
								   * @type {Object}
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this._handlers = {};
							 | 
						||
| 
								 | 
							
								  each(mouseHandlers, function (handler, eventName) {
							 | 
						||
| 
								 | 
							
								    this._handlers[eventName] = zrUtil.bind(handler, this);
							 | 
						||
| 
								 | 
							
								  }, this);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BrushController.prototype = {
							 | 
						||
| 
								 | 
							
								  constructor: BrushController,
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * If set to null/undefined/false, select disabled.
							 | 
						||
| 
								 | 
							
								   * @param {Object} brushOption
							 | 
						||
| 
								 | 
							
								   * @param {string|boolean} brushOption.brushType 'line', 'rect', 'polygon' or false
							 | 
						||
| 
								 | 
							
								   *                          If passing false/null/undefined, disable brush.
							 | 
						||
| 
								 | 
							
								   *                          If passing 'auto', determined by panel.defaultBrushType.
							 | 
						||
| 
								 | 
							
								   *                              ('auto' can not be used in global panel)
							 | 
						||
| 
								 | 
							
								   * @param {number} [brushOption.brushMode='single'] 'single' or 'multiple'
							 | 
						||
| 
								 | 
							
								   * @param {boolean} [brushOption.transformable=true]
							 | 
						||
| 
								 | 
							
								   * @param {boolean} [brushOption.removeOnClick=false]
							 | 
						||
| 
								 | 
							
								   * @param {Object} [brushOption.brushStyle]
							 | 
						||
| 
								 | 
							
								   * @param {number} [brushOption.brushStyle.width]
							 | 
						||
| 
								 | 
							
								   * @param {number} [brushOption.brushStyle.lineWidth]
							 | 
						||
| 
								 | 
							
								   * @param {string} [brushOption.brushStyle.stroke]
							 | 
						||
| 
								 | 
							
								   * @param {string} [brushOption.brushStyle.fill]
							 | 
						||
| 
								 | 
							
								   * @param {number} [brushOption.z]
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								  enableBrush: function (brushOption) {
							 | 
						||
| 
								 | 
							
								    this._brushType && doDisableBrush(this);
							 | 
						||
| 
								 | 
							
								    brushOption.brushType && doEnableBrush(this, brushOption);
							 | 
						||
| 
								 | 
							
								    return this;
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * @param {Array.<Object>} panelOpts If not pass, it is global brush.
							 | 
						||
| 
								 | 
							
								   *        Each items: {
							 | 
						||
| 
								 | 
							
								   *            panelId, // mandatory.
							 | 
						||
| 
								 | 
							
								   *            clipPath, // mandatory. function.
							 | 
						||
| 
								 | 
							
								   *            isTargetByCursor, // mandatory. function.
							 | 
						||
| 
								 | 
							
								   *            defaultBrushType, // optional, only used when brushType is 'auto'.
							 | 
						||
| 
								 | 
							
								   *            getLinearBrushOtherExtent, // optional. function.
							 | 
						||
| 
								 | 
							
								   *        }
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								  setPanels: function (panelOpts) {
							 | 
						||
| 
								 | 
							
								    if (panelOpts && panelOpts.length) {
							 | 
						||
| 
								 | 
							
								      var panels = this._panels = {};
							 | 
						||
| 
								 | 
							
								      zrUtil.each(panelOpts, function (panelOpts) {
							 | 
						||
| 
								 | 
							
								        panels[panelOpts.panelId] = zrUtil.clone(panelOpts);
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      this._panels = null;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return this;
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * @param {Object} [opt]
							 | 
						||
| 
								 | 
							
								   * @return {boolean} [opt.enableGlobalPan=false]
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								  mount: function (opt) {
							 | 
						||
| 
								 | 
							
								    opt = opt || {};
							 | 
						||
| 
								 | 
							
								    this._enableGlobalPan = opt.enableGlobalPan;
							 | 
						||
| 
								 | 
							
								    var thisGroup = this.group;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    this._zr.add(thisGroup);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    thisGroup.attr({
							 | 
						||
| 
								 | 
							
								      position: opt.position || [0, 0],
							 | 
						||
| 
								 | 
							
								      rotation: opt.rotation || 0,
							 | 
						||
| 
								 | 
							
								      scale: opt.scale || [1, 1]
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								    this._transform = thisGroup.getLocalTransform();
							 | 
						||
| 
								 | 
							
								    return this;
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  eachCover: function (cb, context) {
							 | 
						||
| 
								 | 
							
								    each(this._covers, cb, context);
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * Update covers.
							 | 
						||
| 
								 | 
							
								   * @param {Array.<Object>} brushOptionList Like:
							 | 
						||
| 
								 | 
							
								   *        [
							 | 
						||
| 
								 | 
							
								   *            {id: 'xx', brushType: 'line', range: [23, 44], brushStyle, transformable},
							 | 
						||
| 
								 | 
							
								   *            {id: 'yy', brushType: 'rect', range: [[23, 44], [23, 54]]},
							 | 
						||
| 
								 | 
							
								   *            ...
							 | 
						||
| 
								 | 
							
								   *        ]
							 | 
						||
| 
								 | 
							
								   *        `brushType` is required in each cover info. (can not be 'auto')
							 | 
						||
| 
								 | 
							
								   *        `id` is not mandatory.
							 | 
						||
| 
								 | 
							
								   *        `brushStyle`, `transformable` is not mandatory, use DEFAULT_BRUSH_OPT by default.
							 | 
						||
| 
								 | 
							
								   *        If brushOptionList is null/undefined, all covers removed.
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								  updateCovers: function (brushOptionList) {
							 | 
						||
| 
								 | 
							
								    brushOptionList = zrUtil.map(brushOptionList, function (brushOption) {
							 | 
						||
| 
								 | 
							
								      return zrUtil.merge(zrUtil.clone(DEFAULT_BRUSH_OPT), brushOption, true);
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								    var tmpIdPrefix = '\0-brush-index-';
							 | 
						||
| 
								 | 
							
								    var oldCovers = this._covers;
							 | 
						||
| 
								 | 
							
								    var newCovers = this._covers = [];
							 | 
						||
| 
								 | 
							
								    var controller = this;
							 | 
						||
| 
								 | 
							
								    var creatingCover = this._creatingCover;
							 | 
						||
| 
								 | 
							
								    new DataDiffer(oldCovers, brushOptionList, oldGetKey, getKey).add(addOrUpdate).update(addOrUpdate).remove(remove).execute();
							 | 
						||
| 
								 | 
							
								    return this;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function getKey(brushOption, index) {
							 | 
						||
| 
								 | 
							
								      return (brushOption.id != null ? brushOption.id : tmpIdPrefix + index) + '-' + brushOption.brushType;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function oldGetKey(cover, index) {
							 | 
						||
| 
								 | 
							
								      return getKey(cover.__brushOption, index);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function addOrUpdate(newIndex, oldIndex) {
							 | 
						||
| 
								 | 
							
								      var newBrushOption = brushOptionList[newIndex]; // Consider setOption in event listener of brushSelect,
							 | 
						||
| 
								 | 
							
								      // where updating cover when creating should be forbiden.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (oldIndex != null && oldCovers[oldIndex] === creatingCover) {
							 | 
						||
| 
								 | 
							
								        newCovers[newIndex] = oldCovers[oldIndex];
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								        var cover = newCovers[newIndex] = oldIndex != null ? (oldCovers[oldIndex].__brushOption = newBrushOption, oldCovers[oldIndex]) : endCreating(controller, createCover(controller, newBrushOption));
							 | 
						||
| 
								 | 
							
								        updateCoverAfterCreation(controller, cover);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function remove(oldIndex) {
							 | 
						||
| 
								 | 
							
								      if (oldCovers[oldIndex] !== creatingCover) {
							 | 
						||
| 
								 | 
							
								        controller.group.remove(oldCovers[oldIndex]);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  unmount: function () {
							 | 
						||
| 
								 | 
							
								    this.enableBrush(false); // container may 'removeAll' outside.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    clearCovers(this);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    this._zr.remove(this.group);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return this;
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  dispose: function () {
							 | 
						||
| 
								 | 
							
								    this.unmount();
							 | 
						||
| 
								 | 
							
								    this.off();
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								zrUtil.mixin(BrushController, Eventful);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function doEnableBrush(controller, brushOption) {
							 | 
						||
| 
								 | 
							
								  var zr = controller._zr; // Consider roam, which takes globalPan too.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (!controller._enableGlobalPan) {
							 | 
						||
| 
								 | 
							
								    interactionMutex.take(zr, MUTEX_RESOURCE_KEY, controller._uid);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  each(controller._handlers, function (handler, eventName) {
							 | 
						||
| 
								 | 
							
								    zr.on(eventName, handler);
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  controller._brushType = brushOption.brushType;
							 | 
						||
| 
								 | 
							
								  controller._brushOption = zrUtil.merge(zrUtil.clone(DEFAULT_BRUSH_OPT), brushOption, true);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function doDisableBrush(controller) {
							 | 
						||
| 
								 | 
							
								  var zr = controller._zr;
							 | 
						||
| 
								 | 
							
								  interactionMutex.release(zr, MUTEX_RESOURCE_KEY, controller._uid);
							 | 
						||
| 
								 | 
							
								  each(controller._handlers, function (handler, eventName) {
							 | 
						||
| 
								 | 
							
								    zr.off(eventName, handler);
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  controller._brushType = controller._brushOption = null;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function createCover(controller, brushOption) {
							 | 
						||
| 
								 | 
							
								  var cover = coverRenderers[brushOption.brushType].createCover(controller, brushOption);
							 | 
						||
| 
								 | 
							
								  cover.__brushOption = brushOption;
							 | 
						||
| 
								 | 
							
								  updateZ(cover, brushOption);
							 | 
						||
| 
								 | 
							
								  controller.group.add(cover);
							 | 
						||
| 
								 | 
							
								  return cover;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function endCreating(controller, creatingCover) {
							 | 
						||
| 
								 | 
							
								  var coverRenderer = getCoverRenderer(creatingCover);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (coverRenderer.endCreating) {
							 | 
						||
| 
								 | 
							
								    coverRenderer.endCreating(controller, creatingCover);
							 | 
						||
| 
								 | 
							
								    updateZ(creatingCover, creatingCover.__brushOption);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return creatingCover;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function updateCoverShape(controller, cover) {
							 | 
						||
| 
								 | 
							
								  var brushOption = cover.__brushOption;
							 | 
						||
| 
								 | 
							
								  getCoverRenderer(cover).updateCoverShape(controller, cover, brushOption.range, brushOption);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function updateZ(cover, brushOption) {
							 | 
						||
| 
								 | 
							
								  var z = brushOption.z;
							 | 
						||
| 
								 | 
							
								  z == null && (z = COVER_Z);
							 | 
						||
| 
								 | 
							
								  cover.traverse(function (el) {
							 | 
						||
| 
								 | 
							
								    el.z = z;
							 | 
						||
| 
								 | 
							
								    el.z2 = z; // Consider in given container.
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function updateCoverAfterCreation(controller, cover) {
							 | 
						||
| 
								 | 
							
								  getCoverRenderer(cover).updateCommon(controller, cover);
							 | 
						||
| 
								 | 
							
								  updateCoverShape(controller, cover);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function getCoverRenderer(cover) {
							 | 
						||
| 
								 | 
							
								  return coverRenderers[cover.__brushOption.brushType];
							 | 
						||
| 
								 | 
							
								} // return target panel or `true` (means global panel)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function getPanelByPoint(controller, e, localCursorPoint) {
							 | 
						||
| 
								 | 
							
								  var panels = controller._panels;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (!panels) {
							 | 
						||
| 
								 | 
							
								    return true; // Global panel
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var panel;
							 | 
						||
| 
								 | 
							
								  var transform = controller._transform;
							 | 
						||
| 
								 | 
							
								  each(panels, function (pn) {
							 | 
						||
| 
								 | 
							
								    pn.isTargetByCursor(e, localCursorPoint, transform) && (panel = pn);
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  return panel;
							 | 
						||
| 
								 | 
							
								} // Return a panel or true
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function getPanelByCover(controller, cover) {
							 | 
						||
| 
								 | 
							
								  var panels = controller._panels;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (!panels) {
							 | 
						||
| 
								 | 
							
								    return true; // Global panel
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var panelId = cover.__brushOption.panelId; // User may give cover without coord sys info,
							 | 
						||
| 
								 | 
							
								  // which is then treated as global panel.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return panelId != null ? panels[panelId] : true;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function clearCovers(controller) {
							 | 
						||
| 
								 | 
							
								  var covers = controller._covers;
							 | 
						||
| 
								 | 
							
								  var originalLength = covers.length;
							 | 
						||
| 
								 | 
							
								  each(covers, function (cover) {
							 | 
						||
| 
								 | 
							
								    controller.group.remove(cover);
							 | 
						||
| 
								 | 
							
								  }, controller);
							 | 
						||
| 
								 | 
							
								  covers.length = 0;
							 | 
						||
| 
								 | 
							
								  return !!originalLength;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function trigger(controller, opt) {
							 | 
						||
| 
								 | 
							
								  var areas = map(controller._covers, function (cover) {
							 | 
						||
| 
								 | 
							
								    var brushOption = cover.__brushOption;
							 | 
						||
| 
								 | 
							
								    var range = zrUtil.clone(brushOption.range);
							 | 
						||
| 
								 | 
							
								    return {
							 | 
						||
| 
								 | 
							
								      brushType: brushOption.brushType,
							 | 
						||
| 
								 | 
							
								      panelId: brushOption.panelId,
							 | 
						||
| 
								 | 
							
								      range: range
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  controller.trigger('brush', areas, {
							 | 
						||
| 
								 | 
							
								    isEnd: !!opt.isEnd,
							 | 
						||
| 
								 | 
							
								    removeOnClick: !!opt.removeOnClick
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function shouldShowCover(controller) {
							 | 
						||
| 
								 | 
							
								  var track = controller._track;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (!track.length) {
							 | 
						||
| 
								 | 
							
								    return false;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var p2 = track[track.length - 1];
							 | 
						||
| 
								 | 
							
								  var p1 = track[0];
							 | 
						||
| 
								 | 
							
								  var dx = p2[0] - p1[0];
							 | 
						||
| 
								 | 
							
								  var dy = p2[1] - p1[1];
							 | 
						||
| 
								 | 
							
								  var dist = mathPow(dx * dx + dy * dy, 0.5);
							 | 
						||
| 
								 | 
							
								  return dist > UNSELECT_THRESHOLD;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function getTrackEnds(track) {
							 | 
						||
| 
								 | 
							
								  var tail = track.length - 1;
							 | 
						||
| 
								 | 
							
								  tail < 0 && (tail = 0);
							 | 
						||
| 
								 | 
							
								  return [track[0], track[tail]];
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function createBaseRectCover(doDrift, controller, brushOption, edgeNames) {
							 | 
						||
| 
								 | 
							
								  var cover = new graphic.Group();
							 | 
						||
| 
								 | 
							
								  cover.add(new graphic.Rect({
							 | 
						||
| 
								 | 
							
								    name: 'main',
							 | 
						||
| 
								 | 
							
								    style: makeStyle(brushOption),
							 | 
						||
| 
								 | 
							
								    silent: true,
							 | 
						||
| 
								 | 
							
								    draggable: true,
							 | 
						||
| 
								 | 
							
								    cursor: 'move',
							 | 
						||
| 
								 | 
							
								    drift: curry(doDrift, controller, cover, 'nswe'),
							 | 
						||
| 
								 | 
							
								    ondragend: curry(trigger, controller, {
							 | 
						||
| 
								 | 
							
								      isEnd: true
							 | 
						||
| 
								 | 
							
								    })
							 | 
						||
| 
								 | 
							
								  }));
							 | 
						||
| 
								 | 
							
								  each(edgeNames, function (name) {
							 | 
						||
| 
								 | 
							
								    cover.add(new graphic.Rect({
							 | 
						||
| 
								 | 
							
								      name: name,
							 | 
						||
| 
								 | 
							
								      style: {
							 | 
						||
| 
								 | 
							
								        opacity: 0
							 | 
						||
| 
								 | 
							
								      },
							 | 
						||
| 
								 | 
							
								      draggable: true,
							 | 
						||
| 
								 | 
							
								      silent: true,
							 | 
						||
| 
								 | 
							
								      invisible: true,
							 | 
						||
| 
								 | 
							
								      drift: curry(doDrift, controller, cover, name),
							 | 
						||
| 
								 | 
							
								      ondragend: curry(trigger, controller, {
							 | 
						||
| 
								 | 
							
								        isEnd: true
							 | 
						||
| 
								 | 
							
								      })
							 | 
						||
| 
								 | 
							
								    }));
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  return cover;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function updateBaseRect(controller, cover, localRange, brushOption) {
							 | 
						||
| 
								 | 
							
								  var lineWidth = brushOption.brushStyle.lineWidth || 0;
							 | 
						||
| 
								 | 
							
								  var handleSize = mathMax(lineWidth, MIN_RESIZE_LINE_WIDTH);
							 | 
						||
| 
								 | 
							
								  var x = localRange[0][0];
							 | 
						||
| 
								 | 
							
								  var y = localRange[1][0];
							 | 
						||
| 
								 | 
							
								  var xa = x - lineWidth / 2;
							 | 
						||
| 
								 | 
							
								  var ya = y - lineWidth / 2;
							 | 
						||
| 
								 | 
							
								  var x2 = localRange[0][1];
							 | 
						||
| 
								 | 
							
								  var y2 = localRange[1][1];
							 | 
						||
| 
								 | 
							
								  var x2a = x2 - handleSize + lineWidth / 2;
							 | 
						||
| 
								 | 
							
								  var y2a = y2 - handleSize + lineWidth / 2;
							 | 
						||
| 
								 | 
							
								  var width = x2 - x;
							 | 
						||
| 
								 | 
							
								  var height = y2 - y;
							 | 
						||
| 
								 | 
							
								  var widtha = width + lineWidth;
							 | 
						||
| 
								 | 
							
								  var heighta = height + lineWidth;
							 | 
						||
| 
								 | 
							
								  updateRectShape(controller, cover, 'main', x, y, width, height);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (brushOption.transformable) {
							 | 
						||
| 
								 | 
							
								    updateRectShape(controller, cover, 'w', xa, ya, handleSize, heighta);
							 | 
						||
| 
								 | 
							
								    updateRectShape(controller, cover, 'e', x2a, ya, handleSize, heighta);
							 | 
						||
| 
								 | 
							
								    updateRectShape(controller, cover, 'n', xa, ya, widtha, handleSize);
							 | 
						||
| 
								 | 
							
								    updateRectShape(controller, cover, 's', xa, y2a, widtha, handleSize);
							 | 
						||
| 
								 | 
							
								    updateRectShape(controller, cover, 'nw', xa, ya, handleSize, handleSize);
							 | 
						||
| 
								 | 
							
								    updateRectShape(controller, cover, 'ne', x2a, ya, handleSize, handleSize);
							 | 
						||
| 
								 | 
							
								    updateRectShape(controller, cover, 'sw', xa, y2a, handleSize, handleSize);
							 | 
						||
| 
								 | 
							
								    updateRectShape(controller, cover, 'se', x2a, y2a, handleSize, handleSize);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function updateCommon(controller, cover) {
							 | 
						||
| 
								 | 
							
								  var brushOption = cover.__brushOption;
							 | 
						||
| 
								 | 
							
								  var transformable = brushOption.transformable;
							 | 
						||
| 
								 | 
							
								  var mainEl = cover.childAt(0);
							 | 
						||
| 
								 | 
							
								  mainEl.useStyle(makeStyle(brushOption));
							 | 
						||
| 
								 | 
							
								  mainEl.attr({
							 | 
						||
| 
								 | 
							
								    silent: !transformable,
							 | 
						||
| 
								 | 
							
								    cursor: transformable ? 'move' : 'default'
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  each(['w', 'e', 'n', 's', 'se', 'sw', 'ne', 'nw'], function (name) {
							 | 
						||
| 
								 | 
							
								    var el = cover.childOfName(name);
							 | 
						||
| 
								 | 
							
								    var globalDir = getGlobalDirection(controller, name);
							 | 
						||
| 
								 | 
							
								    el && el.attr({
							 | 
						||
| 
								 | 
							
								      silent: !transformable,
							 | 
						||
| 
								 | 
							
								      invisible: !transformable,
							 | 
						||
| 
								 | 
							
								      cursor: transformable ? CURSOR_MAP[globalDir] + '-resize' : null
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function updateRectShape(controller, cover, name, x, y, w, h) {
							 | 
						||
| 
								 | 
							
								  var el = cover.childOfName(name);
							 | 
						||
| 
								 | 
							
								  el && el.setShape(pointsToRect(clipByPanel(controller, cover, [[x, y], [x + w, y + h]])));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function makeStyle(brushOption) {
							 | 
						||
| 
								 | 
							
								  return zrUtil.defaults({
							 | 
						||
| 
								 | 
							
								    strokeNoScale: true
							 | 
						||
| 
								 | 
							
								  }, brushOption.brushStyle);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function formatRectRange(x, y, x2, y2) {
							 | 
						||
| 
								 | 
							
								  var min = [mathMin(x, x2), mathMin(y, y2)];
							 | 
						||
| 
								 | 
							
								  var max = [mathMax(x, x2), mathMax(y, y2)];
							 | 
						||
| 
								 | 
							
								  return [[min[0], max[0]], // x range
							 | 
						||
| 
								 | 
							
								  [min[1], max[1]] // y range
							 | 
						||
| 
								 | 
							
								  ];
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function getTransform(controller) {
							 | 
						||
| 
								 | 
							
								  return graphic.getTransform(controller.group);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function getGlobalDirection(controller, localDirection) {
							 | 
						||
| 
								 | 
							
								  if (localDirection.length > 1) {
							 | 
						||
| 
								 | 
							
								    localDirection = localDirection.split('');
							 | 
						||
| 
								 | 
							
								    var globalDir = [getGlobalDirection(controller, localDirection[0]), getGlobalDirection(controller, localDirection[1])];
							 | 
						||
| 
								 | 
							
								    (globalDir[0] === 'e' || globalDir[0] === 'w') && globalDir.reverse();
							 | 
						||
| 
								 | 
							
								    return globalDir.join('');
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    var map = {
							 | 
						||
| 
								 | 
							
								      w: 'left',
							 | 
						||
| 
								 | 
							
								      e: 'right',
							 | 
						||
| 
								 | 
							
								      n: 'top',
							 | 
						||
| 
								 | 
							
								      s: 'bottom'
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    var inverseMap = {
							 | 
						||
| 
								 | 
							
								      left: 'w',
							 | 
						||
| 
								 | 
							
								      right: 'e',
							 | 
						||
| 
								 | 
							
								      top: 'n',
							 | 
						||
| 
								 | 
							
								      bottom: 's'
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    var globalDir = graphic.transformDirection(map[localDirection], getTransform(controller));
							 | 
						||
| 
								 | 
							
								    return inverseMap[globalDir];
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function driftRect(toRectRange, fromRectRange, controller, cover, name, dx, dy, e) {
							 | 
						||
| 
								 | 
							
								  var brushOption = cover.__brushOption;
							 | 
						||
| 
								 | 
							
								  var rectRange = toRectRange(brushOption.range);
							 | 
						||
| 
								 | 
							
								  var localDelta = toLocalDelta(controller, dx, dy);
							 | 
						||
| 
								 | 
							
								  each(name.split(''), function (namePart) {
							 | 
						||
| 
								 | 
							
								    var ind = DIRECTION_MAP[namePart];
							 | 
						||
| 
								 | 
							
								    rectRange[ind[0]][ind[1]] += localDelta[ind[0]];
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  brushOption.range = fromRectRange(formatRectRange(rectRange[0][0], rectRange[1][0], rectRange[0][1], rectRange[1][1]));
							 | 
						||
| 
								 | 
							
								  updateCoverAfterCreation(controller, cover);
							 | 
						||
| 
								 | 
							
								  trigger(controller, {
							 | 
						||
| 
								 | 
							
								    isEnd: false
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function driftPolygon(controller, cover, dx, dy, e) {
							 | 
						||
| 
								 | 
							
								  var range = cover.__brushOption.range;
							 | 
						||
| 
								 | 
							
								  var localDelta = toLocalDelta(controller, dx, dy);
							 | 
						||
| 
								 | 
							
								  each(range, function (point) {
							 | 
						||
| 
								 | 
							
								    point[0] += localDelta[0];
							 | 
						||
| 
								 | 
							
								    point[1] += localDelta[1];
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  updateCoverAfterCreation(controller, cover);
							 | 
						||
| 
								 | 
							
								  trigger(controller, {
							 | 
						||
| 
								 | 
							
								    isEnd: false
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function toLocalDelta(controller, dx, dy) {
							 | 
						||
| 
								 | 
							
								  var thisGroup = controller.group;
							 | 
						||
| 
								 | 
							
								  var localD = thisGroup.transformCoordToLocal(dx, dy);
							 | 
						||
| 
								 | 
							
								  var localZero = thisGroup.transformCoordToLocal(0, 0);
							 | 
						||
| 
								 | 
							
								  return [localD[0] - localZero[0], localD[1] - localZero[1]];
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function clipByPanel(controller, cover, data) {
							 | 
						||
| 
								 | 
							
								  var panel = getPanelByCover(controller, cover);
							 | 
						||
| 
								 | 
							
								  return panel && panel !== true ? panel.clipPath(data, controller._transform) : zrUtil.clone(data);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function pointsToRect(points) {
							 | 
						||
| 
								 | 
							
								  var xmin = mathMin(points[0][0], points[1][0]);
							 | 
						||
| 
								 | 
							
								  var ymin = mathMin(points[0][1], points[1][1]);
							 | 
						||
| 
								 | 
							
								  var xmax = mathMax(points[0][0], points[1][0]);
							 | 
						||
| 
								 | 
							
								  var ymax = mathMax(points[0][1], points[1][1]);
							 | 
						||
| 
								 | 
							
								  return {
							 | 
						||
| 
								 | 
							
								    x: xmin,
							 | 
						||
| 
								 | 
							
								    y: ymin,
							 | 
						||
| 
								 | 
							
								    width: xmax - xmin,
							 | 
						||
| 
								 | 
							
								    height: ymax - ymin
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function resetCursor(controller, e, localCursorPoint) {
							 | 
						||
| 
								 | 
							
								  // Check active
							 | 
						||
| 
								 | 
							
								  if (!controller._brushType) {
							 | 
						||
| 
								 | 
							
								    return;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var zr = controller._zr;
							 | 
						||
| 
								 | 
							
								  var covers = controller._covers;
							 | 
						||
| 
								 | 
							
								  var currPanel = getPanelByPoint(controller, e, localCursorPoint); // Check whether in covers.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (!controller._dragging) {
							 | 
						||
| 
								 | 
							
								    for (var i = 0; i < covers.length; i++) {
							 | 
						||
| 
								 | 
							
								      var brushOption = covers[i].__brushOption;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (currPanel && (currPanel === true || brushOption.panelId === currPanel.panelId) && coverRenderers[brushOption.brushType].contain(covers[i], localCursorPoint[0], localCursorPoint[1])) {
							 | 
						||
| 
								 | 
							
								        // Use cursor style set on cover.
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  currPanel && zr.setCursorStyle('crosshair');
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function preventDefault(e) {
							 | 
						||
| 
								 | 
							
								  var rawE = e.event;
							 | 
						||
| 
								 | 
							
								  rawE.preventDefault && rawE.preventDefault();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function mainShapeContain(cover, x, y) {
							 | 
						||
| 
								 | 
							
								  return cover.childOfName('main').contain(x, y);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function updateCoverByMouse(controller, e, localCursorPoint, isEnd) {
							 | 
						||
| 
								 | 
							
								  var creatingCover = controller._creatingCover;
							 | 
						||
| 
								 | 
							
								  var panel = controller._creatingPanel;
							 | 
						||
| 
								 | 
							
								  var thisBrushOption = controller._brushOption;
							 | 
						||
| 
								 | 
							
								  var eventParams;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  controller._track.push(localCursorPoint.slice());
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (shouldShowCover(controller) || creatingCover) {
							 | 
						||
| 
								 | 
							
								    if (panel && !creatingCover) {
							 | 
						||
| 
								 | 
							
								      thisBrushOption.brushMode === 'single' && clearCovers(controller);
							 | 
						||
| 
								 | 
							
								      var brushOption = zrUtil.clone(thisBrushOption);
							 | 
						||
| 
								 | 
							
								      brushOption.brushType = determineBrushType(brushOption.brushType, panel);
							 | 
						||
| 
								 | 
							
								      brushOption.panelId = panel === true ? null : panel.panelId;
							 | 
						||
| 
								 | 
							
								      creatingCover = controller._creatingCover = createCover(controller, brushOption);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      controller._covers.push(creatingCover);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (creatingCover) {
							 | 
						||
| 
								 | 
							
								      var coverRenderer = coverRenderers[determineBrushType(controller._brushType, panel)];
							 | 
						||
| 
								 | 
							
								      var coverBrushOption = creatingCover.__brushOption;
							 | 
						||
| 
								 | 
							
								      coverBrushOption.range = coverRenderer.getCreatingRange(clipByPanel(controller, creatingCover, controller._track));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (isEnd) {
							 | 
						||
| 
								 | 
							
								        endCreating(controller, creatingCover);
							 | 
						||
| 
								 | 
							
								        coverRenderer.updateCommon(controller, creatingCover);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      updateCoverShape(controller, creatingCover);
							 | 
						||
| 
								 | 
							
								      eventParams = {
							 | 
						||
| 
								 | 
							
								        isEnd: isEnd
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  } else if (isEnd && thisBrushOption.brushMode === 'single' && thisBrushOption.removeOnClick) {
							 | 
						||
| 
								 | 
							
								    // Help user to remove covers easily, only by a tiny drag, in 'single' mode.
							 | 
						||
| 
								 | 
							
								    // But a single click do not clear covers, because user may have casual
							 | 
						||
| 
								 | 
							
								    // clicks (for example, click on other component and do not expect covers
							 | 
						||
| 
								 | 
							
								    // disappear).
							 | 
						||
| 
								 | 
							
								    // Only some cover removed, trigger action, but not every click trigger action.
							 | 
						||
| 
								 | 
							
								    if (getPanelByPoint(controller, e, localCursorPoint) && clearCovers(controller)) {
							 | 
						||
| 
								 | 
							
								      eventParams = {
							 | 
						||
| 
								 | 
							
								        isEnd: isEnd,
							 | 
						||
| 
								 | 
							
								        removeOnClick: true
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return eventParams;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function determineBrushType(brushType, panel) {
							 | 
						||
| 
								 | 
							
								  if (brushType === 'auto') {
							 | 
						||
| 
								 | 
							
								    return panel.defaultBrushType;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return brushType;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var mouseHandlers = {
							 | 
						||
| 
								 | 
							
								  mousedown: function (e) {
							 | 
						||
| 
								 | 
							
								    if (this._dragging) {
							 | 
						||
| 
								 | 
							
								      // In case some browser do not support globalOut,
							 | 
						||
| 
								 | 
							
								      // and release mose out side the browser.
							 | 
						||
| 
								 | 
							
								      handleDragEnd.call(this, e);
							 | 
						||
| 
								 | 
							
								    } else if (!e.target || !e.target.draggable) {
							 | 
						||
| 
								 | 
							
								      preventDefault(e);
							 | 
						||
| 
								 | 
							
								      var localCursorPoint = this.group.transformCoordToLocal(e.offsetX, e.offsetY);
							 | 
						||
| 
								 | 
							
								      this._creatingCover = null;
							 | 
						||
| 
								 | 
							
								      var panel = this._creatingPanel = getPanelByPoint(this, e, localCursorPoint);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (panel) {
							 | 
						||
| 
								 | 
							
								        this._dragging = true;
							 | 
						||
| 
								 | 
							
								        this._track = [localCursorPoint.slice()];
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  mousemove: function (e) {
							 | 
						||
| 
								 | 
							
								    var localCursorPoint = this.group.transformCoordToLocal(e.offsetX, e.offsetY);
							 | 
						||
| 
								 | 
							
								    resetCursor(this, e, localCursorPoint);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (this._dragging) {
							 | 
						||
| 
								 | 
							
								      preventDefault(e);
							 | 
						||
| 
								 | 
							
								      var eventParams = updateCoverByMouse(this, e, localCursorPoint, false);
							 | 
						||
| 
								 | 
							
								      eventParams && trigger(this, eventParams);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  mouseup: handleDragEnd //,
							 | 
						||
| 
								 | 
							
								  // FIXME
							 | 
						||
| 
								 | 
							
								  // in tooltip, globalout should not be triggered.
							 | 
						||
| 
								 | 
							
								  // globalout: handleDragEnd
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function handleDragEnd(e) {
							 | 
						||
| 
								 | 
							
								  if (this._dragging) {
							 | 
						||
| 
								 | 
							
								    preventDefault(e);
							 | 
						||
| 
								 | 
							
								    var localCursorPoint = this.group.transformCoordToLocal(e.offsetX, e.offsetY);
							 | 
						||
| 
								 | 
							
								    var eventParams = updateCoverByMouse(this, e, localCursorPoint, true);
							 | 
						||
| 
								 | 
							
								    this._dragging = false;
							 | 
						||
| 
								 | 
							
								    this._track = [];
							 | 
						||
| 
								 | 
							
								    this._creatingCover = null; // trigger event shoule be at final, after procedure will be nested.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    eventParams && trigger(this, eventParams);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * key: brushType
							 | 
						||
| 
								 | 
							
								 * @type {Object}
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var coverRenderers = {
							 | 
						||
| 
								 | 
							
								  lineX: getLineRenderer(0),
							 | 
						||
| 
								 | 
							
								  lineY: getLineRenderer(1),
							 | 
						||
| 
								 | 
							
								  rect: {
							 | 
						||
| 
								 | 
							
								    createCover: function (controller, brushOption) {
							 | 
						||
| 
								 | 
							
								      return createBaseRectCover(curry(driftRect, function (range) {
							 | 
						||
| 
								 | 
							
								        return range;
							 | 
						||
| 
								 | 
							
								      }, function (range) {
							 | 
						||
| 
								 | 
							
								        return range;
							 | 
						||
| 
								 | 
							
								      }), controller, brushOption, ['w', 'e', 'n', 's', 'se', 'sw', 'ne', 'nw']);
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    getCreatingRange: function (localTrack) {
							 | 
						||
| 
								 | 
							
								      var ends = getTrackEnds(localTrack);
							 | 
						||
| 
								 | 
							
								      return formatRectRange(ends[1][0], ends[1][1], ends[0][0], ends[0][1]);
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    updateCoverShape: function (controller, cover, localRange, brushOption) {
							 | 
						||
| 
								 | 
							
								      updateBaseRect(controller, cover, localRange, brushOption);
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    updateCommon: updateCommon,
							 | 
						||
| 
								 | 
							
								    contain: mainShapeContain
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  polygon: {
							 | 
						||
| 
								 | 
							
								    createCover: function (controller, brushOption) {
							 | 
						||
| 
								 | 
							
								      var cover = new graphic.Group(); // Do not use graphic.Polygon because graphic.Polyline do not close the
							 | 
						||
| 
								 | 
							
								      // border of the shape when drawing, which is a better experience for user.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      cover.add(new graphic.Polyline({
							 | 
						||
| 
								 | 
							
								        name: 'main',
							 | 
						||
| 
								 | 
							
								        style: makeStyle(brushOption),
							 | 
						||
| 
								 | 
							
								        silent: true
							 | 
						||
| 
								 | 
							
								      }));
							 | 
						||
| 
								 | 
							
								      return cover;
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    getCreatingRange: function (localTrack) {
							 | 
						||
| 
								 | 
							
								      return localTrack;
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    endCreating: function (controller, cover) {
							 | 
						||
| 
								 | 
							
								      cover.remove(cover.childAt(0)); // Use graphic.Polygon close the shape.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      cover.add(new graphic.Polygon({
							 | 
						||
| 
								 | 
							
								        name: 'main',
							 | 
						||
| 
								 | 
							
								        draggable: true,
							 | 
						||
| 
								 | 
							
								        drift: curry(driftPolygon, controller, cover),
							 | 
						||
| 
								 | 
							
								        ondragend: curry(trigger, controller, {
							 | 
						||
| 
								 | 
							
								          isEnd: true
							 | 
						||
| 
								 | 
							
								        })
							 | 
						||
| 
								 | 
							
								      }));
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    updateCoverShape: function (controller, cover, localRange, brushOption) {
							 | 
						||
| 
								 | 
							
								      cover.childAt(0).setShape({
							 | 
						||
| 
								 | 
							
								        points: clipByPanel(controller, cover, localRange)
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    updateCommon: updateCommon,
							 | 
						||
| 
								 | 
							
								    contain: mainShapeContain
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function getLineRenderer(xyIndex) {
							 | 
						||
| 
								 | 
							
								  return {
							 | 
						||
| 
								 | 
							
								    createCover: function (controller, brushOption) {
							 | 
						||
| 
								 | 
							
								      return createBaseRectCover(curry(driftRect, function (range) {
							 | 
						||
| 
								 | 
							
								        var rectRange = [range, [0, 100]];
							 | 
						||
| 
								 | 
							
								        xyIndex && rectRange.reverse();
							 | 
						||
| 
								 | 
							
								        return rectRange;
							 | 
						||
| 
								 | 
							
								      }, function (rectRange) {
							 | 
						||
| 
								 | 
							
								        return rectRange[xyIndex];
							 | 
						||
| 
								 | 
							
								      }), controller, brushOption, [['w', 'e'], ['n', 's']][xyIndex]);
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    getCreatingRange: function (localTrack) {
							 | 
						||
| 
								 | 
							
								      var ends = getTrackEnds(localTrack);
							 | 
						||
| 
								 | 
							
								      var min = mathMin(ends[0][xyIndex], ends[1][xyIndex]);
							 | 
						||
| 
								 | 
							
								      var max = mathMax(ends[0][xyIndex], ends[1][xyIndex]);
							 | 
						||
| 
								 | 
							
								      return [min, max];
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    updateCoverShape: function (controller, cover, localRange, brushOption) {
							 | 
						||
| 
								 | 
							
								      var otherExtent; // If brushWidth not specified, fit the panel.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      var panel = getPanelByCover(controller, cover);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (panel !== true && panel.getLinearBrushOtherExtent) {
							 | 
						||
| 
								 | 
							
								        otherExtent = panel.getLinearBrushOtherExtent(xyIndex, controller._transform);
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								        var zr = controller._zr;
							 | 
						||
| 
								 | 
							
								        otherExtent = [0, [zr.getWidth(), zr.getHeight()][1 - xyIndex]];
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      var rectRange = [localRange, otherExtent];
							 | 
						||
| 
								 | 
							
								      xyIndex && rectRange.reverse();
							 | 
						||
| 
								 | 
							
								      updateBaseRect(controller, cover, rectRange, brushOption);
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    updateCommon: updateCommon,
							 | 
						||
| 
								 | 
							
								    contain: mainShapeContain
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var _default = BrushController;
							 | 
						||
| 
								 | 
							
								module.exports = _default;
							 |