The Pivot Table widget enables the dynamic grouping and aggregation of object data and then displays this aggregated data in tabular form. Module builders configuring a Pivot Table widget can use features including:
The example below shows a configured Pivot Table widget displaying Flight Alerts data and filtering a downstream Object list widget:

When configuring a pivot table, buidlers can either derive data from objects or function output.
The example below shows the initial state of an object-backed pivot table before configuration. The widget's configuration panel shows the initial input Base object set set to Flight Alert: All.

The Pivot Table widget has the following core configuration options:
Total row will be the result of performing the multi-step aggregation on all the raw values of the objects before each aggregation.A function-backed pivot table derives its data from the output of a function.
This approach is useful for the following use cases:
values, which holds the pivot table values.Below is an example of a TypeScript interface that can be used for a function-backed pivot table.
In this interface:
region, productType, productName, and year are fields used for grouping.totalSales and estimatedSales are the values displayed in the pivot table cells.Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18interface SalesData { region?: string; year?: string; productType?: string; productName?: string; // Values object containing the metrics values: { totalSales: Integer; estimatedSales: Integer; } }; @Function() public sales_function_backed_pivot_table(): SalesData[] { // Your implementation here ... };
After selecting a function in the dropdown, builders can choose:
Once configured, the pivot table will render with the data returned from your function:
Function-backed pivot tables support displaying totals. To render a total, return a struct in your list that follows the guidelines below. For the examples below, assume that region and productType are the row grouping fields and year is the column grouping field.
Row totals: To represent a sum of all rows (row total), omit the row grouping fields in the data point.
Example: A data point representing the total for 2021:
Copied!1 2 3 4 5 6 7{ year: "2021"; values: { totalSales: 622000; estimatedSales: 57000; } };
Column totals: To represent a sum of all columns (column total), omit the column grouping fields in the data point.
Example: A data point representing the total for EU and Clothing:
Copied!1 2 3 4 5 6 7 8{ region: "EU"; productType: "Clothing"; values: { totalSales: 57000; estimatedSales: 57000; } }
Grand totals: To represent a grand total, omit all grouping fields.
Copied!1 2 3 4 5 6{ values: { totalSales: 3147000; estimatedSales: 3160000; } }
Null buckets are useful for representing missing or undefined data.
To create a null bucket:
undefined for the bucket's value.Below is an example:
Copied!1 2 3 4 5 6 7interface SiteData { site?: string; part?: string | undefined; // Note the explicit undefined type values: { quantity: Double; } }
Copied!1 2 3 4 5 6 7{ "part": undefined, "source": "SourceA", "values": { "quantity": 100 } }
Omitting a field is different from passing undefined. Omitting a field creates a total, while undefined creates a null bucket.
Expandable rows allow users to drill down into more detailed data.
To implement expandable rows:
Considering the following interface, we would select productName and productType as our expandable rows in the configuration options:
Copied!1 2 3 4 5 6 7 8 9 10interface SalesData { region: string; year: string; productType?: string; productName?: string; values: { totalSales: Integer; estimatedSales: Integer; } };
Below are examples of three levels of expansion:
region level only.Copied!1 2 3 4 5 6 7 8 9[ { "region": "NA", "year": "2021", "values": { "totalSales": 30000 } } ]
region and productType.Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26[ { "region": "NA", "year": "2021", "productType": "Clothing", "values": { "totalSales": 90000 } }, { "region": "NA", "year": "2021", "productType": "Electronics", "values": { "totalSales": 150000 } }, { "region": "NA", "year": "2021", "productType": "Furniture", "values": { "totalSales": 60000 } } ]
region, productType, and productName.Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29[ { "region": "NA", "year": "2021", "productType": "Electronics", "productName": "ProductA", "values": { "totalSales": 5000 } }, { "region": "NA", "year": "2021", "productType": "Electronics", "productName": "ProductB", "values": { "totalSales": 5000 } }, { "region": "NA", "year": "2021", "productType": "Electronics", "productName": "ProductC", "values": { "totalSales": 5000 } } ]
The output selection of a function-backed pivot table can be written to a struct variable. The struct fields are derived from the function's output.
The Pivot Table widget has the following display and styling options: