8000 Fix/brush and datazoom problem by skie1997 · Pull Request #1853 · VisActor/VRender · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Fix/brush and datazoom problem #1853

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 9, 2025
Merged
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,10 @@
{
"changes": [
{
"packageName": "@visactor/vrender-components",
"comment": "fix: brush active problem. fix visactor/vchart#4017",
"type": "none"
}
],
"packageName": "@visactor/vrender-components"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@visactor/vrender-components",
"comment": "fix: brush event pos problem when stage scale",
"type": "none"
}
],
"packageName": "@visactor/vrender-components"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@visactor/vrender-components",
"comment": "fix: use removeAllChild to remove brush mask. fix visactor/vchart#4017",
"type": "none"
}
],
"packageName": "@visactor/vrender-components"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@visactor/vrender-components",
"comment": "fix: datazoom text render error. fix visactor/vchart#4018",
"type": "none"
}
],
"packageName": "@visactor/vrender-components"
}
42 changes: 18 additions & 24 deletions packages/vrender-components/src/brush/brush.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export class Brush extends AbstractComponent<Required<BrushAttributes>> {
private _container!: IGroup;

// 绘制mask时的相关属性
private _activeBrushState = false; // 用于标记激活状态
private _activeDrawState = false; // 用于标记绘制状态
private _cacheDrawPoints: IPointLike[] = []; // 用于维护鼠标走过的路径,主要用于绘制mask的点
// 移动mask时的相关属性
Expand Down Expand Up @@ -67,18 +68,10 @@ export class Brush extends AbstractComponent<Required<BrushAttributes>> {
* @description
* 1. 判断状态: 如果在brushMask中,则属于移动状态; 否则属于绘制状态
*(移动状态和绘制状态互斥, 且移动状态考虑brushMoved配置, 如果在brush点内但brushMoved为false, 则走绘制状态, 而非两个状态都不响应, 此效果与echarts保持一致)
* 2. 判断坐标是否在有效交互范围内
* 2. 如果是移动状态: 标记移动状态 & 标记正在移动的mask & 初始化mask的dx和dy
* 3. 如果是绘制状态: 标记绘制状态 & 标记正在绘制的mask & 清除之前的mask & 添加新的mask
*/
private _onBrushStart = (e: FederatedPointerEvent) => {
if (this._outOfInteractiveRange(e)) {
if (!this._isEmptyMask()) {
this._clearMask();
this._dispatchBrushEvent(IOperateType.brushClear, e);
}
return;
}
const {
updateTrigger = DEFAULT_BRUSH_ATTRIBUTES.updateTrigger,
endTrigger = DEFAULT_BRUSH_ATTRIBUTES.endTrigger,
Expand Down Expand Up @@ -157,12 +150,7 @@ export class Brush extends AbstractComponent<Required<BrushAttributes>> {
brushMode === 'single' && this._clearMask();
this._addBrushMask();
this._dispatchBrushEvent(IOperateType.drawStart, e);
// 无论是多选,还是单选
// 如果这是第一个brush mask
// 证明这第一次绘制, 则触发brushActive事件
if (Object.keys(this._brushMaskAABBBoundsDict).length === 1) {
this._dispatchBrushEvent(IOperateType.brushActive, e);
}
this._activeBrushState = false;
}

/**
Expand Down Expand Up @@ -198,7 +186,7 @@ export class Brush extends AbstractComponent<Required<BrushAttributes>> {
*/
private _drawing(e: FederatedPointerEvent) {
const pos = this.eventPosToStagePos(e);
const { brushType } = this.attribute as BrushAttributes;
const { brushType, sizeThreshold = DEFAULT_SIZE_THRESHOLD } = this.attribute as BrushAttributes;

const cacheLength = this._cacheDrawPoints.length;

Expand All @@ -218,7 +206,20 @@ export class Brush extends AbstractComponent<Required<BrushAttributes>> {
// 更新mask形状
const maskPoints = this._computeMaskPoints();
this._operatingMask.setAttribute('points', maskPoints);
this._dispatchBrushEvent(IOperateType.drawing, e);
const { x: x1, y: y1 } = this._startPos;
const { x: x2, y: y2 } = this.eventPosToStagePos(e);
// 绘制大小超过阈值, 才激活brush
if (Math.abs(x2 - x1) > sizeThreshold || Math.abs(y1 - y2) > sizeThreshold) {
// 无论是多选,还是单选
// 如果这是第一个brush mask
// 证明这第一次绘制, 则触发brushActive事件
if (Object.keys(this._brushMaskAABBBoundsDict).length === 1 && !this._activeBrushState) {
this._activeBrushState = true;
this._dispatchBrushEvent(IOperateType.brushActive, e);
} else {
this._dispatchBrushEvent(IOperateType.drawing, e);
}
}
}

/**
Expand Down Expand Up @@ -441,13 +442,6 @@ export class Brush extends AbstractComponent<Required<BrushAttributes>> {
return false;
}

/**
* 事件系统坐标转换为stage坐标
*/
protected eventPosToStagePos(e: FederatedPointerEvent) {
return this.stage.eventPointTransform(e);
}

/**
* 根据操作类型触发对应的事件
*/
Expand All @@ -464,7 +458,7 @@ export class Brush extends AbstractComponent<Required<BrushAttributes>> {
*/
private _clearMask() {
this._brushMaskAABBBoundsDict = {};
this._container.incrementalClearChild();
this._container.removeAllChild();
this._operatingMask = null;
}

Expand Down
12 changes: 11 additions & 1 deletion packages/vrender-components/src/core/base.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @description 组件基类
*/
import type { IGroupGraphicAttribute, ISetAttributeContext } from '@visactor/vrender-core';
import type { FederatedPointerEvent, IGroupGraphicAttribute, ISetAttributeContext } from '@visactor/ 6D4E vrender-core';
import { Group, CustomEvent } from '@visactor/vrender-core';
import type { Dict } from '@visactor/vutils';
import { merge, isFunction, isPlainObject, isNil } from '@visactor/vutils';
Expand Down Expand Up @@ -166,4 +166,14 @@ export abstract class AbstractComponent<T extends IGroupGraphicAttribute = IGrou

this.dispatchEvent(changeEvent);
}

/** 事件系统坐标转换为stage坐标 */
protected eventPosToStagePos(e: FederatedPointerEvent) {
const result = { x: 0, y: 0 };
// 1. 外部坐标 -> 内部坐标
const stagePoints = this.stage?.eventPointTransform(e as any) ?? { x: 0, y: 0 }; // updateSpec过程中交互的话, stage可能为空
// 2. 内部坐标 -> 组件坐标 (比如: 给layer设置 scale / x / y)
this.globalTransMatrix.transformPoint(stagePoints, result);
return result;
}
}
35 changes: 16 additions & 19 deletions packages/vrender-components/src/data-zoom/data-zoom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,12 +232,6 @@ export class DataZoom extends AbstractComponent<Required<DataZoomAttributes>> {
shouldRender && this.setAttributes({ start, end });
}

/** 事件系统坐标转换为stage坐标 */
protected eventPosToStagePos(e: FederatedPointerEvent) {
// updateSpec过程中交互的话, stage可能为空
return this.stage?.eventPointTransform(e) ?? { x: 0, y: 0 };
}

private _clearDragEvents() {
const evtTarget = vglobal.env === 'browser' ? vglobal : this.stage;
const triggers = getEndTriggersOfDrag();
Expand Down Expand Up @@ -613,10 +607,13 @@ export class DataZoom extends AbstractComponent<Required<DataZoomAttributes>> {
// 第三次绘制: 避免startText和endText重叠, 如果重叠了, 对startText做位置调整(考虑到调整的最小化,只单独调整startText而不调整endText)
if (new Bounds().set(x1, y1, x2, y2).intersects(endTextBounds)) {
const direction = this.attribute.orient === 'bottom' || this.attribute.orient === 'right' ? -1 : 1;

if (this._isHorizontal) {
this._startText.setAttribute('dy', startTextDy + direction * Math.abs(endTextBounds.y1 - endTextBounds.y2));
const boundsYDiff = Math.abs(endTextBounds.y1 - endTextBounds.y2); // visible: false时, bounds可能是非法的
this._startText.setAttribute('dy', startTextDy + direction * (Number.isFinite(boundsYDiff) ? boundsYDiff : 0));
} else {
this._startText.setAttribute('dx', startTextDx + direction * Math.abs(endTextBounds.x1 - endTextBounds.x2));
const boundsXDiff = Math.abs(endTextBounds.x1 - endTextBounds.x2); // visible: false时, bounds可能是非法的
this._startText.setAttribute('dx', startTextDx + direction * (Number.isFinite(boundsXDiff) ? boundsXDiff : 0));
}
} else {
if (this._isHorizontal) {
Expand Down Expand Up @@ -736,7 +733,7 @@ export class DataZoom extends AbstractComponent<Required<DataZoomAttributes>> {
height,
cursor: brushSelect ? 'crosshair' : 'auto',
...backgroundStyle,
pickable: zoomLock ? false : backgroundStyle.pickable ?? true
pickable: zoomLock ? false : (backgroundStyle.pickable ?? true)
},
'rect'
) as IRect;
Expand All @@ -760,7 +757,7 @@ export class DataZoom extends AbstractComponent<Required<DataZoomAttributes>> {
height: height,
cursor: brushSelect ? 'crosshair' : 'move',
...selectedBackgroundStyle,
pickable: zoomLock ? false : (selectedBackgroundChartStyle as any).pickable ?? true
pickable: zoomLock ? false : ((selectedBackgroundChartStyle as any).pickable ?? true)
},
'rect'
) as IRect;
Expand All @@ -775,7 +772,7 @@ export class DataZoom extends AbstractComponent<Required<DataZoomAttributes>> {
height: (end - start) * height,
cursor: brushSelect ? 'crosshair' : 'move',
...selectedBackgroundStyle,
pickable: zoomLock ? false : selectedBackgroundStyle.pickable ?? true
pickable: zoomLock ? false : (selectedBackgroundStyle.pickable ?? true)
},
'rect'
) as IRect;
Expand All @@ -797,7 +794,7 @@ export class DataZoom extends AbstractComponent<Required<DataZoomAttributes>> {
width: (end - start) * width,
height: middleHandlerBackgroundSize,
...middleHandlerStyle.background?.style,
pickable: zoomLock ? false : middleHandlerStyle.background?.style?.pickable ?? true
pickable: zoomLock ? false : (middleHandlerStyle.background?.style?.pickable ?? true)
},
'rect'
) as IRect;
Expand All @@ -810,7 +807,7 @@ export class DataZoom extends AbstractComponent<Required<DataZoomAttributes>> {
angle: 0,
symbolType: middleHandlerStyle.icon?.symbolType ?? 'square',
...middleHandlerStyle.icon,
pickable: zoomLock ? false : middleHandlerStyle.icon.pickable ?? true
pickable: zoomLock ? false : (middleHandlerStyle.icon.pickable ?? true)
},
'symbol'
) as ISymbol;
Expand All @@ -824,7 +821,7 @@ export class DataZoom extends AbstractComponent<Required<DataZoomAttributes>> {
symbolType: startHandlerStyle.symbolType ?? 'square',
...(DEFAULT_HANDLER_ATTR_MAP.horizontal as any),
...startHandlerStyle,
pickable: zoomLock ? false : startHandlerStyle.pickable ?? true
pickable: zoomLock ? false : (startHandlerStyle.pickable ?? true)
},
'symbol'
) as ISymbol;
Expand All @@ -837,7 +834,7 @@ export class DataZoom extends AbstractComponent<Required<DataZoomAttributes>> {
symbolType: endHandlerStyle.symbolType ?? 'square',
...(DEFAULT_HANDLER_ATTR_MAP.horizontal as any),
...endHandlerStyle,
pickable: zoomLock ? false : endHandlerStyle.pickable ?? true
pickable: zoomLock ? false : (endHandlerStyle.pickable ?? true)
},
'symbol'
) as ISymbol;
Expand Down Expand Up @@ -890,7 +887,7 @@ export class DataZoom extends AbstractComponent<Required<DataZoomAttributes>> {
width: middleHandlerBackgroundSize,
height: (end - start) * height,
...middleHandlerStyle.background?.style,
pickable: zoomLock ? false : middleHandlerStyle.background?.style?.pickable ?? true
pickable: zoomLock ? false : (middleHandlerStyle.background?.style?.pickable ?? true)
},
'rect'
) as IRect;
Expand All @@ -907,7 +904,7 @@ export class DataZoom extends AbstractComponent<Required<DataZoomAttributes>> {
symbolType: middleHandlerStyle.icon?.symbolType ?? 'square',
strokeBoundsBuffer: 0,
...middleHandlerStyle.icon,
pickable: zoomLock ? false : middleHandlerStyle.icon?.pickable ?? true
pickable: zoomLock ? false : (middleHandlerStyle.icon?.pickable ?? true)
},
'symbol'
) as ISymbol;
Expand All @@ -921,7 +918,7 @@ export class DataZoom extends AbstractComponent<Required<DataZoomAttributes>> {
symbolType: startHandlerStyle.symbolType ?? 'square',
...(DEFAULT_HANDLER_ATTR_MAP.vertical as any),
...startHandlerStyle,
pickable: zoomLock ? false : startHandlerStyle.pickable ?? true
pickable: zoomLock ? false : (startHandlerStyle.pickable ?? true)
},
'symbol'
) as ISymbol;
Expand All @@ -935,7 +932,7 @@ export class DataZoom extends AbstractComponent<Required<DataZoomAttributes>> {
symbolType: endHandlerStyle.symbolType ?? 'square',
...(DEFAULT_HANDLER_ATTR_MAP.vertical as any),
...endHandlerStyle,
pickable: zoomLock ? false : endHandlerStyle.pickable ?? true
pickable: zoomLock ? false : (endHandlerStyle.pickable ?? true)
},
'symbol'
) as ISymbol;
Expand Down
Loading
0