Skip to content

Commit 553dc51

Browse files
committed
Fix ticklabelindex in the case minor and major ticks overlap
1 parent db2dab9 commit 553dc51

1 file changed

Lines changed: 43 additions & 33 deletions

File tree

src/plots/cartesian/axes.js

Lines changed: 43 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,6 +1155,21 @@ axes.calcTicks = function calcTicks(ax, opts) {
11551155
}
11561156
}
11571157

1158+
function findOverlappingTick(minorTick, majorTicks) {
1159+
const majorTick = majorTicks.find((majorTick) => majorTick.value === minorTick.value);
1160+
if (majorTick != null) {
1161+
return majorTick;
1162+
}
1163+
// add 10e6 to eliminate problematic digits
1164+
const epsilon = 10e6;
1165+
for (var i = 0; i < majorTicks.length; i++) {
1166+
if (epsilon + majorTicks[i].value === epsilon + minorTick.value) {
1167+
return majorTicks[i];
1168+
}
1169+
}
1170+
return null;
1171+
};
1172+
11581173
// check if ticklabelIndex makes sense, otherwise ignore it.
11591174
// It makes sense if in addition to the always present dummy, there are at least 2 minor ticks
11601175
// with the required distance to each other.
@@ -1175,65 +1190,60 @@ axes.calcTicks = function calcTicks(ax, opts) {
11751190
// For each major tick, find the minor tick `ticklabelIndex` steps away.
11761191
// This minor tick will be labeled instead of the major tick.
11771192
if (isPeriod) periodEndTicks = []; // for each minor tick at the start of a labeled period this will hold the neighboring period end tick.
1178-
const minorTickValsAscending = minorTickVals.toSorted((a, b) => a.value - b.value);
1193+
const labelTickValsAscending = minorTickVals
1194+
.map((minor) => {
1195+
// if there is a major tick at the same position, prefer it over the minor tick because overlapping minor ticks are stripped away
1196+
// if both minor and major ticks are drawn on the same side.
1197+
const major = findOverlappingTick(minor, tickVals);
1198+
if (major) {
1199+
return major;
1200+
}
1201+
return minor;
1202+
})
1203+
.toSorted((a, b) => a.value - b.value);
11791204
tickVals.forEach(function(majorTick) {
11801205
if (!majorTick.skipLabel) {
11811206
ticklabelIndex.forEach((labelIndex) => {
11821207
if (labelIndex < 0) {
1183-
const smallerMinorTicks = minorTickValsAscending.filter((minorTick) => minorTick.value <= majorTick.value);
1208+
const smallerTicks = labelTickValsAscending.filter((minorTick) => minorTick.value <= majorTick.value);
11841209
const absLabelIndex = Math.abs(labelIndex);
1185-
const minorTickIndex = smallerMinorTicks.length - absLabelIndex - 1;
1186-
if (absLabelIndex <= smallerMinorTicks.length - 1) {
1187-
const labelVisible = !smallerMinorTicks[minorTickIndex].noTick || (isPeriod && !smallerMinorTicks[minorTickIndex + 1].noTick);
1210+
const labeledTickIndex = smallerTicks.length - absLabelIndex - 1;
1211+
if (absLabelIndex <= smallerTicks.length - 1) {
1212+
const labelVisible = !smallerTicks[labeledTickIndex].noTick || (isPeriod && !smallerTicks[labeledTickIndex + 1].noTick);
11881213
if (labelVisible) {
1189-
allTicklabelVals.push(smallerMinorTicks[minorTickIndex]);
1190-
if (isPeriod) periodEndTicks.push(smallerMinorTicks[minorTickIndex + 1]);
1214+
allTicklabelVals.push(smallerTicks[labeledTickIndex]);
1215+
if (isPeriod) periodEndTicks.push(smallerTicks[labeledTickIndex + 1]);
11911216
}
11921217
}
11931218
} else { // labelIndex >= 0
1194-
const largerMinorTicks = minorTickValsAscending.filter((minorTick) => minorTick.value >= majorTick.value);
1195-
if (labelIndex < largerMinorTicks.length - 1) {
1196-
const labelVisible = !largerMinorTicks[labelIndex].noTick || (isPeriod && !largerMinorTicks[labelIndex + 1].noTick);
1219+
const largerTicks = labelTickValsAscending.filter((minorTick) => minorTick.value >= majorTick.value);
1220+
if (labelIndex < largerTicks.length - 1) {
1221+
const labelVisible = !largerTicks[labelIndex].noTick || (isPeriod && !largerTicks[labelIndex + 1].noTick);
11971222
if (labelVisible) {
1198-
allTicklabelVals.push(largerMinorTicks[labelIndex]);
1199-
if (isPeriod) periodEndTicks.push(largerMinorTicks[labelIndex + 1]);
1223+
allTicklabelVals.push(largerTicks[labelIndex]);
1224+
if (isPeriod) periodEndTicks.push(largerTicks[labelIndex + 1]);
12001225
}
12011226
}
12021227
}
1203-
majorTick.skipLabel = true;
1228+
majorTick.skipLabel = majorTick.skipLabel !== false;
12041229
});
12051230
}
12061231
});
1232+
allTicklabelVals.forEach((t) => t.skipLabel = false);
12071233
}
12081234

12091235
if(hasMinor) {
1210-
var canOverlap =
1236+
var allowedToOverlap =
12111237
(ax.minor.ticks === 'inside' && ax.ticks === 'outside') ||
12121238
(ax.minor.ticks === 'outside' && ax.ticks === 'inside');
12131239

1214-
if(!canOverlap) {
1240+
if(!allowedToOverlap) {
12151241
// remove duplicate minors
1216-
1217-
var majorValues = tickVals.map(function(d) { return d.value; });
1218-
12191242
var list = [];
12201243
for(var k = 0; k < visibleMinorTicks.length; k++) {
1221-
var T = visibleMinorTicks[k];
1222-
var v = T.value;
1223-
if(majorValues.indexOf(v) !== -1) {
1224-
continue;
1225-
}
1226-
var found = false;
1227-
for(var q = 0; !found && (q < tickVals.length); q++) {
1228-
if(
1229-
// add 10e6 to eliminate problematic digits
1230-
10e6 + tickVals[q].value ===
1231-
10e6 + v
1232-
) {
1233-
found = true;
1234-
}
1244+
if (findOverlappingTick(visibleMinorTicks[k], tickVals) == null) {
1245+
list.push(visibleMinorTicks[k]);
12351246
}
1236-
if(!found) list.push(T);
12371247
}
12381248
minorTickVals = list;
12391249
}

0 commit comments

Comments
 (0)