123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923 |
- /*
- * 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(pointerHandlers, 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);
- }
- mountHandlers(zr, controller._handlers);
- 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);
- unmountHandlers(zr, controller._handlers);
- controller._brushType = controller._brushOption = null;
- }
- function mountHandlers(zr, handlers) {
- each(handlers, function (handler, eventName) {
- zr.on(eventName, handler);
- });
- }
- function unmountHandlers(zr, handlers) {
- each(handlers, function (handler, eventName) {
- zr.off(eventName, handler);
- });
- }
- 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) {
- if ( // Check active
- !controller._brushType // resetCursor should be always called when mouse is in zr area,
- // but not called when mouse is out of zr area to avoid bad influence
- // if `mousemove`, `mouseup` are triggered from `document` event.
- || isOutsideZrArea(controller, e)) {
- 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 pointerHandlers = {
- mousedown: function (e) {
- if (this._dragging) {
- // In case some browser do not support globalOut,
- // and release mose out side the browser.
- handleDragEnd(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 x = e.offsetX;
- var y = e.offsetY;
- var localCursorPoint = this.group.transformCoordToLocal(x, y);
- resetCursor(this, e, localCursorPoint);
- if (this._dragging) {
- preventDefault(e);
- var eventParams = updateCoverByMouse(this, e, localCursorPoint, false);
- eventParams && trigger(this, eventParams);
- }
- },
- mouseup: function (e) {
- handleDragEnd(this, e);
- }
- };
- function handleDragEnd(controller, e) {
- if (controller._dragging) {
- preventDefault(e);
- var x = e.offsetX;
- var y = e.offsetY;
- var localCursorPoint = controller.group.transformCoordToLocal(x, y);
- var eventParams = updateCoverByMouse(controller, e, localCursorPoint, true);
- controller._dragging = false;
- controller._track = [];
- controller._creatingCover = null; // trigger event shoule be at final, after procedure will be nested.
- eventParams && trigger(controller, eventParams);
- }
- }
- function isOutsideZrArea(controller, x, y) {
- var zr = controller._zr;
- return x < 0 || x > zr.getWidth() || y < 0 || y > zr.getHeight();
- }
- /**
- * 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;
|