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

Fixup rangebreaks l2p and p2l functions #4699

Merged
merged 14 commits into from
Mar 29, 2020
2 changes: 1 addition & 1 deletion src/plots/cartesian/autorange.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ function getAutoRange(gd, ax) {
lBreaks += brk.max - brk.min;
}
}
return (axReverse ? -1 : 1) * lBreaks;
return lBreaks;
};

var mbest = 0;
Expand Down
6 changes: 4 additions & 2 deletions src/plots/cartesian/axes.js
Original file line number Diff line number Diff line change
Expand Up @@ -636,8 +636,10 @@ axes.calcTicks = function calcTicks(ax) {
var newTickVals = [];
var prevPos;

var signAx = axrev ? -1 : 1;
for(var q = axrev ? 0 : len - 1; signAx * q >= signAx * (axrev ? len - 1 : 0); q -= signAx) { // apply reverse loop to pick greater values in breaks first
var dir = axrev ? 1 : -1;
var first = axrev ? 0 : len - 1;
var last = axrev ? len - 1 : 0;
for(var q = first; dir * q <= dir * last; q += dir) { // apply reverse loop to pick greater values in breaks first
var pos = ax.c2p(tickVals[q].value);

if(prevPos === undefined || Math.abs(pos - prevPos) > tf2) {
Expand Down
75 changes: 30 additions & 45 deletions src/plots/cartesian/set_convert.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,57 +192,46 @@ module.exports = function setConvert(ax, fullLayout) {
};

if(ax.rangebreaks) {
var isY = axLetter === 'y';

l2p = function(v) {
if(!isNumeric(v)) return BADNUM;
var len = ax._rangebreaks.length;
if(!len) return _l2p(v, ax._m, ax._b);

var isY = axLetter === 'y';
var pos = isY ? -v : v;
var flip = isY;
if(ax.range[0] > ax.range[1]) flip = !flip;
var signAx = flip ? -1 : 1;
var pos = signAx * v;

var q = 0;
for(var i = 0; i < len; i++) {
var nextI = i + 1;
var brk = ax._rangebreaks[i];

var min = isY ? -brk.max : brk.min;
var max = isY ? -brk.min : brk.max;
var min = signAx * ax._rangebreaks[i].min;
var max = signAx * ax._rangebreaks[i].max;

if(pos < min) break;
if(pos > max) q = nextI;
if(pos > max) q = i + 1;
else {
// when falls into break, pick 'closest' offset
q = pos > (min + max) / 2 ? nextI : i;
q = pos < (min + max) / 2 ? i : i + 1;
break;
}
}
return _l2p(v, (isY ? -1 : 1) * ax._m2, ax._B[q]);
var b2 = ax._B[q] || 0;
if(!isFinite(b2)) return 0; // avoid NaN translate e.g. in positionLabels if one keep zooming exactly into a break
return _l2p(v, ax._m2, b2);
};

p2l = function(px) {
if(!isNumeric(px)) return BADNUM;
var len = ax._rangebreaks.length;
if(!len) return _p2l(px, ax._m, ax._b);

var isY = axLetter === 'y';
var pos = isY ? -px : px;

var q = 0;
for(var i = 0; i < len; i++) {
var nextI = i + 1;
var brk = ax._rangebreaks[i];

var min = isY ? -brk.pmax : brk.pmin;
var max = isY ? -brk.pmin : brk.pmax;

if(pos < min) break;
if(pos > max) q = nextI;
else {
q = i;
break;
}
if(px < ax._rangebreaks[i].pmin) break;
if(px > ax._rangebreaks[i].pmax) q = i + 1;
}
return _p2l(px, (isY ? -1 : 1) * ax._m2, ax._B[q]);
return _p2l(px, ax._m2, ax._B[q]);
};
}

Expand Down Expand Up @@ -541,7 +530,8 @@ module.exports = function setConvert(ax, fullLayout) {
var rl0 = ax.r2l(ax[rangeAttr][0], calendar);
var rl1 = ax.r2l(ax[rangeAttr][1], calendar);

if(axLetter === 'y') {
var isY = axLetter === 'y';
if(isY) {
ax._offset = gs.t + (1 - ax.domain[1]) * gs.h;
ax._length = gs.h * (ax.domain[1] - ax.domain[0]);
ax._m = ax._length / (rl0 - rl1);
Expand Down Expand Up @@ -569,39 +559,34 @@ module.exports = function setConvert(ax, fullLayout) {
Math.min(rl0, rl1),
Math.max(rl0, rl1)
);
var axReverse = rl0 > rl1;
var signAx = axReverse ? -1 : 1;

if(ax._rangebreaks.length) {
for(i = 0; i < ax._rangebreaks.length; i++) {
brk = ax._rangebreaks[i];
ax._lBreaks += Math.abs(brk.max - brk.min);
}

ax._m2 = ax._length / (rl1 - rl0 - ax._lBreaks * signAx);

if(axLetter === 'y') {
ax._rangebreaks.reverse();
// N.B. top to bottom (negative coord, positive px direction)
ax._B.push(ax._m2 * rl1);
} else {
ax._B.push(-ax._m2 * rl0);
}
var flip = isY;
if(rl0 > rl1) flip = !flip;
if(flip) ax._rangebreaks.reverse();
var sign = flip ? -1 : 1;

ax._m2 = sign * ax._length / (Math.abs(rl1 - rl0) - ax._lBreaks);
ax._B.push(-ax._m2 * (isY ? rl1 : rl0));
for(i = 0; i < ax._rangebreaks.length; i++) {
brk = ax._rangebreaks[i];
ax._B.push(ax._B[ax._B.length - 1] - ax._m2 * (brk.max - brk.min) * signAx);
}
if(axReverse) {
ax._B.reverse();
ax._B.push(
ax._B[ax._B.length - 1] -
sign * ax._m2 * (brk.max - brk.min)
);
}

// fill pixel (i.e. 'p') min/max here,
// to not have to loop through the _rangebreaks twice during `p2l`
for(i = 0; i < ax._rangebreaks.length; i++) {
brk = ax._rangebreaks[i];
brk.pmin = l2p(axReverse ? brk.max : brk.min);
brk.pmax = l2p(axReverse ? brk.min : brk.max);
brk.pmin = l2p(brk.min);
brk.pmax = l2p(brk.max);
}
}
}
Expand Down
Binary file modified test/image/baselines/axes_breaks-night_autorange-reversed.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
237 changes: 237 additions & 0 deletions test/image/mocks/axes_breaks-reversed-without-pattern.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
{
"data": [
{
"type": "scatter",
"mode": "markers+lines",
"x": [
"1970-01-01 00:00:00.000",
"1970-01-01 00:00:00.010",
"1970-01-01 00:00:00.020",
"1970-01-01 00:00:00.030",
"1970-01-01 00:00:00.040",
"1970-01-01 00:00:00.050",
"1970-01-01 00:00:00.060",
"1970-01-01 00:00:00.070",
"1970-01-01 00:00:00.080",
"1970-01-01 00:00:00.090",
"1970-01-01 00:00:00.100",
"1970-01-01 00:00:00.110",
"1970-01-01 00:00:00.120",
"1970-01-01 00:00:00.130",
"1970-01-01 00:00:00.140",
"1970-01-01 00:00:00.150",
"1970-01-01 00:00:00.160",
"1970-01-01 00:00:00.170",
"1970-01-01 00:00:00.180",
"1970-01-01 00:00:00.190",
"1970-01-01 00:00:00.200"
]
},
{
"xaxis": "x2",
"yaxis": "y2",
"type": "scatter",
"mode": "markers+lines",
"x": [
"1970-01-01 00:00:00.000",
"1970-01-01 00:00:00.010",
"1970-01-01 00:00:00.020",
"1970-01-01 00:00:00.030",
"1970-01-01 00:00:00.040",
"1970-01-01 00:00:00.050",
"1970-01-01 00:00:00.060",
"1970-01-01 00:00:00.070",
"1970-01-01 00:00:00.080",
"1970-01-01 00:00:00.090",
"1970-01-01 00:00:00.100",
"1970-01-01 00:00:00.110",
"1970-01-01 00:00:00.120",
"1970-01-01 00:00:00.130",
"1970-01-01 00:00:00.140",
"1970-01-01 00:00:00.150",
"1970-01-01 00:00:00.160",
"1970-01-01 00:00:00.170",
"1970-01-01 00:00:00.180",
"1970-01-01 00:00:00.190",
"1970-01-01 00:00:00.200"
]
},
{
"xaxis": "x3",
"yaxis": "y3",
"type": "scatter",
"mode": "markers+lines",
"orientation": "h",
"y": [
"1970-01-01 00:00:00.000",
"1970-01-01 00:00:00.010",
"1970-01-01 00:00:00.020",
"1970-01-01 00:00:00.030",
"1970-01-01 00:00:00.040",
"1970-01-01 00:00:00.050",
"1970-01-01 00:00:00.060",
"1970-01-01 00:00:00.070",
"1970-01-01 00:00:00.080",
"1970-01-01 00:00:00.090",
"1970-01-01 00:00:00.100",
"1970-01-01 00:00:00.110",
"1970-01-01 00:00:00.120",
"1970-01-01 00:00:00.130",
"1970-01-01 00:00:00.140",
"1970-01-01 00:00:00.150",
"1970-01-01 00:00:00.160",
"1970-01-01 00:00:00.170",
"1970-01-01 00:00:00.180",
"1970-01-01 00:00:00.190",
"1970-01-01 00:00:00.200"
]
},
{
"xaxis": "x4",
"yaxis": "y4",
"type": "scatter",
"mode": "markers+lines",
"orientation": "h",
"y": [
"1970-01-01 00:00:00.000",
"1970-01-01 00:00:00.010",
"1970-01-01 00:00:00.020",
"1970-01-01 00:00:00.030",
"1970-01-01 00:00:00.040",
"1970-01-01 00:00:00.050",
"1970-01-01 00:00:00.060",
"1970-01-01 00:00:00.070",
"1970-01-01 00:00:00.080",
"1970-01-01 00:00:00.090",
"1970-01-01 00:00:00.100",
"1970-01-01 00:00:00.110",
"1970-01-01 00:00:00.120",
"1970-01-01 00:00:00.130",
"1970-01-01 00:00:00.140",
"1970-01-01 00:00:00.150",
"1970-01-01 00:00:00.160",
"1970-01-01 00:00:00.170",
"1970-01-01 00:00:00.180",
"1970-01-01 00:00:00.190",
"1970-01-01 00:00:00.200"
]
}
],
"layout": {
"showlegend": false,
"width": 800,
"height": 800,
"xaxis": {
"rangebreaks": [
{
"bounds": [
"1970-01-01 00:00:00.050",
"1970-01-01 00:00:00.075"
]
},
{
"bounds": [
"1970-01-01 00:00:00.120",
"1970-01-01 00:00:00.180"
]
}
],
"domain": [
0,
0.48
]
},
"xaxis2": {
"rangebreaks": [
{
"bounds": [
"1970-01-01 00:00:00.050",
"1970-01-01 00:00:00.075"
]
},
{
"bounds": [
"1970-01-01 00:00:00.120",
"1970-01-01 00:00:00.180"
]
}
],
"autorange": "reversed",
"anchor": "y2",
"domain": [
0.52,
1
]
},
"xaxis3": {
"anchor": "y3",
"domain": [
0,
0.48
]
},
"xaxis4": {
"anchor": "y4",
"domain": [
0.52,
1
]
},
"yaxis": {
"domain": [
0,
0.48
]
},
"yaxis2": {
"anchor": "x2",
"domain": [
0.52,
1
]
},
"yaxis3": {
"rangebreaks": [
{
"bounds": [
"1970-01-01 00:00:00.050",
"1970-01-01 00:00:00.075"
]
},
{
"bounds": [
"1970-01-01 00:00:00.120",
"1970-01-01 00:00:00.180"
]
}
],
"anchor": "x3",
"domain": [
0.52,
1
]
},
"yaxis4": {
"rangebreaks": [
{
"bounds": [
"1970-01-01 00:00:00.050",
"1970-01-01 00:00:00.075"
]
},
{
"bounds": [
"1970-01-01 00:00:00.120",
"1970-01-01 00:00:00.180"
]
}
],
"autorange": "reversed",
"anchor": "x4",
"domain": [
0,
0.48
]
}
}
}
Loading