Skip to content

Commit d466146

Browse files
committed
add 'inner' radial dragbox when polar.hole>0
- which relayouts `radialaxis.range[0]` - does not try to relayout `radialaxis.angle`
1 parent 1122907 commit d466146

File tree

2 files changed

+77
-24
lines changed

2 files changed

+77
-24
lines changed

Diff for: src/plots/polar/polar.js

+38-24
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ proto.plot = function(polarCalcData, fullLayout) {
8989
_this.updateLayers(fullLayout, polarLayout);
9090
_this.updateLayout(fullLayout, polarLayout);
9191
Plots.generalUpdatePerTraceModule(_this.gd, _this, polarCalcData, polarLayout);
92-
_this.updateFx(fullLayout);
92+
_this.updateFx(fullLayout, polarLayout);
9393
};
9494

9595
proto.updateLayers = function(fullLayout, polarLayout) {
@@ -606,10 +606,11 @@ proto.updateAngularAxis = function(fullLayout, polarLayout) {
606606
.call(Color.stroke, angularLayout.linecolor);
607607
};
608608

609-
proto.updateFx = function(fullLayout) {
609+
proto.updateFx = function(fullLayout, polarLayout) {
610610
if(!this.gd._context.staticPlot) {
611611
this.updateAngularDrag(fullLayout);
612-
this.updateRadialDrag(fullLayout);
612+
this.updateRadialDrag(fullLayout, polarLayout, 1);
613+
if(this.innerRadius) this.updateRadialDrag(fullLayout, polarLayout, 0);
613614
this.updateMainDrag(fullLayout);
614615
}
615616
};
@@ -913,40 +914,47 @@ proto.updateMainDrag = function(fullLayout) {
913914
dragElement.init(dragOpts);
914915
};
915916

916-
proto.updateRadialDrag = function(fullLayout) {
917+
proto.updateRadialDrag = function(fullLayout, polarLayout, rngIndex) {
917918
var _this = this;
918919
var gd = _this.gd;
919920
var layers = _this.layers;
920921
var radius = _this.radius;
922+
var innerRadius = _this.innerRadius;
921923
var cx = _this.cx;
922924
var cy = _this.cy;
923925
var radialAxis = _this.radialAxis;
924926

925927
if(!radialAxis.visible) return;
926928

927929
var angle0 = deg2rad(_this.radialAxisAngle);
928-
var rl0 = radialAxis._rl[0];
929-
var rl1 = radialAxis._rl[1];
930-
var drl = rl1 - rl0;
930+
var rl = radialAxis._rl;
931+
var rl0 = rl[0];
932+
var rl1 = rl[1];
933+
var rbase = rl[rngIndex];
934+
var m = 0.75 * (rl[1] - rl[0]) / (1 - polarLayout.hole) / radius;
931935

932936
var bl = constants.radialDragBoxSize;
933937
var bl2 = bl / 2;
934-
var radialDrag = dragBox.makeRectDragger(layers, 'radialdrag', 'crosshair', -bl2, -bl2, bl, bl);
938+
var className = 'radialdrag' + (rngIndex ? '' : '-inner');
939+
var radialDrag = dragBox.makeRectDragger(layers, className, 'crosshair', -bl2, -bl2, bl, bl);
935940
var dragOpts = {element: radialDrag, gd: gd};
936-
var tx = cx + (radius + bl2) * Math.cos(angle0);
937-
var ty = cy - (radius + bl2) * Math.sin(angle0);
938941

939-
// TODO add 'inner' drag box when innerRadius > 0 !!
940-
941-
d3.select(radialDrag)
942-
.attr('transform', strTranslate(tx, ty));
942+
var tx, ty;
943+
if(rngIndex) {
944+
tx = cx + (radius + bl2) * Math.cos(angle0);
945+
ty = cy - (radius + bl2) * Math.sin(angle0);
946+
} else {
947+
tx = cx + (innerRadius - bl2) * Math.cos(angle0);
948+
ty = cy - (innerRadius - bl2) * Math.sin(angle0);
949+
}
950+
d3.select(radialDrag).attr('transform', strTranslate(tx, ty));
943951

944952
// move function (either rotate or re-range flavor)
945953
var moveFn2;
946954
// rotate angle on done
947955
var angle1;
948-
// re-range range[1] on done
949-
var rng1;
956+
// re-range range[1] (or range[0]) on done
957+
var rprime;
950958

951959
function moveFn(dx, dy) {
952960
if(moveFn2) {
@@ -967,12 +975,15 @@ proto.updateRadialDrag = function(fullLayout) {
967975
function doneFn() {
968976
if(angle1 !== null) {
969977
Registry.call('relayout', gd, _this.id + '.radialaxis.angle', angle1);
970-
} else if(rng1 !== null) {
971-
Registry.call('relayout', gd, _this.id + '.radialaxis.range[1]', rng1);
978+
} else if(rprime !== null) {
979+
Registry.call('relayout', gd, _this.id + '.radialaxis.range[' + rngIndex + ']', rprime);
972980
}
973981
}
974982

975983
function rotateMove(dx, dy) {
984+
// disable for inner drag boxes
985+
if(rngIndex === 0) return;
986+
976987
var x1 = tx + dx;
977988
var y1 = ty + dy;
978989

@@ -992,14 +1003,17 @@ proto.updateRadialDrag = function(fullLayout) {
9921003
function rerangeMove(dx, dy) {
9931004
// project (dx, dy) unto unit radial axis vector
9941005
var dr = Lib.dot([dx, -dy], [Math.cos(angle0), Math.sin(angle0)]);
995-
rng1 = rl1 - drl * dr / radius * 0.75;
1006+
rprime = rbase - m * dr;
9961007

997-
// make sure new range[1] does not change the range[0] -> range[1] sign
998-
if((drl > 0) !== (rng1 > rl0)) return;
1008+
// make sure rprime does not change the range[0] -> range[1] sign
1009+
if((m > 0) !== (rngIndex ? rprime > rl0 : rprime < rl1)) {
1010+
rprime = null;
1011+
return;
1012+
}
9991013

10001014
// update radial range -> update c2g -> update _m,_b
1001-
radialAxis.range[1] = rng1;
1002-
radialAxis._rl[1] = rng1;
1015+
radialAxis.range[rngIndex] = rprime;
1016+
radialAxis._rl[rngIndex] = rprime;
10031017
radialAxis.setGeometry();
10041018
radialAxis.setScale();
10051019

@@ -1027,7 +1041,7 @@ proto.updateRadialDrag = function(fullLayout) {
10271041
dragOpts.prepFn = function() {
10281042
moveFn2 = null;
10291043
angle1 = null;
1030-
rng1 = null;
1044+
rprime = null;
10311045

10321046
dragOpts.moveFn = moveFn;
10331047
dragOpts.doneFn = doneFn;

Diff for: test/jasmine/tests/polar_test.js

+39
Original file line numberDiff line numberDiff line change
@@ -1019,6 +1019,45 @@ describe('Test polar interactions:', function() {
10191019
.then(done);
10201020
});
10211021

1022+
it('should response to drag interactions on inner radial drag area', function(done) {
1023+
var fig = Lib.extendDeep({}, require('@mocks/polar_scatter.json'));
1024+
fig.layout.polar.hole = 0.2;
1025+
// to avoid dragging on hover labels
1026+
fig.layout.hovermode = false;
1027+
// adjust margins so that middle of plot area is at 300x300
1028+
// with its middle at [200,200]
1029+
fig.layout.width = 400;
1030+
fig.layout.height = 400;
1031+
fig.layout.margin = {l: 50, t: 50, b: 50, r: 50};
1032+
1033+
var dragPos0 = [200, 200];
1034+
1035+
// use 'special' drag method - as we need two mousemove events
1036+
// to activate the radial drag mode
1037+
function _drag(p0, dp) {
1038+
var node = d3.select('.polar > .draglayer > .radialdrag-inner').node();
1039+
return drag(node, dp[0], dp[1], null, p0[0], p0[1], 2);
1040+
}
1041+
1042+
function _assert(rng, msg) {
1043+
expect(gd._fullLayout.polar.radialaxis.range)
1044+
.toBeCloseToArray(rng, 1, msg + ' - range');
1045+
}
1046+
1047+
_plot(fig)
1048+
.then(function() { return _drag(dragPos0, [-50, 0]); })
1049+
.then(function() {
1050+
_assert([3.55, 11.36], 'move inward');
1051+
})
1052+
.then(function() { return Plotly.relayout(gd, 'polar.radialaxis.autorange', true); })
1053+
.then(function() { return _drag(dragPos0, [50, 0]); })
1054+
.then(function() {
1055+
_assert([-3.55, 11.36], 'move outward');
1056+
})
1057+
.catch(failTest)
1058+
.then(done);
1059+
});
1060+
10221061
it('should response to drag interactions on angular drag area', function(done) {
10231062
var fig = Lib.extendDeep({}, require('@mocks/polar_scatter.json'));
10241063

0 commit comments

Comments
 (0)