diff --git a/packages/vchart-extension/src/components/extension-mark-sync-state/extension-mark-sync-state.ts b/packages/vchart-extension/src/components/extension-mark-sync-state/extension-mark-sync-state.ts index 4ba8cb81ff..d90c3dd5a0 100644 --- a/packages/vchart-extension/src/components/extension-mark-sync-state/extension-mark-sync-state.ts +++ b/packages/vchart-extension/src/components/extension-mark-sync-state/extension-mark-sync-state.ts @@ -2,8 +2,8 @@ * @description ExtensionMark SyncState 插件 * * 将配置了 syncState: true 的 extensionMark 的 graphics 与主 mark 的 graphics - * 通过 context.key 配对,在 afterRender 回调中将主 mark 的当前状态同步到 - * extensionMark graphic。 + * 通过 context.key 配对,在 beforeRender 回调中将主 mark 的当前状态同步到 + * extensionMark graphic,确保扩展 mark 在当前帧绘制前拿到最新状态。 */ import { type IChartPlugin, @@ -18,6 +18,7 @@ import { registerChartPlugin, isValid } from '@visactor/vchart'; +import type { IStage } from '@visactor/vrender-core'; import type { IExtensionMarkSpecWithSyncState } from './type'; const EXTENSION_MARK_SYNC_STATE_PLUGIN_TYPE = 'ExtensionMarkSyncStatePlugin'; @@ -29,8 +30,12 @@ export class ExtensionMarkSyncStatePlugin extends BasePlugin void; + /** 取消 beforeRender 订阅的函数,release 时调用 */ + private _unsubscribeBeforeRender?: () => void; /** 已订阅的 event 实例,chart reMake 后会更换 */ private _subscribedEvent?: IEvent; + /** 已订阅的 stage 实例,chart reMake 后会更换 */ + private _subscribedStage?: IStage; constructor() { super(EXTENSION_MARK_SYNC_STATE_PLUGIN_TYPE); @@ -38,6 +43,8 @@ export class ExtensionMarkSyncStatePlugin extends BasePlugin this._syncStates(); + // 首次 render 后 stage 才一定存在;后续 reMake 若替换 stage,也通过该事件重新挂载 beforeRender。 + const handler = () => this._ensureBeforeRenderSyncHook(); event.on(ChartEvent.afterRender, handler); this._subscribedEvent = event; this._unsubscribeAfterRender = () => { @@ -65,9 +75,33 @@ export class ExtensionMarkSyncStatePlugin extends BasePlugin this._syncStates(); + stage.hooks.beforeRender.tap(this.name, handler); + this._subscribedStage = stage; + this._unsubscribeBeforeRender = () => { + stage.hooks.beforeRender.unTap(this.name); + this._subscribedStage = undefined; + }; + } + /** 检测 chartSpec 中是否存在配置了 syncState 的 extensionMark */ private _detectSyncState(chartSpec: any): boolean { const seriesSpecs = chartSpec?.series;