Skip to content

Commit

Permalink
Merge pull request #3069 from VisActor/feat/pie-layout-radius
Browse files Browse the repository at this point in the history
Feat/pie layout radius
  • Loading branch information
xile611 authored Aug 14, 2024
2 parents b8d5930 + d00da3c commit 945a1fe
Show file tree
Hide file tree
Showing 10 changed files with 112 additions and 54 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"comment": "feat: support `layoutRadius` of pie\n\n",
"type": "none",
"packageName": "@visactor/vchart"
}
],
"packageName": "@visactor/vchart",
"email": "dingling112@gmail.com"
}
22 changes: 16 additions & 6 deletions docs/assets/option/en/series/pie.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,25 @@ pie: {
}
```

#${prefix} layoutRadius(string|number|function)

Introduced in version **1.11.12**

The layout radius of the polar coordinate, which is the base value for calculating the inner and outer radii. The optional values are as follows:

- Not set: The default value is `Math.min(width, height) / 2`, which is equivalent to this effect before version **1.11.2**
- `'auto'`: Automatically calculate the maximum available layout radius based on `center`, `startAngle`, and `endAngle`
- Custom function, the type definition of the function is as follows:

```ts
(layoutRect: { width: number; height: number }, center: { x: number; y: number }) => number;
```

#${prefix} outerRadius(number)

Pie chart outer sector radius. The default value is 0.6.

#${prefix} outerRadius(number)
#${prefix} innerRadius(number)

Pie chart inner sector radius. The default value is 0.

Expand Down Expand Up @@ -191,11 +205,7 @@ The callback function is defined as follows:
* @params path object, user-defined drawing
* @return Returns the path after drawing is completed
*/
(
text: ITextGraphicAttribute,
attrs: Partial<ILineGraphicAttribute>,
path: ICustomPath2D
) => ICustomPath2D;
(text: ITextGraphicAttribute, attrs: Partial<ILineGraphicAttribute>, path: ICustomPath2D) => ICustomPath2D;
```

###${prefix} style(Object)
Expand Down
24 changes: 17 additions & 7 deletions docs/assets/option/zh/series/pie.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,25 @@ pie: {
}
```

#${prefix} layoutRadius(string|number|function)

**1.11.12**版本开始支持

极坐标的布局半径,即计算内径、外径的基准值,可选值如下:

- 不设置: 默认值为`Math.min(width, height) / 2`**1.11.2**之前的版本相当于这个效果
- `'auto'`: 根据`center``startAngle``endAngle`自动计算最大可用的布局半径
- 自定义函数,函数的类型定义如下:

```ts
(layoutRect: { width: number; height: number }, center: { x: number; y: number }) => number;
```

#${prefix} outerRadius(number)

饼图扇区外半径。默认值为 0.6。

#${prefix} outerRadius(number)
#${prefix} innerRadius(number)

饼图扇区内半径。默认值为 0。

Expand Down Expand Up @@ -181,7 +195,7 @@ pie: {
) }}

##${prefix} customShape(function)
自1.11.11版本, 标签引导线支持自定义path.
自 1.11.11 版本, 标签引导线支持自定义 path.

回调函数的定义如下:

Expand All @@ -192,11 +206,7 @@ pie: {
* @params path对象, 用户自定义绘制
* @return 返回绘制完成后的path
*/
(
text: ITextGraphicAttribute,
attrs: Partial<ILineGraphicAttribute>,
path: ICustomPath2D
) => ICustomPath2D;
(text: ITextGraphicAttribute, attrs: Partial<ILineGraphicAttribute>, path: ICustomPath2D) => ICustomPath2D;
```

###${prefix} style(Object)
Expand Down
3 changes: 2 additions & 1 deletion packages/vchart/src/chart/pie/base/pie-transformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ export class BasePieChartSpecTransformer<T extends IPieChartSpec> extends PolarC
cornerRadius: spec.cornerRadius,

padAngle: spec.padAngle,
minAngle: spec.minAngle
minAngle: spec.minAngle,
layoutRadius: spec.layoutRadius
};
}
}
5 changes: 3 additions & 2 deletions packages/vchart/src/chart/polar/interface.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { IPointLike } from '@visactor/vutils';
import type { IPolarAxisSpec } from '../../component/axis/polar/interface';
import type { IPolarCrosshairSpec } from '../../component/crosshair/interface';
import type { IChartSpec, ILayoutRect, IPoint } from '../../typings';
import type { IChartSpec, ILayoutRect } from '../../typings';

