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, builders 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.The Pivot Table widget supports a maximum of seven row groupings. If you need to work with more groupings, consider adding hidden groupings to your table configuration. This approach allows users to swap between hidden groupings in the UI, effectively managing more groupings than the limit while maintaining performance.
The Pivot Table widget supports the following keyboard shortcuts for working with selected cells:
Cmd+C (macOS) or Ctrl+C (Windows) to copy the selected cells as tab-separated values. The output includes row groupings, aggregation values, or both, depending on the selection.Shift+Left and Shift+Right to refine your selection between full rows, row groupings only, and aggregation values only.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.TypeScript V1 and TypeScript V2 use the same implementation for function-backed pivot tables. The following patterns and examples apply to both versions.
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.Avoid using empty strings ('') for null or missing values in grouping fields. Workshop interprets empty strings as if the field is omitted, causing records with empty strings to roll up into subtotal rows rather than appear as individual grouping rows. Always use undefined for true null buckets.
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: