diff --git a/src/chart/graph/GraphView.js b/src/chart/graph/GraphView.js index c4b835223d7cf54248a08116c5d30920cc49e898..b45e883e6842215dec9d4f4d285bd25bf1f1e24b 100644 --- a/src/chart/graph/GraphView.js +++ b/src/chart/graph/GraphView.js @@ -236,11 +236,13 @@ define(function (require) { _updateController: function (seriesModel, api) { var controller = this._controller; var group = this.group; - controller.rectProvider = function () { + + controller.setContainsPoint(function (x, y) { var rect = group.getBoundingRect(); rect.applyTransform(group.transform); - return rect; - }; + return rect.contain(x, y); + }); + if (seriesModel.coordinateSystem.type !== 'view') { controller.disable(); return; diff --git a/src/chart/treemap/TreemapView.js b/src/chart/treemap/TreemapView.js index 7aa1771dcce6121cdc3d715b03dbd8af3f979c1a..30ab9819485825fc7476a64272dbf823d45e66c4 100644 --- a/src/chart/treemap/TreemapView.js +++ b/src/chart/treemap/TreemapView.js @@ -375,9 +375,9 @@ } var rect = new BoundingRect(0, 0, api.getWidth(), api.getHeight()); - controller.rectProvider = function () { - return rect; - }; + controller.setContainsPoint(function (x, y) { + return rect.contain(x, y); + }); }, /** @@ -762,7 +762,7 @@ var text = nodeModel.get('name'); if (thisLayout.isLeafRoot) { var iconChar = seriesModel.get('drillDownIcon', true); - text = iconChar ? iconChar + ' ' + text : test; + text = iconChar ? iconChar + ' ' + text : text; } setText( diff --git a/src/component/dataZoom/DataZoomModel.js b/src/component/dataZoom/DataZoomModel.js index b9de5c09d9352302289a45184a0facfc3b32e7b0..ce35717e1fff67888ed92706d951023e27e13172 100644 --- a/src/component/dataZoom/DataZoomModel.js +++ b/src/component/dataZoom/DataZoomModel.js @@ -30,7 +30,6 @@ define(function(require) { xAxisIndex: null, // Default the first horizontal category axis. yAxisIndex: null, // Default the first vertical category axis. - filterMode: 'filter', // Possible values: 'filter' or 'empty'. // 'filter': data items which are out of window will be removed. // This option is applicable when filtering outliers. diff --git a/src/component/dataZoom/DataZoomView.js b/src/component/dataZoom/DataZoomView.js index f0e55a6ebc24a4f5d47fba2ba6012142717cf843..3ed494790a07ea0d07b7a38693ef331c71a0d345 100644 --- a/src/component/dataZoom/DataZoomView.js +++ b/src/component/dataZoom/DataZoomView.js @@ -42,21 +42,30 @@ define(function (require) { if (axisModel) { axisModels.push(axisModel); var coordSysName; - if (dimNames.axis === 'xAxis' || dimNames.axis === 'yAxis') { + var axisName = dimNames.axis; + + if (axisName === 'xAxis' || axisName === 'yAxis') { coordSysName = 'grid'; } - else { - // Polar + else if (axisName === 'angleAxis' || axisName === 'radiusAxis') { coordSysName = 'polar'; } - var coordModel = ecModel.queryComponents({ - mainType: coordSysName, - index: axisModel.get(coordSysName + 'Index'), - id: axisModel.get(coordSysName + 'Id') - })[0]; + + var coordModel = coordSysName + ? ecModel.queryComponents({ + mainType: coordSysName, + index: axisModel.get(coordSysName + 'Index'), + id: axisModel.get(coordSysName + 'Id') + })[0] + : null; if (coordModel != null) { - save(coordModel, axisModel, coordSysName === 'grid' ? cartesians : polars, coordModel.componentIndex); + save( + coordModel, + axisModel, + coordSysName === 'grid' ? cartesians : polars, + coordModel.componentIndex + ); } } }, this); diff --git a/src/component/dataZoom/InsideZoomModel.js b/src/component/dataZoom/InsideZoomModel.js index 144a49981a04e5fb9b9b795fd3834d8eddd193f1..e30597ddbd8f943aeaf9acadd7ea900f231c64e7 100644 --- a/src/component/dataZoom/InsideZoomModel.js +++ b/src/component/dataZoom/InsideZoomModel.js @@ -11,7 +11,8 @@ define(function(require) { * @protected */ defaultOption: { - zoomLock: false // Whether disable zoom but only pan. + silent: false, // Whether disable this inside zoom. + zoomLock: false // Whether disable zoom but only pan. } }); }); \ No newline at end of file diff --git a/src/component/dataZoom/InsideZoomView.js b/src/component/dataZoom/InsideZoomView.js index 6e76c3e2315336ec0a0e404c9deddebd3ccbff3e..af5ca2c00766776608840009719acdf0f196a6ea 100644 --- a/src/component/dataZoom/InsideZoomView.js +++ b/src/component/dataZoom/InsideZoomView.js @@ -36,30 +36,36 @@ define(function (require) { this._range = dataZoomModel.getPercentRange(); } + var targetInfo = this.getTargetInfo(); + // Reset controllers. - var coordInfoList = this.getTargetInfo().cartesians; - var allCoordIds = zrUtil.map(coordInfoList, function (coordInfo) { - return roams.generateCoordId(coordInfo.model); - }); - - zrUtil.each(coordInfoList, function (coordInfo) { - var coordModel = coordInfo.model; - roams.register( - api, - { - coordId: roams.generateCoordId(coordModel), - allCoordIds: allCoordIds, - coordinateSystem: coordModel.coordinateSystem, - dataZoomId: dataZoomModel.id, - throttleRate: dataZoomModel.get('throttle', true), - panGetRange: bind(this._onPan, this, coordInfo), - zoomGetRange: bind(this._onZoom, this, coordInfo) - } - ); - }, this); + zrUtil.each(['cartesians', 'polars'], function (coordSysName) { + + var coordInfoList = targetInfo[coordSysName]; + var allCoordIds = zrUtil.map(coordInfoList, function (coordInfo) { + return roams.generateCoordId(coordInfo.model); + }); + + zrUtil.each(coordInfoList, function (coordInfo) { + var coordModel = coordInfo.model; + var coordinateSystem = coordModel.coordinateSystem; + + roams.register( + api, + { + coordId: roams.generateCoordId(coordModel), + allCoordIds: allCoordIds, + coordinateSystem: coordinateSystem, + containsPoint: bind(operations[coordSysName].containsPoint, this, coordinateSystem), + dataZoomId: dataZoomModel.id, + throttleRate: dataZoomModel.get('throttle', true), + panGetRange: bind(this._onPan, this, coordInfo, coordSysName), + zoomGetRange: bind(this._onZoom, this, coordInfo, coordSysName) + } + ); + }, this); - // TODO - // polar支持 + }, this); }, /** @@ -74,100 +80,137 @@ define(function (require) { /** * @private */ - _onPan: function (coordInfo, controller, dx, dy) { - return ( - this._range = panCartesian( - [dx, dy], this._range, controller, coordInfo - ) - ); - }, - - /** - * @private - */ - _onZoom: function (coordInfo, controller, scale, mouseX, mouseY) { - var dataZoomModel = this.dataZoomModel; - - if (dataZoomModel.option.zoomLock) { + _onPan: function (coordInfo, coordSysName, controller, dx, dy, oldX, oldY, newX, newY) { + if (this.dataZoomModel.option.silent) { return this._range; } - return ( - this._range = scaleCartesian( - 1 / scale, [mouseX, mouseY], this._range, - controller, coordInfo, dataZoomModel - ) - ); - } + var range = this._range.slice(); - }); + // Calculate transform by the first axis. + var axisModel = coordInfo.axisModels[0]; + if (!axisModel) { + return; + } - function panCartesian(pixelDeltas, range, controller, coordInfo) { - range = range.slice(); + var directionInfo = operations[coordSysName].getDirectionInfo( + [oldX, oldY], [newX, newY], axisModel, controller, coordInfo + ); - // Calculate transform by the first axis. - var axisModel = coordInfo.axisModels[0]; - if (!axisModel) { - return; - } + var percentDelta = directionInfo.signal + * (range[1] - range[0]) + * directionInfo.pixel / directionInfo.pixelLength; - var directionInfo = getDirectionInfo(pixelDeltas, axisModel, controller); + sliderMove(percentDelta, range, [0, 100], 'rigid'); - var percentDelta = directionInfo.signal - * (range[1] - range[0]) - * directionInfo.pixel / directionInfo.pixelLength; + return (this._range = range); + }, - sliderMove( - percentDelta, - range, - [0, 100], - 'rigid' - ); + /** + * @private + */ + _onZoom: function (coordInfo, coordSysName, controller, scale, mouseX, mouseY) { + var option = this.dataZoomModel.option; - return range; - } + if (option.silent || option.zoomLock) { + return this._range; + } - function scaleCartesian(scale, mousePoint, range, controller, coordInfo, dataZoomModel) { - range = range.slice(); + var range = this._range.slice(); - // Calculate transform by the first axis. - var axisModel = coordInfo.axisModels[0]; - if (!axisModel) { - return; - } + // Calculate transform by the first axis. + var axisModel = coordInfo.axisModels[0]; + if (!axisModel) { + return; + } - var directionInfo = getDirectionInfo(mousePoint, axisModel, controller); + var directionInfo = operations[coordSysName].getDirectionInfo( + null, [mouseX, mouseY], axisModel, controller, coordInfo + ); - var mouse = directionInfo.pixel - directionInfo.pixelStart; - var percentPoint = mouse / directionInfo.pixelLength * (range[1] - range[0]) + range[0]; + var percentPoint = (directionInfo.pixel - directionInfo.pixelStart) / + directionInfo.pixelLength * (range[1] - range[0]) + range[0]; - scale = Math.max(scale, 0); - range[0] = (range[0] - percentPoint) * scale + percentPoint; - range[1] = (range[1] - percentPoint) * scale + percentPoint; + scale = Math.max(1 / scale, 0); + range[0] = (range[0] - percentPoint) * scale + percentPoint; + range[1] = (range[1] - percentPoint) * scale + percentPoint; + return (this._range = fixRange(range)); + } - return fixRange(range); - } + }); - function getDirectionInfo(xy, axisModel, controller) { - var axis = axisModel.axis; - var rect = controller.rectProvider(); - var ret = {}; + var operations = { + + cartesians: { + + getDirectionInfo: function (oldPoint, newPoint, axisModel, controller, coordInfo) { + var axis = axisModel.axis; + var ret = {}; + var rect = coordInfo.model.coordinateSystem.getRect(); + oldPoint = oldPoint || [0, 0]; + + if (axis.dim === 'x') { + ret.pixel = newPoint[0] - oldPoint[0]; + ret.pixelLength = rect.width; + ret.pixelStart = rect.x; + ret.signal = axis.inverse ? 1 : -1; + } + else { // axis.dim === 'y' + ret.pixel = newPoint[1] - oldPoint[1]; + ret.pixelLength = rect.height; + ret.pixelStart = rect.y; + ret.signal = axis.inverse ? -1 : 1; + } + + return ret; + }, + + containsPoint: function (coordinateSystem, x, y) { + return coordinateSystem.getRect().contain(x, y); + } + }, - if (axis.dim === 'x') { - ret.pixel = xy[0]; - ret.pixelLength = rect.width; - ret.pixelStart = rect.x; - ret.signal = axis.inverse ? 1 : -1; - } - else { // axis.dim === 'y' - ret.pixel = xy[1]; - ret.pixelLength = rect.height; - ret.pixelStart = rect.y; - ret.signal = axis.inverse ? -1 : 1; + polars: { + + getDirectionInfo: function (oldPoint, newPoint, axisModel, controller, coordInfo) { + var axis = axisModel.axis; + var ret = {}; + var polar = coordInfo.model.coordinateSystem; + var radiusExtent = polar.getRadiusAxis().getExtent(); + var angleExtent = polar.getAngleAxis().getExtent(); + + oldPoint = oldPoint ? polar.pointToCoord(oldPoint) : [0, 0]; + newPoint = polar.pointToCoord(newPoint); + + if (axisModel.mainType === 'radiusAxis') { + ret.pixel = newPoint[0] - oldPoint[0]; + // ret.pixelLength = Math.abs(radiusExtent[1] - radiusExtent[0]); + // ret.pixelStart = Math.min(radiusExtent[0], radiusExtent[1]); + ret.pixelLength = radiusExtent[1] - radiusExtent[0]; + ret.pixelStart = radiusExtent[0]; + ret.signal = axis.inverse ? 1 : -1; + } + else { // 'angleAxis' + ret.pixel = newPoint[1] - oldPoint[1]; + // ret.pixelLength = Math.abs(angleExtent[1] - angleExtent[0]); + // ret.pixelStart = Math.min(angleExtent[0], angleExtent[1]); + ret.pixelLength = angleExtent[1] - angleExtent[0]; + ret.pixelStart = angleExtent[0]; + ret.signal = axis.inverse ? -1 : 1; + } + + return ret; + }, + + containsPoint: function (coordinateSystem, x, y) { + var radius = coordinateSystem.getRadiusAxis().getExtent()[1]; + var cx = coordinateSystem.cx; + var cy = coordinateSystem.cy; + + return Math.pow(x - cx, 2) + Math.pow(y - cy, 2) <= Math.pow(radius, 2); + } } - - return ret; - } + }; function fixRange(range) { // Clamp, using !(<= or >=) to handle NaN. diff --git a/src/component/dataZoom/roams.js b/src/component/dataZoom/roams.js index 3be54c52d876acfa2691138d258ed39dd0e11088..63d20acc9b051fc58e1465d81846d2a93f56ffc6 100644 --- a/src/component/dataZoom/roams.js +++ b/src/component/dataZoom/roams.js @@ -23,7 +23,7 @@ define(function(require) { * @param {module:echarts/ExtensionAPI} api * @param {Object} dataZoomInfo * @param {string} dataZoomInfo.coordId - * @param {Object} dataZoomInfo.coordinateSystem + * @param {Function} dataZoomInfo.containsPoint * @param {Array.} dataZoomInfo.allCoordIds * @param {string} dataZoomInfo.dataZoomId * @param {number} dataZoomInfo.throttleRate @@ -62,10 +62,7 @@ define(function(require) { } // Consider resize, area should be always updated. - var rect = dataZoomInfo.coordinateSystem.getRect().clone(); - record.controller.rectProvider = function () { - return rect; - }; + record.controller.setContainsPoint(dataZoomInfo.containsPoint); // Update throttle. throttle.createOrUpdate( @@ -150,9 +147,9 @@ define(function(require) { }); } - function onPan(record, dx, dy) { + function onPan(record, dx, dy, oldX, oldY, newX, newY) { wrapAndDispatch(record, function (info) { - return info.panGetRange(record.controller, dx, dy); + return info.panGetRange(record.controller, dx, dy, oldX, oldY, newX, newY); }); } diff --git a/src/component/helper/MapDraw.js b/src/component/helper/MapDraw.js index 7483a844086ea061ce066db2e08c5be87419bdde..653b9ec22c7380d62cb423f3f4eff30a730dc819 100644 --- a/src/component/helper/MapDraw.js +++ b/src/component/helper/MapDraw.js @@ -285,9 +285,9 @@ define(function (require) { } }, this); - controller.rectProvider = function () { - return geo.getViewRectAfterRoam(); - }; + controller.setContainsPoint(function (x, y) { + return geo.getViewRectAfterRoam().contain(x, y); + }); } }; diff --git a/src/component/helper/RoamController.js b/src/component/helper/RoamController.js index c1827dca473924ba4ca94be0e3ccd4cd9a1d8979..c28309fa58b203e0e3253da9b91f484732607f45 100644 --- a/src/component/helper/RoamController.js +++ b/src/component/helper/RoamController.js @@ -16,8 +16,8 @@ define(function (require) { var x = e.offsetX; var y = e.offsetY; - var rect = this.rectProvider && this.rectProvider(); - if (rect && rect.contain(x, y)) { + + if (this.containsPoint && this.containsPoint(x, y)) { this._x = x; this._y = y; this._dragging = true; @@ -40,8 +40,11 @@ define(function (require) { var x = e.offsetX; var y = e.offsetY; - var dx = x - this._x; - var dy = y - this._y; + var oldX = this._x; + var oldY = this._y; + + var dx = x - oldX; + var dy = y - oldY; this._x = x; this._y = y; @@ -56,7 +59,7 @@ define(function (require) { } eventTool.stop(e.event); - this.trigger('pan', dx, dy); + this.trigger('pan', dx, dy, oldX, oldY, x, y); } } @@ -81,9 +84,7 @@ define(function (require) { } function zoom(e, zoomDelta, zoomX, zoomY) { - var rect = this.rectProvider && this.rectProvider(); - - if (rect && rect.contain(zoomX, zoomY)) { + if (this.containsPoint && this.containsPoint(zoomX, zoomY)) { // When mouse is out of roamController rect, // default befavoius should be be disabled, otherwise // page sliding is disabled, contrary to expectation. @@ -128,9 +129,8 @@ define(function (require) { * * @param {module:zrender/zrender~ZRender} zr * @param {module:zrender/Element} target - * @param {Function} [rectProvider] */ - function RoamController(zr, target, rectProvider) { + function RoamController(zr, target) { /** * @type {module:zrender/Element} @@ -140,7 +140,7 @@ define(function (require) { /** * @type {Function} */ - this.rectProvider = rectProvider; + this.containsPoint; /** * { min: 1, max: 2 } @@ -167,6 +167,15 @@ define(function (require) { Eventful.call(this); + /** + * @param {Function} containsPoint + * input: x, y + * output: boolean + */ + this.setContainsPoint = function (containsPoint) { + this.containsPoint = containsPoint; + }; + /** * Notice: only enable needed types. For example, if 'zoom' * is not needed, 'zoom' should not be enabled, otherwise diff --git a/src/coord/axisModelZoomMixin.js b/src/coord/axisModelZoomMixin.js new file mode 100644 index 0000000000000000000000000000000000000000..098ac9f5f9e3ca07b5f5848fce9324442173e3cd --- /dev/null +++ b/src/coord/axisModelZoomMixin.js @@ -0,0 +1,52 @@ +define(function (require) { + + return { + + /** + * @public + * @return {Array.} + */ + getMin: function () { + var option = this.option; + return option.rangeStart != null ? option.rangeStart : option.min; + }, + + /** + * @public + * @return {Array.} + */ + getMax: function () { + var option = this.option; + return option.rangeEnd != null ? option.rangeEnd : option.max; + }, + + /** + * @public + * @return {boolean} + */ + getNeedCrossZero: function () { + var option = this.option; + return (option.rangeStart != null || option.rangeEnd != null) + ? false : !option.scale; + }, + + /** + * @public + * @param {number} rangeStart + * @param {number} rangeEnd + */ + setRange: function (rangeStart, rangeEnd) { + this.option.rangeStart = rangeStart; + this.option.rangeEnd = rangeEnd; + }, + + /** + * @public + */ + resetRange: function () { + // rangeStart and rangeEnd is readonly. + this.option.rangeStart = this.option.rangeEnd = null; + } + }; + +}); \ No newline at end of file diff --git a/src/coord/cartesian/AxisModel.js b/src/coord/cartesian/AxisModel.js index a7098adeb8eb96f8e38be4aa43805478f9475244..f17e86b744a0f5887b47222af2317b57e2320bfd 100644 --- a/src/coord/cartesian/AxisModel.js +++ b/src/coord/cartesian/AxisModel.js @@ -20,7 +20,7 @@ define(function(require) { */ init: function () { AxisModel.superApply(this, 'init', arguments); - this._resetRange(); + this.resetRange(); }, /** @@ -28,7 +28,7 @@ define(function(require) { */ mergeOption: function () { AxisModel.superApply(this, 'mergeOption', arguments); - this._resetRange(); + this.resetRange(); }, /** @@ -36,45 +36,7 @@ define(function(require) { */ restoreData: function () { AxisModel.superApply(this, 'restoreData', arguments); - this._resetRange(); - }, - - /** - * @public - * @param {number} rangeStart - * @param {number} rangeEnd - */ - setRange: function (rangeStart, rangeEnd) { - this.option.rangeStart = rangeStart; - this.option.rangeEnd = rangeEnd; - }, - - /** - * @public - * @return {Array.} - */ - getMin: function () { - var option = this.option; - return option.rangeStart != null ? option.rangeStart : option.min; - }, - - /** - * @public - * @return {Array.} - */ - getMax: function () { - var option = this.option; - return option.rangeEnd != null ? option.rangeEnd : option.max; - }, - - /** - * @public - * @return {boolean} - */ - getNeedCrossZero: function () { - var option = this.option; - return (option.rangeStart != null || option.rangeEnd != null) - ? false : !option.scale; + this.resetRange(); }, /** @@ -86,14 +48,6 @@ define(function(require) { index: this.get('gridIndex'), id: this.get('gridId') })[0]; - }, - - /** - * @private - */ - _resetRange: function () { - // rangeStart and rangeEnd is readonly. - this.option.rangeStart = this.option.rangeEnd = null; } }); @@ -104,6 +58,7 @@ define(function(require) { } zrUtil.merge(AxisModel.prototype, require('../axisModelCommonMixin')); + zrUtil.merge(AxisModel.prototype, require('../axisModelZoomMixin')); var extraOption = { // gridIndex: 0, diff --git a/src/coord/polar/AxisModel.js b/src/coord/polar/AxisModel.js index 36820540e69f67a32b7423ba6be4be16cf328734..739ac86a8b2c8ef3a52db2934200fee19a6f626b 100644 --- a/src/coord/polar/AxisModel.js +++ b/src/coord/polar/AxisModel.js @@ -7,14 +7,18 @@ define(function(require) { var axisModelCreator = require('../axisModelCreator'); var PolarAxisModel = ComponentModel.extend({ + type: 'polarAxis', + /** * @type {module:echarts/coord/polar/AngleAxis|module:echarts/coord/polar/RadiusAxis} */ axis: null + }); zrUtil.merge(PolarAxisModel.prototype, require('../axisModelCommonMixin')); + zrUtil.merge(PolarAxisModel.prototype, require('../axisModelZoomMixin')); var polarAxisDefaultExtendedOption = { angle: { diff --git a/test/dataZoom-scatter-hv-polar.html b/test/dataZoom-scatter-hv-polar.html index 6d0f38b6e994c61c4d99ec19baf8cd9a81e21af2..35b0d26a0f2e61705f54db886c3de36924afe4eb 100644 --- a/test/dataZoom-scatter-hv-polar.html +++ b/test/dataZoom-scatter-hv-polar.html @@ -3,14 +3,26 @@ + +
+ inside zoom radius + inside zoom angle + inside zoom all +
\ No newline at end of file