Skip to content
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

Feat/issue 2918 #2919

Merged
merged 5 commits into from
Jul 10, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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,10 @@
{
"changes": [
{
"packageName": "@visactor/vchart",
"comment": "feat: marker's `coordinates` and `positions` property support callback",
"type": "none"
}
],
"packageName": "@visactor/vchart"
}
103 changes: 12 additions & 91 deletions packages/vchart/src/component/marker/base-marker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,15 @@ import { array, isValid, isNil, isString, isEmpty, isArray, isEqual } from '@vis
import type { IModelRenderOption, IModelSpecInfo } from '../../model/interface';
import type { IRegion } from '../../region/interface';
import type { ICartesianSeries } from '../../series/interface';
import type { ILayoutRect, ILayoutType, IRect, StringOrNumber } from '../../typings';
import type { CoordinateType, ILayoutRect, ILayoutType, IRect, StringOrNumber } from '../../typings';
import { BaseComponent } from '../base/base-component';
import type {
IAggrType,
ICoordinateOption,
IDataPointSpec,
IDataPos,
IDataPosCallback,
IMarkerSpec,
IMarkerSupportSeries
} from './interface';
import type { IAggrType, IDataPos, IDataPosCallback, IMarkerSpec, IMarkerSupportSeries } from './interface';
import type { IGraphic, IGroup } from '@visactor/vrender-core';
import { calcLayoutNumber } from '../../util/space';
import { isAggrSpec } from './utils';
import { getFirstSeries } from '../../util';
import { arrayParser } from '../../data/parser/array';
import type { IOptionWithCoordinates } from '../../data/transforms/aggregation';

export abstract class BaseMarker<T extends IMarkerSpec> extends BaseComponent<T> {
layoutType: ILayoutType | 'none' = 'none';
Expand All @@ -29,7 +22,7 @@ export abstract class BaseMarker<T extends IMarkerSpec> extends BaseComponent<T>
static specKey: string;
static type: string;
static coordinateType: string;
coordinateType: string;
coordinateType: CoordinateType;

protected _startRelativeSeries!: IMarkerSupportSeries;
protected _endRelativeSeries!: IMarkerSupportSeries;
Expand Down Expand Up @@ -145,86 +138,14 @@ export abstract class BaseMarker<T extends IMarkerSpec> extends BaseComponent<T>
};
}

