From 6c112900f3fd27c0fac86fa591cbd18f83a19dc1 Mon Sep 17 00:00:00 2001 From: szxc Date: Wed, 28 May 2025 15:49:47 +0800 Subject: [PATCH 1/5] fix: update VennSeries to handle empty keys and filter valid legend keys --- packages/vchart/src/series/venn/venn.ts | 53 +++++++++++++++---------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/packages/vchart/src/series/venn/venn.ts b/packages/vchart/src/series/venn/venn.ts index 363238bff1..e3f2e1208d 100644 --- a/packages/vchart/src/series/venn/venn.ts +++ b/packages/vchart/src/series/venn/venn.ts @@ -339,27 +339,38 @@ export class VennSeries extends Bas if (selectedKeys.length === originalLegendKeys.length) { return selectedKeys; } - - // 找到缺失的项 - const selectedFilter = {}; - selectedKeys.forEach(s => { - selectedFilter[s] = true; - }); - const disableKeys = originalLegendKeys.filter(key => !selectedFilter[getVennSeriesDataKey(key)]); - - // 找到缺失的项的派生项(如 “A&B” 的派生项 “A&B&C”) - const derivedDisableKeys = originalLegendKeys.filter(key => { - if (disableKeys.includes(key)) { - return false; - } - return disableKeys.some(disableKey => array(disableKey).every(k => key.includes(k))); - }); - - // 将派生项从 selectedKeys 中移除 - selectedKeys = selectedKeys.slice(); - derivedDisableKeys.forEach(key => { - selectedKeys.splice(selectedKeys.indexOf(getVennSeriesDataKey(key)), 1); - }); + const emptyKey = ''; + + const hasEmpty = selectedKeys.includes(emptyKey); + const nonEmpty = selectedKeys.filter(key => key !== emptyKey); + + if (nonEmpty.length > 0) { + // 过滤出非空的原始图例键 + const validKeys = originalLegendKeys.filter(key => getVennSeriesDataKey(key) !== emptyKey); + // 找到缺失的项 + const selectedFilter: Record = {}; + selectedKeys.forEach(s => { + selectedFilter[s] = true; + }); + const disableKeys = validKeys.filter(key => !selectedFilter[getVennSeriesDataKey(key)]); + + // 找到缺失的项的派生项(如 “A&B” 的派生项 “A&B&C”) + const derivedDisableKeys = validKeys.filter(key => { + if (disableKeys.includes(key)) { + return false; + } + return disableKeys.some(disableKey => array(disableKey).every(k => key.includes(k))); + }); + + // 将派生项从 nonEmpty 中移除 + selectedKeys = nonEmpty.slice(); + derivedDisableKeys.forEach(key => { + selectedKeys.splice(selectedKeys.indexOf(getVennSeriesDataKey(key)), 1); + }); + } + if (hasEmpty) { + selectedKeys.push(emptyKey); + } } return selectedKeys; } From 89835efc062fc5fd7cc0be3546404a563414772a Mon Sep 17 00:00:00 2001 From: szxc Date: Wed, 28 May 2025 18:09:02 +0800 Subject: [PATCH 2/5] fix: handle empty sets in VennSeries by returning 'others' key --- packages/vchart/src/series/venn/util.ts | 3 +++ packages/vchart/src/series/venn/venn.ts | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/vchart/src/series/venn/util.ts b/packages/vchart/src/series/venn/util.ts index 25fd2ee3fa..b3be7ac643 100644 --- a/packages/vchart/src/series/venn/util.ts +++ b/packages/vchart/src/series/venn/util.ts @@ -1,5 +1,8 @@ import { array } from '@visactor/vutils'; export const getVennSeriesDataKey = (sets: string | string[]) => { + if (!sets || (Array.isArray(sets) && sets.length === 0)) { + return 'others'; + } return array(sets).join(','); }; diff --git a/packages/vchart/src/series/venn/venn.ts b/packages/vchart/src/series/venn/venn.ts index e3f2e1208d..4741c7efd7 100644 --- a/packages/vchart/src/series/venn/venn.ts +++ b/packages/vchart/src/series/venn/venn.ts @@ -339,7 +339,7 @@ export class VennSeries extends Bas if (selectedKeys.length === originalLegendKeys.length) { return selectedKeys; } - const emptyKey = ''; + const emptyKey = 'others'; const hasEmpty = selectedKeys.includes(emptyKey); const nonEmpty = selectedKeys.filter(key => key !== emptyKey); From af504a7590a0456d0372bfb54b3ed5ce0ae63381 Mon Sep 17 00:00:00 2001 From: szxc Date: Sun, 1 Jun 2025 22:17:07 +0800 Subject: [PATCH 3/5] fix: handle empty sets in VennSeries label rendering --- packages/vchart/src/series/venn/venn.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/vchart/src/series/venn/venn.ts b/packages/vchart/src/series/venn/venn.ts index 4741c7efd7..794e1caa9b 100644 --- a/packages/vchart/src/series/venn/venn.ts +++ b/packages/vchart/src/series/venn/venn.ts @@ -210,7 +210,14 @@ export class VennSeries extends Bas { x: datum => (datum as IVennCircleDatum).labelX, y: datum => (datum as IVennCircleDatum).labelY, - text: datum => getVennSeriesDataKey((datum as IVennCircleDatum).sets), + text: datum => { + const sets = (datum as IVennOverlapDatum).sets; + // 如果是空sets,返回空字符串不显示 + if (!sets || (Array.isArray(sets) && sets.length === 0)) { + return ''; + } + return getVennSeriesDataKey(sets); + }, maxLineWidth: (datum: any) => { const { x, radius, labelX } = datum as IVennCircleDatum; const circleX0 = x - radius; From 141af8a6ded1f88a2651a5fa2b3677daca058a4c Mon Sep 17 00:00:00 2001 From: szxc Date: Thu, 5 Jun 2025 16:50:56 +0800 Subject: [PATCH 4/5] fix: handle empty sets in VennSeries label renderingfix: add emptySetKey handling in VennChart and related components --- .../vchart/src/chart/venn/venn-transformer.ts | 1 + packages/vchart/src/series/venn/interface.ts | 5 ++- .../vchart/src/series/venn/tooltip-helper.ts | 4 +-- packages/vchart/src/series/venn/util.ts | 4 +-- packages/vchart/src/series/venn/venn.ts | 32 +++++++++++++------ 5 files changed, 32 insertions(+), 14 deletions(-) diff --git a/packages/vchart/src/chart/venn/venn-transformer.ts b/packages/vchart/src/chart/venn/venn-transformer.ts index e5224777a5..adba174fb4 100644 --- a/packages/vchart/src/chart/venn/venn-transformer.ts +++ b/packages/vchart/src/chart/venn/venn-transformer.ts @@ -9,6 +9,7 @@ export class VennChartSpecTransformer const series: any = super._getDefaultSeriesSpec(spec, [ 'categoryField', 'valueField', + 'emptySetKey', 'circle', 'overlap', 'overlapLabel' diff --git a/packages/vchart/src/series/venn/interface.ts b/packages/vchart/src/series/venn/interface.ts index 718c9d024e..9f10c98db4 100644 --- a/packages/vchart/src/series/venn/interface.ts +++ b/packages/vchart/src/series/venn/interface.ts @@ -17,7 +17,10 @@ export interface IVennSeriesSpec extends ISeriesSpec, IAnimationSpec { - return getVennSeriesDataKey(datum?.[this.series.getDimensionField()[0]]); + return getVennSeriesDataKey(datum?.[this.series.getDimensionField()[0]], this.series.getSpec().emptySetKey); }; markTooltipKeyCallback = (datum: any) => { - return getVennSeriesDataKey(datum?.[this.series.getDimensionField()[0]]); + return getVennSeriesDataKey(datum?.[this.series.getDimensionField()[0]], this.series.getSpec().emptySetKey); }; } diff --git a/packages/vchart/src/series/venn/util.ts b/packages/vchart/src/series/venn/util.ts index b3be7ac643..0e6e99ef61 100644 --- a/packages/vchart/src/series/venn/util.ts +++ b/packages/vchart/src/series/venn/util.ts @@ -1,8 +1,8 @@ import { array } from '@visactor/vutils'; -export const getVennSeriesDataKey = (sets: string | string[]) => { +export const getVennSeriesDataKey = (sets: string | string[], emptysetKey?: string) => { if (!sets || (Array.isArray(sets) && sets.length === 0)) { - return 'others'; + return emptysetKey || 'others'; } return array(sets).join(','); }; diff --git a/packages/vchart/src/series/venn/venn.ts b/packages/vchart/src/series/venn/venn.ts index 794e1caa9b..33cfa3d457 100644 --- a/packages/vchart/src/series/venn/venn.ts +++ b/packages/vchart/src/series/venn/venn.ts @@ -36,7 +36,6 @@ export class VennSeries extends Bas static readonly mark: SeriesMarkMap = vennSeriesMark; static readonly builtInTheme = { venn }; - static readonly transformerConstructor = VennSeriesSpecTransformer; readonly transformerConstructor = VennSeriesSpecTransformer; @@ -67,11 +66,21 @@ export class VennSeries extends Bas return this._valueField; } + protected _emptySetKey!: string; + getEmptySetKey() { + return this._emptySetKey; + } + setEmptySetKey(f: string): string { + this._emptySetKey = f; + return this._emptySetKey; + } + setAttrFromSpec(): void { super.setAttrFromSpec(); this.setCategoryField(this._spec.categoryField ?? 'sets'); this.setValueField(this._spec.valueField ?? 'size'); this.setSeriesField(this._spec.seriesField ?? DEFAULT_DATA_KEY); + this.setEmptySetKey(this._spec.emptySetKey ?? 'others'); } initData() { @@ -212,7 +221,6 @@ export class VennSeries extends Bas y: datum => (datum as IVennCircleDatum).labelY, text: datum => { const sets = (datum as IVennOverlapDatum).sets; - // 如果是空sets,返回空字符串不显示 if (!sets || (Array.isArray(sets) && sets.length === 0)) { return ''; } @@ -241,7 +249,13 @@ export class VennSeries extends Bas { x: datum => (datum as IVennOverlapDatum).labelX, y: datum => (datum as IVennOverlapDatum).labelY, - text: datum => getVennSeriesDataKey((datum as IVennOverlapDatum).sets) + text: datum => { + const sets = (datum as IVennOverlapDatum).sets; + if (!sets || (Array.isArray(sets) && sets.length === 0)) { + return ''; + } + return getVennSeriesDataKey(sets); + } }, STATE_VALUE_ENUM.STATE_NORMAL, AttributeLevel.Series @@ -317,7 +331,7 @@ export class VennSeries extends Bas protected _getSeriesInfo(field: string, keys: string[]) { const defaultShapeType = this.getDefaultShapeType(); return keys.map(originalKey => { - const dataKey = getVennSeriesDataKey(originalKey); + const dataKey = getVennSeriesDataKey(originalKey, this._emptySetKey); return { key: dataKey, originalKey, @@ -331,7 +345,7 @@ export class VennSeries extends Bas getSeriesFieldValue(datum: Datum, seriesField?: string) { const value = super.getSeriesFieldValue(datum, seriesField); - return getVennSeriesDataKey(value); + return getVennSeriesDataKey(value, this._emptySetKey); } legendSelectedFilter(component: ILegend, selectedKeys: StringOrNumber[]) { @@ -346,20 +360,20 @@ export class VennSeries extends Bas if (selectedKeys.length === originalLegendKeys.length) { return selectedKeys; } - const emptyKey = 'others'; + const emptyKey = this._emptySetKey; const hasEmpty = selectedKeys.includes(emptyKey); const nonEmpty = selectedKeys.filter(key => key !== emptyKey); if (nonEmpty.length > 0) { // 过滤出非空的原始图例键 - const validKeys = originalLegendKeys.filter(key => getVennSeriesDataKey(key) !== emptyKey); + const validKeys = originalLegendKeys.filter(key => getVennSeriesDataKey(key, this._emptySetKey) !== emptyKey); // 找到缺失的项 const selectedFilter: Record = {}; selectedKeys.forEach(s => { selectedFilter[s] = true; }); - const disableKeys = validKeys.filter(key => !selectedFilter[getVennSeriesDataKey(key)]); + const disableKeys = validKeys.filter(key => !selectedFilter[getVennSeriesDataKey(key, this._emptySetKey)]); // 找到缺失的项的派生项(如 “A&B” 的派生项 “A&B&C”) const derivedDisableKeys = validKeys.filter(key => { @@ -372,7 +386,7 @@ export class VennSeries extends Bas // 将派生项从 nonEmpty 中移除 selectedKeys = nonEmpty.slice(); derivedDisableKeys.forEach(key => { - selectedKeys.splice(selectedKeys.indexOf(getVennSeriesDataKey(key)), 1); + selectedKeys.splice(selectedKeys.indexOf(getVennSeriesDataKey(key, this._emptySetKey)), 1); }); } if (hasEmpty) { From d1e50cfe3d56a0b3286098b386a322b35ef31872 Mon Sep 17 00:00:00 2001 From: szxc Date: Thu, 5 Jun 2025 16:58:33 +0800 Subject: [PATCH 5/5] fix: remove empty sets check in VennSeries label rendering --- packages/vchart/src/series/venn/venn.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/vchart/src/series/venn/venn.ts b/packages/vchart/src/series/venn/venn.ts index 33cfa3d457..4d21bbaed5 100644 --- a/packages/vchart/src/series/venn/venn.ts +++ b/packages/vchart/src/series/venn/venn.ts @@ -251,9 +251,6 @@ export class VennSeries extends Bas y: datum => (datum as IVennOverlapDatum).labelY, text: datum => { const sets = (datum as IVennOverlapDatum).sets; - if (!sets || (Array.isArray(sets) && sets.length === 0)) { - return ''; - } return getVennSeriesDataKey(sets); } },