Skip to content
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,11 @@
{
"changes": [
{
"comment": "feat: add config `customFilter` to legend, support cutomized filter function, close #3492\n\n",
"type": "none",
"packageName": "@visactor/vchart"
}
],
"packageName": "@visactor/vchart",
"email": "[email protected]"
}
17 changes: 17 additions & 0 deletions docs/assets/option/en/component/legend-common/base-legend.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,23 @@ Whether to enable legend interaction, enabled by default.

Whether to perform data filtering, the default is true. When this property is turned off, the legend click event will not trigger data filtering.

#${prefix} customFilter(Function)

Supported since version `1.13.1`

Custom legend filter callback function, defined as follows:

```
/**
* Custom filter function
* @param data Current data
* @param selectedRange Selected data range
* @param datumField Field corresponding to the filtered data
* @returns The final displayed data
*/
(data: any, selectedRange: StringOrNumber[], datumField: string) => any;
```

#${prefix} title(Object)

Legend title configuration, not displayed by default.
Expand Down
17 changes: 17 additions & 0 deletions docs/assets/option/zh/component/legend-common/base-legend.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,23 @@

是否进行数据筛选,默认为 true。该属性关闭之后,图例的点击事件将不会触发数据筛选。

#${prefix} customFilter(Function)

自 `1.13.1`版本开始支持

自定义图例筛选的回调函数,类型定义如下:

```
/**
* 自定义筛选函数
* @param data 当前数据
* @param selectedRange 选中的数据范围
* @param datumField 筛选数据对应的字段
* @returns 最终展示的数据
*/
(data: any, selectedRange: StringOrNumber[], datumField: string) => any;
```

#${prefix} title(Object)

图例标题配置,默认不显示。
Expand Down
3 changes: 2 additions & 1 deletion packages/vchart/src/component/legend/continuous/legend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ export class ContinuousLegend<
selected: () => this._selectedData,
field: () => this._field,
data: () => this._legendData.getLatestData(),
isHierarchyData: s.isHierarchyData
isHierarchyData: s.isHierarchyData,
customFilter: this._spec.customFilter
},
level: TransformLevel.legendFilter
});
Expand Down
3 changes: 2 additions & 1 deletion packages/vchart/src/component/legend/discrete/legend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ export class DiscreteLegend extends BaseLegend<IDiscreteLegendSpec> {
series: s,
selected: () => this._selectedData,
field: () => this._getSeriesLegendField(s),
data: () => this.getLegendDefaultData()
data: () => this.getLegendDefaultData(),
customFilter: this._spec.customFilter
},
level: TransformLevel.legendFilter
});
Expand Down
9 changes: 9 additions & 0 deletions packages/vchart/src/component/legend/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,15 @@ export type ILegendCommonSpec = {
* 是否进行数据筛选,默认为 true
*/
filter?: boolean;
/**
* 自定义筛选函数
* @since 1.13.1
* @param data 当前数据
* @param selectedRange 选中的数据范围
* @param datumField 筛选数据对应的字段
* @returns 最终展示的数据
*/
customFilter?: (data: any, selectedRange: StringOrNumber[], datumField: string) => any;

/**
* 图例标题配置
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { constants } from 'fs';
import { isArray, isEmpty, isValidNumber } from '@visactor/vutils';
import { isEmpty, isValidNumber } from '@visactor/vutils';
import type { ISeries } from '../../../../series/interface';
import type { IContinuousLegendDataMakeOption, IContinuousLegendFilterOption } from './interface';
import { filterHierarchyDataByRange, isHierarchyItem } from '../../../../util';
Expand Down Expand Up @@ -36,7 +35,7 @@ export const continuousLegendDataMake = (data: Array<ISeries>, op: IContinuousLe

// 连续数据过滤
export const continuousLegendFilter = (data: Array<any>, op: IContinuousLegendFilterOption) => {
const { selected, field, data: legendData, isHierarchyData } = op;
const { selected, field, data: legendData, isHierarchyData, customFilter } = op;
const selectedRange = selected();
const datumField = field();
const dataRange = legendData();
Expand All @@ -50,13 +49,15 @@ export const continuousLegendFilter = (data: Array<any>, op: IContinuousLegendFi
}
if (datumField && !isEmpty(selectedRange)) {
const [min, max] = selectedRange;
if (isHierarchy(data)) {

if (customFilter) {
return customFilter(data, selectedRange, datumField);
} else if (isHierarchy(data)) {
return filterHierarchyDataByRange(data, +min, +max, datumField);
} else {
return data.filter(datum => {
return datum[datumField] >= min && datum[datumField] <= max;
});
}
return data.filter(datum => {
return datum[datumField] >= min && datum[datumField] <= max;
});
}

return data;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ export interface IContinuousLegendFilterOption {
field: () => string | undefined;
data: () => StringOrNumber[];
isHierarchyData?: () => boolean;
customFilter?: (data: any, selectedRange: StringOrNumber[], datumField: string) => any;
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const discreteLegendDataMake = (data: Array<ISeries>, op: IDiscreteLegend
};

export const discreteLegendFilter = (data: Array<any>, op: IDiscreteLegendFilterOption) => {
const { series, selected, field, data: legendData } = op;
const { series, selected, field, data: legendData, customFilter } = op;
const selectedData = selected();
const legendKeys = legendData(); // 全量的图例项
if (selectedData.length === 0 && legendKeys.length) {
Expand All @@ -45,7 +45,9 @@ export const discreteLegendFilter = (data: Array<any>, op: IDiscreteLegendFilter

const datumField = field() ?? DEFAULT_DATA_SERIES_FIELD;

if (isArray(data) && data[0]?.nodes) {
if (customFilter) {
return customFilter(data, selectedData, datumField);
} else if (isArray(data) && data[0]?.nodes) {
// data silter for sankey chart
data[0].nodes = data[0].nodes.filter((d: any) => selectedFilter[d.key] === true);
if (data[0]?.links) {
Expand All @@ -58,5 +60,6 @@ export const discreteLegendFilter = (data: Array<any>, op: IDiscreteLegendFilter
data = data.filter(d => selectedFilter[series.getSeriesFieldValue(d, datumField)] === true);
}
}

return data;
};
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ export interface IDiscreteLegendFilterOption {
selected: () => StringOrNumber[];
field: () => string;
data: () => StringOrNumber[];
customFilter?: (data: any, selectedRange: StringOrNumber[], datumField: string) => any;
}
Loading