@@ -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