export interface IPolarChartSpec extends IChartSpec {
/**
Expand All @@ -17,5 +18,5 @@ export interface IPolarChartSpec extends IChartSpec {
/**
* @since 1.11.2
*/
layoutRadius?: 'auto' | number | ((layoutRect: ILayoutRect, center: IPoint) => number);
layoutRadius?: 'auto' | number | ((layoutRect: ILayoutRect, center: IPointLike) => number);
}
48 changes: 15 additions & 33 deletions packages/vchart/src/component/axis/polar/axis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,12 @@ import { isPolarAxisSeries } from '../../../series/util/utils';
import { getAxisItem, getAxisLabelOffset, isValidPolarAxis } from '../util';
import type { Dict, Maybe } from '@visactor/vutils';
// eslint-disable-next-line no-duplicate-imports
import {
PointService,
degreeToRadian,
isValid,
isArray,
isValidNumber,
isNumber,
isFunction,
calculateMaxRadius,
polarToCartesian
} from '@visactor/vutils';
import { PointService, degreeToRadian, isValid, isArray, isValidNumber, polarToCartesian } from '@visactor/vutils';
import type { IEffect, IModelSpecInfo } from '../../../model/interface';
import { AxisComponent } from '../base-axis';
import type { IBandAxisSpec, ITick } from '../interface';
import { HOOK_EVENT } from '@visactor/vgrammar-core';
import { getPolarAxisInfo } from './util';
import { computeLayoutRadius, getPolarAxisInfo } from './util';
// eslint-disable-next-line no-duplicate-imports
import { mergeSpec } from '@visactor/vutils-extension';
import { calcLayoutNumber } from '../../../util/space';
Expand Down Expand Up @@ -324,7 +314,7 @@ export abstract class PolarAxis<T extends IPolarAxisCommonSpec = IPolarAxisCommo
coordToPoint: this.coordToPoint.bind(this),
pointToCoord: this.pointToCoord.bind(this),
center: this.getCenter.bind(this),
layoutRadius: this.computeLayoutRadius.bind(this),
layoutRadius: this._computeLayoutRadius.bind(this),
getScale,
getAxisId: () => this.id,
getSpec: () => this._spec
Expand Down Expand Up @@ -528,22 +518,14 @@ export abstract class PolarAxis<T extends IPolarAxisCommonSpec = IPolarAxisCommo
return undefined;
}

