diff --git a/src/component/axisPointer/AxisPointerModel.js b/src/component/axisPointer/AxisPointerModel.js index 55ac795730ffe6959b6bf07efb786f967456ab99..0d233892cef152ca330f301a226b6ac38b930af7 100644 --- a/src/component/axisPointer/AxisPointerModel.js +++ b/src/component/axisPointer/AxisPointerModel.js @@ -86,7 +86,10 @@ define(function(require) { shadowBlur: 3, shadowColor: '#aaa', shadowOffsetX: 0, - shadowOffsetY: 2 + shadowOffsetY: 2, + + // For mobile performance + throttle: 40 } } diff --git a/src/component/axisPointer/AxisPointerView.js b/src/component/axisPointer/AxisPointerView.js index 6d865ec3343016057216f3a58e18728b3bfdc6f8..b28bf67983bf1e7f8927fc58d1755780153ee2eb 100644 --- a/src/component/axisPointer/AxisPointerView.js +++ b/src/component/axisPointer/AxisPointerView.js @@ -44,7 +44,7 @@ define(function (require) { * @override */ dispose: function (ecModel, api) { - globalListener.disopse(api.getZr(), 'axisPointer'); + globalListener.unregister('axisPointer', api); AxisPonterView.superApply(this._model, 'dispose', arguments); } diff --git a/src/component/axisPointer/BaseAxisPointer.js b/src/component/axisPointer/BaseAxisPointer.js index 53c3a4a201b30c6bd8159ee208690555acbf1f81..3ecfeb2f917915ea27ea1c32667b72f22af175bd 100644 --- a/src/component/axisPointer/BaseAxisPointer.js +++ b/src/component/axisPointer/BaseAxisPointer.js @@ -6,6 +6,8 @@ define(function(require) { var graphic = require('../../util/graphic'); var get = require('../../util/model').makeGetter(); var axisPointerModelHelper = require('./modelHelper'); + var eventTool = require('zrender/core/event'); + var throttle = require('../../util/throttle'); var extend = zrUtil.extend; var clone = zrUtil.clone; @@ -49,6 +51,11 @@ define(function(require) { */ _lastStatus: null, + /** + * @private + */ + _handleTrans: null, + /** * In px, arbitrary value. Do not set too small, * no animation is ok for most cases. @@ -277,8 +284,12 @@ define(function(require) { rectHover: true, cursor: 'move', draggable: true, + onmousemove: function (e) { + // Fot mobile devicem, prevent screen slider on the button. + eventTool.stop(e.event); + }, onmousedown: zrUtil.bind( - this._onHandleDragMove, this, axisModel, axisPointerModel, api, 0, 0 + this._onHandleMouseDown, this, axisModel, axisPointerModel, api, 0, 0 ), drift: zrUtil.bind( this._onHandleDragMove, this, axisModel, axisPointerModel, api @@ -306,8 +317,12 @@ define(function(require) { } handle.attr('scale', [handleSize[0] / 2, handleSize[1] / 2]); - // handle margin is from symbol center to axis, - // which is stable when circular move. + throttle.createOrUpdate( + this, + '_doMoveHandleOnDrag', + handleModel.get('throttle') || 0, + 'fixRate' + ); this._moveHandleToValue(handle, value, moveAnimation, axisModel, axisPointerModel, isInit); }, @@ -317,12 +332,19 @@ define(function(require) { */ _moveHandleToValue: function (handle, value, moveAnimation, axisModel, axisPointerModel, isInit) { var trans = this.getHandleTransform(value, axisModel, axisPointerModel); - var valueProps = { - position: trans.position.slice(), - rotation: trans.rotation || 0 - }; + updateProps(axisPointerModel, !isInit && moveAnimation, handle, getHandleTransProps(trans)); + }, - updateProps(axisPointerModel, !isInit && moveAnimation, handle, valueProps); + /** + * @private + */ + _onHandleMouseDown: function (axisModel, axisPointerModel, api) { + var handle = this._handle; + if (handle) { + this._handleTrans = getHandleTransProps(handle); + // Show tooltip. + this._onHandleDragMove(axisModel, axisPointerModel, api, 0, 0); + } }, /** @@ -336,19 +358,30 @@ define(function(require) { this._dragging = true; - handle.stopAnimation(); - - var trans = this.updateHandleTransform( - {position: handle.position.slice(), rotation: handle.rotation}, + // Persistent for throttle. + this._handleTrans = this.updateHandleTransform( + getHandleTransProps(this._handleTrans), [dx, dy], axisModel, axisPointerModel ); - handle.attr({ - position: trans.position, - rotation: trans.rotation || 0 - }); + this._doMoveHandleOnDrag(axisModel, api); + }, + + /** + * Throttled method. + * @private + */ + _doMoveHandleOnDrag: function (axisModel, api) { + var handle = this._handle; + if (!handle) { + return; + } + + var trans = this._handleTrans; + handle.stopAnimation(); + handle.attr(getHandleTransProps(trans)); get(handle).lastProp = null; var payload = { @@ -421,6 +454,7 @@ define(function(require) { handle && zr.remove(handle); this._group = null; this._handle = null; + this._handleTrans = null; } }, @@ -478,6 +512,13 @@ define(function(require) { labelEl[axisPointerModel.get('label.show') ? 'show' : 'hide'](); } + function getHandleTransProps(trans) { + return { + position: trans.position.slice(), + rotation: trans.rotation || 0 + }; + } + clazzUtil.enableClassExtend(BaseAxisPointer); return BaseAxisPointer; diff --git a/src/component/axisPointer/axisTrigger.js b/src/component/axisPointer/axisTrigger.js index cb437ca5dd6a48398249fca7e1bb289155523d6f..dccfc5c0195b1209ca7d745ed2f326c928efb107 100644 --- a/src/component/axisPointer/axisTrigger.js +++ b/src/component/axisPointer/axisTrigger.js @@ -203,6 +203,13 @@ define(function(require) { var valueLabel = viewHelper.getValueLabel( value, axisInfo.axis.model, axisInfo.axisPointerModel ); + + // If no data, do not create anything in dataByCoordSys, + // whose length will be used to judge whether dispatch action. + if (!axisInfo.triggerTooltip || !payloadBatch.length) { + return; + } + var coordSysModel = axisInfo.coordSys.model; var coordSysKey = modelHelper.makeKey(coordSysModel); var coordSysItem = dataByCoordSys.map[coordSysKey]; @@ -217,7 +224,7 @@ define(function(require) { dataByCoordSys.list.push(coordSysItem); } - axisInfo.triggerTooltip && payloadBatch.length && coordSysItem.dataByAxis.push({ + coordSysItem.dataByAxis.push({ axisDim: axis.dim, axisIndex: axisModel.componentIndex, axisType: axisModel.type, @@ -239,7 +246,7 @@ define(function(require) { var valItem = showValueMap[key]; if (valItem) { - option.status = 'show'; + !axisInfo.useHandle && (option.status = 'show'); option.value = valItem.value; // For label formatter param. option.seriesDataIndices = (valItem.payloadBatch || []).slice(); @@ -249,11 +256,7 @@ define(function(require) { else { // If hide, value still need to be set, consider // click legend to toggle axis blank. - option.status = 'hide'; - } - - if (axisInfo.useHandle) { - option.status = axisInfo.axis.scale.isBlank() ? 'hide' : 'show'; + !axisInfo.useHandle && (option.status = 'hide'); } }); } diff --git a/src/component/axisPointer/globalListener.js b/src/component/axisPointer/globalListener.js index 1a0418a742af932b983c20fd15e1a1ac2af85ffa..1fee29b53ca1732118403018513f8b2db1b1e4ca 100644 --- a/src/component/axisPointer/globalListener.js +++ b/src/component/axisPointer/globalListener.js @@ -43,31 +43,13 @@ define(function(require) { function useHandler(eventType, cb) { zr.on(eventType, function (e) { - var pendings = { - showTip: [], - hideTip: [] - }; - // FIXME - // better approach? - // 'showTip' and 'hideTip' can be triggered by axisPointer and tooltip, - // which may be conflict, (axisPointer call showTip but tooltip call hideTip); - // So we have to add "final stage" to merge those dispatched actions. - function dispatchAction(payload) { - var pendingList = pendings[payload.type]; - if (pendingList) { - pendingList.push(payload); - } - else { - payload.dispatchAction = dispatchAction; - api.dispatchAction(payload); - } - } + var dis = makeDispatchAction(api); each(get(zr).records, function (record) { - record && cb(record, e, dispatchAction); + record && cb(record, e, dis.dispatchAction); }); - dispatchTooltipFinally(pendings, api); + dispatchTooltipFinally(dis.pendings, api); }); } } @@ -97,18 +79,44 @@ define(function(require) { record.handler(currTrigger, e, dispatchAction); } + function makeDispatchAction(api) { + var pendings = { + showTip: [], + hideTip: [] + }; + // FIXME + // better approach? + // 'showTip' and 'hideTip' can be triggered by axisPointer and tooltip, + // which may be conflict, (axisPointer call showTip but tooltip call hideTip); + // So we have to add "final stage" to merge those dispatched actions. + var dispatchAction = function (payload) { + var pendingList = pendings[payload.type]; + if (pendingList) { + pendingList.push(payload); + } + else { + payload.dispatchAction = dispatchAction; + api.dispatchAction(payload); + } + }; + + return { + dispatchAction: dispatchAction, + pendings: pendings + }; + } + /** * @param {string} key - * @param {module:zrender} zr + * @param {module:echarts/ExtensionAPI} api */ - globalListener.unregister = function (key, zr) { + globalListener.unregister = function (key, api) { if (env.node) { return; } - + var zr = api.getZr(); var record = (get(zr).records || {})[key]; if (record) { - record.handler('leave'); get(zr).records[key] = null; } }; diff --git a/src/component/axisPointer/modelHelper.js b/src/component/axisPointer/modelHelper.js index 8bf482ade9c385542a272d0bcc37723dfee9c333..f3c505384a16071204e4bc350302ff48b6a5f2e2 100644 --- a/src/component/axisPointer/modelHelper.js +++ b/src/component/axisPointer/modelHelper.js @@ -271,10 +271,11 @@ define(function(require) { value = scale.parse(value); } + var useHandle = isHandleTrigger(axisPointerModel); // If `handle` used, `axisPointer` will always be displayed, so value // and status should be initialized. if (status == null) { - option.status = isHandleTrigger(axisPointerModel) ? 'show' : 'hide'; + option.status = useHandle ? 'show' : 'hide'; } var extent = scale.getExtent().slice(); @@ -294,6 +295,10 @@ define(function(require) { } option.value = value; + + if (useHandle) { + option.status = axisInfo.axis.scale.isBlank() ? 'hide' : 'show'; + } }; helper.getAxisInfo = function (axisModel) { diff --git a/src/component/tooltip/TooltipView.js b/src/component/tooltip/TooltipView.js index 940f39f911c8fbad89112afe0ca581e456865baf..35cdb2f5b53e26f7b6280b5134afbc1a256bbede 100644 --- a/src/component/tooltip/TooltipView.js +++ b/src/component/tooltip/TooltipView.js @@ -562,7 +562,7 @@ define(function (require) { return; } this._tooltipContent.hide(); - globalListener.disopse(api.getZr(), 'itemTooltip'); + globalListener.unregister('itemTooltip', api); } }); diff --git a/src/util/model.js b/src/util/model.js index 6a5b71ac3eea6625a6e84034e340aa0a5bf8a579..950ce83815cdaba9b328f4d920cdc9cd3f9ba369 100644 --- a/src/util/model.js +++ b/src/util/model.js @@ -582,7 +582,7 @@ define(function(require) { || !queryType || value == null || (queryType === 'index' && value === 'none') - || (opt.includeMainTypes && zrUtil.indexOf(opt.includeMainTypes, mainType) < 0) + || (opt && opt.includeMainTypes && zrUtil.indexOf(opt.includeMainTypes, mainType) < 0) ) { return; } diff --git a/test/area.html b/test/area.html index d725b89f686cf67dd113e3c28538dcb6c1dc37f1..b043210a24ca8698deb604450c4c9e0de92f12c4 100644 --- a/test/area.html +++ b/test/area.html @@ -19,7 +19,7 @@ 'echarts', 'echarts/chart/line', 'echarts/component/legend', - 'echarts/component/grid', + 'echarts/component/gridSimple', 'echarts/component/tooltip', 'zrender/vml/vml' ], function (echarts) { diff --git a/test/tooltip-touch.html b/test/tooltip-touch.html index ef561c4657c0eba5e2ad9a069a1f640b9305bb4c..cca4e9b5a563fabb37d00ec3e26666491b831296 100644 --- a/test/tooltip-touch.html +++ b/test/tooltip-touch.html @@ -3,6 +3,7 @@ +