Skip to content
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
123 changes: 61 additions & 62 deletions packages/vchart/src/animation/animate-manager.ts
Original file line number Diff line number Diff line change
@@ -1,66 +1,65 @@
import { StateManager } from '../compile/state-manager';
import { createID } from '../util/id';
import type { IAnimate, IAnimateState } from './interface';
// eslint-disable-next-line no-duplicate-imports
import { AnimationStateEnum } from './interface';
import type { StateValueMap } from '../compile/interface/compilable-item';
import type { IMarkGraphic } from '../mark/interface/common';
// import { StateManager } from '../compile/state-manager';
// import { createID } from '../util/id';
// import type { IAnimate, IAnimateState } from './interface';
// // eslint-disable-next-line no-duplicate-imports
// import { AnimationStateEnum } from './interface';
// import type { StateValueMap } from '../compile/interface/compilable-item';
// import type { IMarkGraphic } from '../mark/interface/common';

// todo @feifei
export class AnimateManager extends StateManager implements IAnimate {
protected declare _stateMap: IAnimateState & StateValueMap;
// export class AnimateManager extends StateManager implements IAnimate {
// protected declare _stateMap: IAnimateState & StateValueMap;

readonly id: number = createID();
// readonly id: number = createID();

updateAnimateState(state: AnimationStateEnum, noRender?: boolean) {
// when animation state is 'update', do animations by element diffState(enter & update & exit)
if (state === AnimationStateEnum.update) {
this.updateState(
{
animationState: {
callback: (datum: any, g: IMarkGraphic) => g.context.diffState
}
},
noRender
);
}
// when animation state is 'appear', all valid elements would do appear animation except from exit elements
else if (state === AnimationStateEnum.appear) {
this.updateState(
{
animationState: {
callback: (datum: any, g: IMarkGraphic) => {
return g.context.diffState === 'exit' ? AnimationStateEnum.none : AnimationStateEnum.appear;
}
}
},
noRender
);
}
// when animation state is other types, all elements would do animation by state
else {
this.updateState(
{
animationState: {
callback: (datum: any, g: IMarkGraphic) => state
}
},
noRender
);
}
}
// updateAnimateState(state: AnimationStateEnum, noRender?: boolean) {
// // when animation state is 'update', do animations by element diffState(enter & update & exit)
// if (state === AnimationStateEnum.update) {
// this.updateState(
// {
// animationState: {
// callback: (datum: any, g: IMarkGraphic) => g.context.diffState
// }
// },
// noRender
// );
// }
// // when animation state is 'appear', all valid elements would do appear animation except from exit elements
// else if (state === AnimationStateEnum.appear) {
// this.updateState(
// {
// animationState: {
// callback: (datum: any, g: IMarkGraphic) => {
// return g.context.diffState === 'exit' ? AnimationStateEnum.none : AnimationStateEnum.appear;
// }
// }
// },
// noRender
// );
// }
// // when animation state is other types, all elements would do animation by state
// else {
// this.updateState(
// {
// animationState: {
// callback: (datum: any, g: IMarkGraphic) => state
// }
// },
// noRender
// );
// }
// }

protected _getDefaultStateMap(): IAnimateState & StateValueMap {
return {
animationState: {
callback: (datum: any, g: IMarkGraphic) => {
return g.context.diffState === 'exit'
? AnimationStateEnum.exit
: g.context.diffState === 'update'
? AnimationStateEnum.update
: AnimationStateEnum.appear;
}
}
};
}
}
// protected _getDefaultStateMap(): IAnimateState & StateValueMap {
// return {
// animationState: {
// callback: (datum: any, g: IMarkGraphic) => {
// return g.context.diffState === 'exit'
// ? AnimationStateEnum.exit
// : g.context.diffState === 'update'
// ? AnimationStateEnum.update
// : AnimationStateEnum.appear;
// }
// }
// };
// }
// }
8 changes: 0 additions & 8 deletions packages/vchart/src/animation/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,6 @@ export interface IAnimateState {
animationState: { callback: (datum: any, element: any) => AnimationStateEnum };
}

export interface IAnimate extends ICompilable {
id: number;
updateAnimateState: (state: AnimationStateEnum, noRender?: boolean) => void;
// TODO: animation control
// pause: () => void;
// resume: () => void;
}

