Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

disable polar rotation drag when dragmode = false #6147

Merged
merged 12 commits into from
May 9, 2022
1 change: 1 addition & 0 deletions draftlogs/6147_fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Disable polar rotation drag when dragmode = false [[#6147](https://github.com/plotly/plotly.js/pull/6147)]
15 changes: 11 additions & 4 deletions src/plots/polar/polar.js
Original file line number Diff line number Diff line change
Expand Up @@ -1150,6 +1150,9 @@ proto.updateRadialDrag = function(fullLayout, polarLayout, rngIndex) {

var radialDrag = dragBox.makeRectDragger(layers, className, 'crosshair', -bl2, -bl2, bl, bl);
var dragOpts = {element: radialDrag, gd: gd};
if(fullLayout.dragmode === false) {
dragOpts.dragmode = false;
}

updateElement(d3.select(radialDrag), radialAxis.visible && innerRadius < radius, {
transform: strTranslate(tx, ty)
Expand Down Expand Up @@ -1295,10 +1298,14 @@ proto.updateAngularDrag = function(fullLayout) {
var angularDrag = dragBox.makeDragger(layers, 'path', 'angulardrag', 'move');
var dragOpts = {element: angularDrag, gd: gd};

d3.select(angularDrag)
.attr('d', _this.pathAnnulus(radius, radius + dbs))
.attr('transform', strTranslate(cx, cy))
.call(setCursor, 'move');
if(fullLayout.dragmode === false) {
dragOpts.dragmode = false;
} else {
d3.select(angularDrag)
.attr('d', _this.pathAnnulus(radius, radius + dbs))
.attr('transform', strTranslate(cx, cy))
.call(setCursor, 'move');
}

function xy2a(x, y) {
return Math.atan2(cyy + dbs - y, x - cxx - dbs);
Expand Down
292 changes: 292 additions & 0 deletions test/jasmine/tests/polar_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1146,6 +1146,298 @@ describe('Test polar interactions:', function() {
.then(done, done.fail);
});

describe('dragmode === false', function() {
it('should not respond to drag interactions on plot area when dragmode === false', function(done) {
var fig = Lib.extendDeep({}, require('@mocks/polar_scatter.json'));

fig.layout.dragmode = false;

// to avoid dragging on hover labels
fig.layout.hovermode = false;

// adjust margins so that middle of plot area is at 300x300
// with its middle at [200,200]
fig.layout.width = 400;
fig.layout.height = 400;
fig.layout.margin = {l: 50, t: 50, b: 50, r: 50};

var mid = [200, 200];
var resetNumber = 0;

function _drag(p0, dp) {
var node = d3Select('.polar > .draglayer > .maindrag').node();
return drag({node: node, dpos: dp, pos0: p0});
}

function _assertRange(rng, msg) {
expect(gd._fullLayout.polar.radialaxis.range).toBeCloseToArray(rng, 1, msg);
}

function _assertBase(extra) {
var msg = 'base range' + (extra ? ' ' + extra : '');
_assertRange([0, 11.1], msg);
}

function _reset() {
resetNumber++;

var extra = '(reset ' + resetNumber + ')';
_assertBase(extra);
expect(eventCnts.plotly_doubleclick).toBe(0, 'doubleclick event #' + extra);
}

_plot(fig)
.then(_assertBase)
.then(function() { return _drag(mid, [50, 50]); })
.then(function() {
_assertBase('from center move toward bottom-right');
})
.then(delay(20))
.then(function() { return _doubleClick(mid); })
.then(delay(20))
.then(_reset)
.then(function() { return _drag(mid, [-50, -50]); })
.then(function() {
_assertBase('from center move toward top-left');
})
.then(delay(20))
.then(function() { return _doubleClick(mid); })
.then(delay(20))
.then(_reset)
.then(function() { return _drag([mid[0] + 30, mid[0] - 30], [50, -50]); })
.then(function() {
_assertBase('from quadrant #1 move top-right');
})
.then(delay(20))
.then(function() { return _doubleClick(mid); })
.then(delay(20))
.then(_reset)
.then(function() { return _drag([345, 200], [-50, 0]); })
.then(function() {
_assertBase('from right edge move left');
})
.then(delay(20))
.then(function() { return _doubleClick(mid); })
.then(delay(20))
.then(_reset)
.then(function() { return _drag(mid, [10, 10]);})
.then(function() { _assertBase('from center to not far enough'); })
.then(function() { return _drag([mid[0] + 30, mid[0] - 30], [-10, 0]);})
.then(function() { _assertBase('from quadrant #1 to not far enough'); })
.then(function() { return _drag([345, 200], [-10, 0]);})
.then(function() { _assertBase('from right edge to not far enough'); })
.then(function() {
expect(eventCnts.plotly_relayout)
.toBe(0, 'no new relayout events after *not far enough* cases');
})
.then(delay(20))
.then(function() { return _doubleClick(mid); })
.then(delay(20))
.then(_reset)
.then(function() { return Plotly.relayout(gd, 'polar.hole', 0.2); })
.then(function() { return _drag([mid[0] + 30, mid[0] - 30], [50, -50]); })
.then(function() {
_assertRange([0, 11.4], 'with polar.hole>0, from quadrant #1 move top-right');
})
.then(done, done.fail);
});

it('should not respond to drag interactions on radial drag area when dragmode === false', function(done) {
var fig = Lib.extendDeep({}, require('@mocks/polar_scatter.json'));

fig.layout.dragmode = false;

// to avoid dragging on hover labels
fig.layout.hovermode = false;

// adjust margins so that middle of plot area is at 300x300
// with its middle at [200,200]
fig.layout.width = 400;
fig.layout.height = 400;
fig.layout.margin = {l: 50, t: 50, b: 50, r: 50};

var dragPos0 = [375, 200];
var resetNumber = 0;

// use 'special' drag method - as we need two mousemove events
// to activate the radial drag mode
function _drag(p0, dp) {
var node = d3Select('.polar > .draglayer > .radialdrag').node();
return drag({node: node, dpos: dp, pos0: p0, nsteps: 2});
}

function _assert(rng, angle, evtRng1, evtAngle, msg) {
expect(gd._fullLayout.polar.radialaxis.range)
.toBeCloseToArray(rng, 1, msg + ' - range');
expect(gd._fullLayout.polar.radialaxis.angle)
.toBeCloseTo(angle, 1, msg + ' - angle');

if(evtRng1 !== null) {
expect(eventData['polar.radialaxis.range[1]'])
.toBeCloseTo(evtRng1, 1, msg + ' - range[1] event data');
}
if(evtAngle !== null) {
expect(eventData['polar.radialaxis.angle'])
.toBeCloseTo(evtAngle, 1, msg + ' - angle event data');
}
}

function _assertBase(extra) {
extra = extra ? ' ' + extra : '';
_assert([0, 11.1], 0, null, null, 'base' + extra);
}

function _reset() {
return delay(100)()
.then(function() { return _doubleClick([200, 200]); })
.then(function() {
resetNumber++;

var extra = '(reset ' + resetNumber + ')';
_assertBase(extra);
expect(eventCnts.plotly_doubleclick).toBe(0, 'doubleclick event #' + extra);
});
}

_plot(fig)
.then(_assertBase)
.then(function() { return _drag(dragPos0, [-50, 0]); })
.then(function() {
_assertBase('move inward');
})
.then(_reset)
.then(function() { return _drag(dragPos0, [50, 0]); })
.then(function() {
_assertBase('move outward');
})
.then(_reset)
.then(function() { return _drag(dragPos0, [0, -50]); })
.then(function() {
_assertBase('move counterclockwise');
})
.then(_reset)
.then(function() { return _drag(dragPos0, [0, 50]); })
.then(function() {
_assertBase('move clockwise');
})
.then(_reset)
.then(function() {
expect(eventCnts.plotly_relayout).toBe(0, 'total # of relayout events');
})
.then(done, done.fail);
});

it('should not responsd to drag interactions on inner radial drag area when dragmode === false', function(done) {
var fig = Lib.extendDeep({}, require('@mocks/polar_scatter.json'));
fig.layout.dragmode = false;
fig.layout.polar.hole = 0.2;
// to avoid dragging on hover labels
fig.layout.hovermode = false;
// adjust margins so that middle of plot area is at 300x300
// with its middle at [200,200]
fig.layout.width = 400;
fig.layout.height = 400;
fig.layout.margin = {l: 50, t: 50, b: 50, r: 50};

var dragPos0 = [200, 200];

// use 'special' drag method - as we need two mousemove events
// to activate the radial drag mode
function _drag(p0, dp) {
var node = d3Select('.polar > .draglayer > .radialdrag-inner').node();
return drag({node: node, dpos: dp, pos0: p0, nsteps: 2});
}

function _assert(rng, msg) {
expect(gd._fullLayout.polar.radialaxis.range)
.toBeCloseToArray(rng, 1, msg + ' - range');
}

function _assertBase(extra) {
extra = extra ? ' ' + extra : '';
_assert([0, 11.4], 'base' + extra);
}

_plot(fig)
.then(function() { return _drag(dragPos0, [-50, 0]); })
.then(function() {
_assertBase('move inward');
})
.then(function() { return Plotly.relayout(gd, 'polar.radialaxis.autorange', true); })
.then(function() { return _drag(dragPos0, [50, 0]); })
.then(function() {
_assertBase('move outward');
})
.then(done, done.fail);
});

it('should not responsd to drag interactions on angular drag area when dragmode === false', function(done) {
var fig = Lib.extendDeep({}, require('@mocks/polar_scatter.json'));

fig.layout.dragmode = false;

// to avoid dragging on hover labels
fig.layout.hovermode = false;

// adjust margins so that middle of plot area is at 300x300
// with its middle at [200,200]
fig.layout.width = 400;
fig.layout.height = 400;
fig.layout.margin = {l: 50, t: 50, b: 50, r: 50};

var dragPos0 = [350, 150];
var resetNumber = 0;

function _drag(p0, dp) {
var node = d3Select('.polar > .draglayer > .angulardrag').node();
return drag({node: node, dpos: dp, pos0: p0});
}

function _assert(rot, msg, noEvent) {
expect(gd._fullLayout.polar.angularaxis.rotation)
.toBeCloseTo(rot, 1, msg + ' - rotation');
if(!noEvent) {
expect(eventData['polar.angularaxis.rotation'])
.toBeCloseTo(rot, 1, msg + ' - rotation event data');
}
}

function _assertBase(extra) {
extra = extra ? ' ' + extra : '';
_assert(0, 'base' + extra, true);
}

function _reset() {
return delay(100)()
.then(function() { return _doubleClick([200, 200]); })
.then(function() {
resetNumber++;

var extra = '(reset ' + resetNumber + ')';
_assertBase(extra);
expect(eventCnts.plotly_doubleclick).toBe(0, 'doubleclick event #' + extra);
});
}

_plot(fig)
.then(_assertBase)
.then(function() { return _drag(dragPos0, [-20, -20]); })
.then(function() {
_assertBase('move counterclockwise');
})
.then(_reset)
.then(function() { return _drag(dragPos0, [20, 20]); })
.then(function() {
_assertBase('move clockwise');
})
.then(_reset)
.then(function() {
expect(eventCnts.plotly_relayout).toBe(0, 'total # of relayout events');
})
.then(done, done.fail);
});
});

describe('should update scene during drag interactions on radial and angular drag area', function() {
var objs = ['scatter2d', 'line2d'];
var scene, gl, nTraces;
Expand Down