Skip to content

Commit 73db02a

Browse files
authored
Merge pull request #4677 from plotly/rangebreaks-autotick
Improve auto ticks over axes with rangebreaks
2 parents 6034f6b + b7f2299 commit 73db02a

11 files changed

+1091
-69
lines changed

src/plots/cartesian/axes.js

+44-22
Original file line numberDiff line numberDiff line change
@@ -611,31 +611,43 @@ axes.calcTicks = function calcTicks(ax) {
611611
generateTicks();
612612

613613
if(ax.rangebreaks) {
614-
var nTicksBefore = tickVals.length;
614+
// replace ticks inside breaks that would get a tick
615+
if(ax.tickmode === 'auto') {
616+
for(var t = 0; t < tickVals.length; t++) {
617+
var value = tickVals[t].value;
618+
if(ax.maskBreaks(value) === BADNUM) {
619+
// find which break we are in
620+
for(var k = 0; k < ax._rangebreaks.length; k++) {
621+
var brk = ax._rangebreaks[k];
622+
if(value >= brk.min && value < brk.max) {
623+
tickVals[t]._realV = tickVals[t].value;
624+
tickVals[t].value = brk.max; // replace with break end
625+
break;
626+
}
627+
}
628+
}
629+
}
630+
}
615631

616-
// remove ticks falling inside rangebreaks
617-
tickVals = tickVals.filter(function(d) {
618-
return ax.maskBreaks(d.value) !== BADNUM;
619-
});
632+
// reduce ticks
633+
var len = tickVals.length;
634+
if(len > 2) {
635+
var tf2 = 2 * (ax.tickfont ? ax.tickfont.size : 12);
620636

621-
// if 'numerous' ticks get placed into rangebreaks,
622-
// increase dtick to generate more ticks,
623-
// so that some hopefully fall between rangebreaks
624-
if(ax.tickmode === 'auto' && tickVals.length < nTicksBefore / 6) {
625-
axes.autoTicks(ax, ax._roughDTick / 3);
626-
autoTickRound(ax);
627-
ax._tmin = axes.tickFirst(ax);
628-
generateTicks();
629-
tickVals = tickVals.filter(function(d) {
630-
return ax.maskBreaks(d.value) !== BADNUM;
631-
});
632-
}
637+
var newTickVals = [];
638+
var prevPos;
633639

634-
// remove "overlapping" ticks (e.g. on either side of a break)
635-
var tf2 = ax.tickfont ? 1.5 * ax.tickfont.size : 0;
636-
tickVals = tickVals.filter(function(d, i, self) {
637-
return !(i && Math.abs(ax.c2p(d.value) - ax.c2p(self[i - 1].value)) < tf2);
638-
});
640+
var signAx = axrev ? -1 : 1;
641+
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
642+
var pos = ax.c2p(tickVals[q].value);
643+
644+
if(prevPos === undefined || Math.abs(pos - prevPos) > tf2) {
645+
prevPos = pos;
646+
newTickVals.push(tickVals[q]);
647+
}
648+
}
649+
tickVals = newTickVals.reverse();
650+
}
639651
}
640652

641653
// If same angle over a full circle, the last tick vals is a duplicate.
@@ -663,6 +675,16 @@ axes.calcTicks = function calcTicks(ax) {
663675
false, // hover
664676
tickVals[i].minor // noSuffixPrefix
665677
);
678+
679+
if(tickVals[i]._realV) {
680+
// correct label
681+
ticksOut[i].text = axes.tickText(
682+
ax,
683+
tickVals[i]._realV,
684+
false, // hover
685+
tickVals[i].minor // noSuffixPrefix
686+
).text;
687+
}
666688
}
667689

668690
ax._inCalcTicks = false;
-666 Bytes
Loading
Loading
Loading
-1.7 KB
Loading
Loading
Loading

test/image/baselines/axes_breaks.png

329 Bytes
Loading

0 commit comments

Comments
 (0)