export interface ICartesianGroupAnimationParams {
direction: () => 'x' | 'y';
orient: () => 'positive' | 'negative';
Expand Down
2 changes: 1 addition & 1 deletion packages/vchart/src/compile/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { isMobileLikeMode, isTrueBrowser } from '../util/env';
import { isString } from '../util/type';
import type { IBoundsLike } from '@visactor/vutils';
// eslint-disable-next-line no-duplicate-imports
import { isObject, isValid, Logger, LoggerLevel } from '@visactor/vutils';
import { isObject, isValid } from '@visactor/vutils';
import type { EventSourceType } from '../event/interface';
import type { IChart } from '../chart/interface';
import { createGroup, Stage, vglobal, waitForAllSubLayers } from '@visactor/vrender-core';
Expand Down
14 changes: 0 additions & 14 deletions packages/vchart/src/component/base/base-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import type { IBoundsLike } from '@visactor/vutils';
// eslint-disable-next-line no-duplicate-imports
import { isEqual } from '@visactor/vutils';
import { Event_Source_Type } from '../../constant/event';
import type { IAnimate } from '../../animation/interface';
import { AnimateManager } from '../../animation/animate-manager';
// import { preprocessSpecOrTheme } from '../../util/spec/preprocess';
import type { Datum, ILayoutRect } from '../../typings';
import type { IComponentSpec } from './interface';
Expand Down Expand Up @@ -46,18 +44,6 @@ export class BaseComponent<T extends IComponentSpec = IComponentSpec> extends La
this.pluginService = new ComponentPluginService(this);
}

animate?: IAnimate;

constructor(spec: T, options: IComponentOption) {
super(spec, options);
// 创建组件自己的动画管理器
if (this._option.animation) {
this.animate = new AnimateManager({
getCompiler: options.getCompiler
});
}
}

