Blazorise PivotGrid component
Build read-only Excel-like pivot tables for multi-dimensional data analysis.
The PivotGrid component groups source records into row and column dimensions, calculates aggregate values, and renders totals and subtotals in a table layout. It is designed for analysis and reporting scenarios where users inspect summarized data instead of editing source records.
To use the PivotGrid component, install the Blazorise.PivotGrid package first.
Installation
NuGet
Install extension from NuGet.Install-Package Blazorise.PivotGrid
Imports
In your main _Imports.razor add:
@using Blazorise.PivotGrid
Fundamentals
Data Areas
PivotGrid uses declarative child components to define each data area:
PivotGridColumns: fields that create column groups.PivotGridRows: fields that create row groups.PivotGridAggregates: value fields that calculate totals, such as sum or count.PivotGridFields: optional field catalog used by the runtime field chooser.
Runtime Layout
Enable FieldChooser when users should rearrange the pivot layout at runtime. The field chooser lets users move available fields into rows, columns, values, and filters.
Data Loading
Bind in-memory data with Data, handle callback loading with ReadData, or provide a reusable implementation with DataProvider. A data provider can be implemented in a separate package when the data comes from a specific backend or protocol.
Examples
Basic Pivot Table
Define columns, rows, and aggregates declaratively.| Category / Product | Berlin | London | Madrid | Paris | Grand Total | |||||
|---|---|---|---|---|---|---|---|---|---|---|
| Amount | Units | Amount | Units | Amount | Units | Amount | Units | Amount | Units | |
| Hardware | $89,600 | 100 | $127,500 | 34 | $68,200 | 19 | $98,400 | 28 | $383,700 | 181 |
| Hardware / Laptops | $51,200 | 18 | $127,500 | 34 | $68,200 | 19 | $98,400 | 28 | $345,300 | 99 |
| Hardware / Monitors | $38,400 | 82 | $38,400 | 82 | ||||||
| Services | $66,300 | 36 | $28,700 | 64 | $118,600 | 47 | $213,600 | 147 | ||
| Services / Consulting | $66,300 | 36 | $66,300 | 36 | ||||||
| Services / Implementation | $118,600 | 47 | $118,600 | 47 | ||||||
| Services / Training | $28,700 | 64 | $28,700 | 64 | ||||||
| Software | $94,200 | 205 | $76,800 | 192 | $45,100 | 135 | $124,500 | 355 | $340,600 | 887 |
| Software / Licenses | $94,200 | 205 | $94,200 | 205 | ||||||
| Software / Subscriptions | $124,500 | 355 | $124,500 | 355 | ||||||
| Software / Support | $76,800 | 192 | $45,100 | 135 | $121,900 | 327 | ||||
| Grand Total | $183,800 | 305 | $270,600 | 262 | $142,000 | 218 | $341,500 | 430 | $937,900 | 1215 |
<PivotGrid TItem="PivotSale" Data="" ShowRowTotals ShowColumnTotals ShowRowSubtotals Striped Hoverable> <PivotGridColumns> <PivotGridColumn Field="@nameof( PivotSale.City )" Caption="City" /> </PivotGridColumns> <PivotGridRows> <PivotGridRow Field="@nameof( PivotSale.Category )" Caption="Category" /> <PivotGridRow Field="@nameof( PivotSale.Product )" Caption="Product" /> </PivotGridRows> <PivotGridAggregates> <PivotGridAggregate Field="@nameof( PivotSale.Amount )" Caption="Amount" DisplayFormat="{0:C0}" DisplayFormatProvider="@System.Globalization.CultureInfo.GetCultureInfo( "en-US" )" /> <PivotGridAggregate Field="@nameof( PivotSale.Units )" Caption="Units" Aggregate="PivotGridAggregateFunction.Sum" /> </PivotGridAggregates> </PivotGrid>
@code { private readonly List<PivotSale> Sales = [ new() { City = "Berlin", Category = "Hardware", Product = "Laptops", Amount = 51200m, Units = 18 }, new() { City = "Berlin", Category = "Hardware", Product = "Monitors", Amount = 38400m, Units = 82 }, new() { City = "Berlin", Category = "Software", Product = "Licenses", Amount = 94200m, Units = 205 }, new() { City = "London", Category = "Hardware", Product = "Laptops", Amount = 127500m, Units = 34 }, new() { City = "London", Category = "Services", Product = "Consulting", Amount = 66300m, Units = 36 }, new() { City = "London", Category = "Software", Product = "Support", Amount = 76800m, Units = 192 }, new() { City = "Madrid", Category = "Hardware", Product = "Laptops", Amount = 68200m, Units = 19 }, new() { City = "Madrid", Category = "Services", Product = "Training", Amount = 28700m, Units = 64 }, new() { City = "Madrid", Category = "Software", Product = "Support", Amount = 45100m, Units = 135 }, new() { City = "Paris", Category = "Hardware", Product = "Laptops", Amount = 98400m, Units = 28 }, new() { City = "Paris", Category = "Services", Product = "Implementation", Amount = 118600m, Units = 47 }, new() { City = "Paris", Category = "Software", Product = "Subscriptions", Amount = 124500m, Units = 355 }, ]; public class PivotSale { public string City { get; set; } public string Category { get; set; } public string Product { get; set; } public decimal Amount { get; set; } public int Units { get; set; } } }
Field Chooser
EnableShowToolbar and FieldChooser to show the built-in toolbar command and modal field chooser. Use ToolbarOptions to hide optional built-in toolbar buttons.
| Category / Product | Berlin | London | Madrid | Paris | Grand Total | |||||
|---|---|---|---|---|---|---|---|---|---|---|
| Amount | Units | Amount | Units | Amount | Units | Amount | Units | Amount | Units | |
| Hardware | $51,200 | 18 | $127,500 | 34 | $178,700 | 52 | ||||
| Hardware / Laptops | $51,200 | 18 | $127,500 | 34 | $178,700 | 52 | ||||
| Services | $66,300 | 36 | $28,700 | 64 | $95,000 | 100 | ||||
| Services / Consulting | $66,300 | 36 | $66,300 | 36 | ||||||
| Services / Training | $28,700 | 64 | $28,700 | 64 | ||||||
| Software | $94,200 | 205 | $124,500 | 355 | $218,700 | 560 | ||||
| Software / Licenses | $94,200 | 205 | $94,200 | 205 | ||||||
| Software / Subscriptions | $124,500 | 355 | $124,500 | 355 | ||||||
| Grand Total | $145,400 | 223 | $193,800 | 70 | $28,700 | 64 | $124,500 | 355 | $492,400 | 712 |
<PivotGrid TItem="PivotSale" Data="" ShowToolbar FieldChooser ShowRowTotals ShowColumnTotals ShowRowSubtotals Striped Hoverable> <PivotGridFields> <PivotGridField Field="@nameof( PivotSale.Region )" Caption="Region" /> <PivotGridField Field="@nameof( PivotSale.City )" Caption="City" /> <PivotGridField Field="@nameof( PivotSale.Category )" Caption="Category" /> <PivotGridField Field="@nameof( PivotSale.Product )" Caption="Product" /> <PivotGridField Field="@nameof( PivotSale.Amount )" Caption="Amount" /> <PivotGridField Field="@nameof( PivotSale.Units )" Caption="Units" /> </PivotGridFields> <PivotGridColumns> <PivotGridColumn Field="@nameof( PivotSale.City )" Caption="City" /> </PivotGridColumns> <PivotGridRows> <PivotGridRow Field="@nameof( PivotSale.Category )" Caption="Category" /> <PivotGridRow Field="@nameof( PivotSale.Product )" Caption="Product" /> </PivotGridRows> <PivotGridAggregates> <PivotGridAggregate Field="@nameof( PivotSale.Amount )" Caption="Amount" DisplayFormat="{0:C0}" DisplayFormatProvider="@System.Globalization.CultureInfo.GetCultureInfo( "en-US" )" /> <PivotGridAggregate Field="@nameof( PivotSale.Units )" Caption="Units" Aggregate="PivotGridAggregateFunction.Sum" /> </PivotGridAggregates> </PivotGrid>
@code { private readonly List<PivotSale> Sales = [ new() { Region = "Central", City = "Berlin", Category = "Hardware", Product = "Laptops", Amount = 51200m, Units = 18 }, new() { Region = "Central", City = "Berlin", Category = "Software", Product = "Licenses", Amount = 94200m, Units = 205 }, new() { Region = "Western", City = "London", Category = "Hardware", Product = "Laptops", Amount = 127500m, Units = 34 }, new() { Region = "Western", City = "London", Category = "Services", Product = "Consulting", Amount = 66300m, Units = 36 }, new() { Region = "Central", City = "Madrid", Category = "Services", Product = "Training", Amount = 28700m, Units = 64 }, new() { Region = "Western", City = "Paris", Category = "Software", Product = "Subscriptions", Amount = 124500m, Units = 355 }, ]; public class PivotSale { public string Region { get; set; } public string City { get; set; } public string Category { get; set; } public string Product { get; set; } public decimal Amount { get; set; } public int Units { get; set; } } }
Custom Toolbar
UseToolbarTemplate to replace the built-in toolbar and invoke PivotGrid commands through the toolbar context.
| Region / Category | Berlin | London | Madrid | Paris | Grand Total |
|---|---|---|---|---|---|
| Central | $145,400 | $145,400 | |||
| Southern | $28,700 | $28,700 | |||
| Western | $193,800 | $124,500 | $318,300 | ||
| Grand Total | $145,400 | $193,800 | $28,700 | $124,500 | $492,400 |
<PivotGrid TItem="ToolbarSale" Data="" FieldChooser ExpandableRows InitiallyExpanded="false" ShowRowTotals ShowColumnTotals ShowRowSubtotals Striped Hoverable> <ToolbarTemplate Context="toolbar"> <Div Padding="Padding.Is3" Border="Border.Is1" Flex="Flex.AlignItems.Center" Gap="Gap.Is2"> @if ( toolbar.CanOpenFieldChooser ) { <Button Color="Color.Primary" Outline Clicked="@(() => toolbar.OpenFieldChooserCommand())"> <Icon Name="IconName.List" Margin="Margin.Is2.FromEnd" /> @toolbar.FieldsText </Button> } <Button Color="Color.Success" Outline Clicked="@(() => toolbar.RefreshCommand())"> <Icon Name="IconName.Reply" Margin="Margin.Is2.FromEnd" /> @toolbar.RefreshText </Button> @if ( toolbar.CanExpandCollapseGroups ) { <Buttons> <Button Color="Color.Secondary" Outline Clicked="@(() => toolbar.ExpandAllCommand())"> <Icon Name="IconName.ChevronDoubleDown" /> </Button> <Button Color="Color.Secondary" Outline Clicked="@(() => toolbar.CollapseAllCommand())"> <Icon Name="IconName.ChevronDoubleUp" /> </Button> </Buttons> } <Button Color="Color.Secondary" Outline Disabled="@(!toolbar.CanResetLayout)" Clicked="@(() => toolbar.ResetLayoutCommand())"> <Icon Name="IconName.Undo" Margin="Margin.Is2.FromEnd" /> @toolbar.ResetLayoutText </Button> </Div> </ToolbarTemplate> <ChildContent> <PivotGridFields> <PivotGridField Field="@nameof( ToolbarSale.Region )" Caption="Region" /> <PivotGridField Field="@nameof( ToolbarSale.City )" Caption="City" /> <PivotGridField Field="@nameof( ToolbarSale.Category )" Caption="Category" /> <PivotGridField Field="@nameof( ToolbarSale.Product )" Caption="Product" /> <PivotGridField Field="@nameof( ToolbarSale.Amount )" Caption="Amount" /> </PivotGridFields> <PivotGridColumns> <PivotGridColumn Field="@nameof( ToolbarSale.City )" Caption="City" /> </PivotGridColumns> <PivotGridRows> <PivotGridRow Field="@nameof( ToolbarSale.Region )" Caption="Region" /> <PivotGridRow Field="@nameof( ToolbarSale.Category )" Caption="Category" /> </PivotGridRows> <PivotGridAggregates> <PivotGridAggregate Field="@nameof( ToolbarSale.Amount )" Caption="Amount" DisplayFormat="{0:C0}" DisplayFormatProvider="@System.Globalization.CultureInfo.GetCultureInfo( "en-US" )" /> </PivotGridAggregates> </ChildContent> </PivotGrid>
@code { private readonly List<ToolbarSale> Sales = [ new() { Region = "Central", City = "Berlin", Category = "Hardware", Product = "Laptops", Amount = 51200m }, new() { Region = "Central", City = "Berlin", Category = "Software", Product = "Licenses", Amount = 94200m }, new() { Region = "Western", City = "London", Category = "Hardware", Product = "Laptops", Amount = 127500m }, new() { Region = "Western", City = "London", Category = "Services", Product = "Consulting", Amount = 66300m }, new() { Region = "Southern", City = "Madrid", Category = "Services", Product = "Training", Amount = 28700m }, new() { Region = "Western", City = "Paris", Category = "Software", Product = "Subscriptions", Amount = 124500m }, ]; public class ToolbarSale { public string Region { get; set; } public string City { get; set; } public string Category { get; set; } public string Product { get; set; } public decimal Amount { get; set; } } }
Paging and Virtualization
Use ShowPager for explicit page navigation, or Virtualize when users should scroll through a larger pivot result.
Virtualize only limits rendered rows. When using local Data, the full pivot result is still computed before rows are virtualized. For large remote datasets, use ReadData or DataProvider with PivotGridReadDataMode.Virtualize and return prepared PivotGridResult rows for the requested range.
The pager range reports pivot result rows. When PageByGroups is enabled, paging is based on top-level row groups instead of every expanded detail row.
| Category / Product | Berlin | London | Madrid | Paris | Grand Total | |||||
|---|---|---|---|---|---|---|---|---|---|---|
| Amount | Units | Amount | Units | Amount | Units | Amount | Units | Amount | Units | |
| Cloud | $455,000 | 561 | $516,300 | 621 | $738,800 | 818 | $591,900 | 606 | $2,302,000 | 2606 |
| Cloud / Backup | $154,800 | 196 | $172,100 | 207 | $189,400 | 218 | $206,700 | 229 | $723,000 | 850 |
| Cloud / Compute | $136,000 | 142 | $170,600 | 164 | $187,900 | 175 | $494,500 | 481 | ||
| Cloud / Database | $164,200 | 223 | $181,500 | 234 | $198,800 | 245 | $544,500 | 702 | ||
| Cloud / Storage | $162,700 | 180 | $180,000 | 191 | $197,300 | 202 | $540,000 | 573 | ||
| Hardware | $122,400 | 216 | $213,600 | 278 | $198,000 | 201 | $259,300 | 261 | $793,300 | 956 |
| Hardware / Laptops | $39,300 | 29 | $56,600 | 40 | $73,900 | 51 | $169,800 | 120 | ||
| Hardware / Monitors | $31,400 | 45 | $48,700 | 56 | $66,000 | 67 | $83,300 | 78 | $229,400 | 246 |
<Field> <Switch @bind-Value="">Virtualize rows</Switch> </Field> <PivotGrid TItem="PivotSale" Data="" ShowPager="@(!virtualize)" ShowPageSizes="@(!virtualize)" PageSize="8" PageSizes="" Virtualize="" VirtualizeOptions="" ShowRowTotals ShowColumnTotals ShowRowSubtotals Striped Hoverable Narrow> <PivotGridColumns> <PivotGridColumn Field="@nameof( PivotSale.City )" Caption="City" /> </PivotGridColumns> <PivotGridRows> <PivotGridRow Field="@nameof( PivotSale.Category )" Caption="Category" /> <PivotGridRow Field="@nameof( PivotSale.Product )" Caption="Product" /> </PivotGridRows> <PivotGridAggregates> <PivotGridAggregate Field="@nameof( PivotSale.Amount )" Caption="Amount" DisplayFormat="{0:C0}" DisplayFormatProvider="@System.Globalization.CultureInfo.GetCultureInfo( "en-US" )" /> <PivotGridAggregate Field="@nameof( PivotSale.Units )" Caption="Units" Aggregate="PivotGridAggregateFunction.Sum" /> </PivotGridAggregates> </PivotGrid>
@code { private bool virtualize; private readonly int[] pageSizes = [8, 16, 32]; private readonly PivotGridVirtualizeOptions virtualizeOptions = new() { Height = "420px", MaxHeight = "420px", ItemSize = 44f, OverscanCount = 6, }; private readonly List<PivotSale> Sales = CreateSales(); private static List<PivotSale> CreateSales() { string[] cities = ["Berlin", "London", "Madrid", "Paris"]; (string Category, string[] Products)[] rows = [ ("Hardware", ["Laptops", "Monitors", "Tablets", "Peripherals"]), ("Software", ["Licenses", "Subscriptions", "Support", "Analytics"]), ("Services", ["Consulting", "Implementation", "Training", "Migration"]), ("Security", ["Firewall", "Identity", "Monitoring", "Audit"]), ("Cloud", ["Compute", "Storage", "Backup", "Database"]), ]; List<PivotSale> data = new(); for ( int rowIndex = 0; rowIndex < rows.Length; rowIndex++ ) { for ( int productIndex = 0; productIndex < rows[rowIndex].Products.Length; productIndex++ ) { for ( int cityIndex = 0; cityIndex < cities.Length; cityIndex++ ) { if ( ( rowIndex + productIndex + cityIndex ) % 5 == 0 ) continue; data.Add( new() { City = cities[cityIndex], Category = rows[rowIndex].Category, Product = rows[rowIndex].Products[productIndex], Amount = 22000m + ( rowIndex * 28500m ) + ( productIndex * 9400m ) + ( cityIndex * 17300m ), Units = 18 + ( rowIndex * 31 ) + ( productIndex * 27 ) + ( cityIndex * 11 ), } ); } } } return data; } public class PivotSale { public string City { get; set; } public string Category { get; set; } public string Product { get; set; } public decimal Amount { get; set; } public int Units { get; set; } } }
Remote Virtualization
For remote virtualization, return the requested pivot result rows through Result and set TotalItems to the total pivot result row count.
When row or column expansion is enabled, use IsRowGroupExpanded and IsColumnGroupExpanded from the request to build the requested expanded result window.
When returning a prepared PivotGridResult, keep the result shape consistent. DataColumns defines the cell order, so every returned PivotGridResultRow should contain the same number of Cells, in the same order. Data columns and aggregate metadata should stay stable across virtualized requests. Row fields, column fields, aggregate info, data columns, rows, and cells should not be null.
| Customer |
|---|
<PivotGrid TItem="RemotePivotSale" ReadData="" Virtualize VirtualizeOptions="" Striped Hoverable> <PivotGridColumns> <PivotGridColumn Field="@nameof( RemotePivotSale.Quarter )" Caption="Quarter" /> </PivotGridColumns> <PivotGridRows> <PivotGridRow Field="@nameof( RemotePivotSale.Customer )" Caption="Customer" /> </PivotGridRows> <PivotGridAggregates> <PivotGridAggregate Field="@nameof( RemotePivotSale.Amount )" Caption="Amount" Aggregate="PivotGridAggregateFunction.Sum" DisplayFormat="{0:C0}" DisplayFormatProvider="@System.Globalization.CultureInfo.GetCultureInfo( "en-US" )" /> </PivotGridAggregates> </PivotGrid>
@code { private static readonly string[] quarters = ["Q1", "Q2", "Q3", "Q4"]; private static readonly IReadOnlyList<RemotePivotSale> sales = CreateSales(); private static readonly int totalPivotRows = sales .Select( sale => sale.Customer ) .Distinct() .Count(); private readonly PivotGridVirtualizeOptions virtualizeOptions = new() { Height = "420px", MaxHeight = "420px", ItemSize = 44f, OverscanCount = 6, }; private Task ReadRemotePivotData( PivotGridReadDataEventArgs<RemotePivotSale> eventArgs ) { PivotGridDataRequest request = eventArgs.Request; int offset = request.ReadDataMode == PivotGridReadDataMode.Virtualize ? Math.Max( 0, request.VirtualizeOffset ) : 0; int count = request.ReadDataMode == PivotGridReadDataMode.Virtualize && request.VirtualizeCount > 0 ? request.VirtualizeCount : 40; eventArgs.Result = CreatePivotResult( offset, count ); eventArgs.TotalItems = totalPivotRows; eventArgs.IsPaged = true; return Task.CompletedTask; } private static PivotGridResult<RemotePivotSale> CreatePivotResult( int offset, int count ) { IReadOnlyList<PivotGridFieldInfo<RemotePivotSale>> rowFields = [ new() { Field = nameof( RemotePivotSale.Customer ), Caption = "Customer", }, ]; IReadOnlyList<PivotGridFieldInfo<RemotePivotSale>> columnFields = [ new() { Field = nameof( RemotePivotSale.Quarter ), Caption = "Quarter", }, ]; PivotGridAggregateInfo<RemotePivotSale> aggregate = new() { Field = nameof( RemotePivotSale.Amount ), Caption = "Amount", Aggregate = PivotGridAggregateFunction.Sum, DisplayFormat = "{0:C0}", DisplayFormatProvider = System.Globalization.CultureInfo.GetCultureInfo( "en-US" ), }; IReadOnlyList<PivotGridAggregateInfo<RemotePivotSale>> aggregates = [aggregate]; List<PivotGridAxisItem<RemotePivotSale>> columnItems = quarters .Select( quarter => new PivotGridAxisItem<RemotePivotSale>( [quarter], sales.Where( sale => sale.Quarter == quarter ).ToList(), 0, false, false ) ) .ToList(); List<PivotGridDataColumn<RemotePivotSale>> dataColumns = columnItems .Select( column => new PivotGridDataColumn<RemotePivotSale>( column, aggregate ) ) .ToList(); List<PivotGridResultRow<RemotePivotSale>> rows = sales .GroupBy( sale => sale.Customer ) .OrderBy( group => group.Key ) .Skip( offset ) .Take( count ) .Select( group => { List<RemotePivotSale> rowItems = group.ToList(); PivotGridAxisItem<RemotePivotSale> row = new( [group.Key], rowItems, 0, false, false ); List<PivotGridCell<RemotePivotSale>> cells = dataColumns .Select( dataColumn => { string quarter = dataColumn.Column.Values[0]?.ToString(); List<RemotePivotSale> cellItems = rowItems .Where( sale => sale.Quarter == quarter ) .ToList(); object value = aggregate.Calculate( cellItems ); return new PivotGridCell<RemotePivotSale>( dataColumn, value, aggregate.FormatValue( value ), cellItems, false, false, false ); } ) .ToList(); return new PivotGridResultRow<RemotePivotSale>( row, cells ); } ) .ToList(); return new( rowFields, columnFields, aggregates, dataColumns, rows ); } private static List<RemotePivotSale> CreateSales() { List<RemotePivotSale> data = new(); for ( int customerIndex = 1; customerIndex <= 500; customerIndex++ ) { for ( int quarterIndex = 0; quarterIndex < quarters.Length; quarterIndex++ ) { data.Add( new() { Customer = $"Customer {customerIndex:000}", Quarter = quarters[quarterIndex], Amount = 8500m + ( customerIndex * 157m ) + ( quarterIndex * 3200m ), } ); } } return data; } public class RemotePivotSale { public string Customer { get; set; } public string Quarter { get; set; } public decimal Amount { get; set; } } }
ReadData and DataProvider
Use ReadData for callback-based loading, or DataProvider when the provider should be reusable. For server-side paging, return a prepared PivotGridResult, set IsPaged, and report the total pivot result row count with TotalItems.
When the field chooser is enabled with remote or prepared results, populate FilterOptions with all available filter values keyed by field name. Selected option keys are sent back on the corresponding request filter as FilterValueKey. Otherwise the field chooser can only infer filter values from the current raw Data page.
Prepared results returned by providers are normalized before rendering. Null structural entries are ignored, row cells are aligned to DataColumns, and missing cells are rendered as empty cells so headers, expansion, and cells stay consistent.
<Field> <FieldLabel>Provider</FieldLabel> <FieldBody> <Select TValue="ProviderMode" @bind-Value=""> <SelectItem TValue="ProviderMode" Value="ProviderMode.ReadData">ReadData callback</SelectItem> <SelectItem TValue="ProviderMode" Value="ProviderMode.DataProvider">DataProvider implementation</SelectItem> </Select> </FieldBody> </Field> <PivotGrid TItem="RemoteSale" ReadData="" DataProvider="" ShowPager PageSize="4" ShowRowTotals Striped Hoverable> <PivotGridColumns> <PivotGridColumn Field="@nameof( RemoteSale.Quarter )" Caption="Quarter" /> </PivotGridColumns> <PivotGridRows> <PivotGridRow Field="@nameof( RemoteSale.Customer )" Caption="Customer" /> </PivotGridRows> <PivotGridAggregates> <PivotGridAggregate Field="@nameof( RemoteSale.Amount )" Caption="Amount" Aggregate="PivotGridAggregateFunction.Sum" DisplayFormat="{0:C0}" DisplayFormatProvider="@System.Globalization.CultureInfo.GetCultureInfo( "en-US" )" /> </PivotGridAggregates> </PivotGrid>
@code { private static readonly string[] quarters = ["Q1", "Q2", "Q3", "Q4"]; private static readonly IReadOnlyList<RemoteSale> sales = CreateSales(); private readonly IPivotGridDataProvider<RemoteSale> dataProvider = new RemoteSaleDataProvider( sales ); private ProviderMode providerMode = ProviderMode.ReadData; private EventCallback<PivotGridReadDataEventArgs<RemoteSale>> CurrentReadData => providerMode == ProviderMode.ReadData ? EventCallback.Factory.Create<PivotGridReadDataEventArgs<RemoteSale>>( this, ReadRemoteData ) : default; private IPivotGridDataProvider<RemoteSale> CurrentDataProvider => providerMode == ProviderMode.DataProvider ? dataProvider : null; private Task ReadRemoteData( PivotGridReadDataEventArgs<RemoteSale> eventArgs ) { PivotGridDataResult<RemoteSale> result = CreatePagedPivotResult( sales, eventArgs.Request ); eventArgs.Result = result.Result; eventArgs.TotalItems = result.TotalItems; eventArgs.IsPaged = result.IsPaged; return Task.CompletedTask; } private static PivotGridDataResult<RemoteSale> CreatePagedPivotResult( IReadOnlyList<RemoteSale> source, PivotGridDataRequest request ) { PivotGridFieldInfo<RemoteSale> rowField = new() { Field = nameof( RemoteSale.Customer ), Caption = "Customer", }; PivotGridFieldInfo<RemoteSale> columnField = new() { Field = nameof( RemoteSale.Quarter ), Caption = "Quarter", }; PivotGridAggregateInfo<RemoteSale> aggregate = new() { Field = nameof( RemoteSale.Amount ), Caption = "Amount", Aggregate = PivotGridAggregateFunction.Sum, DisplayFormat = "{0:C0}", DisplayFormatProvider = System.Globalization.CultureInfo.GetCultureInfo( "en-US" ), }; List<PivotGridAxisItem<RemoteSale>> columnItems = quarters .Select( quarter => new PivotGridAxisItem<RemoteSale>( [quarter], source.Where( sale => sale.Quarter == quarter ).ToList(), 0, false, false ) ) .ToList(); if ( request.ShowRowTotals ) { columnItems.Add( new PivotGridAxisItem<RemoteSale>( [], source, 0, false, true ) ); } List<PivotGridDataColumn<RemoteSale>> dataColumns = columnItems .Select( column => new PivotGridDataColumn<RemoteSale>( column, aggregate ) ) .ToList(); List<IGrouping<string, RemoteSale>> customerGroups = source .GroupBy( sale => sale.Customer ) .OrderBy( group => group.Key ) .ToList(); int totalRows = customerGroups.Count; int skip = request.ReadDataMode == PivotGridReadDataMode.Paging ? Math.Max( 0, ( request.Page - 1 ) * request.PageSize ) : 0; int take = request.ReadDataMode == PivotGridReadDataMode.Paging ? request.PageSize : totalRows; List<PivotGridResultRow<RemoteSale>> rows = customerGroups .Skip( skip ) .Take( take ) .Select( group => { List<RemoteSale> rowItems = group.ToList(); PivotGridAxisItem<RemoteSale> row = new( [group.Key], rowItems, 0, false, false ); List<PivotGridCell<RemoteSale>> cells = dataColumns .Select( dataColumn => { List<RemoteSale> cellItems = dataColumn.Column.IsGrandTotal ? rowItems : rowItems.Where( sale => sale.Quarter == dataColumn.Column.Values[0]?.ToString() ).ToList(); object value = aggregate.Calculate( cellItems ); return new PivotGridCell<RemoteSale>( dataColumn, value, aggregate.FormatValue( value ), cellItems, dataColumn.Column.IsTotal || dataColumn.Column.IsGrandTotal, false, false ); } ) .ToList(); return new PivotGridResultRow<RemoteSale>( row, cells ); } ) .ToList(); return new() { Result = new( [rowField], [columnField], [aggregate], dataColumns, rows ), TotalItems = totalRows, IsPaged = true, }; } private static List<RemoteSale> CreateSales() { List<RemoteSale> data = new(); for ( int customerIndex = 1; customerIndex <= 18; customerIndex++ ) { foreach ( string quarter in quarters ) { data.Add( new() { Customer = $"Customer {customerIndex:00}", Quarter = quarter, Amount = 12000m + ( customerIndex * 950m ) + ( Array.IndexOf( quarters, quarter ) * 2250m ), } ); } } return data; } private enum ProviderMode { ReadData, DataProvider, } private sealed class RemoteSaleDataProvider : IPivotGridDataProvider<RemoteSale> { private readonly IReadOnlyList<RemoteSale> source; public RemoteSaleDataProvider( IReadOnlyList<RemoteSale> source ) { this.source = source; } public Task<PivotGridDataResult<RemoteSale>> ReadDataAsync( PivotGridDataRequest request, System.Threading.CancellationToken cancellationToken ) => Task.FromResult( CreatePagedPivotResult( source, request ) ); } public class RemoteSale { public string Customer { get; set; } public string Quarter { get; set; } public decimal Amount { get; set; } } }
Templates and Cell Clicks
Customize headers, row and column values, aggregate cells, and handleCellClicked to inspect the source items behind a pivot value.
| Category | Central | Western | Grand Total |
|---|---|---|---|
| Hardware | $51,200 | $127,500 | $178,700 |
| Services | $66,300 | $66,300 | |
| Software | $94,200 | $94,200 | |
| Grand Total | $145,400 | $193,800 | $339,200 |
<PivotGrid TItem="TemplateSale" Data="" CellClicked="" ShowRowTotals ShowColumnTotals Striped Hoverable> <PivotGridColumns> <PivotGridColumn Field="@nameof( TemplateSale.Region )" Caption="Region"> <DisplayTemplate Context="context"> <Span TextWeight="TextWeight.SemiBold" TextTransform="TextTransform.Uppercase">@context.FormattedValue</Span> </DisplayTemplate> </PivotGridColumn> </PivotGridColumns> <PivotGridRows> <PivotGridRow Field="@nameof( TemplateSale.Category )" Caption="Category"> <HeaderTemplate Context="context"> <Span TextWeight="TextWeight.Bold">@context.Caption</Span> </HeaderTemplate> <DisplayTemplate Context="context"> <Span TextColor="@(context.IsTotal ? TextColor.Primary : TextColor.Body)">@context.FormattedValue</Span> </DisplayTemplate> </PivotGridRow> </PivotGridRows> <PivotGridAggregates> <PivotGridAggregate Field="@nameof( TemplateSale.Amount )" Caption="Revenue" DisplayFormat="{0:C0}" DisplayFormatProvider="@System.Globalization.CultureInfo.GetCultureInfo( "en-US" )"> <CellTemplate Context="context"> <Span TextWeight="@(context.IsGrandTotal ? TextWeight.Bold : TextWeight.Default)"> @context.FormattedValue </Span> </CellTemplate> </PivotGridAggregate> </PivotGridAggregates> </PivotGrid> <Alert Color="Color.Info" Visible="@(!string.IsNullOrWhiteSpace( selectedCellText ))" Margin="Margin.Is3.FromTop"> @selectedCellText </Alert>
@code { private string selectedCellText; private readonly List<TemplateSale> Sales = [ new() { Region = "Central", Category = "Hardware", Amount = 51200m }, new() { Region = "Central", Category = "Software", Amount = 94200m }, new() { Region = "Western", Category = "Hardware", Amount = 127500m }, new() { Region = "Western", Category = "Services", Amount = 66300m }, ]; private Task OnCellClicked( PivotGridCellClickedEventArgs<TemplateSale> eventArgs ) { selectedCellText = $"{eventArgs.Aggregate.Caption}: {eventArgs.Value:C0} from {eventArgs.Items.Count} source rows"; return Task.CompletedTask; } public class TemplateSale { public string Region { get; set; } public string Category { get; set; } public decimal Amount { get; set; } } }
Filters and Expansion
Use the field chooser to move fields into filters, and enable expandable rows or columns when users should drill into grouped results.
Expandable grouped rows and columns render section headers independently from subtotal display, so users can still expand or collapse groups when subtotals are hidden.
| Region / Category | Berlin | London | Madrid | Paris | Grand Total |
|---|---|---|---|---|---|
| Central | $145,400 | $145,400 | |||
| Southern | $73,800 | $73,800 | |||
| Western | $193,800 | $243,100 | $436,900 | ||
| Grand Total | $145,400 | $193,800 | $73,800 | $243,100 | $656,100 |
<PivotGrid TItem="FilterSale" Data="" ShowToolbar FieldChooser ExpandableRows ExpandableColumns InitiallyExpanded="false" ShowRowTotals ShowColumnTotals ShowRowSubtotals ShowColumnSubtotals Striped Hoverable> <PivotGridFields> <PivotGridField Field="@nameof( FilterSale.Region )" Caption="Region" /> <PivotGridField Field="@nameof( FilterSale.City )" Caption="City" /> <PivotGridField Field="@nameof( FilterSale.Category )" Caption="Category" /> <PivotGridField Field="@nameof( FilterSale.Amount )" Caption="Amount" /> </PivotGridFields> <PivotGridColumns> <PivotGridColumn Field="@nameof( FilterSale.City )" Caption="City" /> </PivotGridColumns> <PivotGridRows> <PivotGridRow Field="@nameof( FilterSale.Region )" Caption="Region" /> <PivotGridRow Field="@nameof( FilterSale.Category )" Caption="Category" /> </PivotGridRows> <PivotGridAggregates> <PivotGridAggregate Field="@nameof( FilterSale.Amount )" Caption="Amount" DisplayFormat="{0:C0}" DisplayFormatProvider="@System.Globalization.CultureInfo.GetCultureInfo( "en-US" )" /> </PivotGridAggregates> </PivotGrid>
@code { private readonly List<FilterSale> Sales = [ new() { Region = "Central", City = "Berlin", Category = "Hardware", Amount = 51200m }, new() { Region = "Central", City = "Berlin", Category = "Software", Amount = 94200m }, new() { Region = "Western", City = "London", Category = "Hardware", Amount = 127500m }, new() { Region = "Western", City = "London", Category = "Services", Amount = 66300m }, new() { Region = "Southern", City = "Madrid", Category = "Services", Amount = 28700m }, new() { Region = "Southern", City = "Madrid", Category = "Software", Amount = 45100m }, new() { Region = "Western", City = "Paris", Category = "Software", Amount = 124500m }, new() { Region = "Western", City = "Paris", Category = "Services", Amount = 118600m }, ]; public class FilterSale { public string Region { get; set; } public string City { get; set; } public string Category { get; set; } public decimal Amount { get; set; } } }
Custom Aggregator
SetAggregator when a value field needs domain-specific aggregation instead of one of the built-in aggregate functions.
| Category | Central | Western | Grand Total | |||
|---|---|---|---|---|---|---|
| Revenue | Margin % | Revenue | Margin % | Revenue | Margin % | |
| Hardware | $51,200 | 18.0% | $127,500 | 21.0% | $178,700 | 20.1% |
| Services | $66,300 | 36.0% | $66,300 | 36.0% | ||
| Software | $94,200 | 42.0% | $94,200 | 42.0% | ||
| Grand Total | $145,400 | 33.5% | $193,800 | 26.1% | $339,200 | 29.3% |
<PivotGrid TItem="MarginSale" Data="" ShowRowTotals ShowColumnTotals Striped Hoverable> <PivotGridColumns> <PivotGridColumn Field="@nameof( MarginSale.Region )" Caption="Region" /> </PivotGridColumns> <PivotGridRows> <PivotGridRow Field="@nameof( MarginSale.Category )" Caption="Category" /> </PivotGridRows> <PivotGridAggregates> <PivotGridAggregate Field="@nameof( MarginSale.Amount )" Caption="Revenue" DisplayFormat="{0:C0}" DisplayFormatProvider="@System.Globalization.CultureInfo.GetCultureInfo( "en-US" )" /> <PivotGridAggregate TItem="MarginSale" Field="@nameof( MarginSale.Margin )" Caption="Margin %" Aggregator="" DisplayFormat="{0:P1}" /> </PivotGridAggregates> </PivotGrid>
@code { private readonly List<MarginSale> Sales = [ new() { Region = "Central", Category = "Hardware", Amount = 51200m, Margin = .18m }, new() { Region = "Central", Category = "Software", Amount = 94200m, Margin = .42m }, new() { Region = "Western", Category = "Hardware", Amount = 127500m, Margin = .21m }, new() { Region = "Western", Category = "Services", Amount = 66300m, Margin = .36m }, ]; private static object WeightedMargin( IReadOnlyList<MarginSale> items ) { decimal totalAmount = items.Sum( item => item.Amount ); if ( totalAmount == 0m ) return null; return items.Sum( item => item.Amount * item.Margin ) / totalAmount; } public class MarginSale { public string Region { get; set; } public string Category { get; set; } public decimal Amount { get; set; } public decimal Margin { get; set; } } }
Styling
UseCellStyling, RowHeaderStyling, and ColumnHeaderStyling to apply conditional styling.
| Category / Product | Berlin | London | Madrid | Paris | Grand Total | |||||
|---|---|---|---|---|---|---|---|---|---|---|
| Amount | Units | Amount | Units | Amount | Units | Amount | Units | Amount | Units | |
| Hardware | $51,200 | 18 | $127,500 | 34 | $178,700 | 52 | ||||
| Hardware / Laptops | $51,200 | 18 | $127,500 | 34 | $178,700 | 52 | ||||
| Services | $66,300 | 36 | $28,700 | 64 | $95,000 | 100 | ||||
| Services / Consulting | $66,300 | 36 | $66,300 | 36 | ||||||
| Services / Training | $28,700 | 64 | $28,700 | 64 | ||||||
| Software | $94,200 | 205 | $124,500 | 355 | $218,700 | 560 | ||||
| Software / Licenses | $94,200 | 205 | $94,200 | 205 | ||||||
| Software / Subscriptions | $124,500 | 355 | $124,500 | 355 | ||||||
| Grand Total | $145,400 | 223 | $193,800 | 70 | $28,700 | 64 | $124,500 | 355 | $492,400 | 712 |
<PivotGrid TItem="PivotSale" Data="" CellStyling="" RowHeaderStyling="" ColumnHeaderStyling="" ShowRowTotals ShowColumnTotals ShowRowSubtotals Striped Hoverable> <PivotGridColumns> <PivotGridColumn Field="@nameof( PivotSale.City )" Caption="City" /> </PivotGridColumns> <PivotGridRows> <PivotGridRow Field="@nameof( PivotSale.Category )" Caption="Category" /> <PivotGridRow Field="@nameof( PivotSale.Product )" Caption="Product" /> </PivotGridRows> <PivotGridAggregates> <PivotGridAggregate Field="@nameof( PivotSale.Amount )" Caption="Amount" DisplayFormat="{0:C0}" DisplayFormatProvider="@System.Globalization.CultureInfo.GetCultureInfo( "en-US" )" /> <PivotGridAggregate Field="@nameof( PivotSale.Units )" Caption="Units" Aggregate="PivotGridAggregateFunction.Sum" /> </PivotGridAggregates> </PivotGrid>
@code { private readonly List<PivotSale> Sales = [ new() { City = "Berlin", Category = "Hardware", Product = "Laptops", Amount = 51200m, Units = 18 }, new() { City = "Berlin", Category = "Software", Product = "Licenses", Amount = 94200m, Units = 205 }, new() { City = "London", Category = "Hardware", Product = "Laptops", Amount = 127500m, Units = 34 }, new() { City = "London", Category = "Services", Product = "Consulting", Amount = 66300m, Units = 36 }, new() { City = "Madrid", Category = "Services", Product = "Training", Amount = 28700m, Units = 64 }, new() { City = "Paris", Category = "Software", Product = "Subscriptions", Amount = 124500m, Units = 355 }, ]; private void OnCellStyling( PivotGridCellContext<PivotSale> context, PivotGridCellStyling styling ) { if ( context.Aggregate.Field != nameof( PivotSale.Amount ) || context.Value is not decimal amount ) return; if ( amount >= 100000m ) { styling.Background = Background.Success; styling.TextColor = TextColor.White; styling.TextWeight = TextWeight.Bold; } else if ( amount <= 30000m ) { styling.Background = Background.Danger; styling.TextColor = TextColor.White; styling.TextWeight = TextWeight.Bold; } } private void OnRowHeaderStyling( PivotGridRowHeaderContext<PivotSale> context, PivotGridCellStyling styling ) { if ( context.IsGrandTotal ) { styling.Background = Background.Info; styling.TextColor = TextColor.White; styling.TextWeight = TextWeight.Bold; } else if ( context.IsTotal ) { styling.Background = Background.Secondary; styling.TextColor = TextColor.White; styling.TextWeight = TextWeight.Bold; } } private void OnColumnHeaderStyling( PivotGridColumnHeaderContext<PivotSale> context, PivotGridCellStyling styling ) { if ( context.IsGrandTotal || context.IsTotal ) { styling.Background = Background.Info; styling.TextColor = TextColor.White; styling.TextWeight = TextWeight.Bold; } } public class PivotSale { public string City { get; set; } public string Category { get; set; } public string Product { get; set; } public decimal Amount { get; set; } public int Units { get; set; } } }
API
Parameters
PivotGrid
| Parameter | Description | Type | Default |
|---|---|---|---|
AggregateHeaderTemplate |
Custom content for aggregate header cells. |
RenderFragment<PivotGridAggregateHeaderContext<TItem>> | null |
Bordered |
Defines whether table cells have borders. |
bool | true |
CellTemplate |
Custom content for aggregate value cells. |
RenderFragment<PivotGridCellContext<TItem>> | null |
ChildContent |
Defines child content. Field components can be declared directly here. |
RenderFragment | null |
ColumnGroupCaptionMode |
Defines how column group captions are displayed. Possible values: |
PivotGridGroupCaptionMode | PivotGridGroupCaptionMode.Leaf |
ColumnHeaderTemplate |
Custom content for column header cells. |
RenderFragment<PivotGridColumnHeaderContext<TItem>> | null |
ColumnTotalPosition |
Defines column subtotal position. Possible values: |
PivotGridTotalPosition | PivotGridTotalPosition.After |
Data |
Defines the source data to be analyzed. |
IEnumerable<TItem> | null |
DataProvider |
Defines an external data provider used to read pivot grid data. When assigned, it has priority over ReadData and Data. |
IPivotGridDataProvider<TItem> | null |
EmptyTemplate |
Custom content shown when the pivot result is empty. |
RenderFragment | null |
ExpandableColumns |
Enables expanding and collapsing column groups. |
bool | false |
ExpandableRows |
Enables expanding and collapsing row groups. |
bool | true |
FieldChooser |
Enables the runtime field chooser. |
bool | false |
GroupCaptionSeparator |
Defines the separator used when group captions show the full path. |
string | " / " |
HeaderTemplate |
Custom content for row field header cells. |
RenderFragment<PivotGridHeaderContext<TItem>> | null |
HeaderThemeContrast |
Defines whether header uses theme contrast. Possible values: |
ThemeContrast | None |
Hoverable |
Defines whether rows show hover styling. |
bool | true |
InitiallyExpanded |
Defines whether expandable groups are expanded on first render. |
bool | true |
Localizers |
Custom localizer handlers to override default PivotGrid localization. |
PivotGridLocalizers | null |
MaxPaginationLinks |
Maximum number of page links visible at once. |
int | 5 |
MissingValuesTemplate |
Custom content shown when no value fields are declared. |
RenderFragment | null |
Narrow |
Defines whether cells use narrow spacing. |
bool | false |
NoDataTemplate |
Custom content shown when there are no data rows. |
RenderFragment | null |
Page |
Currently selected page. |
int | 1 |
PageByGroups |
Defines whether paging is applied to top-level row groups instead of rendered pivot rows. |
bool | false |
PagerSize |
Pager control size. |
Size? | null |
PageSize |
Number of rendered pivot rows per page. |
int | 10 |
PageSizes |
Available page size options. |
IEnumerable<int> | [5, 10, 25, 50, 100] |
Responsive |
Defines whether table is responsive. |
bool | true |
RowGroupCaptionMode |
Defines how row group captions are displayed. Possible values: |
PivotGridGroupCaptionMode | PivotGridGroupCaptionMode.FullPath |
RowHeaderTemplate |
Custom content for row header cells. |
RenderFragment<PivotGridRowHeaderContext<TItem>> | null |
RowTotalPosition |
Defines row subtotal position. Possible values: |
PivotGridTotalPosition | PivotGridTotalPosition.After |
ShowColumnSubtotals |
Shows subtotal columns for column dimensions. |
bool | true |
ShowColumnTotals |
Shows totals for each column as total rows. |
bool | true |
ShowPager |
Shows pager controls for rendered pivot rows. |
bool | false |
ShowPageSizes |
Shows page size selector in the pager. |
bool | false |
ShowRowSubtotals |
Shows subtotal rows for row dimensions. |
bool | true |
ShowRowTotals |
Shows totals for each row as total columns. |
bool | true |
ShowToolbar |
Shows built-in PivotGrid toolbar commands when available. Use ToolbarTemplate for custom toolbar content. |
bool | false |
Striped |
Defines whether rows are striped. |
bool | false |
ToolbarOptions |
Defines options for the built-in toolbar. |
PivotGridToolbarOptions | new() |
ToolbarTemplate |
Custom toolbar content. |
RenderFragment<PivotGridToolbarContext<TItem>> | null |
Virtualize |
Enables virtualized rendering of pivot rows. Ignored when ShowPager is enabled. RemarksWhen local Data is used, virtualization reduces rendered rows only; the full pivot result is still computed before rendering. For large remote datasets, use ReadData or DataProvider with Virtualize and return prepared Result rows for the requested range. |
bool | false |
VirtualizeOptions |
Defines virtualized row rendering options. RemarksThese options tune rendered row virtualization only. They do not change local pivot grouping or aggregate calculation behavior. |
PivotGridVirtualizeOptions | null |
PivotGridField
| Parameter | Description | Type | Default |
|---|---|---|---|
Caption |
Optional caption shown in headers. |
string | |
DisplayFormat |
Specifies display format for default display text. |
string | |
DisplayFormatProvider |
Specifies display format provider. |
IFormatProvider | null |
DisplayTemplate |
Defines custom field value template. |
RenderFragment<PivotGridFieldValueContext<TItem>> | null |
EmptyText |
Text shown when the field value is null. |
string | string.Empty |
Field |
Field path bound to this PivotGrid field. |
string | |
HeaderTemplate |
Defines custom header template. |
RenderFragment<PivotGridHeaderContext<TItem>> | null |
Visible |
Determines whether this field participates in the PivotGrid. |
bool | true |
PivotGridColumn
| Parameter | Description | Type | Default |
|---|---|---|---|
Caption |
Optional caption shown in headers. |
string | |
DisplayFormat |
Specifies display format for default display text. |
string | |
DisplayFormatProvider |
Specifies display format provider. |
IFormatProvider | null |
DisplayTemplate |
Defines custom field value template. |
RenderFragment<PivotGridFieldValueContext<TItem>> | null |
EmptyText |
Text shown when the field value is null. |
string | string.Empty |
Field |
Field path bound to this PivotGrid field. |
string | |
HeaderTemplate |
Defines custom header template. |
RenderFragment<PivotGridHeaderContext<TItem>> | null |
Visible |
Determines whether this field participates in the PivotGrid. |
bool | true |
PivotGridRow
| Parameter | Description | Type | Default |
|---|---|---|---|
Caption |
Optional caption shown in headers. |
string | |
DisplayFormat |
Specifies display format for default display text. |
string | |
DisplayFormatProvider |
Specifies display format provider. |
IFormatProvider | null |
DisplayTemplate |
Defines custom field value template. |
RenderFragment<PivotGridFieldValueContext<TItem>> | null |
EmptyText |
Text shown when the field value is null. |
string | string.Empty |
Field |
Field path bound to this PivotGrid field. |
string | |
HeaderTemplate |
Defines custom header template. |
RenderFragment<PivotGridHeaderContext<TItem>> | null |
Visible |
Determines whether this field participates in the PivotGrid. |
bool | true |
PivotGridAggregate
| Parameter | Description | Type | Default |
|---|---|---|---|
Aggregate |
Defines which built-in aggregate function is used. Possible values: |
PivotGridAggregateFunction | PivotGridAggregateFunction.Sum |
Caption |
Optional caption shown in headers. |
string | |
CellTemplate |
Defines custom aggregate cell template. |
RenderFragment<PivotGridCellContext<TItem>> | null |
DisplayFormat |
Specifies display format for default display text. |
string | |
DisplayFormatProvider |
Specifies display format provider. |
IFormatProvider | null |
DisplayTemplate |
Defines custom field value template. |
RenderFragment<PivotGridFieldValueContext<TItem>> | null |
EmptyText |
Text shown when the field value is null. |
string | string.Empty |
Field |
Field path bound to this PivotGrid field. |
string | |
HeaderTemplate |
Defines custom header template. |
RenderFragment<PivotGridHeaderContext<TItem>> | null |
Visible |
Determines whether this field participates in the PivotGrid. |
bool | true |
PivotGridToolbarOptions
| Parameter | Description | Type | Default |
|---|---|---|---|
ShowExpandCollapseButtons |
Gets or sets whether the expand all and collapse all buttons are shown. |
bool | true |
ShowFieldChooserButton |
Gets or sets whether the field chooser button is shown. |
bool | true |
ShowRefreshButton |
Gets or sets whether the refresh button is shown. |
bool | false |
ShowResetLayoutButton |
Gets or sets whether the reset layout button is shown. |
bool | true |
PivotGridVirtualizeOptions
| Parameter | Description | Type | Default |
|---|---|---|---|
Height |
Gets or sets the PivotGrid table container height when virtualization is enabled. |
string | "500px" |
ItemSize |
Gets or sets the expected virtualized item size in pixels. |
float | 50f |
MaxHeight |
Gets or sets the PivotGrid table container maximum height when virtualization is enabled. |
string | "500px" |
OverscanCount |
Gets or sets how many additional items will be rendered before and after the visible region. |
int | 10 |
Events
PivotGrid
| Event | Description | Type |
|---|---|---|
CellClicked |
Occurs when an aggregate cell is clicked. |
EventCallback<PivotGridCellClickedEventArgs<TItem>> |
CellStyling |
Custom styling for aggregate value cells. |
Action<PivotGridCellContext<TItem>, PivotGridCellStyling> |
ColumnHeaderStyling |
Custom styling for column header cells. |
Action<PivotGridColumnHeaderContext<TItem>, PivotGridCellStyling> |
PageChanged |
Occurs after the page has changed. |
EventCallback<int> |
PageSizeChanged |
Occurs after the page size has changed. |
EventCallback<int> |
ReadData |
Occurs when the pivot grid requests data from an external provider. Ignored when DataProvider is assigned. |
EventCallback<PivotGridReadDataEventArgs<TItem>> |
RowHeaderStyling |
Custom styling for row header cells. |
Action<PivotGridRowHeaderContext<TItem>, PivotGridCellStyling> |
PivotGridAggregate
| Event | Description | Type |
|---|---|---|
Aggregator |
Defines a custom aggregate function. When set, it takes precedence over Aggregate. |
Func<IReadOnlyList<TItem>, object> |
Methods
PivotGrid
| Method | Description | Return | Parameters |
|---|---|---|---|
Reload |
Reloads the PivotGrid data and rebuilds the pivot result. | Task |
PivotGridField
| Method | Description | Return | Parameters |
|---|---|---|---|
FormatValue |
Formats a field value. | string | object value |
GetCaption |
Gets the field caption. | string | |
GetValue |
Gets the field value from the supplied item. | object | TItem item |
PivotGridColumn
| Method | Description | Return | Parameters |
|---|---|---|---|
FormatValue |
Formats a field value. | string | object value |
GetCaption |
Gets the field caption. | string | |
GetValue |
Gets the field value from the supplied item. | object | TItem item |
PivotGridRow
| Method | Description | Return | Parameters |
|---|---|---|---|
FormatValue |
Formats a field value. | string | object value |
GetCaption |
Gets the field caption. | string | |
GetValue |
Gets the field value from the supplied item. | object | TItem item |
PivotGridAggregate
| Method | Description | Return | Parameters |
|---|---|---|---|
Calculate |
Calculates the aggregate value for the supplied source items. | object | IReadOnlyList<TItem> items |
FormatValue |
Formats a field value. | string | object value |
GetCaption |
Gets the field caption. | string | |
GetValue |
Gets the field value from the supplied item. | object | TItem item |