You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by ov...@apache.org on 2024/01/02 11:10:40 UTC
(echarts) branch feat/break-axis updated: feat(WIP): axis with break
This is an automated email from the ASF dual-hosted git repository.
ovilia pushed a commit to branch feat/break-axis
in repository https://gitbox.apache.org/repos/asf/echarts.git
The following commit(s) were added to refs/heads/feat/break-axis by this push:
new d1c0f2a5a feat(WIP): axis with break
d1c0f2a5a is described below
commit d1c0f2a5a0385f75369318dff101bb8d4e715776
Author: Ovilia <zw...@gmail.com>
AuthorDate: Tue Jan 2 19:10:15 2024 +0800
feat(WIP): axis with break
---
src/coord/axisCommonTypes.ts | 3 ++-
src/coord/axisHelper.ts | 10 +++++---
src/scale/Interval.ts | 4 ++--
src/scale/Log.ts | 4 ++--
src/scale/Ordinal.ts | 9 +++++---
src/scale/Scale.ts | 12 +++++++++-
src/scale/Time.ts | 7 +++---
src/scale/helper.ts | 55 ++++++++++++++++++++++++++++++++++++++++----
src/util/types.ts | 6 +++++
9 files changed, 91 insertions(+), 19 deletions(-)
diff --git a/src/coord/axisCommonTypes.ts b/src/coord/axisCommonTypes.ts
index aa92868e3..728c10a7e 100644
--- a/src/coord/axisCommonTypes.ts
+++ b/src/coord/axisCommonTypes.ts
@@ -21,7 +21,7 @@ import { TextAlign, TextVerticalAlign } from 'zrender/src/core/types';
import {
TextCommonOption, LineStyleOption, OrdinalRawValue, ZRColor,
AreaStyleOption, ComponentOption, ColorString,
- AnimationOptionMixin, Dictionary, ScaleDataValue, CommonAxisPointerOption
+ AnimationOptionMixin, Dictionary, ScaleDataValue, CommonAxisPointerOption, ScaleBreak
} from '../util/types';
import { TextStyleProps } from 'zrender/src/graphic/Text';
@@ -81,6 +81,7 @@ export interface AxisBaseOptionCommon extends ComponentOption,
*/
max?: ScaleDataValue | 'dataMax' | ((extent: {min: number, max: number}) => ScaleDataValue);
+ breaks?: ScaleBreak[];
}
export interface NumericAxisBaseOptionCommon extends AxisBaseOptionCommon {
diff --git a/src/coord/axisHelper.ts b/src/coord/axisHelper.ts
index 53485fb31..76c23ad17 100644
--- a/src/coord/axisHelper.ts
+++ b/src/coord/axisHelper.ts
@@ -198,16 +198,20 @@ export function createScaleByModel(model: AxisBaseModel, axisType?: string): Sca
ordinalMeta: model.getOrdinalMeta
? model.getOrdinalMeta()
: model.getCategories(),
- extent: [Infinity, -Infinity]
+ extent: [Infinity, -Infinity],
+ breaks: model.get('breaks')
});
case 'time':
return new TimeScale({
locale: model.ecModel.getLocaleModel(),
- useUTC: model.ecModel.get('useUTC')
+ useUTC: model.ecModel.get('useUTC'),
+ breaks: model.get('breaks')
});
default:
// case 'value'/'interval', 'log', or others.
- return new (Scale.getClass(axisType) || IntervalScale)();
+ return new (Scale.getClass(axisType) || IntervalScale)({
+ breaks: model.get('breaks')
+ });
}
}
}
diff --git a/src/scale/Interval.ts b/src/scale/Interval.ts
index 3fc00cf14..f250b9801 100644
--- a/src/scale/Interval.ts
+++ b/src/scale/Interval.ts
@@ -46,11 +46,11 @@ class IntervalScale<SETTING extends Dictionary<unknown> = Dictionary<unknown>> e
}
normalize(val: number): number {
- return helper.normalize(val, this._extent);
+ return helper.normalize(val, this._extent, this._breaks);
}
scale(val: number): number {
- return helper.scale(val, this._extent);
+ return helper.scale(val, this._extent, this._breaks);
}
setExtent(start: number | string, end: number | string): void {
diff --git a/src/scale/Log.ts b/src/scale/Log.ts
index b1f4d08b1..536e114fc 100644
--- a/src/scale/Log.ts
+++ b/src/scale/Log.ts
@@ -183,11 +183,11 @@ class LogScale extends Scale {
normalize(val: number): number {
val = mathLog(val) / mathLog(this.base);
- return scaleHelper.normalize(val, this._extent);
+ return scaleHelper.normalize(val, this._extent, this._breaks);
}
scale(val: number): number {
- val = scaleHelper.scale(val, this._extent);
+ val = scaleHelper.scale(val, this._extent, this._breaks);
return mathPow(this.base, val);
}
diff --git a/src/scale/Ordinal.ts b/src/scale/Ordinal.ts
index dd7d255c8..29f557c20 100644
--- a/src/scale/Ordinal.ts
+++ b/src/scale/Ordinal.ts
@@ -34,7 +34,8 @@ import {
DimensionLoose,
OrdinalSortInfo,
OrdinalScaleTick,
- ScaleTick
+ ScaleTick,
+ ScaleBreak
} from '../util/types';
import { CategoryAxisBaseOption } from '../coord/axisCommonTypes';
import { isArray, map, isObject, isString } from 'zrender/src/core/util';
@@ -42,6 +43,7 @@ import { isArray, map, isObject, isString } from 'zrender/src/core/util';
type OrdinalScaleSetting = {
ordinalMeta?: OrdinalMeta | CategoryAxisBaseOption['data'];
extent?: [number, number];
+ breaks?: ScaleBreak[];
};
class OrdinalScale extends Scale<OrdinalScaleSetting> {
@@ -127,6 +129,7 @@ class OrdinalScale extends Scale<OrdinalScaleSetting> {
}
this._ordinalMeta = ordinalMeta as OrdinalMeta;
this._extent = this.getSetting('extent') || [0, ordinalMeta.categories.length - 1];
+ this._breaks = this.getSetting('breaks') || [];
}
parse(val: OrdinalRawValue | OrdinalNumber): OrdinalNumber {
@@ -153,7 +156,7 @@ class OrdinalScale extends Scale<OrdinalScaleSetting> {
*/
normalize(val: OrdinalRawValue | OrdinalNumber): number {
val = this._getTickNumber(this.parse(val));
- return scaleHelper.normalize(val, this._extent);
+ return scaleHelper.normalize(val, this._extent, this._breaks);
}
/**
@@ -161,7 +164,7 @@ class OrdinalScale extends Scale<OrdinalScaleSetting> {
* @return raw ordinal number.
*/
scale(val: number): OrdinalNumber {
- val = Math.round(scaleHelper.scale(val, this._extent));
+ val = Math.round(scaleHelper.scale(val, this._extent, this._breaks));
return this.getRawOrdinalNumber(val);
}
diff --git a/src/scale/Scale.ts b/src/scale/Scale.ts
index 143f4c9b7..bb0e2ff0c 100644
--- a/src/scale/Scale.ts
+++ b/src/scale/Scale.ts
@@ -26,8 +26,10 @@ import {
ScaleDataValue,
OptionDataValue,
DimensionLoose,
- ScaleTick
+ ScaleTick,
+ ScaleBreak
} from '../util/types';
+import { getExtentSpanWithoutBreaks } from './helper';
import { ScaleRawExtentInfo } from '../coord/scaleRawExtentInfo';
@@ -38,6 +40,7 @@ abstract class Scale<SETTING extends Dictionary<unknown> = Dictionary<unknown>>
private _setting: SETTING;
protected _extent: [number, number];
+ protected _breaks: ScaleBreak[];
private _isBlank: boolean;
@@ -47,6 +50,7 @@ abstract class Scale<SETTING extends Dictionary<unknown> = Dictionary<unknown>>
constructor(setting?: SETTING) {
this._setting = setting || {} as SETTING;
this._extent = [Infinity, -Infinity];
+ this._breaks = this._setting.breaks as ScaleBreak[] || [];
}
getSetting<KEY extends keyof SETTING>(name: KEY): SETTING[KEY] {
@@ -117,6 +121,12 @@ abstract class Scale<SETTING extends Dictionary<unknown> = Dictionary<unknown>>
}
}
+ getBrokenExtentRatio(): number {
+ const realSpan = getExtentSpanWithoutBreaks(this._extent, this._breaks);
+ const totalSpan = this._extent[1] - this._extent[0];
+ return totalSpan === 0 ? 1 : realSpan / totalSpan;
+ }
+
/**
* If value is in extent range
*/
diff --git a/src/scale/Time.ts b/src/scale/Time.ts
index 2458490b2..b575fd0e8 100644
--- a/src/scale/Time.ts
+++ b/src/scale/Time.ts
@@ -73,7 +73,7 @@ import {
import * as scaleHelper from './helper';
import IntervalScale from './Interval';
import Scale from './Scale';
-import {TimeScaleTick, ScaleTick} from '../util/types';
+import {TimeScaleTick, ScaleTick, ScaleBreak} from '../util/types';
import {TimeAxisLabelFormatterOption} from '../coord/axisCommonTypes';
import { warn } from '../util/log';
import { LocaleOption } from '../core/locale';
@@ -102,6 +102,7 @@ const bisect = function (
type TimeScaleSetting = {
locale: Model<LocaleOption>;
useUTC: boolean;
+ breaks?: ScaleBreak[];
};
class TimeScale extends IntervalScale<TimeScaleSetting> {
@@ -242,11 +243,11 @@ class TimeScale extends IntervalScale<TimeScaleSetting> {
}
normalize(val: number): number {
- return scaleHelper.normalize(this.parse(val), this._extent);
+ return scaleHelper.normalize(this.parse(val), this._extent, this._breaks);
}
scale(val: number): number {
- return scaleHelper.scale(val, this._extent);
+ return scaleHelper.scale(val, this._extent, this._breaks);
}
}
diff --git a/src/scale/helper.ts b/src/scale/helper.ts
index 3302b165e..89b8b1c43 100644
--- a/src/scale/helper.ts
+++ b/src/scale/helper.ts
@@ -18,6 +18,7 @@
*/
import {getPrecision, round, nice, quantityExponent} from '../util/number';
+import { ScaleBreak } from '../util/types';
import IntervalScale from './Interval';
import LogScale from './Log';
import Scale from './Scale';
@@ -126,13 +127,59 @@ export function contain(val: number, extent: [number, number]): boolean {
return val >= extent[0] && val <= extent[1];
}
-export function normalize(val: number, extent: [number, number]): number {
+export function normalize(
+ val: number,
+ extent: [number, number],
+ breaks?: ScaleBreak[]
+): number {
if (extent[1] === extent[0]) {
return 0.5;
}
- return (val - extent[0]) / (extent[1] - extent[0]);
+ if (!breaks) {
+ breaks = [];
+ }
+ if (breaks.length === 0) {
+ return (val - extent[0]) / (extent[1] - extent[0]);
+ }
+
+ // If the value is in the break, return the normalized value in the break
+ let accVal = extent[0];
+ let lastBreakEnd = extent[0];
+ let largerThanLastBreakEnd = true;
+ for (let i = 0; i < breaks.length; i++) {
+ const brk = breaks[i];
+ if (val <= brk.start) {
+ accVal += val - lastBreakEnd;
+ largerThanLastBreakEnd = false;
+ break;
+ }
+ else if (val <= brk.end) {
+ accVal += brk.start - lastBreakEnd;
+ largerThanLastBreakEnd = false;
+ break;
+ }
+ else {
+ accVal += brk.start - lastBreakEnd + brk.gap;
+ lastBreakEnd = brk.end;
+ }
+ }
+ const value = accVal + (largerThanLastBreakEnd ? (val - lastBreakEnd) : 0);
+ return (value - extent[0]) / getExtentSpanWithoutBreaks(extent, breaks);
}
-export function scale(val: number, extent: [number, number]): number {
- return val * (extent[1] - extent[0]) + extent[0];
+export function scale(
+ val: number,
+ extent: [number, number],
+ breaks?: ScaleBreak[]
+): number {
+ return val * getExtentSpanWithoutBreaks(extent, breaks) + extent[0];
+}
+
+export function getExtentSpanWithoutBreaks(extent: [number, number], breaks: ScaleBreak[]): number {
+ // When breaks is defined, calculate the sum of break gaps
+ let span = extent[1] - extent[0];
+ for (let i = 0; i < breaks.length; i++) {
+ span -= breaks[i].end - breaks[i].start - breaks[i].gap;
+ }
+ return span;
}
diff --git a/src/util/types.ts b/src/util/types.ts
index c7b0c4ef3..14c1c214b 100644
--- a/src/util/types.ts
+++ b/src/util/types.ts
@@ -387,6 +387,12 @@ export type ParsedValueNumeric = number | OrdinalNumber;
*/
export type ScaleDataValue = ParsedValueNumeric | OrdinalRawValue | Date;
+export type ScaleBreak = {
+ start: number,
+ end: number,
+ gap: number
+};
+
export interface ScaleTick {
level?: number,
value: number
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org