Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 15af0db

Browse filesBrowse files
committed
fix: Fix min/max label show in category axis. Previously, axisLabel.showMinLabel/showMaxLabel did not control label and ticks on axis edges, but controls the filtered labels by axisLabel.interval settings. This impl did not align with the intent of that option.
1 parent 91a60fc commit 15af0db
Copy full SHA for 15af0db

12 files changed

+365-160Lines changed: 365 additions & 160 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎src/component/axis/AxisBuilder.ts‎

Copy file name to clipboardExpand all lines: src/component/axis/AxisBuilder.ts
+10-3Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ import {
7575
AxisLabelsComputingContext, AxisTickLabelComputingKind, createAxisLabelsComputingContext
7676
} from '../../coord/axisTickLabelBuilder';
7777
import { AxisTickCoord } from '../../coord/Axis';
78-
import { isTimeScale } from '../../scale/helper';
78+
import { isOrdinalScale, isTimeScale } from '../../scale/helper';
7979

8080

8181
const PI = Math.PI;
@@ -1081,6 +1081,7 @@ function fixMinMaxLabelShow(
10811081
) {
10821082
let outmostLabelLayout = ensureLabelLayoutWithGeometry(labelLayoutList[outmostLabelIdx]);
10831083
let innerLabelLayout = ensureLabelLayoutWithGeometry(labelLayoutList[innerLabelIdx]);
1084+
const scale = axis.scale;
10841085
if (!outmostLabelLayout || !innerLabelLayout) {
10851086
return;
10861087
}
@@ -1089,9 +1090,15 @@ function fixMinMaxLabelShow(
10891090
// In this case, users are unlikely to expect labels to be hidden.
10901091
return;
10911092
}
1092-
if (isTimeScale(axis.scale) && getLabelInner(outmostLabelLayout.label).labelInfo.tick.notNice) {
1093-
// TimeScale does not expand extent to "nice", so eliminate labels that are not nice.
1093+
const tick = getLabelInner(outmostLabelLayout.label).labelInfo.tick;
1094+
if (// TimeScale does not expand extent to "nice", so eliminate labels that are not nice.
1095+
(isTimeScale(scale) && tick.notNice)
1096+
// Category axis does not expect tick that out of axisLabel.internal to be displayed
1097+
// unless required.
1098+
|| (isOrdinalScale(scale) && tick.offInterval)
1099+
) {
10941100
ignoreEl(outmostLabelLayout.label);
1101+
return;
10951102
}
10961103
}
10971104

Collapse file

‎src/coord/Axis.ts‎

Copy file name to clipboardExpand all lines: src/coord/Axis.ts
+5-6Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -176,16 +176,15 @@ class Axis {
176176
breakTicks: opt.breakTicks,
177177
pruneByBreak: opt.pruneByBreak,
178178
});
179-
const ticks = result.ticks;
180-
181-
const ticksCoords = map(ticks, function (tickVal) {
179+
const ticksCoords = map(result.ticks, function (tick) {
180+
const tickValue = tick.value;
182181
return {
183182
coord: this.dataToCoord(
184183
isOrdinalScale(this.scale)
185-
? (this.scale as OrdinalScale).getRawOrdinalNumber(tickVal)
186-
: tickVal
184+
? (this.scale as OrdinalScale).getRawOrdinalNumber(tickValue)
185+
: tickValue
187186
),
188-
tickValue: tickVal
187+
tickValue,
189188
};
190189
}, this);
191190

Collapse file

‎src/coord/axisTickLabelBuilder.ts‎

Copy file name to clipboardExpand all lines: src/coord/axisTickLabelBuilder.ts
+37-34Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ interface AxisCategoryLabelCreated {
5353
labelCategoryInterval: number
5454
}
5555
interface AxisCategoryTickCreated {
56-
ticks: number[]
56+
ticks: ScaleTick[]
5757
tickCategoryInterval?: number
5858
}
5959

@@ -105,15 +105,17 @@ export function createAxisLabelsComputingContext(kind: AxisTickLabelComputingKin
105105
};
106106
}
107107

108+
/**
109+
* CAUTION: Do not modify the result.
110+
*/
108111
export function createAxisLabels(axis: Axis, ctx: AxisLabelsComputingContext): {
109112
labels: AxisLabelInfoDetermined[]
110113
} {
111114
const custom = axis.getLabelModel().get('customValues');
112115
if (custom) {
113116
const scale = axis.scale;
114117
return {
115-
labels: zrUtil.map(parseTickLabelCustomValues(custom, scale), (numval, index) => {
116-
const tick = {value: numval};
118+
labels: zrUtil.map(parseTickLabelCustomValues(custom, scale), (tick, index) => {
117119
return {
118120
formattedLabel: makeLabelFormatter(axis)(tick, index),
119121
rawLabel: scale.getLabel(tick),
@@ -129,16 +131,15 @@ export function createAxisLabels(axis: Axis, ctx: AxisLabelsComputingContext): {
129131
}
130132

131133
/**
134+
* CAUTION: Do not modify the result.
135+
*
132136
* @param tickModel For example, can be axisTick, splitLine, splitArea.
133137
*/
134138
export function createAxisTicks(
135139
axis: Axis,
136140
tickModel: AxisBaseModel,
137141
opt?: Pick<ScaleGetTicksOpt, 'breakTicks' | 'pruneByBreak'>
138-
): {
139-
ticks: number[],
140-
tickCategoryInterval?: number
141-
} {
142+
): AxisCategoryTickCreated {
142143
const scale = axis.scale;
143144
const custom = axis.getTickModel().get('customValues');
144145
if (custom) {
@@ -149,13 +150,13 @@ export function createAxisTicks(
149150
// Only ordinal scale support tick interval
150151
return axis.type === 'category'
151152
? makeCategoryTicks(axis, tickModel)
152-
: {ticks: zrUtil.map(scale.getTicks(opt), tick => tick.value)};
153+
: {ticks: scale.getTicks(opt)};
153154
}
154155

155156
function parseTickLabelCustomValues(
156157
customValues: AxisTickLabelCustomValuesOption,
157158
scale: Scale,
158-
): number[] {
159+
): ScaleTick[] {
159160
const extent = scale.getExtent();
160161
const tickNumbers: number[] = [];
161162
zrUtil.each(customValues, function (val) {
@@ -166,7 +167,9 @@ function parseTickLabelCustomValues(
166167
});
167168
removeDuplicates(tickNumbers, removeDuplicatesGetKeyFromItemItself, null);
168169
asc(tickNumbers);
169-
return tickNumbers;
170+
return zrUtil.map(tickNumbers, function (tickVal) {
171+
return {value: tickVal};
172+
});
170173
}
171174

172175
function makeCategoryLabels(axis: Axis, ctx: AxisLabelsComputingContext): ReturnType<typeof createAxisLabels> {
@@ -182,10 +185,7 @@ function makeCategoryLabelsActually(
182185
axis: Axis,
183186
labelModel: Model<AxisBaseOption['axisLabel']>,
184187
ctx: AxisLabelsComputingContext
185-
): {
186-
labels: AxisLabelInfoDetermined[]
187-
labelCategoryInterval: number
188-
} {
188+
): AxisCategoryLabelCreated {
189189
const labelsCache = ensureCategoryLabelCache(axis);
190190
const optionLabelInterval = getOptionCategoryInterval(labelModel);
191191
const isEstimate = ctx.kind === AxisTickLabelComputingKind.estimate;
@@ -226,7 +226,7 @@ function makeCategoryLabelsActually(
226226
return result;
227227
}
228228

229-
function makeCategoryTicks(axis: Axis, tickModel: AxisBaseModel) {
229+
function makeCategoryTicks(axis: Axis, tickModel: AxisBaseModel): AxisCategoryTickCreated {
230230
const ticksCache = ensureCategoryTickCache(axis);
231231
const optionTickInterval = getOptionCategoryInterval(tickModel);
232232
const result = axisCacheGet(ticksCache, optionTickInterval);
@@ -235,7 +235,7 @@ function makeCategoryTicks(axis: Axis, tickModel: AxisBaseModel) {
235235
return result;
236236
}
237237

238-
let ticks: number[];
238+
let ticks: ScaleTick[];
239239
let tickCategoryInterval;
240240

241241
// Optimize for the case that large category data and no label displayed,
@@ -256,7 +256,7 @@ function makeCategoryTicks(axis: Axis, tickModel: AxisBaseModel) {
256256
);
257257
tickCategoryInterval = labelsResult.labelCategoryInterval;
258258
ticks = zrUtil.map(labelsResult.labels, function (labelItem) {
259-
return labelItem.tick.value;
259+
return labelItem.tick;
260260
});
261261
}
262262
else {
@@ -338,7 +338,7 @@ function makeAutoCategoryInterval(axis: Axis, ctx: AxisLabelsComputingContext):
338338
* To get precise result, at least one of `getRotate` and `isHorizontal`
339339
* should be implemented in axis.
340340
*/
341-
export function calculateCategoryInterval(axis: Axis, ctx: AxisLabelsComputingContext) {
341+
export function calculateCategoryInterval(axis: Axis, ctx: AxisLabelsComputingContext): number {
342342
const kind = ctx.kind;
343343

344344
const params = fetchAutoCategoryIntervalCalculationParams(axis);
@@ -474,14 +474,14 @@ function makeLabelsByNumericCategoryInterval(
474474
): AxisLabelInfoDetermined[];
475475
function makeLabelsByNumericCategoryInterval(
476476
axis: Axis, categoryInterval: number, onlyTick: true
477-
): number[];
477+
): ScaleTick[];
478478
function makeLabelsByNumericCategoryInterval(
479479
axis: Axis, categoryInterval: number, onlyTick?: boolean
480480
) {
481481
const labelFormatter = makeLabelFormatter(axis);
482482
const ordinalScale = axis.scale as OrdinalScale;
483483
const ordinalExtent = ordinalScale.getExtent();
484-
const result: (AxisLabelInfoDetermined | number)[] = [];
484+
const result: (AxisLabelInfoDetermined | ScaleTick)[] = [];
485485

486486
// TODO: axisType: ordinalTime, pick the tick from each month/day/year/...
487487

@@ -500,23 +500,23 @@ function makeLabelsByNumericCategoryInterval(
500500
// But they should be always included and the display strategy is adopted uniformly
501501
// later in `AxisBuilder`.
502502
if (startTick !== ordinalExtent[0]) {
503-
addItem(ordinalExtent[0]);
503+
addItem(ordinalExtent[0], true);
504504
}
505505

506506
// Optimize: avoid generating large array by `ordinalScale.getTicks()`.
507507
let tickValue = startTick;
508508
for (; tickValue <= ordinalExtent[1]; tickValue += step) {
509-
addItem(tickValue);
509+
addItem(tickValue, false);
510510
}
511511

512512
if (tickValue - step !== ordinalExtent[1]) {
513-
addItem(ordinalExtent[1]);
513+
addItem(ordinalExtent[1], true);
514514
}
515515

516-
function addItem(tickValue: number) {
517-
const tickObj = {value: tickValue};
516+
function addItem(tickValue: number, offInterval: boolean) {
517+
const tickObj: ScaleTick = {value: tickValue, offInterval};
518518
result.push(onlyTick
519-
? tickValue
519+
? tickObj
520520
: {
521521
formattedLabel: labelFormatter(tickObj),
522522
rawLabel: ordinalScale.getLabel(tickObj),
@@ -540,21 +540,24 @@ function makeLabelsByCustomizedCategoryInterval(
540540
): AxisLabelInfoDetermined[];
541541
function makeLabelsByCustomizedCategoryInterval(
542542
axis: Axis, categoryInterval: CategoryIntervalCb, onlyTick: true
543-
): number[];
543+
): ScaleTick[];
544544
function makeLabelsByCustomizedCategoryInterval(
545545
axis: Axis, categoryInterval: CategoryIntervalCb, onlyTick?: boolean
546546
) {
547547
const ordinalScale = axis.scale;
548548
const labelFormatter = makeLabelFormatter(axis);
549-
const result: (AxisLabelInfoDetermined | number)[] = [];
549+
const result: (AxisLabelInfoDetermined | ScaleTick)[] = [];
550550

551-
zrUtil.each(ordinalScale.getTicks(), function (tick) {
551+
const ticks = ordinalScale.getTicks();
552+
zrUtil.each(ticks, function (tick, idx) {
552553
const rawLabel = ordinalScale.getLabel(tick);
553-
const tickValue = tick.value;
554-
if (categoryInterval(tickValue, rawLabel)) {
555-
result.push(
556-
onlyTick
557-
? tickValue
554+
const isOnInterval = categoryInterval(tick.value, rawLabel);
555+
tick.offInterval = !isOnInterval;
556+
// axis extent min max labels should be always included and the display strategy
557+
// is adopted uniformly later in `AxisBuilder`.
558+
if (isOnInterval || idx === 0 || idx === ticks.length - 1) {
559+
result.push(onlyTick
560+
? tick
558561
: {
559562
formattedLabel: labelFormatter(tick),
560563
rawLabel: rawLabel,
Collapse file

‎src/scale/Scale.ts‎

Copy file name to clipboardExpand all lines: src/scale/Scale.ts
+6Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,14 @@ abstract class Scale<
104104
*/
105105
abstract getLabel(tick: ScaleTick): string;
106106

107+
/**
108+
* Create ticks. The result can be modified by the caller.
109+
*/
107110
abstract getTicks(opt?: ScaleGetTicksOpt): ScaleTick[];
108111

112+
/**
113+
* Create minor ticks. The result can be modified by the caller.
114+
*/
109115
abstract getMinorTicks(splitNumber: number): number[][];
110116

111117
static registerClass: clazzUtil.ClassManager['registerClass'];
Collapse file

‎src/util/types.ts‎

Copy file name to clipboardExpand all lines: src/util/types.ts
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,9 @@ export interface ScaleTick {
590590
time?: TimeScaleTick['time'];
591591
// NOTICE: null/undefined mean it is unknown whether this tick is "nice".
592592
notNice?: boolean | NullUndefined;
593+
// Only works on category axis.
594+
// Be `true` if this tick is out of category interval.
595+
offInterval?: boolean | NullUndefined,
593596
};
594597
export interface TimeScaleTick extends ScaleTick {
595598
time: {
Collapse file

‎test/-cases.js‎

Copy file name to clipboardExpand all lines: test/-cases.js
+3Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.