diff --git a/common/changes/@visactor/vstory-player/feat-vchart-hightlight-action_2024-12-16-11-53.json b/common/changes/@visactor/vstory-player/feat-vchart-hightlight-action_2024-12-16-11-53.json new file mode 100644 index 00000000..cc596e4d --- /dev/null +++ b/common/changes/@visactor/vstory-player/feat-vchart-hightlight-action_2024-12-16-11-53.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@visactor/vstory-player", + "comment": "feat: support highlight action for vchart", + "type": "none" + } + ], + "packageName": "@visactor/vstory-player" +} \ No newline at end of file diff --git a/packages/vstory-player/src/processor/chart/highlight.ts b/packages/vstory-player/src/processor/chart/highlight.ts new file mode 100644 index 00000000..0ca9f46c --- /dev/null +++ b/packages/vstory-player/src/processor/chart/highlight.ts @@ -0,0 +1,56 @@ +import { globalProcessorRegistry, type ICharacter, CharacterType } from '@visactor/vstory-core'; +import type { IVChart } from '@visactor/vchart'; +import type { IChartHighlightPayload, IChartHighlightAction } from './interface'; +import { VChartBaseActionProcessor } from './base'; +import { ACTION_TYPE } from '../constants/action'; + +export class VChartHighlightActionProcessor extends VChartBaseActionProcessor { + name: 'highlight'; + + constructor() { + super(); + } + + run(character: ICharacter, actionSpec: IChartHighlightAction): void { + super.preRun(character, actionSpec); + const instance = (character.graphic as any)._vchart as IVChart; + if (!instance) { + return; + } + + const { payload } = actionSpec as IChartHighlightAction; + const { value, animation, style = {} } = payload as IChartHighlightPayload; + const isDatumEqual = (inputValue: any, elementDatum: any) => + Object.keys(inputValue).every(key => inputValue[key] === elementDatum[key]); + const channel = {}; + + Object.keys(style).forEach(key => { + channel[key] = { + to: style[key] + }; + }); + instance + .getChart() + .getAllMarks() + .forEach(mark => { + if (mark.getAnimationConfig()) { + mark.getProduct().animate?.run({ + timeSlices: { + effects: { + channel, + easing: animation.easing + }, + duration: animation?.duration ?? 0 + }, + partitioner: datum => isDatumEqual(value, datum) + }); + } + }); + } +} + +export function registerVChartHighlightAction() { + globalProcessorRegistry.registerProcessor(CharacterType.VCHART, { + [ACTION_TYPE.HIGHLIGHT]: new VChartHighlightActionProcessor() + }); +} diff --git a/packages/vstory-player/src/processor/chart/index.ts b/packages/vstory-player/src/processor/chart/index.ts index ae15f004..80a78aeb 100644 --- a/packages/vstory-player/src/processor/chart/index.ts +++ b/packages/vstory-player/src/processor/chart/index.ts @@ -2,6 +2,7 @@ export { registerVChartAddAction } from './add'; export { registerVChartUpdateAction } from './update'; export { registerVChartVisibilityAction } from './visibility'; import { registerVChartAddAction } from './add'; +import { registerVChartHighlightAction } from './highlight'; import { registerRankingBarPlayAction, registerRankingBarVisibilityAction } from './rankingBar/rankingBar'; import { registerScatterBarVisibilityAction } from './scatterBar/visibility'; import { registerVChartUpdateAction } from './update'; @@ -10,6 +11,7 @@ import { registerWaveScatterVisibilityAction } from './waveScatter/visibility'; export function registerVChartAction() { registerVChartAddAction(); + registerVChartHighlightAction(); registerVChartUpdateAction(); registerVChartVisibilityAction(); registerWaveScatterVisibilityAction(); diff --git a/packages/vstory-player/src/processor/chart/interface.ts b/packages/vstory-player/src/processor/chart/interface.ts index 5c97e5c1..7951d67a 100644 --- a/packages/vstory-player/src/processor/chart/interface.ts +++ b/packages/vstory-player/src/processor/chart/interface.ts @@ -50,3 +50,16 @@ export interface IChartUpdatePayload extends IActionPayload { export interface IChartUpdateAction extends IAction { action: 'update'; } + +/************ Highlight **************/ +export interface IChartHighlightPayload extends IActionPayload { + value: Datum; + id: string | number; + style: { + [key: string]: number | string; + }; +} + +export interface IChartHighlightAction extends IAction { + action: 'highlight'; +} diff --git a/packages/vstory-player/src/processor/constants/action.ts b/packages/vstory-player/src/processor/constants/action.ts index 9ca703c9..47990c3b 100644 --- a/packages/vstory-player/src/processor/constants/action.ts +++ b/packages/vstory-player/src/processor/constants/action.ts @@ -8,5 +8,6 @@ export const ACTION_TYPE = { BOUNCE: 'bounce', PLAY: 'play', UPDATE: 'update', - ADD: 'add' + ADD: 'add', + HIGHLIGHT: 'highlight' }; diff --git a/packages/vstory-player/tsconfig.json b/packages/vstory-player/tsconfig.json index cf7f5ce7..7a500b93 100644 --- a/packages/vstory-player/tsconfig.json +++ b/packages/vstory-player/tsconfig.json @@ -8,5 +8,9 @@ "composite": true }, "include": ["src"], - "references": [] + "references": [ + { + "path": "../vstory-core" + } + ] } diff --git a/packages/vstory/demo/src/demos/arrange/Pie1.tsx b/packages/vstory/demo/src/demos/arrange/Pie1.tsx index 7331051f..89e58023 100644 --- a/packages/vstory/demo/src/demos/arrange/Pie1.tsx +++ b/packages/vstory/demo/src/demos/arrange/Pie1.tsx @@ -97,6 +97,21 @@ export const Pie1 = () => { ] } }, + { + action: 'highlight', + startTime: 4000, + payload: { + animation: { + duration: 200, + easing: 'bounceOut' + }, + value: { type: 'shebao', value: '4.6' }, + style: { + fill: 'red', + outerRadius: 260 + } + } + }, { action: 'update', startTime: 5500, @@ -141,7 +156,6 @@ export const Pie1 = () => { story.init(player); console.log(story); player.play(0); - exportVideo(story); return () => {