initLayout(): void {
super.initLayout();
this._regions = this._regions ?? this._option.getRegionsInIndex();
Expand Down
2 changes: 0 additions & 2 deletions packages/vchart/src/component/interface/common.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { ISeriesFilter } from '../../region/interface';
import type { IAnimate } from '../../animation/interface';
import type { ILayoutModel, IModelConstructor, IModelOption, IModelSpecInfo } from '../../model/interface';
// eslint-disable-next-line no-duplicate-imports
import type { IRegion } from '../../region/interface';
Expand Down Expand Up @@ -35,7 +34,6 @@ export interface IComponentOption extends IModelOption {

export interface IComponent extends ILayoutModel {
readonly name: string;
readonly animate?: IAnimate;

// 区域
getRegions: () => IRegion[];
Expand Down
40 changes: 19 additions & 21 deletions packages/vchart/src/core/vchart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ import type { GeoSourceOption } from '../series/map/geo-source';
// eslint-disable-next-line no-duplicate-imports
import { getMapSource } from '../series/map/geo-source';
// eslint-disable-next-line no-duplicate-imports
import type { IMark, MarkConstructor } from '../mark/interface';
import type { IMark, IMarkGraphic, MarkConstructor } from '../mark/interface';
import { registerDataSetInstanceParser, registerDataSetInstanceTransform } from '../data/register';
import { dataToDataView } from '../data/initialize';
import { copyDataView } from '../data/transforms/copy-data-view';
Expand Down Expand Up @@ -773,7 +773,6 @@ export class VChart implements IVChart {
if (this._isReleased) {
return false;
}
this._updateAnimateState();
this._event.emit(ChartEvent.rendered, {
chart: this._chart,
vchart: this
Expand Down Expand Up @@ -823,18 +822,17 @@ export class VChart implements IVChart {
}

private _updateAnimateState(initial?: boolean) {
// todo @feifei
if (this._option.animation) {
const animationState = initial ? AnimationStateEnum.appear : AnimationStateEnum.update;

this._chart?.getAllRegions().forEach(region => {
// region.getAllMarks().forEach(mark => {
const updateGraphicAnimationState = (graphic: IMarkGraphic) => {
const diffState = graphic.context.diffState;
if (initial) {
return diffState === 'exit' ? undefined : AnimationStateEnum.appear;
}
return diffState;
};

// })
region.animate?.updateAnimateState(animationState, true);
});
this._chart?.getAllComponents().forEach(component => {
component.animate?.updateAnimateState(animationState, true);
this._compiler.getRootMarks().forEach(mark => {
mark.updateAnimationState(updateGraphicAnimationState);
});
}
}
Expand Down Expand Up @@ -954,15 +952,15 @@ export class VChart implements IVChart {
return this as unknown as IVChart;
}
if (this._chart) {
if (userUpdateOptions?.reAnimate) {
this.stopAnimation();
this._updateAnimateState(true);
}

this._chart.updateData(id, data, true, parserOptions);

// after layout
this._compiler.render();

if (userUpdateOptions?.reAnimate) {
this.stopAnimation();
this._updateAnimateState(true);
}
return this as unknown as IVChart;
}
this._spec.data = array(this._spec.data);
Expand All @@ -983,13 +981,13 @@ export class VChart implements IVChart {
userUpdateOptions?: IUpdateSpecResult
) {
if (this._chart) {
if (userUpdateOptions?.reAnimate) {
this.stopAnimation();
this._updateAnimateState(true);
}
this._chart.updateFullData(data);
if (reRender) {
this._compiler.render();
if (userUpdateOptions?.reAnimate) {
this.stopAnimation();
this._updateAnimateState(true);
}
}
return this as unknown as IVChart;
}
Expand Down
27 changes: 20 additions & 7 deletions packages/vchart/src/mark/base/base-mark.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { DiffState } from './../interface/enum';
import { type IStateInfo, type IModelMarkAttributeContext, STATE_VALUE_ENUM } from '../../compile/mark/interface';
import type { BaseSeries } from '../../series/base/base-series';
import type {
Expand Down Expand Up @@ -34,7 +35,8 @@ import type {
DiffStateValues,
ProgressiveContext,
IProgressiveTransformResult,
MarkType
MarkType,
AnimationStateValues
} from '../interface';
import { DiffState } from '../interface/enum';
import { GradientType, DEFAULT_GRADIENT_CONFIG } from '../../constant/gradient';
Expand All @@ -57,7 +59,7 @@ import { GrammarItem } from '../../compile/grammar-item';
import { LayoutZIndex } from '../../constant/layout';
import type { IModel } from '../../model/interface';
import type { ICompilableData } from '../../compile/data/interface';
import type { MarkAnimationSpec } from '../../animation/interface';
import { AnimationStateEnum, type MarkAnimationSpec } from '../../animation/interface';
import { CompilableData } from '../../compile/data/compilable-data';
import { log } from '../../util';

Expand Down Expand Up @@ -1126,14 +1128,15 @@ export class BaseMark<T extends ICommonSpec> extends GrammarItem implements IMar
g.context = {
...this._getCommonContext(),
diffState,
// todo @feifei animationState
animationState: diffState,
data: newData,
uniqueKey: key,
key: newData ? this._keyGetter(newData[0]) : g.context?.key,
groupKey: newData ? this._groupKeyGetter(newData[0]) : g.context?.groupKey
};
enterGraphics.delete(g);
}
return g;
};

if (prevGroupedData && newGroupedData) {
Expand All @@ -1152,13 +1155,17 @@ export class BaseMark<T extends ICommonSpec> extends GrammarItem implements IMar
});
} else if (newGroupedData) {
newGroupedData.keys.forEach(key => {
// enter
callback(key, newGroupedData.data.get(key), null);
// appear
const g = callback(key, newGroupedData.data.get(key), null);
if (g) {
g.context.animationState = AnimationStateEnum.appear;
}
});
} else if (prevGroupedData) {
prevGroupedData.keys.forEach(key => {
// exit
callback(key, null, prevGroupedData.data.get(key));
// disappear
const g = callback(key, null, prevGroupedData.data.get(key));
g.context.animationState = AnimationStateEnum.disappear;
});
}

Expand Down Expand Up @@ -1672,4 +1679,10 @@ export class BaseMark<T extends ICommonSpec> extends GrammarItem implements IMar
this._runProgressiveStep();
}
}

updateAnimationState(callback: (graphic: IMarkGraphic) => AnimationStateValues) {
if (this._graphics) {
this._graphics.forEach(g => (g.context.animationState = callback(g)));
}
}
}
8 changes: 7 additions & 1 deletion packages/vchart/src/mark/group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { Maybe } from '../typings';
import { log, warn } from '../util/debug';
import type { IGroupMarkSpec } from '../typings/visual';
import { BaseMark } from './base/base-mark';
import type { IGroupMark, IMark, IMarkGraphic, MarkType } from './interface';
import type { AnimationStateValues, IGroupMark, IMark, IMarkGraphic, MarkType } from './interface';
// eslint-disable-next-line no-duplicate-imports
import { MarkTypeEnum } from './interface/type';
import { type IMarkCompileOption } from '../compile/mark';
Expand Down Expand Up @@ -126,6 +126,12 @@ export class GroupMark extends BaseMark<IGroupMarkSpec> implements IGroupMark {
});
}

updateAnimationState(callback: (g: IMarkGraphic) => AnimationStateValues) {
this.getMarks().forEach(mark => {
mark.updateAnimationState(callback);
});
}

release() {
super.release();
this.removeProduct();
Expand Down
Loading