Customizing Pivot Columns
There are a number of ways to customize the generated pivot columns and we'll cover each of them in this page. For a longer walkthrough with live demos, see customizing generated pivot columns.
You can pass a column object (or a function that returns one) in three places. Choose the one that matches the scope you want:
pivotColumnon<InfiniteTable />— every generated pivot columnpivotBy.column— all columns in the group generated for that pivot field- aggregationReducers.pivotColumn — only columns generated for that aggregation
Those objects have the same shape as a normal
column, so you can set header, size, style, defaultSortable, and so on.Global: the pivotColumn prop
pivotColumn is applied to every generated pivot column (leaf values and totals). Use it to override inherited column properties(sortability, width, headers, etc).<InfiniteTable
pivotColumn={{
defaultSortable: true,
defaultWidth: 180,
}}
/> COPY
You can also pass a function when the config should depend on the generated column — for example to make leaf columns sortable but keep totals unsortable:
<InfiniteTable
pivotColumn={({ column }) => ({
defaultSortable: !column.pivotTotalColumn,
})}
/> COPY
Per pivot field: pivotBy.column
pivotBy.column applies to all pivot columns in the column group generated for that field. Use it when only one pivot level should be customized — for example, make every canDesign column sortable, without touching the country group.const pivotBy: DataSourcePivotBy<Developer>[] = [
{ field: 'country' },
{
field: 'canDesign',
column: {
defaultSortable: true,
defaultWidth: 400,
},
},
]; COPY
A function receives the generated column, so you can vary the header (or any other property) per pivot value:
const pivotBy: DataSourcePivotBy<Developer>[] = [
{ field: 'country' },
{
field: 'canDesign',
column: ({ column }) => ({
header: column.pivotGroupKey === 'yes' ? 'Designer' : 'Not a Designer',
}),
},
]; COPY
Per aggregation: aggregationReducers.pivotColumn
Each
reducer can define a pivotColumn. That config is applied only to columns generated for that aggregation — so you can make salary columns sortable and leave a count aggregation as it is.const aggregationReducers: DataSourceProps<Developer>['aggregationReducers'] = {
salary: {
field: 'salary',
initialValue: 0,
reducer: (acc, sum) => acc + sum,
pivotColumn: {
defaultSortable: true,
},
},
license: {
field: 'license',
initialValue: 0,
reducer: (acc) => acc + 1,
},
}; COPY
aggregationReducers.pivotColumn on a reducer can also choose which original column to inherit from, or opt out of inheritance entirely — see below.Inheriting from initial columns#
Pivoting is all about aggregations, so you need to specify the
reducers that will aggregate your data. Each reducer can have a field property that specifies the field that will be used for aggregation.If the table
columns collection already has a column bound to the field used in the aggregation, the column configuration will be inherited by the generated pivot column. Override that with aggregationReducers.pivotColumn.inheritFromColumn — pass another column id to inherit from that column instead, or false to inherit from none. See the aggregationReducers.pivotColumn reference for the full column config you can set on the reducer.const columns: InfiniteTablePropColumns<Developer> = {
preferredLanguage: {
field: 'preferredLanguage',
style: { color: 'blue' },
},
age: {
field: 'age',
style: {
color: 'magenta',
background: 'yellow',
},
},
salary: {
field: 'salary',
type: 'number',
style: {
color: 'red',
},
},
canDesign: { field: 'canDesign' },
country: { field: 'country' },
firstName: { field: 'firstName' },
id: { field: 'id' },
};
const avgReducer: InfiniteTableColumnAggregator<Developer, any> = {
initialValue: 0,
reducer: (acc, sum) => acc + sum,
done: (sum, arr) => {
return Math.floor(arr.length ? sum / arr.length : 0);
},
};
const aggregationReducers: DataSourceProps<Developer>['aggregationReducers'] = {
// will have the same configuration as the `salary` column
avgSalary: { field: 'salary', ...avgReducer },
avgAge: {
field: 'age',
...avgReducer,
pivotColumn: {
// will have the same configuration as the `preferredLanguage` column
inheritFromColumn: 'preferredLanguage',
// but specify a custom default width
defaultWidth: 500,
},
},
}; COPY
View Mode
Fork Forkimport { InfiniteTable, DataSource, GroupRowsState, } from '@infinite-table/infinite-react'; import type { DataSourcePropAggregationReducers, InfiniteTableColumnAggregator, InfiniteTablePropColumns, DataSourceGroupBy, DataSourcePivotBy, } from '@infinite-table/infinite-react'; import * as React from 'react'; type Developer = { id: number; firstName: string; lastName: string; country: string; city: string; currency: string; preferredLanguage: string; stack: string; canDesign: 'yes' | 'no'; hobby: string; salary: number; age: number; }; const dataSource = () => { return fetch('https://data.infinite-table.com' + '/developers100') .then((r) => r.json()) .then((data: Developer[]) => data); }; const avgReducer: InfiniteTableColumnAggregator<Developer, any> = { initialValue: 0, reducer: (acc, sum) => acc + sum, done: (sum, arr) => (arr.length ? sum / arr.length : 0), }; const columnAggregations: DataSourcePropAggregationReducers<Developer> = { avgSalary: { field: 'salary', name: 'Average salary', ...avgReducer, }, avgAge: { field: 'age', ...avgReducer, pivotColumn: { defaultWidth: 500, inheritFromColumn: 'firstName', }, }, }; const columns: InfiniteTablePropColumns<Developer> = { id: { field: 'id' }, firstName: { field: 'firstName', style: { fontWeight: 'bold', }, renderValue: ({ value }) => <>{value}!</>, }, preferredLanguage: { field: 'preferredLanguage' }, stack: { field: 'stack' }, country: { field: 'country' }, canDesign: { field: 'canDesign' }, hobby: { field: 'hobby' }, city: { field: 'city' }, age: { field: 'age' }, salary: { field: 'salary', type: 'number', header: 'Salary', style: { color: 'red' }, }, currency: { field: 'currency' }, }; const groupRowsState = new GroupRowsState({ expandedRows: [], collapsedRows: true, }); export default function PivotByExample() { const groupBy: DataSourceGroupBy<Developer>[] = React.useMemo( () => [ { field: 'preferredLanguage', }, { field: 'stack' }, ], [], ); const pivotBy: DataSourcePivotBy<Developer>[] = React.useMemo( () => [ { field: 'country' }, { field: 'canDesign', }, ], [], ); return ( <> <DataSource<Developer> primaryKey="id" data={dataSource} groupBy={groupBy} pivotBy={pivotBy} aggregationReducers={columnAggregations} defaultGroupRowsState={groupRowsState} > {({ pivotColumns, pivotColumnGroups }) => { return ( <InfiniteTable<Developer> debugId="pivot-column-inherit-example" columns={columns} hideEmptyGroupColumns pivotColumns={pivotColumns} pivotColumnGroups={pivotColumnGroups} columnDefaultWidth={180} /> ); }} </DataSource> </> ); }