diff --git a/common/changes/@visactor/vchart/feat-fix-issue-of-mark-state-when-updateSpec_2026-03-17-06-14.json b/common/changes/@visactor/vchart/feat-fix-issue-of-mark-state-when-updateSpec_2026-03-17-06-14.json new file mode 100644 index 0000000000..fb73222957 --- /dev/null +++ b/common/changes/@visactor/vchart/feat-fix-issue-of-mark-state-when-updateSpec_2026-03-17-06-14.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "comment": "update changes for 009-fix-issue-of-mark-state-when-updateSpec: Fix an issue where mark states were not properly cleared when updateSpec was called, causing incorrect state persistence.", + "type": "none", + "packageName": "@visactor/vchart" + } + ], + "packageName": "@visactor/vchart", + "email": "lixuef1313@163.com" +} \ No newline at end of file diff --git a/packages/vchart/src/compile/mark/interface.ts b/packages/vchart/src/compile/mark/interface.ts index 01c0568fca..b1c26c9435 100644 --- a/packages/vchart/src/compile/mark/interface.ts +++ b/packages/vchart/src/compile/mark/interface.ts @@ -64,6 +64,7 @@ export interface IMarkStateManager { addStateInfo: (stateInfo: IStateInfo) => void; changeStateInfo: (stateInfo: Partial) => void; clearStateInfo: (stateValues: StateValue[]) => void; + clearAllStateInfo: () => void; checkOneState: (renderNode: IMarkGraphic, datum: Datum[], state: IStateInfo) => 'in' | 'out' | 'skip'; checkState: (renderNode: IMarkGraphic, datum: Datum[]) => StateValue[]; getStateMap: () => StateValueMap; diff --git a/packages/vchart/src/compile/mark/mark-state-manager.ts b/packages/vchart/src/compile/mark/mark-state-manager.ts index c7d1d065bf..1374d48ef2 100644 --- a/packages/vchart/src/compile/mark/mark-state-manager.ts +++ b/packages/vchart/src/compile/mark/mark-state-manager.ts @@ -123,6 +123,10 @@ export class MarkStateManager extends StateManager implements IMarkStateManager }); } + clearAllStateInfo() { + this._stateInfoList = []; + } + protected _isMultiMark() { return !this._mark || isMultiDatumMark(this._mark.type as MarkTypeEnum); } diff --git a/packages/vchart/src/mark/base/base-mark.ts b/packages/vchart/src/mark/base/base-mark.ts index 7765d236ca..5be19dcc09 100644 --- a/packages/vchart/src/mark/base/base-mark.ts +++ b/packages/vchart/src/mark/base/base-mark.ts @@ -1087,7 +1087,11 @@ export class BaseMark extends GrammarItem implements IMar return; } this._product = mark.getProduct(); + this._product.clearStates(); this._graphics = mark.getGraphics(); + this._graphics.forEach(g => { + g.clearStates(); + }); this._graphicMap = (mark as any)._graphicMap; this._graphicMap.forEach(g => { @@ -2056,4 +2060,13 @@ export class BaseMark extends GrammarItem implements IMar runAnimation() { this._runStateAnimation(this.getGraphics()); } + + clearBeforeReInit() { + this.state.clearAllStateInfo(); + this.uncommit(); + this.stateStyle = {}; + this.getGraphics().forEach(g => { + g.clearStates(); + }); + } } diff --git a/packages/vchart/src/mark/interface/common.ts b/packages/vchart/src/mark/interface/common.ts index 9ead7699d6..56df36e444 100644 --- a/packages/vchart/src/mark/interface/common.ts +++ b/packages/vchart/src/mark/interface/common.ts @@ -246,6 +246,8 @@ export interface IMarkRaw extends ICompilableMark { disableAnimationByState: (state: string | string[]) => void; /** 启用状态动画 */ enableAnimationByState: (state: string | string[]) => void; + /** 重新加载前清除缓存 */ + clearBeforeReInit: () => void; } export type IMark = IMarkRaw; diff --git a/packages/vchart/src/series/base/base-series.ts b/packages/vchart/src/series/base/base-series.ts index 725e6bc791..5214cbbf02 100644 --- a/packages/vchart/src/series/base/base-series.ts +++ b/packages/vchart/src/series/base/base-series.ts @@ -1109,6 +1109,7 @@ export abstract class BaseSeries extends BaseModel imp const marks = this.getMarksWithoutRoot(); // FIXME: 合并 mark spec 的时机是否需要统一调整到 this.initMarkStyle() 中? marks.forEach(mark => { + mark.clearBeforeReInit(); (this._spec as any)[mark.name] && this.initMarkStyleWithSpec(mark, (this._spec as any)[mark.name]); }); this.initMarkStyle(); diff --git a/specs/009-fix-issue-of-mark-state-when-updateSpec/plan.md b/specs/009-fix-issue-of-mark-state-when-updateSpec/plan.md new file mode 100644 index 0000000000..d25d86b062 --- /dev/null +++ b/specs/009-fix-issue-of-mark-state-when-updateSpec/plan.md @@ -0,0 +1,25 @@ +# Implementation Plan: Fix mark state issue during updateSpec + +## Summary +Fix an issue where mark states were not properly cleared when `updateSpec` was called, causing incorrect state persistence. + +## Technical Context +The `updateSpec` process re-initializes marks but previous state information was lingering. +Changes include: +- Added `clearAllStateInfo` method to `IMarkStateManager` interface and implementation. +- Added `clearBeforeReInit` method to `IMarkRaw` interface and implementation. +- Invoked `clearBeforeReInit` in `BaseMark` during re-initialization. +- Updated `BaseSeries` to handle state cleanup during spec updates. + +### Source Code (repository root) +``` +packages/vchart/src/compile/mark/interface.ts +packages/vchart/src/compile/mark/mark-state-manager.ts +packages/vchart/src/mark/base/base-mark.ts +packages/vchart/src/mark/interface/common.ts +packages/vchart/src/series/base/base-series.ts +``` + +## Verification Plan +- Verify that mark states (e.g., hover, select) are reset correctly after `updateSpec`. +- Ensure no regression in normal state interactions.