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 2019/11/25 13:55:45 UTC
[incubator-echarts] branch fix/brush-globalout updated: feature:
support `toolbox.dataZoom` `brush component` `dataZoom.slider`
`visualMap.continuous` drag outside and release outside.
This is an automated email from the ASF dual-hosted git repository.
sushuang pushed a commit to branch fix/brush-globalout
in repository https://gitbox.apache.org/repos/asf/incubator-echarts.git
The following commit(s) were added to refs/heads/fix/brush-globalout by this push:
new 93534d6 feature: support `toolbox.dataZoom` `brush component` `dataZoom.slider` `visualMap.continuous` drag outside and release outside.
93534d6 is described below
commit 93534d6a131d6b1b9ba56554fd99d5756734efc3
Author: SHUANG SU <su...@gmail.com>
AuthorDate: Mon Nov 25 21:54:42 2019 +0800
feature: support `toolbox.dataZoom` `brush component` `dataZoom.slider` `visualMap.continuous` drag outside and release outside.
---
src/component/dataZoom/SliderZoomView.js | 13 +-
src/component/helper/BrushController.js | 125 ++++++++++-------
test/drag-out.html | 227 +++++++++++++++++++++++++++++++
3 files changed, 305 insertions(+), 60 deletions(-)
diff --git a/src/component/dataZoom/SliderZoomView.js b/src/component/dataZoom/SliderZoomView.js
index 4b875da..abfd922 100644
--- a/src/component/dataZoom/SliderZoomView.js
+++ b/src/component/dataZoom/SliderZoomView.js
@@ -450,10 +450,6 @@ var SliderZoomView = DataZoomView.extend({
draggable: true,
cursor: getCursor(this._orient),
drift: bind(this._onDragMove, this, 'all'),
- onmousemove: function (e) {
- // Fot mobile devicem, prevent screen slider on the button.
- eventTool.stop(e.event);
- },
ondragstart: bind(this._showDataInfo, this, true),
ondragend: bind(this._onDragEnd, this),
onmouseover: bind(this._showDataInfo, this, true),
@@ -489,10 +485,6 @@ var SliderZoomView = DataZoomView.extend({
cursor: getCursor(this._orient),
draggable: true,
drift: bind(this._onDragMove, this, handleIndex),
- onmousemove: function (e) {
- // Fot mobile devicem, prevent screen slider on the button.
- eventTool.stop(e.event);
- },
ondragend: bind(this._onDragEnd, this),
onmouseover: bind(this._showDataInfo, this, true),
onmouseout: bind(this._showDataInfo, this, false)
@@ -714,9 +706,12 @@ var SliderZoomView = DataZoomView.extend({
handleLabels[1].attr('invisible', !showOrHide);
},
- _onDragMove: function (handleIndex, dx, dy) {
+ _onDragMove: function (handleIndex, dx, dy, event) {
this._dragging = true;
+ // For mobile device, prevent screen slider on the button.
+ eventTool.stop(event.event);
+
// Transform dx, dy to bar coordination.
var barTransform = this._displayables.barGroup.getLocalTransform();
var vertex = graphic.applyTransform([dx, dy], barTransform, true);
diff --git a/src/component/helper/BrushController.js b/src/component/helper/BrushController.js
index caa753d..901a9f1 100644
--- a/src/component/helper/BrushController.js
+++ b/src/component/helper/BrushController.js
@@ -138,12 +138,6 @@ function BrushController(zr) {
/**
* @private
- * @type {Object}
- */
- this._lastMouseMovePoint = {};
-
- /**
- * @private
* @type {Array}
*/
this._covers = [];
@@ -186,8 +180,26 @@ function BrushController(zr) {
* @type {Object}
*/
this._handlers = {};
- each(mouseHandlers, function (handler, eventName) {
- this._handlers[eventName] = zrUtil.bind(handler, this);
+
+ /**
+ * @private
+ * @type {Object}
+ */
+ this._localHandlers = {};
+
+ /**
+ * @private
+ * @type {Object}
+ */
+ this._pageHandlers = {};
+
+ each(localMouseHandlers, function (handler, eventName) {
+ this._handlers[eventName] =
+ this._localHandlers[eventName] = zrUtil.bind(handler, this);
+ }, this);
+ each(pageMouseHandlers, function (handler, eventName) {
+ this._handlers[eventName] =
+ this._pageHandlers[eventName] = zrUtil.bind(handler, this);
}, this);
}
@@ -382,9 +394,7 @@ function doEnableBrush(controller, brushOption) {
interactionMutex.take(zr, MUTEX_RESOURCE_KEY, controller._uid);
}
- each(controller._handlers, function (handler, eventName) {
- zr.on(eventName, handler);
- });
+ mountHandlers(zr, controller._localHandlers);
controller._brushType = brushOption.brushType;
controller._brushOption = zrUtil.merge(zrUtil.clone(DEFAULT_BRUSH_OPT), brushOption, true);
@@ -395,13 +405,23 @@ function doDisableBrush(controller) {
interactionMutex.release(zr, MUTEX_RESOURCE_KEY, controller._uid);
- each(controller._handlers, function (handler, eventName) {
- zr.off(eventName, handler);
- });
+ 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;
@@ -744,8 +764,12 @@ function resetCursor(controller, e, localCursorPoint) {
}
function preventDefault(e) {
- var rawE = e.event;
- rawE.preventDefault && rawE.preventDefault();
+ // Just be worried about bring some side effect to the world
+ // out of echarts, we do not `preventDefault` for globalout.
+ if (e.zrIsFromLocal) {
+ var rawE = e.event;
+ rawE.preventDefault && rawE.preventDefault();
+ }
}
function mainShapeContain(cover, x, y) {
@@ -820,7 +844,7 @@ function determineBrushType(brushType, panel) {
return brushType;
}
-var mouseHandlers = {
+var localMouseHandlers = {
mousedown: function (e) {
if (this._dragging) {
@@ -841,60 +865,44 @@ var mouseHandlers = {
this._dragging = true;
this._track = [localCursorPoint.slice()];
}
+
+ // Mount page handlers only when needed to minimize unexpected side-effect.
+ mountHandlers(this._zr, this._pageHandlers);
}
},
mousemove: function (e) {
- var lastPoint = this._lastMouseMovePoint;
- lastPoint.x = e.offsetX;
- lastPoint.y = e.offsetY;
-
- var localCursorPoint = this.group.transformCoordToLocal(lastPoint.x, lastPoint.y);
-
+ var localCursorPoint = this.group.transformCoordToLocal(e.offsetX, e.offsetY);
+ // resetCursor should be always called when mouse is in zr area,
+ // but not called when mouse is out of zr area.
resetCursor(this, e, localCursorPoint);
+ }
+};
+var pageMouseHandlers = {
+
+ pagemousemove: function (e) {
if (this._dragging) {
+ var xy = getLocalMouseXY(e, this._zr);
+ var localCursorPoint = this.group.transformCoordToLocal(xy[0], xy[1]);
preventDefault(e);
-
var eventParams = updateCoverByMouse(this, e, localCursorPoint, false);
-
eventParams && trigger(this, eventParams);
}
},
- mouseup: function (e) {
+ pagemouseup: function (e) {
handleDragEnd(this, e);
- },
-
- globalout: function (e) {
- handleDragEnd(this, e, true);
}
};
-function handleDragEnd(controller, e, isGlobalOut) {
+function handleDragEnd(controller, e) {
if (controller._dragging) {
+ preventDefault(e);
- // Just be worried about bring some side effect to the world
- // out of echarts, we do not `preventDefault` for globalout.
- !isGlobalOut && preventDefault(e);
-
- var pointerX = e.offsetX;
- var pointerY = e.offsetY;
- var lastPoint = controller._lastMouseMovePoint;
- if (isGlobalOut) {
- pointerX = lastPoint.x;
- pointerY = lastPoint.y;
- }
-
- var localCursorPoint = controller.group.transformCoordToLocal(pointerX, pointerY);
- // FIXME
- // Here `e` is used only in `onIrrelevantElement` finally. And it's OK
- // that pass the `e` of `globalout` to `onIrrelevantElement`. But it is
- // not a good design of these interfaces. However, we do not refactor
- // these code now because the implementation of `onIrrelevantElement`
- // need to be discussed and probably be changed in future, becuase it
- // slows down the performance of zrender in some cases.
+ var xy = getLocalMouseXY(e, controller._zr);
+ var localCursorPoint = controller.group.transformCoordToLocal(xy[0], xy[1]);
var eventParams = updateCoverByMouse(controller, e, localCursorPoint, true);
controller._dragging = false;
@@ -903,9 +911,24 @@ function handleDragEnd(controller, e, isGlobalOut) {
// trigger event shoule be at final, after procedure will be nested.
eventParams && trigger(controller, eventParams);
+
+ unmountHandlers(controller._zr, controller._pageHandlers);
}
}
+function getLocalMouseXY(event, zr) {
+ var x = event.offsetX;
+ var y = event.offsetY;
+ var w = zr.getWidth();
+ var h = zr.getHeight();
+ x < 0 && (x = 0);
+ x > w && (x = w);
+ y < 0 && (y = 0);
+ y > h && (y = h);
+
+ return [x, y];
+}
+
/**
* key: brushType
* @type {Object}
diff --git a/test/drag-out.html b/test/drag-out.html
new file mode 100644
index 0000000..deac082
--- /dev/null
+++ b/test/drag-out.html
@@ -0,0 +1,227 @@
+<!DOCTYPE html>
+<!--
+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.
+-->
+
+
+<html>
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
+ <script src="lib/esl.js"></script>
+ <script src="lib/config.js"></script>
+ <script src="lib/jquery.min.js"></script>
+ <script src="lib/facePrint.js"></script>
+ <script src="lib/testHelper.js"></script>
+ <!-- <script src="ut/lib/canteen.js"></script> -->
+ <link rel="stylesheet" href="lib/reset.css" />
+ </head>
+ <body>
+ <style>
+ body {
+ background: #000 !important;
+ }
+ .test-chart {
+ margin: 80px auto 80px auto !important;
+ background: #fff !important;
+ }
+ #live-info-panel {
+ position: fixed;
+ right: 5px;
+ top: 5px;
+ width: 120px;
+ height: 120px;
+ box-shadow: 0 0 5px #fff;
+ border: 2px solid green;
+ z-index: 999999;
+ color: #fff;
+ font-size: 10px;
+ background: #000;
+ }
+ #live-info-panel .title {
+ font-size: 10px;
+ color: yellow;
+ text-align: center;
+ }
+ #live-info-panel #live-info-content {
+ padding: 2px 3px;
+ }
+ #parent-of-main0 {
+ overflow: hidden;
+ }
+ </style>
+
+
+ <div id="live-info-panel">
+ <div class="title">Live Info Panel</div>
+ <div id="live-info-content"></div>
+ </div>
+
+ <div id="parent-of-main0">
+ <div id="main0"></div>
+ </div>
+ <div id="main1"></div>
+
+
+
+
+ <script>
+ var _liveInfoPanel = document.getElementById('live-info-panel');
+ var _liveInfoContent = document.getElementById('live-info-content');;
+ function _printLiveInfo(msg) {
+ _liveInfoContent.innerHTML = testHelper.encodeHTML(msg).replace(/\n/g, '<br>');
+ }
+ function _printEvent(event) {
+ _printLiveInfo([
+ 'type: ' + event.type,
+ 'x: ' + event.offsetX,
+ 'y: ' + event.offsetY,
+ 'isFromLocal: ' + !!event.zrIsFromLocal
+ ].join('\n'));
+ }
+ </script>
+
+
+
+
+
+ <script>
+ require(['echarts'/*, 'map/js/china' */], function (echarts) {
+ var option;
+ // $.getJSON('./data/nutrients.json', function (data) {});
+
+ option = {
+ xAxis: {},
+ yAxis: {},
+ brush: {},
+ series: {
+ type: 'line',
+ data: [[11, 22]]
+ }
+ };
+
+ var chart = testHelper.create(echarts, 'main0', {
+ title: [
+ '[ Test this case in **PC** / **Touch device** / **WeApp(no document)** ]',
+ '(1) Before anything clicked, **mousemove** / **click** on both inside and outside echarts.',
+ '**Live Info Panel** should have nothing.',
+ '(2) Click "mount page event listeners"',
+ '**mousemove** / **click** on both inside and outside echarts.',
+ '**Live Info Panel** should display mouse **xy** and **isFromLocal** correctly.',
+ '(3) Click "add stopPropagation on parent"',
+ 'Move outside echarts, **Live Info Panel** should have nothing changed.',
+ 'Move inside echarts, **Live Info Panel** should have page event.'
+ ],
+ option: option,
+ width: 300,
+ height: 200,
+ buttons: [{
+ text: 'mount page event listeners',
+ onclick: function () {
+ if (mounted) {
+ return;
+ }
+ mounted = true;
+ zr.on('pagemousemove', function (event) {
+ _printEvent(event)
+ });
+ zr.on('pagemouseup', function (event) {
+ _printEvent(event)
+ });
+ }
+ }, {
+ text: 'add stopPropagation on parent',
+ onclick: function () {
+ var parent = document.getElementById('parent-of-main0');
+ parent.addEventListener('mousemove', function (event) {
+ event.stopPropagation();
+ });
+ }
+ }]
+ });
+
+ var zr;
+ var mounted;
+ if (chart) {
+ zr = chart.getZr();
+ }
+ });
+ </script>
+
+
+
+
+
+
+ <script>
+ require(['echarts'/*, 'map/js/china' */], function (echarts) {
+ var option;
+ // $.getJSON('./data/nutrients.json', function (data) {});
+
+ option = {
+ xAxis: {},
+ yAxis: {},
+ toolbox: {
+ feature: {
+ dataZoom: {}
+ }
+ },
+ grid: {
+ left: 100
+ },
+ brush: {},
+ dataZoom: [{
+ type: 'slider'
+ }, {
+ type: 'inside'
+ }],
+ visualMap: {
+ type: 'continuous',
+ calculable: true,
+ left: 0,
+ top: 20,
+ min: 0,
+ max: 50,
+ itemHeight: 80
+ },
+ series: {
+ type: 'line',
+ data: [[11, 22], [33, 44], [42, 11], [52, 33]]
+ }
+ };
+
+ var chart = testHelper.create(echarts, 'main1', {
+ title: [
+ 'Drag **toolbox.dataZoom** / **dataZoom-slider** / **brush**',
+ 'to the **top** / **right** / **bottom** / **left** of the **black area** (out of echarts)',
+ 'and then mouseup or go back.',
+ 'Should act like listening to document `mousemove` and `mouseup`'
+ ],
+ option: option,
+ width: 350,
+ height: 260,
+ // buttons: [{text: 'btn-txt', onclick: function () {}}],
+ // recordCanvas: true,
+ });
+ });
+ </script>
+
+
+ </body>
+</html>
+
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org