Skip to content

Commit defb8aa

Browse files
authored
Merge pull request #2279 from plotly/fixedrange-click
Fixedrange click
2 parents cb2729e + a26d400 commit defb8aa

File tree

4 files changed

+116
-67
lines changed

4 files changed

+116
-67
lines changed

src/plots/cartesian/dragbox.js

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,14 @@ function makeDragBox(gd, plotinfo, x, y, w, h, ns, ew) {
113113

114114
var dragger = makeRectDragger(plotinfo, ns + ew + 'drag', cursor, x, y, w, h);
115115

116+
var allFixedRanges = !yActive && !xActive;
117+
116118
// still need to make the element if the axes are disabled
117119
// but nuke its events (except for maindrag which needs them for hover)
118120
// and stop there
119-
if(!yActive && !xActive && !isSelectOrLasso(fullLayout.dragmode)) {
121+
if(allFixedRanges && !isMainDrag) {
120122
dragger.onmousedown = null;
121-
dragger.style.pointerEvents = isMainDrag ? 'all' : 'none';
123+
dragger.style.pointerEvents = 'none';
122124
return dragger;
123125
}
124126

@@ -129,24 +131,34 @@ function makeDragBox(gd, plotinfo, x, y, w, h, ns, ew) {
129131
prepFn: function(e, startX, startY) {
130132
var dragModeNow = gd._fullLayout.dragmode;
131133

132-
if(isMainDrag) {
133-
// main dragger handles all drag modes, and changes
134-
// to pan (or to zoom if it already is pan) on shift
135-
if(e.shiftKey) {
136-
if(dragModeNow === 'pan') dragModeNow = 'zoom';
137-
else if(!isSelectOrLasso(dragModeNow)) dragModeNow = 'pan';
138-
}
139-
else if(e.ctrlKey) {
140-
dragModeNow = 'pan';
134+
if(!allFixedRanges) {
135+
if(isMainDrag) {
136+
// main dragger handles all drag modes, and changes
137+
// to pan (or to zoom if it already is pan) on shift
138+
if(e.shiftKey) {
139+
if(dragModeNow === 'pan') dragModeNow = 'zoom';
140+
else if(!isSelectOrLasso(dragModeNow)) dragModeNow = 'pan';
141+
}
142+
else if(e.ctrlKey) {
143+
dragModeNow = 'pan';
144+
}
141145
}
146+
// all other draggers just pan
147+
else dragModeNow = 'pan';
142148
}
143-
// all other draggers just pan
144-
else dragModeNow = 'pan';
145149

146150
if(dragModeNow === 'lasso') dragOptions.minDrag = 1;
147151
else dragOptions.minDrag = undefined;
148152

149-
if(dragModeNow === 'zoom') {
153+
if(isSelectOrLasso(dragModeNow)) {
154+
dragOptions.xaxes = xa;
155+
dragOptions.yaxes = ya;
156+
prepSelect(e, startX, startY, dragOptions, dragModeNow);
157+
}
158+
else if(allFixedRanges) {
159+
clearSelect(zoomlayer);
160+
}
161+
else if(dragModeNow === 'zoom') {
150162
dragOptions.moveFn = zoomMove;
151163
dragOptions.doneFn = zoomDone;
152164

@@ -162,11 +174,6 @@ function makeDragBox(gd, plotinfo, x, y, w, h, ns, ew) {
162174
dragOptions.doneFn = dragTail;
163175
clearSelect(zoomlayer);
164176
}
165-
else if(isSelectOrLasso(dragModeNow)) {
166-
dragOptions.xaxes = xa;
167-
dragOptions.yaxes = ya;
168-
prepSelect(e, startX, startY, dragOptions, dragModeNow);
169-
}
170177
},
171178
clickFn: function(numClicks, evt) {
172179
removeZoombox(gd);

test/jasmine/tests/cartesian_interact_test.js

Lines changed: 62 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ describe('zoom box element', function() {
6363

6464
describe('main plot pan', function() {
6565

66-
var mock = require('@mocks/10.json'),
67-
gd, modeBar, relayoutCallback;
66+
var mock = require('@mocks/10.json');
67+
var gd, modeBar, relayoutCallback;
6868

6969
beforeEach(function(done) {
7070
gd = createGraphDiv();
@@ -106,70 +106,86 @@ describe('main plot pan', function() {
106106
expect(gd.layout.xaxis.range).toBeCloseToArray(originalX, precision);
107107
expect(gd.layout.yaxis.range).toBeCloseToArray(originalY, precision);
108108

109-
delay(MODEBAR_DELAY)()
110-
.then(function() {
109+
function _drag(x0, y0, x1, y1) {
110+
mouseEvent('mousedown', x0, y0);
111+
mouseEvent('mousemove', x1, y1);
112+
mouseEvent('mouseup', x1, y1);
113+
}
111114

112-
expect(relayoutCallback).toHaveBeenCalledTimes(1);
113-
relayoutCallback.calls.reset();
115+
function _checkAxes(xRange, yRange) {
116+
expect(gd.layout.xaxis.range).toBeCloseToArray(xRange, precision);
117+
expect(gd.layout.yaxis.range).toBeCloseToArray(yRange, precision);
118+
}
114119

120+
function _runDrag(xr0, xr1, yr0, yr1) {
115121
// Drag scene along the X axis
116-
117-
mouseEvent('mousedown', 110, 150);
118-
mouseEvent('mousemove', 220, 150);
119-
mouseEvent('mouseup', 220, 150);
120-
121-
expect(gd.layout.xaxis.range).toBeCloseToArray(newX, precision);
122-
expect(gd.layout.yaxis.range).toBeCloseToArray(originalY, precision);
122+
_drag(110, 150, 220, 150);
123+
_checkAxes(xr1, yr0);
123124

124125
// Drag scene back along the X axis (not from the same starting point but same X delta)
125-
126-
mouseEvent('mousedown', 280, 150);
127-
mouseEvent('mousemove', 170, 150);
128-
mouseEvent('mouseup', 170, 150);
129-
130-
expect(gd.layout.xaxis.range).toBeCloseToArray(originalX, precision);
131-
expect(gd.layout.yaxis.range).toBeCloseToArray(originalY, precision);
126+
_drag(280, 150, 170, 150);
127+
_checkAxes(xr0, yr0);
132128

133129
// Drag scene along the Y axis
134-
135-
mouseEvent('mousedown', 110, 150);
136-
mouseEvent('mousemove', 110, 190);
137-
mouseEvent('mouseup', 110, 190);
138-
139-
expect(gd.layout.xaxis.range).toBeCloseToArray(originalX, precision);
140-
expect(gd.layout.yaxis.range).toBeCloseToArray(newY, precision);
130+
_drag(110, 150, 110, 190);
131+
_checkAxes(xr0, yr1);
141132

142133
// Drag scene back along the Y axis (not from the same starting point but same Y delta)
143-
144-
mouseEvent('mousedown', 280, 130);
145-
mouseEvent('mousemove', 280, 90);
146-
mouseEvent('mouseup', 280, 90);
147-
148-
expect(gd.layout.xaxis.range).toBeCloseToArray(originalX, precision);
149-
expect(gd.layout.yaxis.range).toBeCloseToArray(originalY, precision);
134+
_drag(280, 130, 280, 90);
135+
_checkAxes(xr0, yr0);
150136

151137
// Drag scene along both the X and Y axis
152-
153-
mouseEvent('mousedown', 110, 150);
154-
mouseEvent('mousemove', 220, 190);
155-
mouseEvent('mouseup', 220, 190);
156-
157-
expect(gd.layout.xaxis.range).toBeCloseToArray(newX, precision);
158-
expect(gd.layout.yaxis.range).toBeCloseToArray(newY, precision);
138+
_drag(110, 150, 220, 190);
139+
_checkAxes(xr1, yr1);
159140

160141
// Drag scene back along the X and Y axis (not from the same starting point but same delta vector)
142+
_drag(280, 130, 170, 90);
143+
_checkAxes(xr0, yr0);
144+
}
161145

162-
mouseEvent('mousedown', 280, 130);
163-
mouseEvent('mousemove', 170, 90);
164-
mouseEvent('mouseup', 170, 90);
146+
delay(MODEBAR_DELAY)()
147+
.then(function() {
165148

166-
expect(gd.layout.xaxis.range).toBeCloseToArray(originalX, precision);
167-
expect(gd.layout.yaxis.range).toBeCloseToArray(originalY, precision);
149+
expect(relayoutCallback).toHaveBeenCalledTimes(1);
150+
relayoutCallback.calls.reset();
151+
_runDrag(originalX, newX, originalY, newY);
168152
})
169153
.then(delay(MODEBAR_DELAY))
170154
.then(function() {
171155
// X and back; Y and back; XY and back
172156
expect(relayoutCallback).toHaveBeenCalledTimes(6);
157+
return Plotly.relayout(gd, {'xaxis.fixedrange': true});
158+
})
159+
.then(function() {
160+
relayoutCallback.calls.reset();
161+
_runDrag(originalX, originalX, originalY, newY);
162+
})
163+
.then(delay(MODEBAR_DELAY))
164+
.then(function() {
165+
// Y and back; XY and back
166+
// should perhaps be 4, but the noop drags still generate a relayout call.
167+
// TODO: should we try and remove this call?
168+
expect(relayoutCallback).toHaveBeenCalledTimes(6);
169+
return Plotly.relayout(gd, {'yaxis.fixedrange': true});
170+
})
171+
.then(function() {
172+
relayoutCallback.calls.reset();
173+
_runDrag(originalX, originalX, originalY, originalY);
174+
})
175+
.then(delay(MODEBAR_DELAY))
176+
.then(function() {
177+
// both axes are fixed - no changes
178+
expect(relayoutCallback).toHaveBeenCalledTimes(0);
179+
return Plotly.relayout(gd, {'xaxis.fixedrange': false, dragmode: 'pan'});
180+
})
181+
.then(function() {
182+
relayoutCallback.calls.reset();
183+
_runDrag(originalX, newX, originalY, originalY);
184+
})
185+
.then(delay(MODEBAR_DELAY))
186+
.then(function() {
187+
// X and back; XY and back
188+
expect(relayoutCallback).toHaveBeenCalledTimes(6);
173189
})
174190
.catch(failTest)
175191
.then(done);

test/jasmine/tests/click_test.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,31 @@ describe('Test click interactions:', function() {
138138
expect(evt.clientY).toEqual(pointPos[1]);
139139
});
140140

141+
it('works with fixedrange axes', function(done) {
142+
Plotly.relayout(gd, {'xaxis.fixedrange': true, 'yaxis.fixedrange': true}).then(function() {
143+
click(pointPos[0], pointPos[1]);
144+
expect(futureData.points.length).toEqual(1);
145+
expect(clickPassthroughs).toBe(2);
146+
expect(contextPassthroughs).toBe(0);
147+
148+
var pt = futureData.points[0];
149+
expect(Object.keys(pt)).toEqual([
150+
'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex',
151+
'x', 'y', 'xaxis', 'yaxis'
152+
]);
153+
expect(pt.curveNumber).toEqual(0);
154+
expect(pt.pointNumber).toEqual(11);
155+
expect(pt.x).toEqual(0.125);
156+
expect(pt.y).toEqual(2.125);
157+
158+
var evt = futureData.event;
159+
expect(evt.clientX).toEqual(pointPos[0]);
160+
expect(evt.clientY).toEqual(pointPos[1]);
161+
})
162+
.catch(fail)
163+
.then(done);
164+
});
165+
141166
var modClickOpts = {
142167
altKey: true,
143168
ctrlKey: true, // this makes it effectively into a right-click

test/jasmine/tests/fx_test.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,11 +231,12 @@ describe('relayout', function() {
231231

232232
return Plotly.relayout(gd, 'yaxis.fixedrange', true);
233233
}).then(function() {
234-
assertMainDrag('pointer', false);
234+
// still active with fixedrange because we're handling clicks here too.
235+
assertMainDrag('pointer', true);
235236

236237
return Plotly.relayout(gd, 'dragmode', 'drag');
237238
}).then(function() {
238-
assertMainDrag('pointer', false);
239+
assertMainDrag('pointer', true);
239240

240241
return Plotly.relayout(gd, 'dragmode', 'lasso');
241242
}).then(function() {

0 commit comments

Comments
 (0)