You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by su...@apache.org on 2018/04/17 20:04:36 UTC

[incubator-echarts] 02/03: Enhance dataZoom: do not trigger if range not changed, otherwise cause bad effect when progressive rendering.

This is an automated email from the ASF dual-hosted git repository.

sushuang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-echarts.git

commit df46e28e729b1c89344756c29a3f1e21323816d8
Author: sushuang <su...@gmail.com>
AuthorDate: Wed Apr 18 03:25:38 2018 +0800

    Enhance dataZoom: do not trigger if range not changed, otherwise cause bad effect when progressive rendering.
---
 src/component/dataZoom/InsideZoomView.js | 28 ++++++++++++++++++----------
 src/component/dataZoom/SliderZoomView.js | 16 +++++++++++-----
 src/component/dataZoom/roams.js          | 16 +---------------
 src/util/throttle.js                     |  8 ++++++++
 4 files changed, 38 insertions(+), 30 deletions(-)

diff --git a/src/component/dataZoom/InsideZoomView.js b/src/component/dataZoom/InsideZoomView.js
index dc01599..668f041 100644
--- a/src/component/dataZoom/InsideZoomView.js
+++ b/src/component/dataZoom/InsideZoomView.js
@@ -28,12 +28,10 @@ var InsideZoomView = DataZoomView.extend({
     render: function (dataZoomModel, ecModel, api, payload) {
         InsideZoomView.superApply(this, 'render', arguments);
 
-        // Notice: origin this._range should be maintained, and should not be re-fetched
-        // from dataZoomModel when payload.type is 'dataZoom', otherwise 'pan' or 'zoom'
-        // info will be missed because of 'throttle' of this.dispatchAction.
-        if (roams.shouldRecordRange(payload, dataZoomModel.id)) {
-            this._range = dataZoomModel.getPercentRange();
-        }
+        // Hance the `throttle` util ensures to preserve command order,
+        // here simply updating range all the time will not cause missing
+        // any of the the roam change.
+        this._range = dataZoomModel.getPercentRange();
 
         // Reset controllers.
         zrUtil.each(this.getTargetCoordInfo(), function (coordInfoList, coordSysName) {
@@ -85,7 +83,8 @@ var InsideZoomView = DataZoomView.extend({
      * @private
      */
     _onPan: function (coordInfo, coordSysName, controller, dx, dy, oldX, oldY, newX, newY) {
-        var range = this._range.slice();
+        var lastRange = this._range;
+        var range = lastRange.slice();
 
         // Calculate transform by the first axis.
         var axisModel = coordInfo.axisModels[0];
@@ -103,14 +102,19 @@ var InsideZoomView = DataZoomView.extend({
 
         sliderMove(percentDelta, range, [0, 100], 'all');
 
-        return (this._range = range);
+        this._range = range;
+
+        if (lastRange[0] !== range[0] || lastRange[1] !== range[1]) {
+            return range;
+        }
     },
 
     /**
      * @private
      */
     _onZoom: function (coordInfo, coordSysName, controller, scale, mouseX, mouseY) {
-        var range = this._range.slice();
+        var lastRange = this._range;
+        var range = lastRange.slice();
 
         // Calculate transform by the first axis.
         var axisModel = coordInfo.axisModels[0];
@@ -136,7 +140,11 @@ var InsideZoomView = DataZoomView.extend({
 
         sliderMove(0, range, [0, 100], 0, minMaxSpan.minSpan, minMaxSpan.maxSpan);
 
-        return (this._range = range);
+        this._range = range;
+
+        if (lastRange[0] !== range[0] || lastRange[1] !== range[1]) {
+            return range;
+        }
     }
 
 });
diff --git a/src/component/dataZoom/SliderZoomView.js b/src/component/dataZoom/SliderZoomView.js
index 25c71e1..9dcde39 100644
--- a/src/component/dataZoom/SliderZoomView.js
+++ b/src/component/dataZoom/SliderZoomView.js
@@ -529,6 +529,7 @@ var SliderZoomView = DataZoomView.extend({
      * @private
      * @param {(number|string)} handleIndex 0 or 1 or 'all'
      * @param {number} delta
+     * @return {boolean} changed
      */
     _updateInterval: function (handleIndex, delta) {
         var dataZoomModel = this.dataZoomModel;
@@ -548,10 +549,13 @@ var SliderZoomView = DataZoomView.extend({
                 ? linearMap(minMaxSpan.maxSpan, percentExtent, viewExtend, true) : null
         );
 
-        this._range = asc([
+        var lastRange = this._range;
+        var range = this._range = asc([
             linearMap(handleEnds[0], viewExtend, percentExtent, true),
             linearMap(handleEnds[1], viewExtend, percentExtent, true)
         ]);
+
+        return !lastRange || lastRange[0] !== range[0] || lastRange[1] !== range[1];
     },
 
     /**
@@ -697,13 +701,15 @@ var SliderZoomView = DataZoomView.extend({
         var barTransform = this._displayables.barGroup.getLocalTransform();
         var vertex = graphic.applyTransform([dx, dy], barTransform, true);
 
-        this._updateInterval(handleIndex, vertex[0]);
+        var changed = this._updateInterval(handleIndex, vertex[0]);
 
         var realtime = this.dataZoomModel.get('realtime');
 
         this._updateView(!realtime);
 
-        realtime && this._dispatchZoomAction();
+        // Avoid dispatch dataZoom repeatly but range not changed,
+        // which cause bad visual effect when progressive enabled.
+        changed && realtime && this._dispatchZoomAction();
     },
 
     _onDragEnd: function () {
@@ -729,9 +735,9 @@ var SliderZoomView = DataZoomView.extend({
         var handleEnds = this._handleEnds;
         var center = (handleEnds[0] + handleEnds[1]) / 2;
 
-        this._updateInterval('all', localPoint[0] - center);
+        var changed = this._updateInterval('all', localPoint[0] - center);
         this._updateView();
-        this._dispatchZoomAction();
+        changed && this._dispatchZoomAction();
     },
 
     /**
diff --git a/src/component/dataZoom/roams.js b/src/component/dataZoom/roams.js
index d4541b7..21a8261 100644
--- a/src/component/dataZoom/roams.js
+++ b/src/component/dataZoom/roams.js
@@ -100,20 +100,6 @@ export function unregister(api, dataZoomId) {
 /**
  * @public
  */
-export function shouldRecordRange(payload, dataZoomId) {
-    if (payload && payload.type === 'dataZoom' && payload.batch) {
-        for (var i = 0, len = payload.batch.length; i < len; i++) {
-            if (payload.batch[i].dataZoomId === dataZoomId) {
-                return false;
-            }
-        }
-    }
-    return true;
-}
-
-/**
- * @public
- */
 export function generateCoordId(coordModel) {
     return coordModel.type + '\0_' + coordModel.id;
 }
@@ -170,7 +156,7 @@ function wrapAndDispatch(record, getRange) {
         });
     });
 
-    record.dispatchAction(batch);
+    batch.length && record.dispatchAction(batch);
 }
 
 /**
diff --git a/src/util/throttle.js b/src/util/throttle.js
index 143d7ab..3cee4c3 100755
--- a/src/util/throttle.js
+++ b/src/util/throttle.js
@@ -42,6 +42,14 @@ export function throttle(fn, delay, debounce) {
 
         clearTimeout(timer);
 
+        // Here we should make sure that: the `exec` SHOULD NOT be called later
+        // than a new call of `cb`, that is, preserving the command order. Consider
+        // calculating "scale rate" when roaming as an example. When a call of `cb`
+        // happens, either the `exec` is called dierectly, or the call is delayed.
+        // But the delayed call should never be later than next call of `cb`. Under
+        // this assurance, we can simply update view state each time `dispatchAction`
+        // triggered by user roaming, but not need to add extra code to avoid the
+        // state being "rolled-back".
         if (thisDebounce) {
             timer = setTimeout(exec, thisDelay);
         }

-- 
To stop receiving notification emails like this one, please contact
sushuang@apache.org.

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org