Skip to content

Commit

Permalink
Merge pull request #19919 from apache/dvdkon-fix-13627
Browse files Browse the repository at this point in the history
feat(axis): custom axis tick/label positions
  • Loading branch information
pissang committed Jun 17, 2024
2 parents 0ab5f72 + 0c90824 commit a282471
Show file tree
Hide file tree
Showing 3 changed files with 239 additions and 4 deletions.
9 changes: 5 additions & 4 deletions src/coord/axisCommonTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,8 @@ interface AxisTickOption {
inside?: boolean,
// The length of axisTick.
length?: number,
lineStyle?: LineStyleOption
lineStyle?: LineStyleOption,
customValues?: (number | string | Date)[]
}

type AxisLabelValueFormatter = (value: number, index: number) => string;
Expand Down Expand Up @@ -238,9 +239,10 @@ interface AxisLabelBaseOption extends Omit<TextCommonOption, 'color'> {
/**
* If hide overlapping labels.
*/
hideOverlap?: boolean;
hideOverlap?: boolean,
customValues?: (number | string | Date)[],
// Color can be callback
color?: ColorString | ((value?: string | number, index?: number) => ColorString)
color?: ColorString | ((value?: string | number, index?: number) => ColorString),
overflow?: TextStyleProps['overflow']
}
interface AxisLabelOption<TType extends OptionAxisType> extends AxisLabelBaseOption {
Expand Down Expand Up @@ -273,6 +275,5 @@ interface SplitAreaOption {
areaStyle?: AreaStyleOption<ZRColor[]>
}


export type AxisBaseOption = ValueAxisBaseOption | LogAxisBaseOption
| CategoryAxisBaseOption | TimeAxisBaseOption | AxisBaseOptionCommon;
32 changes: 32 additions & 0 deletions src/coord/axisTickLabelBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,18 @@ type InnerStore = {

const inner = makeInner<InnerStore, any>();

function tickValuesToNumbers(axis: Axis, values: (number | string | Date)[]) {
const nums = zrUtil.map(values, val => axis.scale.parse(val));
if (axis.type === 'time' && nums.length > 0) {
// Time axis needs duplicate first/last tick (see TimeScale.getTicks())
// The first and last tick/label don't get drawn
nums.sort();
nums.unshift(nums[0]);
nums.push(nums[nums.length - 1]);
}
return nums;
}

export function createAxisLabels(axis: Axis): {
labels: {
level?: number,
Expand All @@ -69,6 +81,20 @@ export function createAxisLabels(axis: Axis): {
}[],
labelCategoryInterval?: number
} {
const custom = axis.getLabelModel().get('customValues');
if (custom) {
const labelFormatter = makeLabelFormatter(axis);
return {
labels: tickValuesToNumbers(axis, custom).map(numval => {
const tick = {value: numval};
return {
formattedLabel: labelFormatter(tick),
rawLabel: axis.scale.getLabel(tick),
tickValue: numval
};
})
};
}
// Only ordinal scale support tick interval
return axis.type === 'category'
? makeCategoryLabels(axis)
Expand All @@ -87,6 +113,12 @@ export function createAxisTicks(axis: Axis, tickModel: AxisBaseModel): {
ticks: number[],
tickCategoryInterval?: number
} {
const custom = axis.getTickModel().get('customValues');
if (custom) {
return {
ticks: tickValuesToNumbers(axis, custom)
};
}
// Only ordinal scale support tick interval
return axis.type === 'category'
? makeCategoryTicks(axis, tickModel)
Expand Down
202 changes: 202 additions & 0 deletions test/axis-customTicks.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit a282471

Please sign in to comment.