Skip to content

Feat/soft min max #2556

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"comment": "feat: support `softMin` and `softMax` in linear-axis, close #2498\n\n",
"type": "none",
"packageName": "@visactor/vchart"
}
],
"packageName": "@visactor/vchart",
"email": "[email protected]"
}
16 changes: 16 additions & 0 deletions docs/assets/option/en/component/axis-common/linear-axis.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,22 @@

**Applies only when the axis is a linear or time axis**. Maximum value(time axis only support timeStamp), **takes precedence over zero and nice**.

#${prefix} softMin(number)

Supported since version **1.11.0**

Only effective when the axis is a linear or time axis, minimum value (time axis only supports timestamps), only takes effect when this value is less than the minimum data value, **takes precedence over zero and nice**.

- Note: Not recommended to use together with configuring `min`

#${prefix} softMax(number)

Supported since version **1.11.0**

Only effective when the axis is a linear or time axis, maximum value (time axis only supports timestamps), only takes effect when this value is greater than the maximum data value, **takes precedence over zero and nice**.

Note: Not recommended to use together with configuring `max`

#${prefix} nice(boolean) = true

**Applies only when the axis is a linear or time axis**. Whether to adjust the axis range to a relatively neat value based on the data. When `min` and `max` are configured, this option is invalid.
Expand Down
16 changes: 16 additions & 0 deletions docs/assets/option/zh/component/axis-common/linear-axis.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,22 @@

**仅当轴为线性轴或时间轴时生效**,最大值(时间轴仅支持时间戳),**优先级高于 zero,nice**。

#${prefix} softMin(number)

自**1.11.0**版本开始支持

**仅当轴为线性轴或时间轴时生效**,最小值(时间轴仅支持时间戳),当且仅当该值小于数据最小值时,才能生效,**优先级高于 zero,nice**。

- 注意:不建议和配置`min`一起使用

#${prefix} softMmax(number)

自**1.11.0**版本开始支持

**仅当轴为线性轴或时间轴时生效**,最大值(时间轴仅支持时间戳),当且仅当该值大于数据最大值时,才能生效,**优先级高于 zero,nice**。

注意:不建议和配置`max`一起使用

#${prefix} nice(boolean) = true

**仅当轴为线性轴或时间轴时生效**,是否根据数据将轴范围调整到相对规整的数值,当配置了 `min` 和 `max`,该配置项失效。
Expand Down
13 changes: 13 additions & 0 deletions packages/vchart/src/component/axis/interface/spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,19 @@ export interface ILinearAxisSpec {
/** 最大值,**优先级高于 zero,nice** */
max?: number;

/**
* 最小值,当且仅当该值小于数据最小值时,才能生效
* 注意:不建议和配置`min`一起使用
* @since 1.11.0
*/
softMin?: number | ((domain: number[]) => number);
/**
* 最大值,当且仅当该值大于数据最大值时,才能生效
* 注意:不建议和配置`max`一起使用
* @since 1.11.0
*/
softMax?: number | ((domain: number[]) => number);

/** @deparated 线性轴数值范围配置(已弃用,请使用外层 min/max) */
range?: {
/** @deparated 最小值 */
Expand Down
4 changes: 2 additions & 2 deletions packages/vchart/src/component/axis/mixin/band-axis-mixin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ export class BandAxisMixin {
this._scales[i].domain(userDomain);
} else {
const data = this.collectData(i);
const domain = this.computeDomain(data);
const domain = this.computeBandDomain(data);
this._scales[i].domain(domain.sort((a, b) => this._rawDomainIndex[i][a] - this._rawDomainIndex[i][b]));
}
}
Expand Down Expand Up @@ -232,7 +232,7 @@ export class BandAxisMixin {
this._scales[i].domain(userDomain);
} else {
const data = this.collectData(i, true);
const domain = this.computeDomain(data);
const domain = this.computeBandDomain(data);
this._rawDomainIndex[i] = {};
domain.forEach((d, _i) => (this._rawDomainIndex[i][d] = _i));
}
Expand Down
48 changes: 41 additions & 7 deletions packages/vchart/src/component/axis/mixin/linear-axis-mixin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ export interface LinearAxisMixin {
* 用于在插件(如0值对齐等功能)中使用
*/
_domainAfterSpec: number[];
_softMinValue?: number;
_softMaxValue?: number;
_expand?: { max?: number; min?: number };
_tick: ITick | undefined;
isSeriesDataEnable: any;
Expand Down Expand Up @@ -91,11 +93,11 @@ export class LinearAxisMixin {
tickCount = Math.max(DEFAULT_TICK_COUNT, tickCount);
}
const { min, max } = this._domain ?? {};
if (isNil(min) && isNil(max)) {
if (isNil(min) && isNil(max) && isNil(this._softMaxValue) && isNil(this._softMinValue)) {
return this._scale.nice(tickCount);
} else if (isValid(min) && isNil(max)) {
} else if ((isValid(min) || isValid(this._softMinValue)) && isNil(max) && isNil(this._softMaxValue)) {
return this._scale.niceMax(tickCount);
} else if (isNil(min) && isValid(max)) {
} else if (isNil(min) && isNil(this._softMinValue) && (isValid(max) || isValid(this._softMaxValue))) {
return this._scale.niceMin(tickCount);
}

Expand All @@ -108,11 +110,11 @@ export class LinearAxisMixin {
}

const { min, max } = this._domain ?? {};
if (isNil(min) && isNil(max)) {
if (isNil(min) && isNil(max) && isNil(this._softMaxValue) && isNil(this._softMinValue)) {
return this._scale.nice();
} else if (isValid(min) && isNil(max)) {
} else if ((isValid(min) || isValid(this._softMinValue)) && isNil(max) && isNil(this._softMaxValue)) {
return this._scale.niceMax();
} else if (isNil(min) && isValid(max)) {
} else if (isNil(min) && isNil(this._softMinValue) && (isValid(max) || isValid(this._softMaxValue))) {
return this._scale.niceMin();
}

Expand Down Expand Up @@ -148,6 +150,7 @@ export class LinearAxisMixin {
domain[0] = 0;
domain[1] = 0;
}
this.setSoftDomainMinMax(domain);
this.expandDomain(domain);
this.includeZero(domain);
this.setDomainMinMax(domain);
Expand Down Expand Up @@ -268,6 +271,37 @@ export class LinearAxisMixin {
isValid(max) && (domain[1] = max);
}

protected setSoftDomainMinMax(domain: number[]): void {
const { softMin, softMax } = this._spec;

if (isValid(softMin)) {
let softMinValue = isFunction(softMin) ? softMin(domain) : (softMin as number);

if (isNil(softMinValue)) {
softMinValue = domain[0];
}

if (softMinValue <= domain[0]) {
domain[0] = softMinValue;
this._softMinValue = softMinValue;
}
}

if (isValid(softMax)) {
let softMaxValue = isFunction(softMax) ? softMax(domain) : (softMax as number);

if (isNil(softMaxValue)) {
softMaxValue = domain[1];
}

if (softMaxValue >= domain[1]) {
domain[1] = softMaxValue;
}

this._softMaxValue = softMaxValue;
}
}

setZero(zero: boolean) {
if (this._zero !== zero) {
this._zero = zero;
Expand All @@ -283,7 +317,7 @@ export class LinearAxisMixin {
return;
}
const data = this.collectData();
const domain: number[] = this.computeDomain(data) as number[];
const domain: number[] = this.computeLinearDomain(data) as number[];
this.updateScaleDomainByModel(domain);
}

Expand Down