diff --git a/common/changes/@visactor/vchart/fix-event-prevent-level_2025-03-26-10-08.json b/common/changes/@visactor/vchart/fix-event-prevent-level_2025-03-26-10-08.json new file mode 100644 index 0000000000..c516804b74 --- /dev/null +++ b/common/changes/@visactor/vchart/fix-event-prevent-level_2025-03-26-10-08.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@visactor/vchart", + "comment": " fix: fix the bubble level issue prevented by event.prevent, #3728", + "type": "none" + } + ], + "packageName": "@visactor/vchart" +} \ No newline at end of file diff --git a/packages/vchart/src/constant/event.ts b/packages/vchart/src/constant/event.ts index 87cff18dae..c5d3673507 100644 --- a/packages/vchart/src/constant/event.ts +++ b/packages/vchart/src/constant/event.ts @@ -126,3 +126,11 @@ export enum Event_Bubble_Level { model = 'model', mark = 'mark' } + +// 事件冒泡逻辑:Mark -> Model -> Chart -> VChart +export const EventBubbleLevels = [ + Event_Bubble_Level.mark, + Event_Bubble_Level.model, + Event_Bubble_Level.chart, + Event_Bubble_Level.vchart +]; diff --git a/packages/vchart/src/event/event-dispatcher.ts b/packages/vchart/src/event/event-dispatcher.ts index 124c071742..16eb693c58 100644 --- a/packages/vchart/src/event/event-dispatcher.ts +++ b/packages/vchart/src/event/event-dispatcher.ts @@ -1,6 +1,12 @@ import { Bubble } from './bubble'; import { isValid, debounce, throttle, get, isFunction } from '@visactor/vutils'; -import { BASE_EVENTS, Event_Bubble_Level, Event_Source_Type, VGRAMMAR_HOOK_EVENT } from '../constant/event'; +import { + BASE_EVENTS, + Event_Bubble_Level, + Event_Source_Type, + VGRAMMAR_HOOK_EVENT, + EventBubbleLevels as levels +} from '../constant/event'; import type { EventType, EventQuery, @@ -152,12 +158,6 @@ export class EventDispatcher implements IEventDispatcher { const handlers = bubble.getHandlers(level); stopBubble = this._invoke(handlers, eType, params); } else { - const levels = [ - Event_Bubble_Level.mark, - Event_Bubble_Level.model, - Event_Bubble_Level.chart, - Event_Bubble_Level.vchart - ]; let i = 0; // Mark 级别的事件只包含对语法层代理的基础事件 @@ -170,14 +170,28 @@ export class EventDispatcher implements IEventDispatcher { return this; } - prevent(eType: Evt, except?: EventCallback): this { - const eventTypes = ['canvas', 'chart', 'window'] as EventSourceType[]; - eventTypes.forEach(type => { + prevent( + eType: Evt, + except?: { + handler: EventCallback; + level: EventBubbleLevel; + } + ): this { + const eventSourceTypes = ['canvas', 'chart', 'window'] as EventSourceType[]; + eventSourceTypes.forEach(type => { const bubble = this.getEventBubble(type).get(eType); if (bubble) { bubble.getAllHandlers().forEach(handler => { - if (!except || handler.callback !== except) { + if (!except) { bubble.preventHandler(handler); + } else if ( + // 只能 prevent 比当前 level 更低的事件 + (levels as EventBubbleLevel[]).indexOf(handler.filter.level) < + (levels as EventBubbleLevel[]).indexOf(except.level) + ) { + if (handler.callback !== except.handler) { + bubble.preventHandler(handler); + } } }); } diff --git a/packages/vchart/src/event/interface.ts b/packages/vchart/src/event/interface.ts index 9fd9bd18ab..f0c10e626a 100644 --- a/packages/vchart/src/event/interface.ts +++ b/packages/vchart/src/event/interface.ts @@ -317,7 +317,13 @@ export interface IEventDispatcher { dispatch: (eType: Evt, params?: EventParamsDefinition[Evt], level?: EventBubbleLevel) => this; clear: () => void; release: () => void; - prevent: (eType: Evt, except: EventCallback) => void; + prevent: ( + eType: Evt, + except?: { + handler: EventCallback; + level: EventBubbleLevel; + } + ) => void; allow: (eType: Evt) => void; } @@ -338,7 +344,13 @@ export interface IEvent { release: () => void; getComposedEventMap: () => Map, { eventType: EventType; event: IComposedEvent }>; - prevent: (eType: Evt, except: EventCallback) => void; + prevent: ( + eType: Evt, + except?: { + handler: EventCallback; + level: EventBubbleLevel; + } + ) => void; allow: (eType: Evt) => void; } diff --git a/packages/vchart/src/interaction/zoom/zoomable.ts b/packages/vchart/src/interaction/zoom/zoomable.ts index 989344b438..505854a424 100644 --- a/packages/vchart/src/interaction/zoom/zoomable.ts +++ b/packages/vchart/src/interaction/zoom/zoomable.ts @@ -538,7 +538,12 @@ export class Zoomable implements IZoomable { return; } this._clickEnable = false; - end.forEach(endEventType => this._eventObj.prevent(endEventType, this._handleDragMouseUp as any)); + end.forEach(endEventType => { + this._eventObj.prevent(endEventType, { + handler: this._handleDragMouseUp as any, + level: Event_Bubble_Level.chart // 这里的level 与下面 end 事件的默认 level 一致 + }); + }); const event = params.event; const dx = event.canvasX - moveX;