private computeLayoutRadius() {
const layoutRect = this.getRefLayoutRect();

if (isNumber(this._spec.layoutRadius)) {
return this._spec.layoutRadius;
} else if (isFunction(this._spec.layoutRadius)) {
return this._spec.layoutRadius(layoutRect, this.getCenter());
}

const { width, height } = layoutRect;

if (this._spec.layoutRadius === 'auto' && width > 0 && height > 0) {
return calculateMaxRadius(layoutRect, this.getCenter(), this._startAngle, this._endAngle);
}

return Math.min(width / 2, height / 2);
private _computeLayoutRadius() {
return computeLayoutRadius(
this._spec.layoutRadius,
this.getRefLayoutRect,
this.getCenter,
this._startAngle,
this._endAngle
);
}

private computeLayoutOuterRadius() {
Expand All @@ -553,17 +535,17 @@ export abstract class PolarAxis<T extends IPolarAxisCommonSpec = IPolarAxisCommo
*/
const radius = this._spec.outerRadius ?? this._spec.radius;
const outerRadius = radius ?? this.getRefSeriesRadius().outerRadius;
return this.computeLayoutRadius() * outerRadius;
return this._computeLayoutRadius() * outerRadius;
}

private computeLayoutInnerRadius() {
const innerRadius = this._spec.innerRadius ?? this.getRefSeriesRadius().innerRadius;
return this.computeLayoutRadius() * innerRadius;
return this._computeLayoutRadius() * innerRadius;
}

private getRefLayoutRect() {
private getRefLayoutRect = () => {
return this.getRegions()[0].getLayoutRect();
}
};

private getRefSeriesRadius() {
let outerRadius: number = POLAR_DEFAULT_RADIUS;
Expand Down
5 changes: 3 additions & 2 deletions packages/vchart/src/component/axis/polar/interface/spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { ILayoutRect, IPoint, IPolarOrientType } from '../../../../typings';
import type { IPointLike } from '@visactor/vutils';
import type { ILayoutRect, IPolarOrientType } from '../../../../typings';
import type { IBandAxisSpec, IDomainLine, ILinearAxisSpec, ITitle, ILabel, ICommonAxisSpec } from '../../interface';
import type { IPolarGrid } from './common';

Expand All @@ -11,7 +12,7 @@ export type IPolarAxisCommonSpec = Omit<ICommonAxisSpec, 'center'> & {
* 默认值为: region宽度、高度最小值的一般
* @since 1.11.2
*/
layoutRadius?: 'auto' | number | ((layoutRect: ILayoutRect, center: IPoint) => number);
layoutRadius?: 'auto' | number | ((layoutRect: ILayoutRect, center: IPointLike) => number);
/**
* 当配置了 innerRadius 时,可以通过设置 inside: true,将坐标轴展示在内圆。
* @default false
Expand Down
26 changes: 25 additions & 1 deletion packages/vchart/src/component/axis/polar/util/common.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { isValid } from '@visactor/vutils';
import { calculateMaxRadius, isFunction, isNumber, isValid } from '@visactor/vutils';
import { POLAR_DEFAULT_RADIUS, POLAR_END_ANGLE, POLAR_START_ANGLE } from '../../../../constant';
import { ComponentTypeEnum } from '../../../interface';
import type { IPolarAxisCommonSpec } from '../interface';
import type { ILayoutRect } from '../../../../typings/layout';
import type { IPoint } from '../../../../typings/coordinate';

export const getPolarAxisInfo = (spec: IPolarAxisCommonSpec, chartSpec: any) => {
// TODO: 基于数据处理 axis 类型
Expand All @@ -28,3 +30,25 @@ export const getPolarAxisInfo = (spec: IPolarAxisCommonSpec, chartSpec: any) =>
layoutRadius: chartSpec.layoutRadius
};
};

export const computeLayoutRadius = (
layoutRadius: 'auto' | number | ((layoutRect: ILayoutRect, center: IPoint) => number),
getLayoutRect: () => ILayoutRect,
getCenter: () => IPoint,
startAngle: number = 0,
endAngle: number = 0 * Math.PI
) => {
if (isNumber(layoutRadius)) {
return layoutRadius;
} else if (isFunction(layoutRadius)) {
return layoutRadius(getLayoutRect(), getCenter());
}

const rect = getLayoutRect();

if (layoutRadius === 'auto' && rect.width > 0 && rect.height > 0) {
return calculateMaxRadius(rect, getCenter(), startAngle, endAngle);
}

return Math.min(rect.width / 2, rect.height / 2);
};
7 changes: 7 additions & 0 deletions packages/vchart/src/series/pie/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import type { IPolarSeriesSpec, IPolarSeriesTheme } from '../polar/interface';
import type { PieAppearPreset } from './animation/animation';
import type { ILabelSpec, IMultiLabelSpec } from '../../component/label';
import type { ICustomPath2D, ILineGraphicAttribute, ITextGraphicAttribute } from '@visactor/vrender-core';
import type { ILayoutRect } from '../../typings/layout';
import type { IPointLike } from '@visactor/vutils';

export type PieMarks = 'pie' | 'label' | 'labelLine';

Expand Down Expand Up @@ -73,6 +75,11 @@ export interface IPieSeriesSpec extends IPolarSeriesSpec, IAnimationSpec<PieMark
*/
minAngle?: number;

/**
* @since 1.11.12
*/
layoutRadius?: 'auto' | number | ((layoutRect: ILayoutRect, center: IPointLike) => number);

/** 扇区样式 */
[SeriesMarkNameEnum.pie]?: IMarkSpec<IArcMarkSpec>;
/** 标签配置 */
Expand Down
15 changes: 13 additions & 2 deletions packages/vchart/src/series/pie/pie.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import { pieSeriesMark } from './constant';
import { Factory } from '../../core/factory';
import { isNil, polarToCartesian } from '@visactor/vutils';
import { PieSeriesSpecTransformer } from './pie-transformer';
import { computeLayoutRadius } from '../../component/axis/polar/util/common';

export class BasePieSeries<T extends IBasePieSeriesSpec> extends PolarSeries<T> implements IArcSeries {
static readonly transformerConstructor = PieSeriesSpecTransformer as any;
Expand All @@ -62,13 +63,13 @@ export class BasePieSeries<T extends IBasePieSeriesSpec> extends PolarSeries<T>
protected _viewDataLabel!: SeriesData;

// 饼图渲染不依赖于极坐标系轴,因此由 series 自己存储相关配置信息
getCenter(): IPoint {
getCenter = (): IPoint => {
const { width, height } = this._region.getLayoutRect();
return {
x: this._spec?.centerX ?? width / 2,
y: this._spec?.centerY ?? height / 2
};
}
};
protected _centerOffset!: number;

protected _cornerRadius!: number;
Expand Down Expand Up @@ -184,6 +185,16 @@ export class BasePieSeries<T extends IBasePieSeriesSpec> extends PolarSeries<T>
return field(ARC_END_ANGLE)(datum);
}

protected _computeLayoutRadius() {
return computeLayoutRadius(
this._spec.layoutRadius,
this.getLayoutRect,
this.getCenter,
this._startAngle,
this._endAngle
);
}

initMarkStyle(): void {
const pieMark = this._pieMark;
if (pieMark) {
Expand Down

0 comments on commit 945a1fe

Please sign in to comment.