Skip to content

Commit abcc6cc

Browse files
authored
Merge pull request #2649 from plotly/sloppy-click
fix #2598 - sloppy click on cartesian zoom
2 parents a9040d1 + c56f223 commit abcc6cc

File tree

5 files changed

+30
-12
lines changed

5 files changed

+30
-12
lines changed

src/components/dragelement/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ dragElement.init = function init(options) {
217217
}
218218

219219
if(gd._dragged) {
220-
if(options.doneFn) options.doneFn(e);
220+
if(options.doneFn) options.doneFn();
221221
}
222222
else {
223223
if(options.clickFn) options.clickFn(numClicks, initialEvent);

src/plots/cartesian/dragbox.js

+8-6
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,9 @@ function makeDragBox(gd, plotinfo, x, y, w, h, ns, ew) {
252252
zb,
253253
corners;
254254

255+
// zoom takes over minDrag, so it also has to take over gd._dragged
256+
var zoomDragged;
257+
255258
// collected changes to be made to the plot by relayout at the end
256259
var updates = {};
257260

@@ -266,6 +269,7 @@ function makeDragBox(gd, plotinfo, x, y, w, h, ns, ew) {
266269
path0 = 'M0,0H' + pw + 'V' + ph + 'H0V0';
267270
dimmed = false;
268271
zoomMode = 'xy';
272+
zoomDragged = false;
269273

270274
zb = makeZoombox(zoomlayer, lum, xs, ys, path0);
271275

@@ -341,6 +345,9 @@ function makeDragBox(gd, plotinfo, x, y, w, h, ns, ew) {
341345
box.w = box.r - box.l;
342346
box.h = box.b - box.t;
343347

348+
if(zoomMode) zoomDragged = true;
349+
gd._dragged = zoomDragged;
350+
344351
updateZoombox(zb, corners, box, path0, dimmed, lum);
345352
dimmed = true;
346353
}
@@ -458,12 +465,7 @@ function makeDragBox(gd, plotinfo, x, y, w, h, ns, ew) {
458465
// no more scrolling is coming
459466
redrawTimer = setTimeout(function() {
460467
scrollViewBox = [0, 0, pw, ph];
461-
462-
var zoomMode;
463-
if(isSubplotConstrained) zoomMode = 'xy';
464-
else zoomMode = (ew ? 'x' : '') + (ns ? 'y' : '');
465-
466-
dragTail(zoomMode);
468+
dragTail();
467469
}, REDRAWDELAY);
468470

469471
e.preventDefault();

test/jasmine/assets/click.js

+8
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ var Lib = require('../../../src/lib');
2121
* @param {bool} cancelContext: act as though `preventDefault` was called during a `contextmenu`
2222
* handler, which stops native contextmenu and therefore allows mouseup events to be fired.
2323
* Only relevant if button=2 or ctrlKey=true.
24+
* @param {array(2)} opts.slop - shift [x, y] between mousedown and mouseup.
25+
* Just for testing purposes, to simulate a sloppy click
2426
*/
2527
module.exports = function click(x, y, optsIn) {
2628
var opts = Lib.extendFlat({}, optsIn || {});
@@ -43,10 +45,16 @@ module.exports = function click(x, y, optsIn) {
4345

4446
var downOpts = Lib.extendFlat({buttons: buttons}, opts);
4547
var upOpts = opts;
48+
var slop = opts.slop || [];
49+
var slopX = slop[0] || 0;
50+
var slopY = slop[1] || 0;
51+
var slopOpts = Lib.extendFlat({}, downOpts);
52+
delete slopOpts.button;
4653

4754
mouseEvent('mousemove', x, y, moveOpts);
4855
mouseEvent('mousedown', x, y, downOpts);
4956
if(callContext) mouseEvent('contextmenu', x, y, downOpts);
57+
if(slopX || slopY) mouseEvent('mousemove', x + slopX, y + slopY, slopOpts);
5058
if(!callContext) mouseEvent('mouseup', x, y, upOpts);
5159
if(!rightClick) mouseEvent('click', x, y, upOpts);
5260
};

test/jasmine/tests/click_test.js

+11-2
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,7 @@ describe('Test click interactions:', function() {
117117
expect(contextPassthroughs).toBe(0);
118118
});
119119

120-
it('should contain the correct fields', function() {
121-
click(pointPos[0], pointPos[1]);
120+
function checkPointData() {
122121
expect(futureData.points.length).toEqual(1);
123122
expect(clickPassthroughs).toBe(2);
124123
expect(contextPassthroughs).toBe(0);
@@ -136,6 +135,16 @@ describe('Test click interactions:', function() {
136135
var evt = futureData.event;
137136
expect(evt.clientX).toEqual(pointPos[0]);
138137
expect(evt.clientY).toEqual(pointPos[1]);
138+
}
139+
140+
it('should contain the correct fields', function() {
141+
click(pointPos[0], pointPos[1]);
142+
checkPointData();
143+
});
144+
145+
it('should work with a sloppy click (shift < minDrag before mouseup)', function() {
146+
click(pointPos[0], pointPos[1], {slop: [4, 4]});
147+
checkPointData();
139148
});
140149

141150
it('works with fixedrange axes', function(done) {

test/jasmine/tests/dragelement_test.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ describe('dragElement', function() {
8181
expect(args[1]).toEqual(10);
8282
});
8383

84-
it('should pass the event to doneFn on mouseup after mousemove', function() {
84+
it('does not pass the event to doneFn on mouseup after mousemove', function() {
8585
var args = [];
8686
var options = {
8787
element: this.element,
@@ -99,8 +99,7 @@ describe('dragElement', function() {
9999
mouseEvent('mousemove', this.x + 10, this.y + 10);
100100
mouseEvent('mouseup', this.x, this.y);
101101

102-
expect(args.length).toBe(1);
103-
expect(args[0].type).toBe('mouseup');
102+
expect(args.length).toBe(0);
104103
});
105104

106105
it('should pass numClicks and event to clickFn on mouseup after no/small mousemove', function() {

0 commit comments

Comments
 (0)