Skip to content

Commit 95bb63e

Browse files
Fran McDadeFran McDade
authored andcommitted
feat: customize getfacetedminmaxvalues for mixed column values (#440)
1 parent 7144e20 commit 95bb63e

3 files changed

Lines changed: 55 additions & 4 deletions

File tree

src/components/Index/table/hook.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import {
22
ColumnDef,
33
ColumnSort,
44
getCoreRowModel,
5-
getFacetedMinMaxValues,
65
getFacetedRowModel,
76
getFilteredRowModel,
87
getPaginationRowModel,
@@ -34,6 +33,7 @@ import {
3433
isClientFilteringEnabled,
3534
sortingFn,
3635
} from "../../Table/common/utils";
36+
import { getFacetedMinMaxValues } from "../../Table/featureOptions/facetedColumn/getFacetedMinMaxValues";
3737
import { ROW_POSITION } from "../../Table/features/RowPosition/constants";
3838
import { ROW_PREVIEW } from "../../Table/features/RowPreview/constants";
3939
import { RowPreviewState } from "../../Table/features/RowPreview/entities";

src/components/Table/common/utils.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
sortingFns,
1010
Table,
1111
} from "@tanstack/react-table";
12+
import { assertIsRange } from "../../../common/categories/models/range/utils";
1213
import { Category } from "../../../common/categories/models/types";
1314
import { EXPLORE_MODE, ExploreMode } from "../../../hooks/useExploreMode/types";
1415
import { COLUMN_IDENTIFIER } from "./columnIdentifier";
@@ -54,12 +55,15 @@ export function buildCategoryViews<T extends RowData>(
5455
const label = columnHeader as string;
5556
// Handle range categories.
5657
if (columnDef.filterFn === "inNumberRange") {
57-
const [min, max] = getFacetedMinMaxValues() || [];
58+
const minMax = getFacetedMinMaxValues();
59+
// Assert for the column that the minMax values are a range.
60+
assertIsRange(minMax);
61+
const [min, max] = minMax;
5862
categoryViews.push({
5963
key,
6064
label,
61-
max: max ?? Infinity,
62-
min: min ?? -Infinity,
65+
max,
66+
min,
6367
selectedMax: null, // Selected state updated in reducer.
6468
selectedMin: null, // Selected state updated in reducer.
6569
});
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { getMemoOptions, memo, RowData, Table } from "@tanstack/react-table";
2+
3+
/**
4+
* Returns an array of two numbers, the minimum and maximum values for the column, or undefined if the column does not exist or has no values.
5+
* Customized version of the default getFacetedMinMaxValues function from tanstack table handling mixed null and possible NaN values.
6+
* See https://tanstack.com/table/v8/docs/api/features/column-faceting#getfacetedminmaxvalues.
7+
* @returns An array of two numbers, the minimum and maximum values for the column, or undefined if the column does not exist or has no values.
8+
*/
9+
export function getFacetedMinMaxValues<TData extends RowData>(): (
10+
table: Table<TData>,
11+
columnId: string
12+
) => () => undefined | [number, number] {
13+
// eslint-disable-next-line sonarjs/cognitive-complexity -- Customized copy of tanstack table function.
14+
return (table, columnId) =>
15+
memo(
16+
() => [table.getColumn(columnId)?.getFacetedRowModel()],
17+
(facetedRowModel) => {
18+
if (!facetedRowModel) return undefined;
19+
20+
// Initialize with the smallest and largest possible numbers.
21+
const facetedMinMaxValues: [number, number] = [Infinity, -Infinity];
22+
23+
for (let i = 0; i < facetedRowModel.flatRows.length; i++) {
24+
const values =
25+
facetedRowModel.flatRows[i]!.getUniqueValues<number>(columnId);
26+
27+
for (let j = 0; j < values.length; j++) {
28+
const value = values[j]!;
29+
// Convert value to a number.
30+
const numericValue = Number(value);
31+
32+
// Skip null and NaN values.
33+
if (value === null || isNaN(numericValue)) continue;
34+
35+
if (numericValue < facetedMinMaxValues[0]) {
36+
facetedMinMaxValues[0] = numericValue;
37+
} else if (numericValue > facetedMinMaxValues[1]) {
38+
facetedMinMaxValues[1] = numericValue;
39+
}
40+
}
41+
}
42+
43+
return facetedMinMaxValues;
44+
},
45+
getMemoOptions(table.options, "debugTable", "getFacetedMinMaxValues")
46+
);
47+
}

0 commit comments

Comments
 (0)