Skip to content

Commit 20b17e5

Browse files
committed
set radialaxis.rangemode dflt to 'tozero' + add support for -ve r ranges
1 parent b4af46f commit 20b17e5

File tree

7 files changed

+2608
-827
lines changed

7 files changed

+2608
-827
lines changed

src/plots/polar/layout_attributes.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,21 @@ var radialAxisAttrs = {
6868
// -> mpl allow radial ranges to start off 0
6969
// -> same for matlab: https://www.mathworks.com/help/matlab/ref/rlim.html
7070
autorange: axesAttrs.autorange,
71-
// might make 'nonnegative' the default,
72-
// or add a special polar algo.
73-
rangemode: axesAttrs.rangemode,
71+
rangemode: {
72+
valType: 'enumerated',
73+
values: ['tozero', 'nonnegative', 'normal'],
74+
dflt: 'tozero',
75+
role: 'style',
76+
editType: 'calc',
77+
description: [
78+
'If *tozero*`, the range extends to 0,',
79+
'regardless of the input data',
80+
'If *nonnegative*, the range is non-negative,',
81+
'regardless of the input data.',
82+
'If *normal*, the range is computed in relation to the extrema',
83+
'of the input data (same behavior as for cartesian axes).'
84+
].join(' ')
85+
},
7486
range: axesAttrs.range,
7587

7688
categoryorder: axesAttrs.categoryorder,

src/plots/polar/layout_defaults.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,14 +83,19 @@ function handleDefaults(contIn, contOut, coerce, opts) {
8383
// as both radial and angular axes don't have a set domain.
8484
// Furthermore, angular axes don't have a set range.
8585
//
86-
// Mocked domains and ranges are set by the polar subplot instances.
87-
// By setting, _m to 1 here, we make Axes.expand think that range[1] > range[0].
86+
// Mocked domains and ranges are set by the polar subplot instances,
87+
// but Axes.expand uses the sign of _m to determine which padding value
88+
// to use.
89+
//
90+
// By setting, _m to 1 here, we make Axes.expand think that range[1] > range[0],
91+
// and vice-versa for `autorange: 'reversed'` below.
8892
axOut._m = 1;
8993

9094
switch(axName) {
9195
case 'radialaxis':
9296
var autoRange = coerceAxis('autorange', !axOut.isValidRange(axIn.range));
9397
if(autoRange) coerceAxis('rangemode');
98+
if(autoRange === 'reversed') axOut._m = -1;
9499

95100
coerceAxis('range');
96101
axOut.cleanRange('range', {dfltRange: [0, 1]});

src/plots/polar/polar.js

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,7 @@ proto.updateRadialDrag = function(fullLayout, polarLayout) {
791791
var radialLayout = polarLayout.radialaxis;
792792
var angle0 = deg2rad(radialLayout.position);
793793
var range0 = radialAxis.range.slice();
794+
var drange = range0[1] - range0[0];
794795

795796
if(!radialLayout.visible) return;
796797

@@ -825,9 +826,9 @@ proto.updateRadialDrag = function(fullLayout, polarLayout) {
825826
}
826827

827828
function doneFn() {
828-
if(angle1) {
829+
if(angle1 !== null) {
829830
Plotly.relayout(gd, _this.id + '.radialaxis.position', angle1);
830-
} else if(rng1) {
831+
} else if(rng1 !== null) {
831832
Plotly.relayout(gd, _this.id + '.radialaxis.range[1]', rng1);
832833
}
833834
}
@@ -843,15 +844,20 @@ proto.updateRadialDrag = function(fullLayout, polarLayout) {
843844
var transform = strTranslate(cx, cy) + strRotate(-angle1);
844845
layers['radial-axis'].attr('transform', transform);
845846
layers['radial-line'].select('line').attr('transform', transform);
847+
848+
var fullLayoutNow = _this.gd._fullLayout;
849+
var polarLayoutNow = fullLayoutNow[_this.id];
850+
_this.updateRadialAxisTitle(fullLayoutNow, polarLayoutNow, angle1);
846851
}
847852

848853
function rerangeMove(dx, dy) {
849854
// project (dx, dy) unto unit radial axis vector
850855
var dr = Lib.dot([dx, -dy], [Math.cos(angle0), Math.sin(angle0)]);
851-
rng1 = range0[1] * (1 - dr / radius);
852-
radialAxis.range[1] = rng1;
856+
var rprime = range0[1] - drange * dr / radius * 0.75;
853857

854-
// TODO should we restrict updates to same sign as range0 ???
858+
// make sure new range[1] does not change the range[0] -> range[1] sign
859+
if((drange > 0) !== (rprime > range0[0])) return;
860+
rng1 = radialAxis.range[1] = rprime;
855861

856862
Axes.doTicks(gd, _this.radialAxis, true);
857863
layers['radial-grid']
@@ -911,11 +917,19 @@ proto.isPtWithinSector = function(d) {
911917
var deg = wrap360(rad2deg(d.rad));
912918
var nextTurnDeg = deg + 360;
913919

920+
var r0, r1;
921+
if(radialRange[1] >= radialRange[0]) {
922+
r0 = radialRange[0];
923+
r1 = radialRange[1];
924+
} else {
925+
r0 = radialRange[1];
926+
r1 = radialRange[0];
927+
}
928+
914929
// TODO add calendar support
915930

916931
return (
917-
r >= radialRange[0] &&
918-
r <= radialRange[1] &&
932+
(r >= r0 && r <= r1) &&
919933
(isFullCircle(sector) ||
920934
(deg >= s0 && deg <= s1) ||
921935
(nextTurnDeg >= s0 && nextTurnDeg <= s1)

src/traces/scatterpolar/calc.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ module.exports = function calc(gd, trace) {
4848
}
4949

5050
var ppad = calcMarkerSize(trace, len);
51-
Axes.expand(radialAxis, rArray, {tozero: true, ppad: ppad});
51+
Axes.expand(radialAxis, rArray, {ppad: ppad});
5252

5353
if(angularAxis.type !== 'linear') {
5454
angularAxis.autorange = true;

src/traces/scatterpolar/plot.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ module.exports = function plot(subplot, moduleCalcData) {
2323

2424
var radialAxis = subplot.radialAxis;
2525
var radialRange = radialAxis.range;
26+
var rFilter;
27+
28+
if(radialRange[0] > radialRange[1]) {
29+
rFilter = function(v) { return v <= 0; };
30+
} else {
31+
rFilter = function(v) { return v >= 0; };
32+
}
2633

2734
// map (r, theta) first to a 'geometric' r and then to (x,y)
2835
// on-par with what scatterPlot expects.
@@ -36,7 +43,7 @@ module.exports = function plot(subplot, moduleCalcData) {
3643
// convert to 'r' data to fit with mocked polar x/y axis
3744
// which are always `type: 'linear'`
3845
var rr = radialAxis.c2r(r) - radialRange[0];
39-
if(rr >= 0) {
46+
if(rFilter(rr)) {
4047
var rad = cdi.rad;
4148
cdi.x = rr * Math.cos(rad);
4249
cdi.y = rr * Math.sin(rad);
65.6 KB
Loading

0 commit comments

Comments
 (0)