diff --git a/src/coord/Axis.ts b/src/coord/Axis.ts index 1bcb13a01b..facf98ebaa 100644 --- a/src/coord/Axis.ts +++ b/src/coord/Axis.ts @@ -189,6 +189,7 @@ class Axis { this, preTicksCoords, alignWithLabel, + result.tickCategoryInterval, ); return map(preTicksCoords, function (item) { @@ -318,6 +319,7 @@ function fixOnBandTicksCoords( tick: ScaleTick }[], alignWithLabel: boolean, + tickCategoryInterval: number | NullUndefined, // return: whether coords are modified according to `onBand`. ): boolean { const ticksLen = preTicksCoords.length; @@ -340,15 +342,17 @@ function fixOnBandTicksCoords( ticksItem.coord -= bandWidth / 2; }); - const dataExtent = axis.scale.getExtent(); - const oldLast = preTicksCoords[ticksLen - 1]; - if (oldLast.tick.offInterval) { - preTicksCoords.pop(); + if (tickCategoryInterval != null) { + const dataExtent = axis.scale.getExtent(); + const oldLast = preTicksCoords[ticksLen - 1]; + if (oldLast.tick.offInterval) { + preTicksCoords.pop(); + } + preTicksCoords.push({ + coord: oldLast.coord + bandWidth, + tick: {value: dataExtent[1] + 1}, + }); } - preTicksCoords.push({ - coord: oldLast.coord + bandWidth, - tick: {value: dataExtent[1] + 1}, - }); return true; } diff --git a/src/coord/axisTickLabelBuilder.ts b/src/coord/axisTickLabelBuilder.ts index 904dcd894b..397302a3a0 100644 --- a/src/coord/axisTickLabelBuilder.ts +++ b/src/coord/axisTickLabelBuilder.ts @@ -501,9 +501,10 @@ function makeTicksLabelsByCategoryIntervalNumOrCb( // It is time consuming for large category data. const isOnInterval = !!categoryInterval(tickObj.value, tickLabel); tickObj.offInterval = !isOnInterval; - // axis extent min max labels should be always included and the display strategy - // is adopted uniformly later in `AxisBuilder`. - if (!isOnInterval && !isExtentBoundary) { + // Axis extent min max labels should be always included and the display strategy + // is adopted uniformly later in `AxisBuilder`. For ticks, keep strictly to the + // callback result. + if (!isOnInterval && (onlyTick || !isExtentBoundary)) { return; } } diff --git a/test/ut/spec/scale/interval.test.ts b/test/ut/spec/scale/interval.test.ts index 545d967ff7..98b68b018d 100755 --- a/test/ut/spec/scale/interval.test.ts +++ b/test/ut/spec/scale/interval.test.ts @@ -115,6 +115,57 @@ describe('scale_interval', function () { }); + describe('categoryAxisTickInterval', function () { + it('should respect custom axisTick interval callback exactly', function () { + const categoryData = ['Sat', 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri']; + + chart.setOption({ + xAxis: { + type: 'category', + data: categoryData, + axisTick: { + interval: function (categoryIndex: number, value: string) { + return value === 'Mon'; + } + } + }, + yAxis: {}, + series: [{ + type: 'bar', + data: [1, 2, 3, 4, 5, 6, 7] + }] + }); + + const xAxis = getECModel(chart).getComponent('xAxis', 0) as CartesianAxisModel; + expect(xAxis.axis.getTicksCoords().map(tick => tick.tickValue)).toEqual([2]); + }); + + it('should not append an end tick for custom axisTick interval callback', function () { + const categoryData = ['Sat', 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri']; + + chart.setOption({ + xAxis: { + type: 'category', + data: categoryData, + axisTick: { + interval: function (categoryIndex: number) { + return categoryIndex === 2 || categoryIndex === 5; + } + } + }, + yAxis: {}, + series: [{ + type: 'bar', + data: [1, 2, 3, 4, 5, 6, 7] + }] + }); + + const xAxis = getECModel(chart).getComponent('xAxis', 0) as CartesianAxisModel; + expect(xAxis.axis.getTicksCoords().map(tick => tick.tickValue)).toEqual([2, 5]); + }); + }); + + describe('ticks', function () { function randomNumber(quantity: number): number {