diff --git a/common/changes/@visactor/vrender-components/feat-support-filterBeforeOverlap-in-label_2025-11-11-08-55.json b/common/changes/@visactor/vrender-components/feat-support-filterBeforeOverlap-in-label_2025-11-11-08-55.json new file mode 100644 index 000000000..ccf3a0796 --- /dev/null +++ b/common/changes/@visactor/vrender-components/feat-support-filterBeforeOverlap-in-label_2025-11-11-08-55.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "comment": "feat: support filterBeforeOverlap in label\n\n", + "type": "none", + "packageName": "@visactor/vrender-components" + } + ], + "packageName": "@visactor/vrender-components", + "email": "lixuef1313@163.com" +} \ No newline at end of file diff --git a/packages/vrender-components/src/label/base.ts b/packages/vrender-components/src/label/base.ts index c8240ffac..383c2d8d5 100644 --- a/packages/vrender-components/src/label/base.ts +++ b/packages/vrender-components/src/label/base.ts @@ -29,7 +29,8 @@ import { isNil, isArray, isObject, - pointInRect + pointInRect, + isBoolean } from '@visactor/vutils'; import type { PointLocationCfg } from '../core/type'; import { labelSmartInvert, contrastAccessibilityChecker, smartInvertStrategy } from '../util/label-smartInvert'; @@ -212,17 +213,30 @@ export class LabelBase extends AnimateComponent { labels = this._layout(labels); } + const filteredLabels: (IText | IRichText)[] = []; + const overlapLabels: (IText | IRichText)[] = labels; + if (!isBoolean(overlap) && isFunction(overlap.filterBeforeOverlap)) { + const getRelatedGraphic = this.getRelatedGraphic.bind(this); + labels.forEach(label => { + if (overlap.filterBeforeOverlap(label, getRelatedGraphic, this)) { + overlapLabels.push(label); + } else { + filteredLabels.push(label); + } + }); + } + if (isFunction(customOverlapFunc)) { labels = customOverlapFunc( - labels as Text[], + overlapLabels as Text[], this.getRelatedGraphic.bind(this), this._isCollectionBase ? (d: LabelItem) => this._idToPoint.get(d.id) : null, this - ); + ).concat(filteredLabels); } else { // 防重叠逻辑 if (overlap !== false) { - labels = this._overlapping(labels); + labels = this._overlapping(overlapLabels).concat(filteredLabels); } } diff --git a/packages/vrender-components/src/label/type.ts b/packages/vrender-components/src/label/type.ts index 9d726993b..65e3ed068 100644 --- a/packages/vrender-components/src/label/type.ts +++ b/packages/vrender-components/src/label/type.ts @@ -152,6 +152,19 @@ export interface BaseLabelAttrs extends IGroupGraphicAttribute { getRelatedPoint: ((data: LabelItem) => IPointLike) | null | undefined, labelComponent: IGroup ) => void; + + /** + * 防重叠计算前的回调函数 + * 返回true的标签会被计算防重叠 + * 返回false的标签会被直接跳过防重叠计算 + * @since 1.19.16 + */ + filterBeforeOverlap?: ( + label: IText | IRichText, + getRelatedGraphic: (data: LabelItem) => IGraphic, + labelComponent: IGroup + ) => boolean; + /** * 关闭交互效果 * @default false @@ -225,6 +238,18 @@ export interface OverlapAttrs { * @returns number 数值越大,权重越高。权重越高的标签越优先被布局。 */ priority?: (labelItem: LabelItem) => number; + + /** + * 防重叠计算前的回调函数 + * 返回true的标签会被计算防重叠 + * 返回false的标签会被直接跳过防重叠计算 + * @since 1.0.24 + */ + filterBeforeOverlap?: ( + label: IText | IRichText, + getRelatedGraphic: (data: LabelItem) => IGraphic, + labelComponent: IGroup + ) => boolean; } export interface SmartInvertAttrs {