From e5809046ea46fde228c7e19f11cd3fa57e0dcf87 Mon Sep 17 00:00:00 2001 From: xiaoluoHe Date: Thu, 9 Jan 2025 15:36:09 +0800 Subject: [PATCH 1/3] fix: fix the issue where map drag interaction cannot be terminated outside the canvas --- .../vchart/fix-zoomable-outside_2025-01-09-07-35.json | 10 ++++++++++ packages/vchart/src/interaction/zoom/zoomable.ts | 9 +++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 common/changes/@visactor/vchart/fix-zoomable-outside_2025-01-09-07-35.json diff --git a/common/changes/@visactor/vchart/fix-zoomable-outside_2025-01-09-07-35.json b/common/changes/@visactor/vchart/fix-zoomable-outside_2025-01-09-07-35.json new file mode 100644 index 0000000000..ddc54f5836 --- /dev/null +++ b/common/changes/@visactor/vchart/fix-zoomable-outside_2025-01-09-07-35.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@visactor/vchart", + "comment": "fix: fix the issue where map drag interaction cannot be terminated outside the canvas, #3650", + "type": "none" + } + ], + "packageName": "@visactor/vchart" +} \ No newline at end of file diff --git a/packages/vchart/src/interaction/zoom/zoomable.ts b/packages/vchart/src/interaction/zoom/zoomable.ts index aef175bc5d..3fbee7985f 100644 --- a/packages/vchart/src/interaction/zoom/zoomable.ts +++ b/packages/vchart/src/interaction/zoom/zoomable.ts @@ -473,7 +473,10 @@ export class Zoomable implements IZoomable { } as unknown as BaseEventParams); this._zoomableTrigger.pointerId = null; this._eventObj.off(move, { level: Event_Bubble_Level.chart, source: Event_Source_Type.chart }, mousemove as any); - this._eventObj.off(end, { level: Event_Bubble_Level.chart, source: Event_Source_Type.window }, mouseup as any); + [end, `${end}outside`].forEach(type => { + this._eventObj.off(type, { level: Event_Bubble_Level.chart, source: Event_Source_Type.chart }, mouseup as any); + }); + this._eventObj.allow(end); }, delayTime); @@ -502,6 +505,8 @@ export class Zoomable implements IZoomable { }, delayTime); this._eventObj.on(move, { level: Event_Bubble_Level.chart, source: Event_Source_Type.chart }, mousemove as any); - this._eventObj.on(end, { level: Event_Bubble_Level.chart, source: Event_Source_Type.chart }, mouseup as any); + [end, `${end}outside`].forEach(type => { + this._eventObj.on(type, { level: Event_Bubble_Level.chart, source: Event_Source_Type.chart }, mouseup as any); + }); } } From 5ae3011c819831e18e72c4f53641c615fda68786 Mon Sep 17 00:00:00 2001 From: xiaoluoHe Date: Thu, 9 Jan 2025 16:16:10 +0800 Subject: [PATCH 2/3] fix: fix the issue where pictorial charts cannot zoom in the blank areas of a region --- .../vchart/fix-zoomable-outside_2025-01-09-08-15.json | 10 ++++++++++ packages/vchart/src/region/region.ts | 7 ++++++- 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 common/changes/@visactor/vchart/fix-zoomable-outside_2025-01-09-08-15.json diff --git a/common/changes/@visactor/vchart/fix-zoomable-outside_2025-01-09-08-15.json b/common/changes/@visactor/vchart/fix-zoomable-outside_2025-01-09-08-15.json new file mode 100644 index 0000000000..29d6723bb0 --- /dev/null +++ b/common/changes/@visactor/vchart/fix-zoomable-outside_2025-01-09-08-15.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@visactor/vchart", + "comment": "fix: fix the issue where map drag interaction cannot be terminated outside the canvas.", + "type": "none" + } + ], + "packageName": "@visactor/vchart" +} \ No newline at end of file diff --git a/packages/vchart/src/region/region.ts b/packages/vchart/src/region/region.ts index 1cd6fd8791..a888183f3d 100644 --- a/packages/vchart/src/region/region.ts +++ b/packages/vchart/src/region/region.ts @@ -8,7 +8,7 @@ import { MarkTypeEnum } from '../mark/interface/type'; import type { ISeries } from '../series/interface'; import type { IModelOption } from '../model/interface'; import type { CoordinateType } from '../typings/coordinate'; -import type { IRegion, IRegionSpec, IRegionSpecInfo } from './interface'; +import type { IGeoRegionSpec, IRegion, IRegionSpec, IRegionSpecInfo } from './interface'; import type { IInteraction, ITrigger } from '../interaction/interface'; import { Interaction } from '../interaction/interaction'; import { ChartEvent } from '../constant/event'; @@ -167,6 +167,11 @@ export class Region extends LayoutModel 'normal', AttributeLevel.User_Mark ); + + if ((this._spec as IGeoRegionSpec).roam) { + groupMark.setMarkConfig({ interactive: true }); + } + this._marks.addMark(groupMark); return groupMark; } From 9de801197606acb188a153e2a16ea1c0c20936af Mon Sep 17 00:00:00 2001 From: xiaoluoHe Date: Fri, 10 Jan 2025 15:22:45 +0800 Subject: [PATCH 3/3] fix: region event & event trigger --- .../src/component/common/trigger/config.ts | 4 +- .../vchart/src/interaction/zoom/zoomable.ts | 37 +++++++++++-------- packages/vchart/src/region/region.ts | 8 ++-- 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/packages/vchart/src/component/common/trigger/config.ts b/packages/vchart/src/component/common/trigger/config.ts index 11d0c46ac8..7091fd9291 100644 --- a/packages/vchart/src/component/common/trigger/config.ts +++ b/packages/vchart/src/component/common/trigger/config.ts @@ -10,7 +10,7 @@ export function getDefaultTriggerEventByMode(mode: RenderMode) { return { start: 'pointerdown', move: 'pointermove', - end: 'pointerup', + end: ['pointerup', 'pointerupoutside'], zoom: 'wheel', zoomEnd: 'pointerup', scroll: 'wheel', @@ -23,7 +23,7 @@ export function getDefaultTriggerEventByMode(mode: RenderMode) { return { start: 'pointerdown', move: 'pointermove', - end: 'pointerup', + end: ['pointerup', 'pointerupoutside'], zoom: 'pinch', zoomEnd: 'pinchend', scroll: 'pan', diff --git a/packages/vchart/src/interaction/zoom/zoomable.ts b/packages/vchart/src/interaction/zoom/zoomable.ts index 3fbee7985f..cdef2acdf0 100644 --- a/packages/vchart/src/interaction/zoom/zoomable.ts +++ b/packages/vchart/src/interaction/zoom/zoomable.ts @@ -96,7 +96,7 @@ export class Zoomable implements IZoomable { } // event - private _getZoomTriggerEvent(type: string): EventType { + private _getZoomTriggerEvent(type: string): EventType | EventType[] { return getDefaultTriggerEventByMode(this._renderMode)[type]; } @@ -168,8 +168,8 @@ export class Zoomable implements IZoomable { ? [this._getZoomTriggerEvent('zoom')] : [this._getZoomTriggerEvent('zoom'), { level: Event_Bubble_Level.chart, consume: true }]; const zoomEndParams: [string] | [string, EventQuery] = this._isGestureListener - ? [this._getZoomTriggerEvent('zoomEnd')] - : [this._getZoomTriggerEvent('zoomEnd'), { level: Event_Bubble_Level.chart, consume: false }]; + ? [this._getZoomTriggerEvent('zoomEnd') as string] + : [this._getZoomTriggerEvent('zoomEnd') as string, { level: Event_Bubble_Level.chart, consume: false }]; // pc端没有scrollEnd事件,所以漫游模式下scroll仅支持realTime (event as any).on( ...zoomEndParams, @@ -337,7 +337,7 @@ export class Zoomable implements IZoomable { callback?: (delta: [number, number], e: BaseEventParams['event']) => void, option?: ITriggerOption ) { - eventObj.on(this._getZoomTriggerEvent('start'), { level: Event_Bubble_Level.chart }, (params: any) => { + eventObj.on(this._getZoomTriggerEvent('start') as string, { level: Event_Bubble_Level.chart }, (params: any) => { if (!params.event) { return; } @@ -376,7 +376,7 @@ export class Zoomable implements IZoomable { } if (getDefaultTriggerEventByMode(this._renderMode)) { s.event.on( - this._getZoomTriggerEvent('start'), + this._getZoomTriggerEvent('start') as string, { level: Event_Bubble_Level.model, filter: ({ model }) => model?.id === s.id }, params => { this._handleDrag(params, callback, option); @@ -400,7 +400,7 @@ export class Zoomable implements IZoomable { r.getSeries().forEach(s => { if (filter(s)) { s.event.on( - this._getZoomTriggerEvent('start'), + this._getZoomTriggerEvent('start') as string, { level: Event_Bubble_Level.model, filter: ({ model }) => model?.id === s.id }, params => { this._handleDrag(params, callback); @@ -445,8 +445,8 @@ export class Zoomable implements IZoomable { const delayType = option?.delayType ?? 'throttle'; const delayTime = option?.delayTime ?? 0; const realTime = option?.realTime ?? true; - const move = this._getZoomTriggerEvent('move'); - const end = this._getZoomTriggerEvent('end'); + const move = this._getZoomTriggerEvent('move') as string; + const end = this._getZoomTriggerEvent('end') as string[]; const event = params.event; let moveX = event.canvasX; let moveY = event.canvasY; @@ -473,11 +473,14 @@ export class Zoomable implements IZoomable { } as unknown as BaseEventParams); this._zoomableTrigger.pointerId = null; this._eventObj.off(move, { level: Event_Bubble_Level.chart, source: Event_Source_Type.chart }, mousemove as any); - [end, `${end}outside`].forEach(type => { - this._eventObj.off(type, { level: Event_Bubble_Level.chart, source: Event_Source_Type.chart }, mouseup as any); + end.forEach(endEventType => { + this._eventObj.off( + endEventType, + { level: Event_Bubble_Level.chart, source: Event_Source_Type.chart }, + mouseup as any + ); + this._eventObj.allow(endEventType); }); - - this._eventObj.allow(end); }, delayTime); const mousemove = delayMap[delayType]((params: BaseEventParams) => { @@ -485,7 +488,7 @@ export class Zoomable implements IZoomable { return; } this._clickEnable = false; - this._eventObj.prevent(end, mouseup as any); + end.forEach(endEventType => this._eventObj.prevent(endEventType, mouseup as any)); const event = params.event; const dx = event.canvasX - moveX; @@ -505,8 +508,12 @@ export class Zoomable implements IZoomable { }, delayTime); this._eventObj.on(move, { level: Event_Bubble_Level.chart, source: Event_Source_Type.chart }, mousemove as any); - [end, `${end}outside`].forEach(type => { - this._eventObj.on(type, { level: Event_Bubble_Level.chart, source: Event_Source_Type.chart }, mouseup as any); + end.forEach(endEventType => { + this._eventObj.on( + endEventType, + { level: Event_Bubble_Level.chart, source: Event_Source_Type.chart }, + mouseup as any + ); }); } } diff --git a/packages/vchart/src/region/region.ts b/packages/vchart/src/region/region.ts index a888183f3d..0f4dd2a2bf 100644 --- a/packages/vchart/src/region/region.ts +++ b/packages/vchart/src/region/region.ts @@ -108,6 +108,10 @@ export class Region extends LayoutModel super.created(); const clip = this._spec.clip ?? this._getClipDefaultValue(); this._groupMark = this._createGroupMark('regionGroup', this.userId, this.layoutZIndex); + if ((this._spec as IGeoRegionSpec).roam) { + this._groupMark.setMarkConfig({ interactive: true }); + } + // 交互层 this._interactionMark = this._createGroupMark( 'regionInteractionGroup', @@ -168,10 +172,6 @@ export class Region extends LayoutModel AttributeLevel.User_Mark ); - if ((this._spec as IGeoRegionSpec).roam) { - groupMark.setMarkConfig({ interactive: true }); - } - this._marks.addMark(groupMark); return groupMark; }