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-map-roam-pointer-drag: This plan fixes a map roam drag bug where mobile browsers lose stable vertical dragging after supportsTouchEvents is forced to false",
"type": "none",
"packageName": "@visactor/vchart"
}
],
"packageName": "@visactor/vchart",
"email": "lixuef1313@163.com"
}
34 changes: 34 additions & 0 deletions packages/vchart/src/compile/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,38 @@ export class Compiler implements ICompiler {
this._compileChart?.getEvent()?.emit(ChartEvent.afterRender, { chart: this._compileChart });
};

private _isGeoRegionRoamDragEnabled() {
const chartSpec = this._compileChart?.getSpec?.();
const regions = chartSpec?.region;
if (!isArray(regions)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

在 VChart 中,spec.region 可以是数组,也可以是单个对象。这里建议使用 const regionList = isArray(regions) ? regions : [regions] 并进行判空,以支持单 Region 的场景。

return false;
}

return regions.some((region: any) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

建议使用具体的 Spec 类型(如 IRegionSpec)代替 any,以对齐仓库的类型安全标准。

if (region?.coordinate !== 'geo' || !region.roam) {
return false;
}

if (region.roam === true) {
return true;
}

return region.roam.drag ?? true;
});
}

private _shouldDisableCanvasTouchAction() {
if (!isTrueBrowser(this._option.mode)) {
return false;
}

const supportsTouchEvents = isValid(this._option.supportsTouchEvents)
? this._option.supportsTouchEvents
: vglobal.supportsTouchEvents;

return supportsTouchEvents === false && this._isGeoRegionRoamDragEnabled();
}

private _setCanvasStyle() {
if (!this._stage) {
return;
Expand All @@ -234,6 +266,7 @@ export class Compiler implements ICompiler {
const canvas = this.getCanvas();
if (canvas) {
canvas.style.display = 'block';
canvas.style.touchAction = this._shouldDisableCanvasTouchAction() ? 'none' : '';
}
}
}
Expand All @@ -256,6 +289,7 @@ export class Compiler implements ICompiler {
}

chart.compile();
this._setCanvasStyle();
chart.afterCompile();
}
protected clearNextRender() {
Expand Down
26 changes: 26 additions & 0 deletions specs/009-fix-map-roam-pointer-drag/checklists/requirements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Specification Quality Checklist: Fix Map Roam Drag in Pointer-Only Mobile Browsers

**Purpose**: Validate specification completeness and quality before delivery
**Created**: 2026-03-19
**Feature**: [spec.md](../spec.md)

## Content Quality

- [x] No unnecessary implementation detail beyond delivery-critical context
- [x] Focused on user-visible behavior and constraints
- [x] Written clearly enough for downstream release artifacts
- [x] All mandatory sections completed

## Requirement Completeness

- [x] No `[NEEDS CLARIFICATION]` markers remain
- [x] Requirements are testable and unambiguous
- [x] Success criteria are measurable
- [x] Edge cases are identified
- [x] Scope is clearly bounded

## Feature Readiness

- [x] Functional requirements map to the implemented bug fix
- [x] User scenario covers the affected interaction path
- [x] The feature is ready for changelog, commit, and PR generation
59 changes: 59 additions & 0 deletions specs/009-fix-map-roam-pointer-drag/plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Implementation Plan: Fix Map Roam Drag in Pointer-Only Mobile Browsers

**Branch**: `009-fix-map-roam-pointer-drag` | **Date**: 2026-03-19 | **Spec**: [spec.md](./spec.md)
**Input**: Feature specification from `/specs/009-fix-map-roam-pointer-drag/spec.md`

## Summary

This plan fixes a map roam drag bug where mobile browsers lose stable vertical dragging after `supportsTouchEvents` is forced to `false`, because the browser's default touch gesture handling interrupts pointer-based drag sequences for geo roam regions.

## Technical Context

**Language/Version**: TypeScript 4.x
**Primary Dependencies**:
- `@visactor/vrender-core`: Provides stage, canvas access, and global environment capability flags.
- `@visactor/vutils`: Provides utility helpers already used by the compiler layer.
**Storage**: N/A
**Testing**: No new automated test is required for this change.
**Target Platform**: Browser rendering, especially mobile browsers using pointer events without touch events.
**Project Type**: Visualization Library (Monorepo)
**Performance Goals**: No regression in render or interaction performance.
**Constraints**: Must only affect geo roam drag scenarios and must not globally disable page scroll for unrelated charts.
**Scale/Scope**: Compiler-level canvas style adjustment for map roam interaction.

## Constitution Check

- [x] Quality First: Fix is isolated to the browser interaction environment for the affected scenario.
- [x] User Experience-Driven: Removes a broken drag path in a valid mobile embedding scenario.
- [x] SDD: Uses specs as the semantic source for delivery artifacts.
- [x] Unit Tests: Not required for this change by request.
- [x] Compatibility: Non-breaking fix (PATCH).

## Project Structure

### Documentation (this feature)

```text
specs/009-fix-map-roam-pointer-drag/
├── plan.md
├── spec.md
└── checklists/
└── requirements.md
```

### Source Code (repository root)

```text
packages/vchart/
├── src/
│ └── compile/
│ └── compiler.ts
└── specs/
└── 009-fix-map-roam-pointer-drag/
├── plan.md
├── spec.md
└── checklists/
└── requirements.md
```

**Structure Decision**: Update the compiler canvas style handling in `packages/vchart/src/compile/compiler.ts` and describe the change in a dedicated spec directory for downstream changelog, commit, and PR generation.
36 changes: 36 additions & 0 deletions specs/009-fix-map-roam-pointer-drag/spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Feature Specification: Fix Map Roam Drag in Pointer-Only Mobile Browsers

**Feature Branch**: `009-fix-map-roam-pointer-drag`
**Created**: 2026-03-19
**Status**: Draft

## Summary

Fix a map interaction bug where dragging a roam-enabled map fails on mobile browsers when VChart is configured to use pointer events without touch events.

## User Scenarios

### Primary User Story

As a VChart user embedding a roam-enabled map in a mobile web page, I want vertical and horizontal dragging to remain stable when `supportsTouchEvents` is disabled, so that the map can still be panned reliably in pointer-only environments.

## Requirements

### Functional Requirements

1. The map component MUST support stable drag roaming on mobile browsers when `VChart.vglobal.supportsTouchEvents` is set to `false`.
2. The fix MUST prevent the browser's default touch gesture handling from interrupting map drag sequences when a geo region enables roam dragging.
3. The fix MUST preserve existing drag behavior for roam-enabled geo maps in normal browser rendering.
4. The fix MUST NOT change interaction behavior for charts that are not geo roam drag scenarios.

### Edge Cases

1. When a geo region disables `roam.drag`, the browser's default touch behavior should remain unchanged.
2. When a chart does not use geo regions, the fix should not alter canvas touch handling.
3. When roam is toggled by spec updates, the canvas touch handling should reflect the latest spec state.

## Success Criteria

1. In pointer-only mobile browser mode, initial vertical dragging on a roam-enabled map no longer enters a broken partial-drag state.
2. Horizontal and vertical panning both work consistently without requiring a prior horizontal gesture.
3. Non-map or non-roam charts keep their existing page scrolling behavior.
Loading