From 0c013fe71e0630b9c4080fec45d2eb655fba8466 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ko=C5=88a=C5=99=C3=ADk?= Date: Tue, 17 Nov 2020 13:26:41 +0100 Subject: [PATCH 1/2] feat(axis): custom axis tick/label positions. close #13627 --- src/coord/axisCommonTypes.ts | 4 +- src/coord/axisTickLabelBuilder.ts | 42 +++++++ test/axis-customTicks.html | 202 ++++++++++++++++++++++++++++++ 3 files changed, 247 insertions(+), 1 deletion(-) create mode 100644 test/axis-customTicks.html diff --git a/src/coord/axisCommonTypes.ts b/src/coord/axisCommonTypes.ts index 3ba456835f..4287256f03 100644 --- a/src/coord/axisCommonTypes.ts +++ b/src/coord/axisCommonTypes.ts @@ -144,6 +144,7 @@ interface AxisTickOption { // The length of axisTick. length?: number, lineStyle?: LineStyleOption + customValues?: (number | string | Date)[], // -------------------------------------------- // [Properties below only for 'category' axis]: @@ -183,6 +184,7 @@ interface AxisLabelOption extends Omit { margin?: number, // value is supposed to be OptionDataPrimitive but for time axis, it is time stamp. formatter?: AxisLabelFormatterOption | TimeAxisLabelFormatterOption, + customValues?: (number | string | Date)[], // -------------------------------------------- // [Properties below only for 'category' axis]: @@ -219,4 +221,4 @@ interface SplitAreaOption { interval?: 'auto' | number | ((index:number, value: string) => boolean) // colors will display in turn areaStyle?: AreaStyleOption -} \ No newline at end of file +} diff --git a/src/coord/axisTickLabelBuilder.ts b/src/coord/axisTickLabelBuilder.ts index 332e542e83..8787207ca8 100644 --- a/src/coord/axisTickLabelBuilder.ts +++ b/src/coord/axisTickLabelBuilder.ts @@ -60,6 +60,28 @@ type InnerStore = { const inner = makeInner(); +function tickValuesToNumbers(axis: Axis, values: (number | string | Date)[]) { + const nums = values.map(val => { + if (zrUtil.isString(val)) { + return axis.model.get('data').indexOf(val); + } + else if (val instanceof Date) { + return val.getTime(); + } + else { + return 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: { formattedLabel: string, @@ -68,6 +90,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) @@ -86,6 +122,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) diff --git a/test/axis-customTicks.html b/test/axis-customTicks.html new file mode 100644 index 0000000000..d11ec2972c --- /dev/null +++ b/test/axis-customTicks.html @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + From 0c908241d8cf6ee2e3daf26c0582fae40061179f Mon Sep 17 00:00:00 2001 From: Ovilia Date: Fri, 10 May 2024 14:53:21 +0800 Subject: [PATCH 2/2] fix: fix failed test cases and improve code --- src/coord/axisTickLabelBuilder.ts | 12 +----------- test/axis-customTicks.html | 2 +- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/src/coord/axisTickLabelBuilder.ts b/src/coord/axisTickLabelBuilder.ts index dcd9febd7e..e7f7bbb088 100644 --- a/src/coord/axisTickLabelBuilder.ts +++ b/src/coord/axisTickLabelBuilder.ts @@ -61,17 +61,7 @@ type InnerStore = { const inner = makeInner(); function tickValuesToNumbers(axis: Axis, values: (number | string | Date)[]) { - const nums = values.map(val => { - if (zrUtil.isString(val)) { - return axis.model.get('data').indexOf(val); - } - else if (val instanceof Date) { - return val.getTime(); - } - else { - return val; - } - }); + 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 diff --git a/test/axis-customTicks.html b/test/axis-customTicks.html index d11ec2972c..24f9c7dc97 100644 --- a/test/axis-customTicks.html +++ b/test/axis-customTicks.html @@ -23,7 +23,7 @@ - +