@tanstack/table-core 9.0.0-beta.47 → 9.0.0-beta.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/row-models/coreRowModelsFeature.types.d.cts +1 -1
- package/dist/core/row-models/coreRowModelsFeature.types.d.ts +1 -1
- package/dist/core/row-models/coreRowModelsFeature.utils.cjs +1 -1
- package/dist/core/row-models/coreRowModelsFeature.utils.cjs.map +1 -1
- package/dist/core/row-models/coreRowModelsFeature.utils.d.cts +1 -1
- package/dist/core/row-models/coreRowModelsFeature.utils.d.ts +1 -1
- package/dist/core/row-models/coreRowModelsFeature.utils.js +1 -1
- package/dist/core/row-models/coreRowModelsFeature.utils.js.map +1 -1
- package/dist/features/aggregation/aggregationFeature.cjs +38 -0
- package/dist/features/aggregation/aggregationFeature.cjs.map +1 -0
- package/dist/features/aggregation/aggregationFeature.d.cts +10 -0
- package/dist/features/aggregation/aggregationFeature.d.ts +10 -0
- package/dist/features/aggregation/aggregationFeature.js +38 -0
- package/dist/features/aggregation/aggregationFeature.js.map +1 -0
- package/dist/features/aggregation/aggregationFeature.types.cjs +13 -0
- package/dist/features/aggregation/aggregationFeature.types.cjs.map +1 -0
- package/dist/features/aggregation/aggregationFeature.types.d.cts +172 -0
- package/dist/features/aggregation/aggregationFeature.types.d.ts +172 -0
- package/dist/features/aggregation/aggregationFeature.types.js +12 -0
- package/dist/features/aggregation/aggregationFeature.types.js.map +1 -0
- package/dist/features/aggregation/aggregationFeature.utils.cjs +198 -0
- package/dist/features/aggregation/aggregationFeature.utils.cjs.map +1 -0
- package/dist/features/aggregation/aggregationFeature.utils.d.cts +33 -0
- package/dist/features/aggregation/aggregationFeature.utils.d.ts +33 -0
- package/dist/features/aggregation/aggregationFeature.utils.js +192 -0
- package/dist/features/aggregation/aggregationFeature.utils.js.map +1 -0
- package/dist/features/aggregation/aggregationFns.cjs +240 -0
- package/dist/features/aggregation/aggregationFns.cjs.map +1 -0
- package/dist/features/aggregation/aggregationFns.d.cts +67 -0
- package/dist/features/aggregation/aggregationFns.d.ts +67 -0
- package/dist/features/aggregation/aggregationFns.js +229 -0
- package/dist/features/aggregation/aggregationFns.js.map +1 -0
- package/dist/features/column-faceting/createFacetedMinMaxValues.cjs +7 -4
- package/dist/features/column-faceting/createFacetedMinMaxValues.cjs.map +1 -1
- package/dist/features/column-faceting/createFacetedMinMaxValues.js +8 -5
- package/dist/features/column-faceting/createFacetedMinMaxValues.js.map +1 -1
- package/dist/features/column-faceting/createFacetedRowModel.cjs +1 -1
- package/dist/features/column-faceting/createFacetedRowModel.cjs.map +1 -1
- package/dist/features/column-faceting/createFacetedRowModel.js +1 -1
- package/dist/features/column-faceting/createFacetedRowModel.js.map +1 -1
- package/dist/features/column-faceting/createFacetedUniqueValues.cjs +8 -4
- package/dist/features/column-faceting/createFacetedUniqueValues.cjs.map +1 -1
- package/dist/features/column-faceting/createFacetedUniqueValues.js +9 -5
- package/dist/features/column-faceting/createFacetedUniqueValues.js.map +1 -1
- package/dist/features/column-filtering/columnFilteringFeature.types.d.cts +1 -1
- package/dist/features/column-filtering/columnFilteringFeature.types.d.ts +1 -1
- package/dist/{fns → features/column-filtering}/filterFns.cjs +1 -1
- package/dist/features/column-filtering/filterFns.cjs.map +1 -0
- package/dist/{fns → features/column-filtering}/filterFns.d.cts +4 -4
- package/dist/{fns → features/column-filtering}/filterFns.d.ts +4 -4
- package/dist/{fns → features/column-filtering}/filterFns.js +1 -1
- package/dist/features/column-filtering/filterFns.js.map +1 -0
- package/dist/features/column-grouping/columnGroupingFeature.cjs +3 -12
- package/dist/features/column-grouping/columnGroupingFeature.cjs.map +1 -1
- package/dist/features/column-grouping/columnGroupingFeature.d.cts +1 -1
- package/dist/features/column-grouping/columnGroupingFeature.d.ts +1 -1
- package/dist/features/column-grouping/columnGroupingFeature.js +4 -13
- package/dist/features/column-grouping/columnGroupingFeature.js.map +1 -1
- package/dist/features/column-grouping/columnGroupingFeature.types.d.cts +6 -87
- package/dist/features/column-grouping/columnGroupingFeature.types.d.ts +6 -87
- package/dist/features/column-grouping/columnGroupingFeature.utils.cjs +0 -64
- package/dist/features/column-grouping/columnGroupingFeature.utils.cjs.map +1 -1
- package/dist/features/column-grouping/columnGroupingFeature.utils.d.cts +2 -44
- package/dist/features/column-grouping/columnGroupingFeature.utils.d.ts +2 -44
- package/dist/features/column-grouping/columnGroupingFeature.utils.js +2 -63
- package/dist/features/column-grouping/columnGroupingFeature.utils.js.map +1 -1
- package/dist/features/column-grouping/createGroupedRowModel.cjs +23 -16
- package/dist/features/column-grouping/createGroupedRowModel.cjs.map +1 -1
- package/dist/features/column-grouping/createGroupedRowModel.d.cts +2 -6
- package/dist/features/column-grouping/createGroupedRowModel.d.ts +2 -6
- package/dist/features/column-grouping/createGroupedRowModel.js +25 -18
- package/dist/features/column-grouping/createGroupedRowModel.js.map +1 -1
- package/dist/features/global-filtering/globalFilteringFeature.utils.cjs +1 -1
- package/dist/features/global-filtering/globalFilteringFeature.utils.cjs.map +1 -1
- package/dist/features/global-filtering/globalFilteringFeature.utils.js +1 -1
- package/dist/features/global-filtering/globalFilteringFeature.utils.js.map +1 -1
- package/dist/features/row-sorting/rowSortingFeature.types.d.cts +1 -1
- package/dist/features/row-sorting/rowSortingFeature.types.d.ts +1 -1
- package/dist/features/row-sorting/rowSortingFeature.utils.cjs +1 -1
- package/dist/features/row-sorting/rowSortingFeature.utils.cjs.map +1 -1
- package/dist/features/row-sorting/rowSortingFeature.utils.js +1 -1
- package/dist/features/row-sorting/rowSortingFeature.utils.js.map +1 -1
- package/dist/{fns → features/row-sorting}/sortFns.cjs +1 -1
- package/dist/{fns/sortFns.js.map → features/row-sorting/sortFns.cjs.map} +1 -1
- package/dist/{fns → features/row-sorting}/sortFns.d.cts +4 -4
- package/dist/{fns → features/row-sorting}/sortFns.d.ts +4 -4
- package/dist/{fns → features/row-sorting}/sortFns.js +1 -1
- package/dist/features/row-sorting/sortFns.js.map +1 -0
- package/dist/features/stockFeatures.cjs +2 -0
- package/dist/features/stockFeatures.cjs.map +1 -1
- package/dist/features/stockFeatures.d.cts +2 -0
- package/dist/features/stockFeatures.d.ts +2 -0
- package/dist/features/stockFeatures.js +2 -0
- package/dist/features/stockFeatures.js.map +1 -1
- package/dist/index.cjs +7 -4
- package/dist/index.d.cts +7 -5
- package/dist/index.d.ts +7 -5
- package/dist/index.js +6 -4
- package/dist/static-functions.cjs +8 -3
- package/dist/static-functions.d.cts +3 -2
- package/dist/static-functions.d.ts +3 -2
- package/dist/static-functions.js +3 -2
- package/dist/types/Cell.d.cts +3 -1
- package/dist/types/Cell.d.ts +3 -1
- package/dist/types/Column.d.cts +4 -2
- package/dist/types/Column.d.ts +4 -2
- package/dist/types/ColumnDef.d.cts +5 -3
- package/dist/types/ColumnDef.d.ts +5 -3
- package/dist/types/Row.d.cts +3 -1
- package/dist/types/Row.d.ts +3 -1
- package/dist/types/RowModel.d.cts +1 -1
- package/dist/types/RowModel.d.ts +1 -1
- package/dist/types/RowModelFns.d.cts +3 -3
- package/dist/types/RowModelFns.d.ts +3 -3
- package/dist/types/Table.d.cts +1 -1
- package/dist/types/Table.d.ts +1 -1
- package/dist/types/TableFeatures.d.cts +4 -4
- package/dist/types/TableFeatures.d.ts +4 -4
- package/dist/types/TableOptions.d.cts +5 -3
- package/dist/types/TableOptions.d.ts +5 -3
- package/dist/types/TableState.d.cts +1 -1
- package/dist/types/TableState.d.ts +1 -1
- package/dist/worker/initTableWorker.cjs.map +1 -1
- package/dist/worker/initTableWorker.js.map +1 -1
- package/package.json +1 -1
- package/skills/aggregation/SKILL.md +131 -0
- package/skills/api-not-found/SKILL.md +1 -1
- package/skills/client-vs-server/SKILL.md +1 -1
- package/skills/column-faceting/SKILL.md +1 -1
- package/skills/column-filtering/SKILL.md +1 -1
- package/skills/column-ordering/SKILL.md +1 -1
- package/skills/column-pinning/SKILL.md +1 -1
- package/skills/column-resizing/SKILL.md +1 -1
- package/skills/column-sizing/SKILL.md +1 -1
- package/skills/column-visibility/SKILL.md +1 -1
- package/skills/core/SKILL.md +1 -1
- package/skills/custom-features/SKILL.md +1 -1
- package/skills/expanding/SKILL.md +1 -1
- package/skills/global-filtering/SKILL.md +1 -1
- package/skills/grouping/SKILL.md +12 -18
- package/skills/migrate-v8-to-v9/SKILL.md +15 -2
- package/skills/pagination/SKILL.md +1 -1
- package/skills/row-pinning/SKILL.md +1 -1
- package/skills/row-selection/SKILL.md +1 -1
- package/skills/sorting/SKILL.md +1 -1
- package/skills/table-features/SKILL.md +5 -2
- package/skills/typescript/SKILL.md +1 -1
- package/src/core/row-models/coreRowModelsFeature.utils.ts +1 -1
- package/src/features/aggregation/aggregationFeature.ts +59 -0
- package/src/features/aggregation/aggregationFeature.types.ts +312 -0
- package/src/features/aggregation/aggregationFeature.utils.ts +401 -0
- package/src/features/aggregation/aggregationFns.ts +336 -0
- package/src/features/column-faceting/createFacetedMinMaxValues.ts +33 -7
- package/src/features/column-faceting/createFacetedRowModel.ts +4 -1
- package/src/features/column-faceting/createFacetedUniqueValues.ts +45 -11
- package/src/features/column-filtering/columnFilteringFeature.types.ts +1 -1
- package/src/{fns → features/column-filtering}/filterFns.ts +4 -4
- package/src/features/column-grouping/columnGroupingFeature.ts +1 -20
- package/src/features/column-grouping/columnGroupingFeature.types.ts +4 -141
- package/src/features/column-grouping/columnGroupingFeature.utils.ts +1 -122
- package/src/features/column-grouping/createGroupedRowModel.ts +32 -41
- package/src/features/global-filtering/globalFilteringFeature.utils.ts +1 -1
- package/src/features/row-sorting/rowSortingFeature.types.ts +1 -1
- package/src/features/row-sorting/rowSortingFeature.utils.ts +1 -1
- package/src/{fns → features/row-sorting}/sortFns.ts +4 -7
- package/src/features/stockFeatures.ts +3 -0
- package/src/index.ts +7 -8
- package/src/static-functions.ts +1 -0
- package/src/types/Cell.ts +2 -0
- package/src/types/Column.ts +3 -1
- package/src/types/ColumnDef.ts +6 -3
- package/src/types/Row.ts +2 -0
- package/src/types/RowModelFns.ts +3 -3
- package/src/types/TableFeatures.ts +4 -4
- package/src/types/TableOptions.ts +5 -1
- package/src/worker/initTableWorker.ts +1 -1
- package/dist/fns/aggregationFns.cjs +0 -234
- package/dist/fns/aggregationFns.cjs.map +0 -1
- package/dist/fns/aggregationFns.d.cts +0 -139
- package/dist/fns/aggregationFns.d.ts +0 -139
- package/dist/fns/aggregationFns.js +0 -221
- package/dist/fns/aggregationFns.js.map +0 -1
- package/dist/fns/filterFns.cjs.map +0 -1
- package/dist/fns/filterFns.js.map +0 -1
- package/dist/fns/sortFns.cjs.map +0 -1
- package/src/fns/aggregationFns.ts +0 -303
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
import { constructAggregationFn } from './aggregationFeature.types'
|
|
2
|
+
import type { AggregationContext } from './aggregationFeature.types'
|
|
3
|
+
|
|
4
|
+
type RangeValue = Date | number
|
|
5
|
+
|
|
6
|
+
function isNumber(value: unknown): value is number {
|
|
7
|
+
return typeof value === 'number'
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function isValidDate(value: unknown): value is Date {
|
|
11
|
+
return value instanceof Date && !Number.isNaN(value.getTime())
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function getRangeKind(value: unknown): 'date' | 'number' | undefined {
|
|
15
|
+
if (isNumber(value)) return 'number'
|
|
16
|
+
if (isValidDate(value)) return 'date'
|
|
17
|
+
return undefined
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function compareRangeValues(left: RangeValue, right: RangeValue) {
|
|
21
|
+
const leftValue = left instanceof Date ? left.getTime() : left
|
|
22
|
+
const rightValue = right instanceof Date ? right.getTime() : right
|
|
23
|
+
return leftValue - rightValue
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function collectRangeValues(context: AggregationContext<any, any, unknown>) {
|
|
27
|
+
const values: Array<RangeValue> = []
|
|
28
|
+
let kind: 'date' | 'number' | undefined
|
|
29
|
+
|
|
30
|
+
for (let i = 0; i < context.rows.length; i++) {
|
|
31
|
+
const value = context.getValue(context.rows[i]!)
|
|
32
|
+
const valueKind = getRangeKind(value)
|
|
33
|
+
if (!valueKind) continue
|
|
34
|
+
kind ??= valueKind
|
|
35
|
+
if (valueKind === kind) values.push(value as RangeValue)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return values
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Sums numeric row values. Non-number values contribute zero. As in the
|
|
43
|
+
* previous API, `NaN` is a number and therefore propagates through the sum.
|
|
44
|
+
*/
|
|
45
|
+
export const aggregationFn_sum = constructAggregationFn<
|
|
46
|
+
any,
|
|
47
|
+
any,
|
|
48
|
+
unknown,
|
|
49
|
+
number
|
|
50
|
+
>({
|
|
51
|
+
aggregate: (context) => {
|
|
52
|
+
let sum = 0
|
|
53
|
+
for (let i = 0; i < context.rows.length; i++) {
|
|
54
|
+
const value = context.getValue(context.rows[i]!)
|
|
55
|
+
sum += typeof value === 'number' ? value : 0
|
|
56
|
+
}
|
|
57
|
+
return sum
|
|
58
|
+
},
|
|
59
|
+
merge: ({ childResults }) => {
|
|
60
|
+
let sum = 0
|
|
61
|
+
for (let i = 0; i < childResults.length; i++) {
|
|
62
|
+
const value = childResults[i]
|
|
63
|
+
if (isNumber(value)) sum += value
|
|
64
|
+
}
|
|
65
|
+
return sum
|
|
66
|
+
},
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Finds the minimum numeric or Date value. Invalid value types are ignored;
|
|
71
|
+
* `NaN` preserves the legacy numeric seeding behavior.
|
|
72
|
+
*/
|
|
73
|
+
export const aggregationFn_min = constructAggregationFn<
|
|
74
|
+
any,
|
|
75
|
+
any,
|
|
76
|
+
unknown,
|
|
77
|
+
RangeValue | undefined
|
|
78
|
+
>({
|
|
79
|
+
aggregate: (context) => {
|
|
80
|
+
const values = collectRangeValues(context)
|
|
81
|
+
let result = values[0]
|
|
82
|
+
for (let i = 1; i < values.length; i++) {
|
|
83
|
+
if (compareRangeValues(values[i]!, result!) < 0) result = values[i]
|
|
84
|
+
}
|
|
85
|
+
return result
|
|
86
|
+
},
|
|
87
|
+
merge: ({ childResults }) => {
|
|
88
|
+
let result: RangeValue | undefined
|
|
89
|
+
let kind: 'date' | 'number' | undefined
|
|
90
|
+
for (let i = 0; i < childResults.length; i++) {
|
|
91
|
+
const value = childResults[i]
|
|
92
|
+
const valueKind = getRangeKind(value)
|
|
93
|
+
if (!valueKind) continue
|
|
94
|
+
kind ??= valueKind
|
|
95
|
+
if (kind !== valueKind) continue
|
|
96
|
+
if (result === undefined || compareRangeValues(value!, result) < 0) {
|
|
97
|
+
result = value
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return result
|
|
101
|
+
},
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Finds the maximum numeric or Date value. Invalid value types are ignored;
|
|
106
|
+
* `NaN` preserves the legacy numeric seeding behavior.
|
|
107
|
+
*/
|
|
108
|
+
export const aggregationFn_max = constructAggregationFn<
|
|
109
|
+
any,
|
|
110
|
+
any,
|
|
111
|
+
unknown,
|
|
112
|
+
RangeValue | undefined
|
|
113
|
+
>({
|
|
114
|
+
aggregate: (context) => {
|
|
115
|
+
const values = collectRangeValues(context)
|
|
116
|
+
let result = values[0]
|
|
117
|
+
for (let i = 1; i < values.length; i++) {
|
|
118
|
+
if (compareRangeValues(values[i]!, result!) > 0) result = values[i]
|
|
119
|
+
}
|
|
120
|
+
return result
|
|
121
|
+
},
|
|
122
|
+
merge: ({ childResults }) => {
|
|
123
|
+
let result: RangeValue | undefined
|
|
124
|
+
let kind: 'date' | 'number' | undefined
|
|
125
|
+
for (let i = 0; i < childResults.length; i++) {
|
|
126
|
+
const value = childResults[i]
|
|
127
|
+
const valueKind = getRangeKind(value)
|
|
128
|
+
if (!valueKind) continue
|
|
129
|
+
kind ??= valueKind
|
|
130
|
+
if (kind !== valueKind) continue
|
|
131
|
+
if (result === undefined || compareRangeValues(value!, result) > 0) {
|
|
132
|
+
result = value
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return result
|
|
136
|
+
},
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Finds the minimum and maximum numeric or Date values. Empty inputs return
|
|
141
|
+
* `[undefined, undefined]`, preserving the previous built-in result shape.
|
|
142
|
+
*/
|
|
143
|
+
export const aggregationFn_extent = constructAggregationFn<
|
|
144
|
+
any,
|
|
145
|
+
any,
|
|
146
|
+
unknown,
|
|
147
|
+
[RangeValue | undefined, RangeValue | undefined]
|
|
148
|
+
>({
|
|
149
|
+
aggregate: (context) => {
|
|
150
|
+
const values = collectRangeValues(context)
|
|
151
|
+
if (!values.length) return [undefined, undefined]
|
|
152
|
+
let min = values[0]!
|
|
153
|
+
let max = values[0]!
|
|
154
|
+
for (let i = 1; i < values.length; i++) {
|
|
155
|
+
const value = values[i]!
|
|
156
|
+
if (compareRangeValues(value, min) < 0) min = value
|
|
157
|
+
if (compareRangeValues(value, max) > 0) max = value
|
|
158
|
+
}
|
|
159
|
+
return [min, max]
|
|
160
|
+
},
|
|
161
|
+
merge: ({ childResults }) => {
|
|
162
|
+
let result: [RangeValue | undefined, RangeValue | undefined] = [
|
|
163
|
+
undefined,
|
|
164
|
+
undefined,
|
|
165
|
+
]
|
|
166
|
+
let kind: 'date' | 'number' | undefined
|
|
167
|
+
for (let i = 0; i < childResults.length; i++) {
|
|
168
|
+
const extent = childResults[i]!
|
|
169
|
+
const valueKind = getRangeKind(extent[0])
|
|
170
|
+
if (!valueKind) continue
|
|
171
|
+
kind ??= valueKind
|
|
172
|
+
if (kind !== valueKind) continue
|
|
173
|
+
if (result[0] === undefined) {
|
|
174
|
+
result = [extent[0], extent[1]]
|
|
175
|
+
} else {
|
|
176
|
+
if (compareRangeValues(extent[0]!, result[0]) < 0) {
|
|
177
|
+
result[0] = extent[0]
|
|
178
|
+
}
|
|
179
|
+
if (compareRangeValues(extent[1]!, result[1]!) > 0) {
|
|
180
|
+
result[1] = extent[1]
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return result
|
|
185
|
+
},
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Averages number and number-like row values. Nullish and non-numeric values
|
|
190
|
+
* are ignored; other values retain the legacy unary-plus coercion behavior.
|
|
191
|
+
*/
|
|
192
|
+
export const aggregationFn_mean = constructAggregationFn<
|
|
193
|
+
any,
|
|
194
|
+
any,
|
|
195
|
+
unknown,
|
|
196
|
+
number | undefined
|
|
197
|
+
>({
|
|
198
|
+
aggregate: (context) => {
|
|
199
|
+
let count = 0
|
|
200
|
+
let sum = 0
|
|
201
|
+
for (let i = 0; i < context.rows.length; i++) {
|
|
202
|
+
const value = context.getValue(context.rows[i]!)
|
|
203
|
+
if (value == null) continue
|
|
204
|
+
const numberValue = typeof value === 'number' ? value : +value
|
|
205
|
+
if (!Number.isNaN(numberValue)) {
|
|
206
|
+
count++
|
|
207
|
+
sum += numberValue
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return count ? sum / count : undefined
|
|
211
|
+
},
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Computes the median when every row value is a number. Returns `undefined`
|
|
216
|
+
* for empty inputs or when any value is non-numeric.
|
|
217
|
+
*/
|
|
218
|
+
export const aggregationFn_median = constructAggregationFn<
|
|
219
|
+
any,
|
|
220
|
+
any,
|
|
221
|
+
unknown,
|
|
222
|
+
number | undefined
|
|
223
|
+
>({
|
|
224
|
+
aggregate: (context) => {
|
|
225
|
+
if (!context.rows.length) return undefined
|
|
226
|
+
const values = new Array<number>(context.rows.length)
|
|
227
|
+
for (let i = 0; i < context.rows.length; i++) {
|
|
228
|
+
const value = context.getValue(context.rows[i]!)
|
|
229
|
+
if (typeof value !== 'number') return undefined
|
|
230
|
+
values[i] = value
|
|
231
|
+
}
|
|
232
|
+
values.sort((a, b) => a - b)
|
|
233
|
+
const mid = Math.floor(values.length / 2)
|
|
234
|
+
return values.length % 2
|
|
235
|
+
? values[mid]
|
|
236
|
+
: (values[mid - 1]! + values[mid]!) / 2
|
|
237
|
+
},
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
/** Collects distinct row values using JavaScript `Set` semantics. */
|
|
241
|
+
export const aggregationFn_unique = constructAggregationFn<
|
|
242
|
+
any,
|
|
243
|
+
any,
|
|
244
|
+
unknown,
|
|
245
|
+
Array<unknown>
|
|
246
|
+
>({
|
|
247
|
+
aggregate: (context) => {
|
|
248
|
+
const values = new Set<unknown>()
|
|
249
|
+
for (let i = 0; i < context.rows.length; i++) {
|
|
250
|
+
values.add(context.getValue(context.rows[i]!))
|
|
251
|
+
}
|
|
252
|
+
return Array.from(values)
|
|
253
|
+
},
|
|
254
|
+
})
|
|
255
|
+
|
|
256
|
+
/** Counts distinct row values using JavaScript `Set` semantics. */
|
|
257
|
+
export const aggregationFn_uniqueCount = constructAggregationFn<
|
|
258
|
+
any,
|
|
259
|
+
any,
|
|
260
|
+
unknown,
|
|
261
|
+
number
|
|
262
|
+
>({
|
|
263
|
+
aggregate: (context) => {
|
|
264
|
+
const values = new Set<unknown>()
|
|
265
|
+
for (let i = 0; i < context.rows.length; i++) {
|
|
266
|
+
values.add(context.getValue(context.rows[i]!))
|
|
267
|
+
}
|
|
268
|
+
return values.size
|
|
269
|
+
},
|
|
270
|
+
})
|
|
271
|
+
|
|
272
|
+
/** Counts rows, independently of the column's values. */
|
|
273
|
+
export const aggregationFn_count = constructAggregationFn<
|
|
274
|
+
any,
|
|
275
|
+
any,
|
|
276
|
+
unknown,
|
|
277
|
+
number
|
|
278
|
+
>({
|
|
279
|
+
aggregate: ({ rows }) => rows.length,
|
|
280
|
+
merge: ({ childResults }) => {
|
|
281
|
+
let count = 0
|
|
282
|
+
for (let i = 0; i < childResults.length; i++) {
|
|
283
|
+
const value = childResults[i]
|
|
284
|
+
if (isNumber(value)) count += value
|
|
285
|
+
}
|
|
286
|
+
return count
|
|
287
|
+
},
|
|
288
|
+
})
|
|
289
|
+
|
|
290
|
+
/** Returns the first row's value, including a nullish value. */
|
|
291
|
+
export const aggregationFn_first = constructAggregationFn<
|
|
292
|
+
any,
|
|
293
|
+
any,
|
|
294
|
+
unknown,
|
|
295
|
+
unknown
|
|
296
|
+
>({
|
|
297
|
+
aggregate: (context) =>
|
|
298
|
+
context.rows[0] ? context.getValue(context.rows[0]) : undefined,
|
|
299
|
+
merge: ({ childResults }) => childResults[0],
|
|
300
|
+
})
|
|
301
|
+
|
|
302
|
+
/** Returns the last row's value, including a nullish value. */
|
|
303
|
+
export const aggregationFn_last = constructAggregationFn<
|
|
304
|
+
any,
|
|
305
|
+
any,
|
|
306
|
+
unknown,
|
|
307
|
+
unknown
|
|
308
|
+
>({
|
|
309
|
+
aggregate: (context) => {
|
|
310
|
+
const row = context.rows[context.rows.length - 1]
|
|
311
|
+
return row ? context.getValue(row) : undefined
|
|
312
|
+
},
|
|
313
|
+
merge: ({ childResults }) => childResults[childResults.length - 1],
|
|
314
|
+
})
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Full built-in registry. Register individual definitions for tree-shaking.
|
|
318
|
+
*
|
|
319
|
+
* @deprecated Import individual `aggregationFn_*` definitions instead for a
|
|
320
|
+
* smaller bundle. This registry remains available for compatibility.
|
|
321
|
+
*/
|
|
322
|
+
export const aggregationFns = {
|
|
323
|
+
sum: aggregationFn_sum,
|
|
324
|
+
min: aggregationFn_min,
|
|
325
|
+
max: aggregationFn_max,
|
|
326
|
+
extent: aggregationFn_extent,
|
|
327
|
+
mean: aggregationFn_mean,
|
|
328
|
+
median: aggregationFn_median,
|
|
329
|
+
unique: aggregationFn_unique,
|
|
330
|
+
uniqueCount: aggregationFn_uniqueCount,
|
|
331
|
+
count: aggregationFn_count,
|
|
332
|
+
first: aggregationFn_first,
|
|
333
|
+
last: aggregationFn_last,
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
export type BuiltInAggregationFn = keyof typeof aggregationFns
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { callMemoOrStaticFn, tableMemo } from '../../utils'
|
|
2
|
-
import {
|
|
2
|
+
import { column_getCanGlobalFilter } from '../global-filtering/globalFilteringFeature.utils'
|
|
3
|
+
import {
|
|
4
|
+
column_getFacetedRowModel,
|
|
5
|
+
table_getGlobalFacetedRowModel,
|
|
6
|
+
} from './columnFacetingFeature.utils'
|
|
3
7
|
import type { Row } from '../../types/Row'
|
|
4
8
|
import type { Table, Table_Internal } from '../../types/Table'
|
|
5
9
|
import type { TableFeatures } from '../../types/TableFeatures'
|
|
@@ -21,9 +25,18 @@ export function createFacetedMinMaxValues<
|
|
|
21
25
|
const table = _table as unknown as Table_Internal<TFeatures, TData>
|
|
22
26
|
return tableMemo({
|
|
23
27
|
feature: 'columnFacetingFeature',
|
|
24
|
-
fn: (flatRows) => _createFacetedMinMaxValues(columnId, flatRows),
|
|
28
|
+
fn: (flatRows) => _createFacetedMinMaxValues(table, columnId, flatRows),
|
|
25
29
|
fnName: 'table.getFacetedMinMaxValues',
|
|
26
30
|
memoDeps: () => {
|
|
31
|
+
if (columnId === '__global__') {
|
|
32
|
+
return [
|
|
33
|
+
callMemoOrStaticFn(
|
|
34
|
+
table,
|
|
35
|
+
'getGlobalFacetedRowModel',
|
|
36
|
+
table_getGlobalFacetedRowModel,
|
|
37
|
+
).flatRows,
|
|
38
|
+
]
|
|
39
|
+
}
|
|
27
40
|
const column = table.getColumn(columnId)
|
|
28
41
|
if (!column) return [table.getPreFilteredRowModel().flatRows]
|
|
29
42
|
return [
|
|
@@ -44,21 +57,34 @@ function _createFacetedMinMaxValues<
|
|
|
44
57
|
TFeatures extends TableFeatures,
|
|
45
58
|
TData extends RowData = any,
|
|
46
59
|
>(
|
|
60
|
+
table: Table_Internal<TFeatures, TData>,
|
|
47
61
|
columnId: string,
|
|
48
62
|
flatRows: Array<Row<TFeatures, TData>>,
|
|
49
63
|
): undefined | [number, number] {
|
|
50
64
|
if (!flatRows.length) return undefined
|
|
51
65
|
|
|
66
|
+
// The global context aggregates values across every column that
|
|
67
|
+
// participates in global filtering
|
|
68
|
+
const columnIds =
|
|
69
|
+
columnId === '__global__'
|
|
70
|
+
? table
|
|
71
|
+
.getAllLeafColumns()
|
|
72
|
+
.filter((column) => column_getCanGlobalFilter(column))
|
|
73
|
+
.map((column) => column.id)
|
|
74
|
+
: [columnId]
|
|
75
|
+
|
|
52
76
|
let facetedMinValue = Number.POSITIVE_INFINITY
|
|
53
77
|
let facetedMaxValue = Number.NEGATIVE_INFINITY
|
|
54
78
|
let foundAny = false
|
|
55
79
|
|
|
56
80
|
for (let i = 0; i < flatRows.length; i++) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
81
|
+
for (let c = 0; c < columnIds.length; c++) {
|
|
82
|
+
const value = Number(flatRows[i]!.getValue(columnIds[c]!))
|
|
83
|
+
if (Number.isNaN(value)) continue
|
|
84
|
+
foundAny = true
|
|
85
|
+
if (value < facetedMinValue) facetedMinValue = value
|
|
86
|
+
if (value > facetedMaxValue) facetedMaxValue = value
|
|
87
|
+
}
|
|
62
88
|
}
|
|
63
89
|
|
|
64
90
|
if (!foundAny) return undefined
|
|
@@ -67,7 +67,10 @@ function _createFacetedRowModel<
|
|
|
67
67
|
if (id !== columnId) filterableIds.push(id)
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
|
-
|
|
70
|
+
// The global context excludes the global filter itself, mirroring how a
|
|
71
|
+
// column's faceted model excludes that column's own filter
|
|
72
|
+
if (globalFilter && columnId !== '__global__')
|
|
73
|
+
filterableIds.push('__global__')
|
|
71
74
|
|
|
72
75
|
if (!filterableIds.length) {
|
|
73
76
|
return preRowModel
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { callMemoOrStaticFn, tableMemo } from '../../utils'
|
|
2
|
-
import {
|
|
2
|
+
import { column_getCanGlobalFilter } from '../global-filtering/globalFilteringFeature.utils'
|
|
3
|
+
import {
|
|
4
|
+
column_getFacetedRowModel,
|
|
5
|
+
table_getGlobalFacetedRowModel,
|
|
6
|
+
} from './columnFacetingFeature.utils'
|
|
3
7
|
import type { Row } from '../../types/Row'
|
|
4
8
|
import type { Table, Table_Internal } from '../../types/Table'
|
|
5
9
|
import type { TableFeatures } from '../../types/TableFeatures'
|
|
@@ -24,6 +28,15 @@ export function createFacetedUniqueValues<
|
|
|
24
28
|
table,
|
|
25
29
|
fnName: 'table.getFacetedUniqueValues',
|
|
26
30
|
memoDeps: () => {
|
|
31
|
+
if (columnId === '__global__') {
|
|
32
|
+
return [
|
|
33
|
+
callMemoOrStaticFn(
|
|
34
|
+
table,
|
|
35
|
+
'getGlobalFacetedRowModel',
|
|
36
|
+
table_getGlobalFacetedRowModel,
|
|
37
|
+
).flatRows,
|
|
38
|
+
]
|
|
39
|
+
}
|
|
27
40
|
const column = table.getColumn(columnId)
|
|
28
41
|
if (!column) return [table.getPreFilteredRowModel().flatRows]
|
|
29
42
|
return [
|
|
@@ -35,7 +48,7 @@ export function createFacetedUniqueValues<
|
|
|
35
48
|
).flatRows,
|
|
36
49
|
]
|
|
37
50
|
},
|
|
38
|
-
fn: (flatRows) => _createFacetedUniqueValues(columnId, flatRows),
|
|
51
|
+
fn: (flatRows) => _createFacetedUniqueValues(table, columnId, flatRows),
|
|
39
52
|
})
|
|
40
53
|
}
|
|
41
54
|
}
|
|
@@ -43,19 +56,40 @@ export function createFacetedUniqueValues<
|
|
|
43
56
|
function _createFacetedUniqueValues<
|
|
44
57
|
TFeatures extends TableFeatures,
|
|
45
58
|
TData extends RowData = any,
|
|
46
|
-
>(
|
|
59
|
+
>(
|
|
60
|
+
table: Table_Internal<TFeatures, TData>,
|
|
61
|
+
columnId: string,
|
|
62
|
+
flatRows: Array<Row<TFeatures, TData>>,
|
|
63
|
+
): Map<any, number> {
|
|
64
|
+
// The global context aggregates unique values across every column that
|
|
65
|
+
// participates in global filtering
|
|
66
|
+
const columnIds =
|
|
67
|
+
columnId === '__global__'
|
|
68
|
+
? table
|
|
69
|
+
.getAllLeafColumns()
|
|
70
|
+
.filter((column) => column_getCanGlobalFilter(column))
|
|
71
|
+
.map((column) => column.id)
|
|
72
|
+
: [columnId]
|
|
73
|
+
|
|
47
74
|
const facetedUniqueValues = new Map<any, number>()
|
|
48
75
|
|
|
49
76
|
for (let i = 0; i < flatRows.length; i++) {
|
|
50
|
-
|
|
77
|
+
for (let c = 0; c < columnIds.length; c++) {
|
|
78
|
+
// the declared return type is Array, but rows return undefined for
|
|
79
|
+
// columns without an accessor (e.g. display columns)
|
|
80
|
+
const values = flatRows[i]!.getUniqueValues(columnIds[c]!) as
|
|
81
|
+
| Array<unknown>
|
|
82
|
+
| undefined
|
|
83
|
+
if (!values) continue
|
|
51
84
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
85
|
+
for (let j = 0; j < values.length; j++) {
|
|
86
|
+
const value = values[j]
|
|
87
|
+
const previousValue = facetedUniqueValues.get(value)
|
|
88
|
+
facetedUniqueValues.set(
|
|
89
|
+
value,
|
|
90
|
+
previousValue === undefined ? 1 : previousValue + 1,
|
|
91
|
+
)
|
|
92
|
+
}
|
|
59
93
|
}
|
|
60
94
|
}
|
|
61
95
|
|
|
@@ -2,10 +2,10 @@ import type {
|
|
|
2
2
|
CreatedFilterFn,
|
|
3
3
|
ExtractFilterMeta,
|
|
4
4
|
FilterFnDef,
|
|
5
|
-
} from '
|
|
6
|
-
import type { RowData } from '
|
|
7
|
-
import type { TableFeatures } from '
|
|
8
|
-
import type { Row } from '
|
|
5
|
+
} from './columnFilteringFeature.types'
|
|
6
|
+
import type { RowData } from '../../types/type-utils'
|
|
7
|
+
import type { TableFeatures } from '../../types/TableFeatures'
|
|
8
|
+
import type { Row } from '../../types/Row'
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Builds a `FilterFn` from a value-level comparator plus optional resolvers.
|
|
@@ -5,11 +5,8 @@ import {
|
|
|
5
5
|
makeStateUpdater,
|
|
6
6
|
} from '../../utils'
|
|
7
7
|
import {
|
|
8
|
-
cell_getIsAggregated,
|
|
9
8
|
cell_getIsGrouped,
|
|
10
9
|
cell_getIsPlaceholder,
|
|
11
|
-
column_getAggregationFn,
|
|
12
|
-
column_getAutoAggregationFn,
|
|
13
10
|
column_getCanGroup,
|
|
14
11
|
column_getGroupedIndex,
|
|
15
12
|
column_getIsGrouped,
|
|
@@ -24,7 +21,7 @@ import {
|
|
|
24
21
|
import type { TableFeature } from '../../types/TableFeatures'
|
|
25
22
|
|
|
26
23
|
/**
|
|
27
|
-
* Feature that adds column grouping state
|
|
24
|
+
* Feature that adds column grouping state and grouped row APIs.
|
|
28
25
|
*/
|
|
29
26
|
export const columnGroupingFeature: TableFeature = {
|
|
30
27
|
getInitialState: (initialState) => {
|
|
@@ -34,13 +31,6 @@ export const columnGroupingFeature: TableFeature = {
|
|
|
34
31
|
}
|
|
35
32
|
},
|
|
36
33
|
|
|
37
|
-
getDefaultColumnDef: () => {
|
|
38
|
-
return {
|
|
39
|
-
aggregatedCell: ({ getValue }: any) => getValue()?.toString?.() ?? null,
|
|
40
|
-
aggregationFn: 'auto',
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
|
|
44
34
|
getDefaultTableOptions: (table) => {
|
|
45
35
|
return {
|
|
46
36
|
onGroupingChange: makeStateUpdater('grouping', table),
|
|
@@ -56,9 +46,6 @@ export const columnGroupingFeature: TableFeature = {
|
|
|
56
46
|
cell_getIsPlaceholder: {
|
|
57
47
|
fn: (cell) => cell_getIsPlaceholder(cell),
|
|
58
48
|
},
|
|
59
|
-
cell_getIsAggregated: {
|
|
60
|
-
fn: (cell) => cell_getIsAggregated(cell),
|
|
61
|
-
},
|
|
62
49
|
})
|
|
63
50
|
},
|
|
64
51
|
|
|
@@ -79,12 +66,6 @@ export const columnGroupingFeature: TableFeature = {
|
|
|
79
66
|
column_getToggleGroupingHandler: {
|
|
80
67
|
fn: (column) => column_getToggleGroupingHandler(column),
|
|
81
68
|
},
|
|
82
|
-
column_getAutoAggregationFn: {
|
|
83
|
-
fn: (column) => column_getAutoAggregationFn(column),
|
|
84
|
-
},
|
|
85
|
-
column_getAggregationFn: {
|
|
86
|
-
fn: (column) => column_getAggregationFn(column),
|
|
87
|
-
},
|
|
88
69
|
})
|
|
89
70
|
},
|
|
90
71
|
|