Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -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"
}
1 change: 1 addition & 0 deletions packages/vchart/src/compile/mark/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export interface IMarkStateManager {
addStateInfo: (stateInfo: IStateInfo) => void;
changeStateInfo: (stateInfo: Partial<IStateInfo>) => 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;
Expand Down
4 changes: 4 additions & 0 deletions packages/vchart/src/compile/mark/mark-state-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
13 changes: 13 additions & 0 deletions packages/vchart/src/mark/base/base-mark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1087,7 +1087,11 @@ export class BaseMark<T extends ICommonSpec> extends GrammarItem implements IMar
return;
}
this._product = mark.getProduct();
this._product.clearStates();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BaseMark.reuse 中无条件清理 states 会导致交互态(hover/select 等)在非 updateSpec 路径(如常规 compile)中被重置。建议确认是否应将清理逻辑更精准地收敛在 reInit/updateSpec 相关路径。

this._graphics = mark.getGraphics();
this._graphics.forEach(g => {
g.clearStates();
});
this._graphicMap = (mark as any)._graphicMap;

this._graphicMap.forEach(g => {
Expand Down Expand Up @@ -2056,4 +2060,13 @@ export class BaseMark<T extends ICommonSpec> extends GrammarItem implements IMar
runAnimation() {
this._runStateAnimation(this.getGraphics());
}

clearBeforeReInit() {
this.state.clearAllStateInfo();
this.uncommit();
this.stateStyle = {};
this.getGraphics().forEach(g => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clearBeforeReInit 目前只对 getGraphics() 返回的图元调用了 clearStates(),但不会清理 mark 的 _product(group)与 _graphicMap 上已有的 states。建议在重载前同时清理这些对象的 states,避免 state 写入时产生残留。

参考建议

clearBeforeReInit() {
  this.state.clearAllStateInfo();
  this.uncommit();
  this.stateStyle = {};

  this._product?.clearStates();
  this._graphics.forEach(g => {
    g.clearStates();
  });
  this._graphicMap.forEach(g => {
    g.clearStates();
  });
}

g.clearStates();
});
}
}
2 changes: 2 additions & 0 deletions packages/vchart/src/mark/interface/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,8 @@ export interface IMarkRaw<T extends ICommonSpec> extends ICompilableMark {
disableAnimationByState: (state: string | string[]) => void;
/** 启用状态动画 */
enableAnimationByState: (state: string | string[]) => void;
/** 重新加载前清除缓存 */
clearBeforeReInit: () => void;
}

export type IMark = IMarkRaw<ICommonSpec>;
Expand Down
1 change: 1 addition & 0 deletions packages/vchart/src/series/base/base-series.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1109,6 +1109,7 @@ export abstract class BaseSeries<T extends ISeriesSpec> extends BaseModel<T> 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();
Expand Down
25 changes: 25 additions & 0 deletions specs/009-fix-issue-of-mark-state-when-updateSpec/plan.md
Original file line number Diff line number Diff line change
@@ -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.
Loading