protected _processSpecCoo(spec: any) {
const coordinates = spec.coordinates ?? array(spec.coordinate);
let option: ICoordinateOption;
return coordinates.map((coordinate: IDataPointSpec) => {
const refRelativeSeries = this._getSeriesByIdOrIndex(
coordinate.refRelativeSeriesId,
coordinate.refRelativeSeriesIndex
);

if (this.coordinateType === 'cartesian') {
const { xField, yField } = refRelativeSeries.getSpec();
const { xFieldDim, xFieldIndex, yFieldDim, yFieldIndex } = coordinate;
let bindXField = xField;
if (isValid(xFieldIndex)) {
bindXField = array(xField)[xFieldIndex];
}
if (xFieldDim && array(xField).includes(xFieldDim)) {
bindXField = xFieldDim;
}

let bindYField = yField;
if (isValid(yFieldIndex)) {
bindYField = array(yField)[yFieldIndex];
}
if (yFieldDim && array(yField).includes(yFieldDim)) {
bindYField = yFieldDim;
}

option = {
x: undefined,
y: undefined,
...this._getAllRelativeSeries()
};

if (isString(coordinate[bindXField]) && isAggrSpec(coordinate[bindXField] as IDataPos)) {
option.x = { field: bindXField, aggrType: coordinate[bindXField] as IAggrType };
} else {
option.x = array(bindXField).map(field => coordinate[field]);
}

if (isString(coordinate[bindYField]) && isAggrSpec(coordinate[bindYField] as IDataPos)) {
option.y = { field: bindYField, aggrType: coordinate[bindYField] as IAggrType };
} else {
option.y = array(bindYField).map(field => coordinate[field]);
}
} else if (this.coordinateType === 'polar') {
const { valueField: radiusField, categoryField: angleField } = refRelativeSeries.getSpec();
const { angleFieldDim, angleFieldIndex } = coordinate;
let bindAngleField = angleField;
if (isValid(angleFieldIndex)) {
bindAngleField = array(angleField)[angleFieldIndex];
}
if (angleFieldDim && array(angleField).includes(angleFieldDim)) {
bindAngleField = angleFieldDim;
}

const bindRadiusField = radiusField;

option = {
angle: undefined,
radius: undefined,
...this._getAllRelativeSeries()
};

if (isString(coordinate[bindAngleField]) && isAggrSpec(coordinate[bindAngleField] as IDataPos)) {
option.angle = { field: bindAngleField, aggrType: coordinate[bindAngleField] as IAggrType };
} else {
option.angle = array(bindAngleField).map(field => coordinate[field]);
}

if (isString(coordinate[bindRadiusField]) && isAggrSpec(coordinate[bindRadiusField] as IDataPos)) {
option.radius = { field: bindRadiusField, aggrType: coordinate[bindRadiusField] as IAggrType };
} else {
option.radius = array(bindRadiusField).map(field => coordinate[field]);
}
}

option.getRefRelativeSeries = () => refRelativeSeries;
return option;
});
protected _processSpecCoo(spec: any): IOptionWithCoordinates {
return {
coordinates: spec.coordinates || spec.coordinate,
...this._getAllRelativeSeries(),
getSeriesByIdOrIndex: (seriesUserId: StringOrNumber, seriesIndex: number) =>
this._getSeriesByIdOrIndex(seriesUserId, seriesIndex),
coordinateType: this.coordinateType
};
}

protected _getRelativeDataView() {
Expand Down
14 changes: 11 additions & 3 deletions packages/vchart/src/component/marker/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ import type {
import type { IComponentSpec } from '../base/interface';
import type { Datum } from '@visactor/vrender-components';
import type { ICartesianSeries, IGeoSeries, IPolarSeries } from '../../series/interface';
import type { IOptionAggr, IOptionAggrField, IOptionSeries } from '../../data/transforms/aggregation';
import type {
IOptionAggr,
IOptionAggrField,
IOptionSeries,
IOptionWithCoordinates
} from '../../data/transforms/aggregation';
import type { IOptionRegr } from '../../data/transforms/regression';

export type IMarkerSupportSeries = ICartesianSeries | IPolarSeries | IGeoSeries;
Expand Down Expand Up @@ -129,8 +134,11 @@ export type ICoordinateOption = {
export type IMarkerPositionsSpec = {
/**
* 画布坐标
* `positions` 自 1.12.0 版本开始支持回调函数
*/
positions: MarkerPositionPoint[];
positions:
kkxxkk2019 marked this conversation as resolved.
Show resolved Hide resolved
| MarkerPositionPoint[]
| ((seriesData: Datum[], relativeSeries: IMarkerSupportSeries) => MarkerPositionPoint[]);
/**
* 是否为相对 region 的坐标,默认为 false,即相对画布的坐标
* @default false
Expand Down Expand Up @@ -310,7 +318,7 @@ export type IMarkerState<T> = {
export type MarkCoordinateType = 'cartesian' | 'polar' | 'geo';

export type IMarkProcessOptions = {
options: IOptionAggr[] | IOptionRegr;
options: IOptionAggr[] | IOptionRegr | IOptionWithCoordinates;
needAggr?: boolean;
needRegr?: boolean;
processData?: DataView;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { ComponentTypeEnum } from '../../interface/type';
import type { IOptionAggr } from '../../../data/transforms/aggregation';
import type { IOptionAggr, IOptionWithCoordinates } from '../../../data/transforms/aggregation';
import { cartesianCoordinateLayout, getMarkAreaProcessInfo, positionLayout, xyLayout } from '../utils';
import type { MarkAreaAttrs } from '@visactor/vrender-components';
// eslint-disable-next-line no-duplicate-imports
import { MarkArea as MarkAreaComponent, registerMarkAreaAnimate } from '@visactor/vrender-components';
// eslint-disable-next-line no-duplicate-imports
import { isValid } from '@visactor/vutils';
import { Factory } from '../../../core/factory';
import type { IPoint } from '../../../typings';
import type { CoordinateType, IPoint } from '../../../typings';
import type { IMarkProcessOptions } from '../interface';
import { BaseMarkArea } from './base-mark-area';

Expand All @@ -16,7 +16,7 @@ export class CartesianMarkArea extends BaseMarkArea {
type = ComponentTypeEnum.markArea;
name: string = ComponentTypeEnum.markArea;
static coordinateType = 'cartesian';
coordinateType = 'cartesian';
coordinateType = 'cartesian' as CoordinateType;

protected _newMarkAreaComponent(attr: MarkAreaAttrs): MarkAreaComponent {
return new MarkAreaComponent(attr);
Expand Down Expand Up @@ -74,7 +74,7 @@ export class CartesianMarkArea extends BaseMarkArea {
const spec = this._spec as any;
const { doXProcess, doYProcess, doXYProcess, doCoordinatesProcess } = getMarkAreaProcessInfo(spec);

let options: IOptionAggr[];
let options: IOptionAggr[] | IOptionWithCoordinates;
if (doXYProcess) {
options = [
this._processSpecByDims([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ import type {
IMarkerSpec,
IDataPosCallback,
IMarkerCrossSeriesSpec,
OffsetPoint
OffsetPoint,
IMarkerSupportSeries
} from '../../interface';
import type { IMarkAreaTheme } from './theme';
import type { Datum } from '../../../../typings/common';

export type IMarkArea = IComponent;

Expand Down Expand Up @@ -127,8 +129,9 @@ export interface IMarkAreaAngleRadiusSpec extends IMarkerCrossSeriesSpec {
export type IMarkAreaCoordinateSpec = {
/**
* 指定数据点的参考线。基于指定数据点进行参考线的绘制,可以对数据点进行数据处理
* `coordinates` 自 1.12.0 版本开始支持回调函数
*/
coordinates: IDataPointSpec[];
coordinates: IDataPointSpec[] | ((seriesData: Datum[], relativeSeries: IMarkerSupportSeries) => IDataPointSpec[]);
kkxxkk2019 marked this conversation as resolved.
Show resolved Hide resolved

/**
* 对每个数据点转化后的画布坐标点进行偏移,该偏移值可以是像素值,也可以是 string 类型,如 '20%' 代表百分比
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ComponentTypeEnum } from '../../interface/type';
import type { IOptionAggr } from '../../../data/transforms/aggregation';
import type { IOptionAggr, IOptionWithCoordinates } from '../../../data/transforms/aggregation';
import { getMarkAreaProcessInfo, polarCoordinateLayout, polarLayout } from '../utils';
import type { MarkArcAreaAttrs, MarkAreaAttrs } from '@visactor/vrender-components';
// eslint-disable-next-line no-duplicate-imports
Expand All @@ -10,7 +10,7 @@ import {
registerMarkAreaAnimate
} from '@visactor/vrender-components';
import { Factory } from '../../../core/factory';
import type { IPoint, IPolarPoint } from '../../../typings';
import type { CoordinateType, IPoint, IPolarPoint } from '../../../typings';
import type { IPolarSeries } from 'src/series';
import { BaseMarkArea } from './base-mark-area';
import type { IMarkProcessOptions } from '../interface';
Expand All @@ -21,7 +21,7 @@ export class PolarMarkArea extends BaseMarkArea {
type = ComponentTypeEnum.polarMarkArea;
name: string = ComponentTypeEnum.polarMarkArea;
static coordinateType = 'polar';
coordinateType = 'polar';
coordinateType = 'polar' as CoordinateType;

protected declare _markerComponent: MarkArcAreaComponent;

Expand Down Expand Up @@ -110,7 +110,7 @@ export class PolarMarkArea extends BaseMarkArea {
const spec = this._spec as any;
const { doAngleProcess, doRadiusProcess, doRadAngProcess, doCoordinatesProcess } = getMarkAreaProcessInfo(spec);

let options: IOptionAggr[];
let options: IOptionAggr[] | IOptionWithCoordinates;
if (doRadAngProcess) {
options = [
this._processSpecByDims([
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
import { DataView } from '@visactor/vdataset';
import type { IStepMarkLineSpec } from './interface';
import { ComponentTypeEnum } from '../../interface/type';
import type { IOptionAggr } from '../../../data/transforms/aggregation';
import {
computeClipRange,
cartesianCoordinateLayout,
positionLayout,
xyLayout,
getMarkLineProcessInfo
} from '../utils';
import type { IOptionAggr, IOptionWithCoordinates } from '../../../data/transforms/aggregation';
import { cartesianCoordinateLayout, positionLayout, xyLayout, getMarkLineProcessInfo } from '../utils';
import {
type MarkLineAttrs,
MarkLine as MarkLineComponent,
Expand All @@ -20,15 +14,15 @@ import type { IOptionRegr } from '../../../data/transforms/regression';
import { getInsertPoints, getTextOffset } from './util';
import { Factory } from '../../../core/factory';
import { isPercent } from '../../../util';
import type { IPoint } from '../../../typings';
import type { CoordinateType, IPoint } from '../../../typings';
import { BaseMarkLine } from './base-mark-line';

export class CartesianMarkLine extends BaseMarkLine {
static type = ComponentTypeEnum.markLine;
type = ComponentTypeEnum.markLine;
name: string = ComponentTypeEnum.markLine;
static coordinateType = 'cartesian';
coordinateType = 'cartesian';
coordinateType = 'cartesian' as CoordinateType;

protected declare _markerComponent: MarkLineComponent;

Expand Down Expand Up @@ -182,7 +176,7 @@ export class CartesianMarkLine extends BaseMarkLine {
}

protected _computeOptions(): IMarkProcessOptions {
let options: IOptionAggr[] | IOptionRegr;
let options: IOptionAggr[] | IOptionRegr | IOptionWithCoordinates;
let processData: DataView = this._getRelativeDataView();
let needAggr: boolean = true;
let needRegr: boolean = false;
Expand Down
16 changes: 11 additions & 5 deletions packages/vchart/src/component/marker/mark-line/interface/spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ import type {
IMarkerCrossSeriesSpec,
OffsetPoint,
MarkerStateValue,
MarkerStateCallback
MarkerStateCallback,
IMarkerSupportSeries
} from '../../interface';
import type { IRegressType } from '../../mark-area/interface';
import type { IMarkLineTheme } from './theme';
import type { ILineMarkSpec, IPoint } from '../../../../typings';
import type { Datum, ILineMarkSpec, IPoint } from '../../../../typings';
import type { BaseMarkerAnimation, MarkCommonLineAnimationType } from '@visactor/vrender-components/es/marker/type';

export type IMarkLine = IComponent;
Expand Down Expand Up @@ -210,8 +211,9 @@ export interface IMarkLineAngRadSpec extends IMarkerCrossSeriesSpec {
export type IMarkLineCoordinateSpec = {
/**
* 指定数据点的参考线。基于指定数据点进行参考线的绘制,可以对数据点进行数据处理
* `coordinates` 自 1.12.0 版本开始支持回调函数
*/
coordinates: IDataPointSpec[];
coordinates: IDataPointSpec[] | ((seriesData: Datum[], relativeSeries: IMarkerSupportSeries) => IDataPointSpec[]);
/**
* 对每个数据点转化后的画布坐标点进行偏移,该偏移值可以是像素值,也可以是 string 类型,如 '20%' 代表百分比
* 每个元素对应一个坐标点的偏移量
Expand Down Expand Up @@ -275,8 +277,11 @@ export type IStepMarkLineSpec = IMarkerSpec & {
| {
/**
* 指定数据点的参考线。基于指定数据点进行参考线的绘制,可以对数据点进行数据处理
* `coordinates` 自 1.12.0 版本开始支持回调函数
*/
coordinates: [IDataPointSpec, IDataPointSpec];
coordinates:
| [IDataPointSpec, IDataPointSpec]
| ((seriesData: Datum[], relativeSeries: IMarkerSupportSeries) => [IDataPointSpec, IDataPointSpec]);
/**
* 数据点的处理方法。 如果不配置则按照coordinate数组直接连接成line。
*/
Expand All @@ -294,8 +299,9 @@ export type IStepMarkLineSpec = IMarkerSpec & {
| {
/**
* 画布坐标
* `positions` 自 1.12.0 版本开始支持回调函数
*/
positions: [IPoint, IPoint];
positions: [IPoint, IPoint] | ((seriesData: Datum[], relativeSeries: IMarkerSupportSeries) => [IPoint, IPoint]);
/**
* 是否为相对 region 的坐标,默认为 false,即相对画布的坐标
* @default false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { DataView } from '@visactor/vdataset';
// eslint-disable-next-line no-duplicate-imports
import { ComponentTypeEnum } from '../../interface/type';
// eslint-disable-next-line no-duplicate-imports
import type { IOptionAggr } from '../../../data/transforms/aggregation';
import type { IOptionAggr, IOptionWithCoordinates } from '../../../data/transforms/aggregation';
import { polarLayout, getMarkLineProcessInfo, polarCoordinateLayout } from '../utils';
import type { MarkArcLineAttrs, MarkLineAttrs } from '@visactor/vrender-components';
// eslint-disable-next-line no-duplicate-imports
Expand All @@ -14,7 +14,7 @@ import {
} from '@visactor/vrender-components';
import type { IOptionRegr } from '../../../data/transforms/regression';
import { Factory } from '../../../core/factory';
import type { IPoint, IPolarPoint } from '../../../typings';
import type { CoordinateType, IPoint, IPolarPoint } from '../../../typings';
import type { IPolarSeries } from 'src/series';
import { BaseMarkLine } from './base-mark-line';
import { polarToCartesian } from '@visactor/vutils';
Expand All @@ -24,7 +24,7 @@ export class PolarMarkLine extends BaseMarkLine {
type = ComponentTypeEnum.polarMarkLine;
name: string = ComponentTypeEnum.polarMarkLine;
static coordinateType = 'polar';
coordinateType = 'polar';
coordinateType = 'polar' as CoordinateType;

protected declare _markerComponent: MarkArcLineComponent;

Expand Down Expand Up @@ -118,7 +118,7 @@ export class PolarMarkLine extends BaseMarkLine {
doCoordinatesProcess
} = getMarkLineProcessInfo(spec);

let options: IOptionAggr[] | IOptionRegr;
let options: IOptionAggr[] | IOptionRegr | IOptionWithCoordinates;
const processData: DataView = this._getRelativeDataView();
const needAggr: boolean = true;
const needRegr: boolean = false;
Expand Down
Loading
Loading