From 0d45df003cdd351264679abbd1e4e171c12c7b31 Mon Sep 17 00:00:00 2001 From: Dimo Dimov <961014+dimodi@users.noreply.github.com> Date: Wed, 12 Feb 2025 09:58:44 +0200 Subject: [PATCH 1/4] docs(pivotgrid): Explain differences between local and XMLA binding --- components/pivotgrid/data-binding.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/components/pivotgrid/data-binding.md b/components/pivotgrid/data-binding.md index 4b0267e99..d079aa292 100644 --- a/components/pivotgrid/data-binding.md +++ b/components/pivotgrid/data-binding.md @@ -20,15 +20,22 @@ The PivotGrid supports different data sources via its `DataProviderType` paramet * [`Local`](#local) (default) * [`Xmla`](#xmla) +### Usage Differences + +The available data providers differ in several ways: + +* XMLA binding is more complex to setup, but more flexible. +* Local data with a `DateTime` property does not support automatic aggregations by date periods like years, months, weeks, and so on. +* XMLA binding supports [load on demand](slug:pivotgrid-overview#pivotgrid-parameters), which offloads all calculations to the external data source. Local binding receives all data at once and performs all aggregate calculations in-memory. Large amounts of local data may impact the performance, especially in WebAssembly apps. +* When using load on demand, XMLA binding supports custom aggregate functions that are defined and performed in the OLAP cube. Local data supports only the [predefined aggregate types in the `PivotGridAggregateType` enum](slug:telerik.blazor.pivotgridaggregatetype). +* When using local data, all defined measures in `` render by default in the PivotGrid. Users can uncheck and hide the measures they don't need from the [PivotGrid Configurator](slug:pivotgrid-configurator). ## Local -When bound to local data, the Pivot Grid requires its `Data` parameter to provide all the data at once as `IEnumerable`. The component will perform all aggregate calculations in-memory and there is no [load on demand](slug:pivotgrid-overview#pivotgrid-parameters). +When bound to local data, the Pivot Grid requires its `Data` parameter to provide all the data at once as `IEnumerable`. If the local data changes programmatically, you need to reset the collection instance or [call the PivotGrid `Rebind()` method](slug:pivotgrid-overview#pivotgrid-reference-and-methods). See the common documentation about [refreshing component data](slug:common-features-data-binding-overview#refresh-data) for details. -> Large amounts of local data may impact the performance, especially in WebAssembly applications. - >caption PivotGrid bound to Local data provider
From 38552fa3ad2daedc074d9b8003ff4af8c9173f41 Mon Sep 17 00:00:00 2001 From: Dimo Dimov <961014+dimodi@users.noreply.github.com> Date: Wed, 12 Feb 2025 11:59:07 +0200 Subject: [PATCH 2/4] kb(PivotGrid): Add KB for local date aggregates --- components/pivotgrid/data-binding.md | 2 +- .../pivotgrid-local-date-aggregates.md | 169 ++++++++++++++++++ 2 files changed, 170 insertions(+), 1 deletion(-) create mode 100644 knowledge-base/pivotgrid-local-date-aggregates.md diff --git a/components/pivotgrid/data-binding.md b/components/pivotgrid/data-binding.md index d079aa292..8a5acca69 100644 --- a/components/pivotgrid/data-binding.md +++ b/components/pivotgrid/data-binding.md @@ -25,7 +25,7 @@ The PivotGrid supports different data sources via its `DataProviderType` paramet The available data providers differ in several ways: * XMLA binding is more complex to setup, but more flexible. -* Local data with a `DateTime` property does not support automatic aggregations by date periods like years, months, weeks, and so on. +* Local data does not support aggregations by date periods for `DateTime` properties. If you need [aggregations by year, month, week, and so on, then create additional `int` or `string` properties in the PivotGrid model class](slug:pivotgrid-kb-local-date-aggregates). * XMLA binding supports [load on demand](slug:pivotgrid-overview#pivotgrid-parameters), which offloads all calculations to the external data source. Local binding receives all data at once and performs all aggregate calculations in-memory. Large amounts of local data may impact the performance, especially in WebAssembly apps. * When using load on demand, XMLA binding supports custom aggregate functions that are defined and performed in the OLAP cube. Local data supports only the [predefined aggregate types in the `PivotGridAggregateType` enum](slug:telerik.blazor.pivotgridaggregatetype). * When using local data, all defined measures in `` render by default in the PivotGrid. Users can uncheck and hide the measures they don't need from the [PivotGrid Configurator](slug:pivotgrid-configurator). diff --git a/knowledge-base/pivotgrid-local-date-aggregates.md b/knowledge-base/pivotgrid-local-date-aggregates.md new file mode 100644 index 000000000..7d5d58ba5 --- /dev/null +++ b/knowledge-base/pivotgrid-local-date-aggregates.md @@ -0,0 +1,169 @@ +--- +title: Use Date Aggregates with Local Data +description: Learn how to implement and configure aggregate calculations by date periods like year, month, week, and day, when using local data binding with the Telerik PivotGrid for Blazor. +type: how-to +page_title: How to Use Date Aggregates with Local Data +slug: pivotgrid-kb-local-date-aggregates +tags: blazor, pivotgrid, aggregates +ticketid: 1678109 +res_type: kb +--- + +## Environment + + + + + + + + +
ProductPivotGrid for Blazor
+ +## Description + +This KB answers the following questions: + +* How to allow users to aggregate local data by date periods, such as years, months, weeks, and days? +* How to enable date aggregations with local PivotGrid data binding? +* How to calculate date aggregates by period with a local data provider? + +## Solution + +The [PivotGrid supports date aggregates by period](slug:pivotgrid-data-binding#usage-differences) only with [XMLA data binding](slug:pivotgrid-data-binding#xmla). Consider the following approach for local data scenarios: + +1. Define all `DateTime` properties in the PivotGrid model class as `internal` or `private`, so that the PivotGrid ignores them. +1. Define additional helper properties in the PivotGrid model class, which will extract the year, month, week, and day values from the `DateTime` properties. +1. Use the helper properties in the PivotGrid definition and UI. +1. (optional) Use a [PivotGrid column header template](slug:pivotgrid-templates#column-header-template) to format the values of the helper properties. This may be necessary, because the PivotGrid sorts `string` values alphabetically in the column headers. In this case, you may also need to [get the correct localized value for the "TOTAL" label](slug:globalization-localization). + +>caption Using date period aggregations in the Telerik PivotGrid for Blazor + +````RAZOR.skip-repl +@using System.Globalization +@using Telerik.Blazor.Services + +@inject ITelerikStringLocalizer TelerikStringLocalizer + + + + + + + + + + + + + + + + + + + + + + @{ var c = (PivotGridColumnHeaderTemplateContext)context; } + @ConvertYearMonthString(c.Text) + + + + + +@code { + private List PivotData { get; set; } = new List(); + + protected override void OnInitialized() + { + TotalSuffix = " " + TelerikStringLocalizer["PivotGrid_TotalValueFormat"].Replace("{0}", string.Empty).Trim(); + + GenerateData(); + } + + /// + /// Gets or sets the correct localized TOTAL string. + /// + private string TotalSuffix { get; set; } = " Total"; + + /// + /// Convert a yyyy MM string to MMM yyyy. + /// + /// The PivotGrid column header text that will render without a template. + /// If the yearMonth argument is valid, returns a DateTime string in format MMM yyyy plus the optional Total suffix. + /// Otherwise, return the argument as is. + private string ConvertYearMonthString(string yearMonth) + { + string yearMonthWithoutTotal = yearMonth.Replace(TotalSuffix, string.Empty, StringComparison.InvariantCultureIgnoreCase); + string totalSuffixConditional = yearMonth.Replace(yearMonthWithoutTotal, string.Empty); + string[] separateYearMonth = yearMonthWithoutTotal.Split(" "); + + if (yearMonthWithoutTotal.Length == 7 && + yearMonthWithoutTotal.IndexOf(" ") == 4 && + separateYearMonth.Length == 2) + { + bool yearSuccess = int.TryParse(separateYearMonth[0], NumberStyles.None, CultureInfo.InvariantCulture, out int year); + bool monthSuccess = int.TryParse(separateYearMonth[1], NumberStyles.None, CultureInfo.InvariantCulture, out int month); + + if (yearSuccess && monthSuccess) + { + DateTime actualDate = new DateTime(year, month, 1); + + return $"{actualDate.ToString("MMM yyyy")} {totalSuffixConditional}"; + } + } + + return yearMonth; + } + + private void GenerateData() + { + int dataItemCount = 100; + int categoryCount = 3; + int productCount = 7 + 1; // effectively 7 + int cityCount = 3 + 1; // effectively 3 + int daysBack = 6 * 30; + Random rnd = Random.Shared; + + for (int i = 1; i <= dataItemCount; i++) + { + var productNumber = rnd.Next(1, productCount); + + PivotData.Add(new SalesModel() + { + Category = $"Category {productNumber % categoryCount + 1}", + Product = $"Product {productNumber}", + City = $"City {rnd.Next(1, cityCount)}", + ContractDate = DateTime.Today.AddDays(-rnd.Next(1, daysBack)), + Revenue = rnd.Next(123, 987) * 1.23m + }); + + PivotData.OrderBy(p => p.ContractDate); + } + } + + public class SalesModel + { + public string Category { get; set; } = null!; + public string Product { get; set; } = null!; + public string City { get; set; } = null!; + internal DateTime ContractDate { get; set; } + + public int Year => ContractDate.Year; + public string Month => ContractDate.ToString("yyyy MM"); + public string Week => $"Week {ISOWeek.GetWeekOfYear(ContractDate)} {ContractDate.ToString("yyyy")}"; + + public decimal Revenue { get; set; } + } +} +```` + +## See Also + +* [Pivot Grid Data Providers](slug:pivotgrid-data-binding) From 190eb69c55adf68ac8d9c787cf90cba2a0eb4853 Mon Sep 17 00:00:00 2001 From: Dimo Dimov <961014+dimodi@users.noreply.github.com> Date: Wed, 12 Feb 2025 12:01:06 +0200 Subject: [PATCH 3/4] Update knowledge-base/pivotgrid-local-date-aggregates.md --- knowledge-base/pivotgrid-local-date-aggregates.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/knowledge-base/pivotgrid-local-date-aggregates.md b/knowledge-base/pivotgrid-local-date-aggregates.md index 7d5d58ba5..9ef90facd 100644 --- a/knowledge-base/pivotgrid-local-date-aggregates.md +++ b/knowledge-base/pivotgrid-local-date-aggregates.md @@ -32,7 +32,7 @@ This KB answers the following questions: The [PivotGrid supports date aggregates by period](slug:pivotgrid-data-binding#usage-differences) only with [XMLA data binding](slug:pivotgrid-data-binding#xmla). Consider the following approach for local data scenarios: -1. Define all `DateTime` properties in the PivotGrid model class as `internal` or `private`, so that the PivotGrid ignores them. +1. Define all `DateTime` properties in the PivotGrid model class as `internal`, `protected`, or `private`, so that the PivotGrid ignores them. 1. Define additional helper properties in the PivotGrid model class, which will extract the year, month, week, and day values from the `DateTime` properties. 1. Use the helper properties in the PivotGrid definition and UI. 1. (optional) Use a [PivotGrid column header template](slug:pivotgrid-templates#column-header-template) to format the values of the helper properties. This may be necessary, because the PivotGrid sorts `string` values alphabetically in the column headers. In this case, you may also need to [get the correct localized value for the "TOTAL" label](slug:globalization-localization). From b6c89f2a03635599f7419b71d74dd0d776800697 Mon Sep 17 00:00:00 2001 From: Dimo Dimov <961014+dimodi@users.noreply.github.com> Date: Wed, 12 Feb 2025 13:04:59 +0200 Subject: [PATCH 4/4] Update components/pivotgrid/data-binding.md --- components/pivotgrid/data-binding.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pivotgrid/data-binding.md b/components/pivotgrid/data-binding.md index 8a5acca69..b7f006b6b 100644 --- a/components/pivotgrid/data-binding.md +++ b/components/pivotgrid/data-binding.md @@ -25,7 +25,7 @@ The PivotGrid supports different data sources via its `DataProviderType` paramet The available data providers differ in several ways: * XMLA binding is more complex to setup, but more flexible. -* Local data does not support aggregations by date periods for `DateTime` properties. If you need [aggregations by year, month, week, and so on, then create additional `int` or `string` properties in the PivotGrid model class](slug:pivotgrid-kb-local-date-aggregates). +* Local data does not support aggregations by date periods for `DateTime` properties. If a `DateTime` property is added as a row or column, the PivotGrid will generate a separate row or column for each unique `DateTime` value. If you need [aggregations by year, month, week, and so on, then create additional `int` or `string` properties in the PivotGrid model class](slug:pivotgrid-kb-local-date-aggregates). * XMLA binding supports [load on demand](slug:pivotgrid-overview#pivotgrid-parameters), which offloads all calculations to the external data source. Local binding receives all data at once and performs all aggregate calculations in-memory. Large amounts of local data may impact the performance, especially in WebAssembly apps. * When using load on demand, XMLA binding supports custom aggregate functions that are defined and performed in the OLAP cube. Local data supports only the [predefined aggregate types in the `PivotGridAggregateType` enum](slug:telerik.blazor.pivotgridaggregatetype). * When using local data, all defined measures in `` render by default in the PivotGrid. Users can uncheck and hide the measures they don't need from the [PivotGrid Configurator](slug:pivotgrid-configurator).