Skip to content

Commit

Permalink
Merge pull request #2668 from plotly/fix-select-pan-clickfn-swap
Browse files Browse the repository at this point in the history
Fix select <-> pan double-click behavior
  • Loading branch information
etpinard committed May 25, 2018
2 parents 887cae6 + 1be1742 commit b042f93
Show file tree
Hide file tree
Showing 2 changed files with 183 additions and 73 deletions.
148 changes: 76 additions & 72 deletions src/plots/cartesian/dragbox.js
Expand Up @@ -144,40 +144,44 @@ function makeDragBox(gd, plotinfo, x, y, w, h, ns, ew) {
var dragOptions = {
element: dragger,
gd: gd,
plotinfo: plotinfo,
prepFn: function(e, startX, startY) {
var dragModeNow = gd._fullLayout.dragmode;

recomputeAxisLists();

if(!allFixedRanges) {
if(isMainDrag) {
// main dragger handles all drag modes, and changes
// to pan (or to zoom if it already is pan) on shift
if(e.shiftKey) {
if(dragModeNow === 'pan') dragModeNow = 'zoom';
else if(!isSelectOrLasso(dragModeNow)) dragModeNow = 'pan';
}
else if(e.ctrlKey) {
dragModeNow = 'pan';
}
plotinfo: plotinfo
};

dragOptions.prepFn = function(e, startX, startY) {
var dragModeNow = gd._fullLayout.dragmode;

recomputeAxisLists();

if(!allFixedRanges) {
if(isMainDrag) {
// main dragger handles all drag modes, and changes
// to pan (or to zoom if it already is pan) on shift
if(e.shiftKey) {
if(dragModeNow === 'pan') dragModeNow = 'zoom';
else if(!isSelectOrLasso(dragModeNow)) dragModeNow = 'pan';
}
else if(e.ctrlKey) {
dragModeNow = 'pan';
}
// all other draggers just pan
else dragModeNow = 'pan';
}
// all other draggers just pan
else dragModeNow = 'pan';
}

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

if(isSelectOrLasso(dragModeNow)) {
dragOptions.xaxes = xaxes;
dragOptions.yaxes = yaxes;
prepSelect(e, startX, startY, dragOptions, dragModeNow);
}
else if(allFixedRanges) {
if(isSelectOrLasso(dragModeNow)) {
dragOptions.xaxes = xaxes;
dragOptions.yaxes = yaxes;
// this attaches moveFn, clickFn, doneFn on dragOptions
prepSelect(e, startX, startY, dragOptions, dragModeNow);
} else {
dragOptions.clickFn = clickFn;

if(allFixedRanges) {
clearSelect(zoomlayer);
}
else if(dragModeNow === 'zoom') {
} else if(dragModeNow === 'zoom') {
dragOptions.moveFn = zoomMove;
dragOptions.doneFn = zoomDone;

Expand All @@ -187,58 +191,58 @@ function makeDragBox(gd, plotinfo, x, y, w, h, ns, ew) {
dragOptions.minDrag = 1;

zoomPrep(e, startX, startY);
}
else if(dragModeNow === 'pan') {
} else if(dragModeNow === 'pan') {
dragOptions.moveFn = plotDrag;
dragOptions.doneFn = dragTail;
clearSelect(zoomlayer);
}
},
clickFn: function(numClicks, evt) {
removeZoombox(gd);
}
};

if(numClicks === 2 && !singleEnd) doubleClick();
function clickFn(numClicks, evt) {
removeZoombox(gd);

if(isMainDrag) {
Fx.click(gd, evt, plotinfo.id);
if(numClicks === 2 && !singleEnd) doubleClick();

if(isMainDrag) {
Fx.click(gd, evt, plotinfo.id);
}
else if(numClicks === 1 && singleEnd) {
var ax = ns ? ya0 : xa0,
end = (ns === 's' || ew === 'w') ? 0 : 1,
attrStr = ax._name + '.range[' + end + ']',
initialText = getEndText(ax, end),
hAlign = 'left',
vAlign = 'middle';

if(ax.fixedrange) return;

if(ns) {
vAlign = (ns === 'n') ? 'top' : 'bottom';
if(ax.side === 'right') hAlign = 'right';
}
else if(numClicks === 1 && singleEnd) {
var ax = ns ? ya0 : xa0,
end = (ns === 's' || ew === 'w') ? 0 : 1,
attrStr = ax._name + '.range[' + end + ']',
initialText = getEndText(ax, end),
hAlign = 'left',
vAlign = 'middle';

if(ax.fixedrange) return;

if(ns) {
vAlign = (ns === 'n') ? 'top' : 'bottom';
if(ax.side === 'right') hAlign = 'right';
}
else if(ew === 'e') hAlign = 'right';

if(gd._context.showAxisRangeEntryBoxes) {
d3.select(dragger)
.call(svgTextUtils.makeEditable, {
gd: gd,
immediate: true,
background: gd._fullLayout.paper_bgcolor,
text: String(initialText),
fill: ax.tickfont ? ax.tickfont.color : '#444',
horizontalAlign: hAlign,
verticalAlign: vAlign
})
.on('edit', function(text) {
var v = ax.d2r(text);
if(v !== undefined) {
Registry.call('relayout', gd, attrStr, v);
}
});
}
else if(ew === 'e') hAlign = 'right';

if(gd._context.showAxisRangeEntryBoxes) {
d3.select(dragger)
.call(svgTextUtils.makeEditable, {
gd: gd,
immediate: true,
background: gd._fullLayout.paper_bgcolor,
text: String(initialText),
fill: ax.tickfont ? ax.tickfont.color : '#444',
horizontalAlign: hAlign,
verticalAlign: vAlign
})
.on('edit', function(text) {
var v = ax.d2r(text);
if(v !== undefined) {
Registry.call('relayout', gd, attrStr, v);
}
});
}
}
};
}

dragElement.init(dragOptions);

Expand Down
108 changes: 107 additions & 1 deletion test/jasmine/tests/select_test.js
Expand Up @@ -612,9 +612,115 @@ describe('@flaky Test select box and lasso in general:', function() {
})
.catch(failTest)
.then(done);

});

it('should clear selected points on double click only on pan/lasso modes', function(done) {
var gd = createGraphDiv();
var fig = Lib.extendDeep({}, require('@mocks/0.json'));
fig.data = [fig.data[0]];
fig.layout.xaxis.autorange = false;
fig.layout.xaxis.range = [2, 8];
fig.layout.yaxis.autorange = false;
fig.layout.yaxis.range = [0, 3];

function _assert(msg, exp) {
expect(gd.layout.xaxis.range)
.toBeCloseToArray(exp.xrng, 2, 'xaxis range - ' + msg);
expect(gd.layout.yaxis.range)
.toBeCloseToArray(exp.yrng, 2, 'yaxis range - ' + msg);

if(exp.selpts === null) {
expect('selectedpoints' in gd.data[0])
.toBe(false, 'cleared selectedpoints - ' + msg);
} else {
expect(gd.data[0].selectedpoints)
.toBeCloseToArray(exp.selpts, 2, 'selectedpoints - ' + msg);
}
}

Plotly.plot(gd, fig).then(function() {
_assert('base', {
xrng: [2, 8],
yrng: [0, 3],
selpts: null
});
return Plotly.relayout(gd, 'xaxis.range', [0, 10]);
})
.then(function() {
_assert('after xrng relayout', {
xrng: [0, 10],
yrng: [0, 3],
selpts: null
});
return doubleClick(200, 200);
})
.then(function() {
_assert('after double-click under dragmode zoom', {
xrng: [2, 8],
yrng: [0, 3],
selpts: null
});
return Plotly.relayout(gd, 'dragmode', 'select');
})
.then(function() {
_assert('after relayout to select', {
xrng: [2, 8],
yrng: [0, 3],
selpts: null
});
return drag([[100, 100], [400, 400]]);
})
.then(function() {
_assert('after selection', {
xrng: [2, 8],
yrng: [0, 3],
selpts: [40, 41, 42, 43, 44, 45, 46, 47, 48]
});
return doubleClick(200, 200);
})
.then(function() {
_assert('after double-click under dragmode select', {
xrng: [2, 8],
yrng: [0, 3],
selpts: null
});
return drag([[100, 100], [400, 400]]);
})
.then(function() {
_assert('after selection 2', {
xrng: [2, 8],
yrng: [0, 3],
selpts: [40, 41, 42, 43, 44, 45, 46, 47, 48]
});
return Plotly.relayout(gd, 'dragmode', 'pan');
})
.then(function() {
_assert('after relayout to pan', {
xrng: [2, 8],
yrng: [0, 3],
selpts: [40, 41, 42, 43, 44, 45, 46, 47, 48]
});
return Plotly.relayout(gd, 'yaxis.range', [0, 20]);
})
.then(function() {
_assert('after yrng relayout', {
xrng: [2, 8],
yrng: [0, 20],
selpts: [40, 41, 42, 43, 44, 45, 46, 47, 48]
});
return doubleClick(200, 200);
})
.then(function() {
_assert('after double-click under dragmode pan', {
xrng: [2, 8],
yrng: [0, 3],
// N.B. does not clear selection!
selpts: [40, 41, 42, 43, 44, 45, 46, 47, 48]
});
})
.catch(failTest)
.then(done);
});
});

describe('@flaky Test select box and lasso per trace:', function() {
Expand Down

0 comments on commit b042f93

Please sign in to comment.