Skip to content

Commit ebab12b

Browse files
authored
Merge pull request #4699 from plotly/rangebreak-hover
Fixup rangebreaks l2p and p2l functions
2 parents 0e01a5a + ff5db2b commit ebab12b

8 files changed

+412
-50
lines changed

src/plots/cartesian/autorange.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ function getAutoRange(gd, ax) {
105105
lBreaks += brk.max - brk.min;
106106
}
107107
}
108-
return (axReverse ? -1 : 1) * lBreaks;
108+
return lBreaks;
109109
};
110110

111111
var mbest = 0;

src/plots/cartesian/axes.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -636,8 +636,10 @@ axes.calcTicks = function calcTicks(ax) {
636636
var newTickVals = [];
637637
var prevPos;
638638

639-
var signAx = axrev ? -1 : 1;
640-
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
639+
var dir = axrev ? 1 : -1;
640+
var first = axrev ? 0 : len - 1;
641+
var last = axrev ? len - 1 : 0;
642+
for(var q = first; dir * q <= dir * last; q += dir) { // apply reverse loop to pick greater values in breaks first
641643
var pos = ax.c2p(tickVals[q].value);
642644

643645
if(prevPos === undefined || Math.abs(pos - prevPos) > tf2) {

src/plots/cartesian/set_convert.js

+30-45
Original file line numberDiff line numberDiff line change
@@ -192,57 +192,46 @@ module.exports = function setConvert(ax, fullLayout) {
192192
};
193193

194194
if(ax.rangebreaks) {
195+
var isY = axLetter === 'y';
196+
195197
l2p = function(v) {
196198
if(!isNumeric(v)) return BADNUM;
197199
var len = ax._rangebreaks.length;
198200
if(!len) return _l2p(v, ax._m, ax._b);
199201

200-
var isY = axLetter === 'y';
201-
var pos = isY ? -v : v;
202+
var flip = isY;
203+
if(ax.range[0] > ax.range[1]) flip = !flip;
204+
var signAx = flip ? -1 : 1;
205+
var pos = signAx * v;
202206

203207
var q = 0;
204208
for(var i = 0; i < len; i++) {
205-
var nextI = i + 1;
206-
var brk = ax._rangebreaks[i];
207-
208-
var min = isY ? -brk.max : brk.min;
209-
var max = isY ? -brk.min : brk.max;
209+
var min = signAx * ax._rangebreaks[i].min;
210+
var max = signAx * ax._rangebreaks[i].max;
210211

211212
if(pos < min) break;
212-
if(pos > max) q = nextI;
213+
if(pos > max) q = i + 1;
213214
else {
214215
// when falls into break, pick 'closest' offset
215-
q = pos > (min + max) / 2 ? nextI : i;
216+
q = pos < (min + max) / 2 ? i : i + 1;
216217
break;
217218
}
218219
}
219-
return _l2p(v, (isY ? -1 : 1) * ax._m2, ax._B[q]);
220+
var b2 = ax._B[q] || 0;
221+
if(!isFinite(b2)) return 0; // avoid NaN translate e.g. in positionLabels if one keep zooming exactly into a break
222+
return _l2p(v, ax._m2, b2);
220223
};
221224

222225
p2l = function(px) {
223-
if(!isNumeric(px)) return BADNUM;
224226
var len = ax._rangebreaks.length;
225227
if(!len) return _p2l(px, ax._m, ax._b);
226228

227-
var isY = axLetter === 'y';
228-
var pos = isY ? -px : px;
229-
230229
var q = 0;
231230
for(var i = 0; i < len; i++) {
232-
var nextI = i + 1;
233-
var brk = ax._rangebreaks[i];
234-
235-
var min = isY ? -brk.pmax : brk.pmin;
236-
var max = isY ? -brk.pmin : brk.pmax;
237-
238-
if(pos < min) break;
239-
if(pos > max) q = nextI;
240-
else {
241-
q = i;
242-
break;
243-
}
231+
if(px < ax._rangebreaks[i].pmin) break;
232+
if(px > ax._rangebreaks[i].pmax) q = i + 1;
244233
}
245-
return _p2l(px, (isY ? -1 : 1) * ax._m2, ax._B[q]);
234+
return _p2l(px, ax._m2, ax._B[q]);
246235
};
247236
}
248237

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

544-
if(axLetter === 'y') {
533+
var isY = axLetter === 'y';
534+
if(isY) {
545535
ax._offset = gs.t + (1 - ax.domain[1]) * gs.h;
546536
ax._length = gs.h * (ax.domain[1] - ax.domain[0]);
547537
ax._m = ax._length / (rl0 - rl1);
@@ -569,39 +559,34 @@ module.exports = function setConvert(ax, fullLayout) {
569559
Math.min(rl0, rl1),
570560
Math.max(rl0, rl1)
571561
);
572-
var axReverse = rl0 > rl1;
573-
var signAx = axReverse ? -1 : 1;
574562

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

581-
ax._m2 = ax._length / (rl1 - rl0 - ax._lBreaks * signAx);
582-
583-
if(axLetter === 'y') {
584-
ax._rangebreaks.reverse();
585-
// N.B. top to bottom (negative coord, positive px direction)
586-
ax._B.push(ax._m2 * rl1);
587-
} else {
588-
ax._B.push(-ax._m2 * rl0);
589-
}
569+
var flip = isY;
570+
if(rl0 > rl1) flip = !flip;
571+
if(flip) ax._rangebreaks.reverse();
572+
var sign = flip ? -1 : 1;
590573

574+
ax._m2 = sign * ax._length / (Math.abs(rl1 - rl0) - ax._lBreaks);
575+
ax._B.push(-ax._m2 * (isY ? rl1 : rl0));
591576
for(i = 0; i < ax._rangebreaks.length; i++) {
592577
brk = ax._rangebreaks[i];
593-
ax._B.push(ax._B[ax._B.length - 1] - ax._m2 * (brk.max - brk.min) * signAx);
594-
}
595-
if(axReverse) {
596-
ax._B.reverse();
578+
ax._B.push(
579+
ax._B[ax._B.length - 1] -
580+
sign * ax._m2 * (brk.max - brk.min)
581+
);
597582
}
598583

599584
// fill pixel (i.e. 'p') min/max here,
600585
// to not have to loop through the _rangebreaks twice during `p2l`
601586
for(i = 0; i < ax._rangebreaks.length; i++) {
602587
brk = ax._rangebreaks[i];
603-
brk.pmin = l2p(axReverse ? brk.max : brk.min);
604-
brk.pmax = l2p(axReverse ? brk.min : brk.max);
588+
brk.pmin = l2p(brk.min);
589+
brk.pmax = l2p(brk.max);
605590
}
606591
}
607592
}
Loading
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
{
2+
"data": [
3+
{
4+
"type": "scatter",
5+
"mode": "markers+lines",
6+
"x": [
7+
"1970-01-01 00:00:00.000",
8+
"1970-01-01 00:00:00.010",
9+
"1970-01-01 00:00:00.020",
10+
"1970-01-01 00:00:00.030",
11+
"1970-01-01 00:00:00.040",
12+
"1970-01-01 00:00:00.050",
13+
"1970-01-01 00:00:00.060",
14+
"1970-01-01 00:00:00.070",
15+
"1970-01-01 00:00:00.080",
16+
"1970-01-01 00:00:00.090",
17+
"1970-01-01 00:00:00.100",
18+
"1970-01-01 00:00:00.110",
19+
"1970-01-01 00:00:00.120",
20+
"1970-01-01 00:00:00.130",
21+
"1970-01-01 00:00:00.140",
22+
"1970-01-01 00:00:00.150",
23+
"1970-01-01 00:00:00.160",
24+
"1970-01-01 00:00:00.170",
25+
"1970-01-01 00:00:00.180",
26+
"1970-01-01 00:00:00.190",
27+
"1970-01-01 00:00:00.200"
28+
]
29+
},
30+
{
31+
"xaxis": "x2",
32+
"yaxis": "y2",
33+
"type": "scatter",
34+
"mode": "markers+lines",
35+
"x": [
36+
"1970-01-01 00:00:00.000",
37+
"1970-01-01 00:00:00.010",
38+
"1970-01-01 00:00:00.020",
39+
"1970-01-01 00:00:00.030",
40+
"1970-01-01 00:00:00.040",
41+
"1970-01-01 00:00:00.050",
42+
"1970-01-01 00:00:00.060",
43+
"1970-01-01 00:00:00.070",
44+
"1970-01-01 00:00:00.080",
45+
"1970-01-01 00:00:00.090",
46+
"1970-01-01 00:00:00.100",
47+
"1970-01-01 00:00:00.110",
48+
"1970-01-01 00:00:00.120",
49+
"1970-01-01 00:00:00.130",
50+
"1970-01-01 00:00:00.140",
51+
"1970-01-01 00:00:00.150",
52+
"1970-01-01 00:00:00.160",
53+
"1970-01-01 00:00:00.170",
54+
"1970-01-01 00:00:00.180",
55+
"1970-01-01 00:00:00.190",
56+
"1970-01-01 00:00:00.200"
57+
]
58+
},
59+
{
60+
"xaxis": "x3",
61+
"yaxis": "y3",
62+
"type": "scatter",
63+
"mode": "markers+lines",
64+
"orientation": "h",
65+
"y": [
66+
"1970-01-01 00:00:00.000",
67+
"1970-01-01 00:00:00.010",
68+
"1970-01-01 00:00:00.020",
69+
"1970-01-01 00:00:00.030",
70+
"1970-01-01 00:00:00.040",
71+
"1970-01-01 00:00:00.050",
72+
"1970-01-01 00:00:00.060",
73+
"1970-01-01 00:00:00.070",
74+
"1970-01-01 00:00:00.080",
75+
"1970-01-01 00:00:00.090",
76+
"1970-01-01 00:00:00.100",
77+
"1970-01-01 00:00:00.110",
78+
"1970-01-01 00:00:00.120",
79+
"1970-01-01 00:00:00.130",
80+
"1970-01-01 00:00:00.140",
81+
"1970-01-01 00:00:00.150",
82+
"1970-01-01 00:00:00.160",
83+
"1970-01-01 00:00:00.170",
84+
"1970-01-01 00:00:00.180",
85+
"1970-01-01 00:00:00.190",
86+
"1970-01-01 00:00:00.200"
87+
]
88+
},
89+
{
90+
"xaxis": "x4",
91+
"yaxis": "y4",
92+
"type": "scatter",
93+
"mode": "markers+lines",
94+
"orientation": "h",
95+
"y": [
96+
"1970-01-01 00:00:00.000",
97+
"1970-01-01 00:00:00.010",
98+
"1970-01-01 00:00:00.020",
99+
"1970-01-01 00:00:00.030",
100+
"1970-01-01 00:00:00.040",
101+
"1970-01-01 00:00:00.050",
102+
"1970-01-01 00:00:00.060",
103+
"1970-01-01 00:00:00.070",
104+
"1970-01-01 00:00:00.080",
105+
"1970-01-01 00:00:00.090",
106+
"1970-01-01 00:00:00.100",
107+
"1970-01-01 00:00:00.110",
108+
"1970-01-01 00:00:00.120",
109+
"1970-01-01 00:00:00.130",
110+
"1970-01-01 00:00:00.140",
111+
"1970-01-01 00:00:00.150",
112+
"1970-01-01 00:00:00.160",
113+
"1970-01-01 00:00:00.170",
114+
"1970-01-01 00:00:00.180",
115+
"1970-01-01 00:00:00.190",
116+
"1970-01-01 00:00:00.200"
117+
]
118+
}
119+
],
120+
"layout": {
121+
"showlegend": false,
122+
"width": 800,
123+
"height": 800,
124+
"xaxis": {
125+
"rangebreaks": [
126+
{
127+
"bounds": [
128+
"1970-01-01 00:00:00.050",
129+
"1970-01-01 00:00:00.075"
130+
]
131+
},
132+
{
133+
"bounds": [
134+
"1970-01-01 00:00:00.120",
135+
"1970-01-01 00:00:00.180"
136+
]
137+
}
138+
],
139+
"domain": [
140+
0,
141+
0.48
142+
]
143+
},
144+
"xaxis2": {
145+
"rangebreaks": [
146+
{
147+
"bounds": [
148+
"1970-01-01 00:00:00.050",
149+
"1970-01-01 00:00:00.075"
150+
]
151+
},
152+
{
153+
"bounds": [
154+
"1970-01-01 00:00:00.120",
155+
"1970-01-01 00:00:00.180"
156+
]
157+
}
158+
],
159+
"autorange": "reversed",
160+
"anchor": "y2",
161+
"domain": [
162+
0.52,
163+
1
164+
]
165+
},
166+
"xaxis3": {
167+
"anchor": "y3",
168+
"domain": [
169+
0,
170+
0.48
171+
]
172+
},
173+
"xaxis4": {
174+
"anchor": "y4",
175+
"domain": [
176+
0.52,
177+
1
178+
]
179+
},
180+
"yaxis": {
181+
"domain": [
182+
0,
183+
0.48
184+
]
185+
},
186+
"yaxis2": {
187+
"anchor": "x2",
188+
"domain": [
189+
0.52,
190+
1
191+
]
192+
},
193+
"yaxis3": {
194+
"rangebreaks": [
195+
{
196+
"bounds": [
197+
"1970-01-01 00:00:00.050",
198+
"1970-01-01 00:00:00.075"
199+
]
200+
},
201+
{
202+
"bounds": [
203+
"1970-01-01 00:00:00.120",
204+
"1970-01-01 00:00:00.180"
205+
]
206+
}
207+
],
208+
"anchor": "x3",
209+
"domain": [
210+
0.52,
211+
1
212+
]
213+
},
214+
"yaxis4": {
215+
"rangebreaks": [
216+
{
217+
"bounds": [
218+
"1970-01-01 00:00:00.050",
219+
"1970-01-01 00:00:00.075"
220+
]
221+
},
222+
{
223+
"bounds": [
224+
"1970-01-01 00:00:00.120",
225+
"1970-01-01 00:00:00.180"
226+
]
227+
}
228+
],
229+
"autorange": "reversed",
230+
"anchor": "x4",
231+
"domain": [
232+
0,
233+
0.48
234+
]
235+
}
236+
}
237+
}

0 commit comments

Comments
 (0)