I would be much appreciated feature if we could export a pivot grid to excel in the same way that we can export a grid to excel.
Extra Credit: As an added bonus, if the excel export was actually in an Excel Pivot Table format, that would be awesome.
I want to save or restore the state of the PivotGrid Configurator. Potentially, the user may have spent some time setting up their perfect PivotGrid that suited their needs, hence saving state seems critical.
===
ADMIN EDIT
===
The request covers exposing a state feature to programmatically manage various data operations in the PivotGrid - sorting, filtering, reordering of columns, expanding of items.
I'd like to allow the users to resize the columns, so they can see the full cell content.
Column auto-fitting can also be included.
I want to control the visibility of the total and sub-total. I want to be able to hide them if needed.
=====
TELERIK EDIT: It is possible to hide the Grand Total column and all Total rows with CSS. You can also hide only the non-Grand Total rows if you like.
<TelerikPivotGridContainer>
<TelerikPivotGridConfigurator />
<TelerikPivotGridConfiguratorButton />
<TelerikPivotGrid Data="@PivotData"
DataProviderType="@PivotGridDataProviderType.Local"
ColumnHeadersWidth="160px"
Class="no-headers">
<PivotGridColumns>
<PivotGridColumn Name="@nameof(PivotModel.Country)" Title="Country" />
<PivotGridColumn Name="@nameof(PivotModel.City)" Title="City" />
</PivotGridColumns>
<PivotGridRows>
<PivotGridRow Name="@nameof(PivotModel.Category)" Title="Category" />
<PivotGridRow Name="@nameof(PivotModel.Product)" Title="Product" />
</PivotGridRows>
<PivotGridMeasures>
<PivotGridMeasure Name="@nameof(PivotModel.ContractValue)"
Title="Contract Value"
Aggregate="@PivotGridAggregateType.Sum" />
</PivotGridMeasures>
</TelerikPivotGrid>
</TelerikPivotGridContainer>
<style>
/* Hide Grand Total column text. Remove cell paddings and borders. */
.k-pivotgrid-column-headers .k-pivotgrid-row:first-child .k-pivotgrid-header-total:last-child,
.k-pivotgrid-values .k-pivotgrid-header-total:last-child {
color: transparent;
font-size: 0;
padding: 0;
border-width: 0;
}
/* Shrink Grand Total column */
div.k-pivotgrid.no-headers .k-pivotgrid-column-headers col:last-child,
div.k-pivotgrid.no-headers .k-pivotgrid-values col:last-child {
width: 0 !important;
}
/* Hide Total row headers text */
/* Uncomment the not:() selector if you want to show back the Grand Total row. There must be no space before :not() */
div.k-pivotgrid.no-headers .k-pivotgrid-row-headers tr.k-pivotgrid-row:has(.k-pivotgrid-header-total)/*:not(:last-child)*/,
div.k-pivotgrid.no-headers .k-pivotgrid-values tr.k-pivotgrid-row:has(.k-pivotgrid-header-total:first-child)/*:not(:last-child)*/ {
font-size: 0;
color: transparent;
}
/* Remove Total headers cell paddings and borders */
/* Uncomment the not:() selector if you want to show back the Grand Total row. There must be no space before :not() */
div.k-pivotgrid.no-headers .k-pivotgrid-row-headers tr.k-pivotgrid-row:has(.k-pivotgrid-header-total)/*:not(:last-child)*/ th,
div.k-pivotgrid.no-headers .k-pivotgrid-values tr.k-pivotgrid-row:has(.k-pivotgrid-header-total:first-child)/*:not(:last-child)*/ td {
padding: 0;
border-width: 0;
}
</style>
@code {
private List<PivotModel> PivotData { get; set; } = new();
protected override void OnInitialized()
{
var dataItemCount = 100;
var categoryCount = 3;
var productCount = 10 + 1;
var countryCount = 2;
var cityCount = 4 + 1;
var rnd = Random.Shared;
for (int i = 1; i <= dataItemCount; i++)
{
var productNumber = Random.Shared.Next(1, productCount);
var categoryNumber = productNumber % categoryCount + 1;
var cityNumber = rnd.Next(1, cityCount);
var countryNumber = cityNumber % countryCount + 1;
PivotData.Add(new PivotModel()
{
Category = $"Category {categoryNumber}",
Product = $"Product {productNumber}",
Country = $"Country {countryNumber}",
City = $"City {cityNumber}",
ContractDate = DateTime.Now.AddDays(-rnd.Next(1, 31)).AddMonths(-rnd.Next(1, 12)).AddYears(-rnd.Next(0, 5)),
ContractValue = (productNumber == 3 || cityNumber == 2 || categoryNumber == 1) ? 0 : rnd.Next(123, 987)
});
}
base.OnInitialized();
}
public class PivotModel
{
public string Category { get; set; } = string.Empty;
public string Product { get; set; } = string.Empty;
public string Country { get; set; } = string.Empty;
public string City { get; set; } = string.Empty;
public DateTime ContractDate { get; set; }
public decimal ContractValue { get; set; }
}
}
Hello,
in the WPF Pivot component I created custom calculated fields. Please expose a similar feature in the Blazor PivotGrid.
var OeeA = new OeeA_BerechnetesFeld(); //Telerik.Pivot.Core.CalculatedField
OeeA.Name = "OEE A";
DataSource.CalculatedFields.Add(OeeA); // DataSource is the LocalDataSourceProvider
DataSource.AggregateDescriptions.Add(new CalculatedAggregateDescription { CalculatedFieldName = "OEE A", StringFormat = "#.#0" });
I had already tried using reflection via dataTemplate to access the ColumnGroup and RowGroup properties. It would be nice if in future versions, if possible, these were accessible directly and without having to use reflection for efficiency reasons. Expose the current field as well.
In addition to this, it would be convenient to know which row and column they refer to, in order to know which field of the Pivot dataset relates to the calculation performed, and apply custom logic to them.
In summary, expose: ColumnGroup, RowGroup, and the current field.
When using local data binding, all defined PivotGrid measures are checked by default and render in the Grid.
Please provide the ability to define measures, which are not checked and visible in the Grid area by default.
It would be nice to be able to customize the comparer used to display data in a specific order.
I think by default it uses a simple alphabetic comparison
But we have a lot of data using alpha and numeric information like:
And the user wants data in the numeric order, so we often implement our own comparer everywhere for it to work.
The PivotGrid doesn't seem to provide a way to customize the order of data even with a provider Local, ordering the source in a specific way before giving it to the component doesn't work either.
Thanks
Thomas
The PivotGrid layout and cell alignment break when filtering expanded child columns by a value that exists only in some of the columns.
Here is a test page:
<TelerikPivotGridContainer>
<TelerikPivotGridConfiguratorButton></TelerikPivotGridConfiguratorButton>
<TelerikPivotGridConfigurator></TelerikPivotGridConfigurator>
<TelerikPivotGrid Data="@PivotGridData" DataProviderType="@PivotGridDataProviderType.Local"
@ref="PivotGridRef" ColumnHeadersWidth="100px" RowHeadersWidth="130px">
<ColumnHeaderTemplate>
@{
var ctx = (PivotGridColumnHeaderTemplateContext)context;
int underscoreIndex = ctx.Text.IndexOf("-");
string text = ctx.Text;
if (underscoreIndex > 0)
{
text = text.Replace(text.Substring(0, underscoreIndex + 1), "");
<span>@text</span>
}
else
{
<span>@ctx.Text</span>
}
}
</ColumnHeaderTemplate>
<DataCellTemplate Context="dataCellContext">
@{
var c = (PivotGridDataCellTemplateContext)dataCellContext;
var amt = c.Value == null ? (0m).ToString("C2") : ((decimal)c.Value).ToString("C2");
}
<div style="text-align: right;">
@amt
</div>
</DataCellTemplate>
<PivotGridRows>
<PivotGridRow Name="@nameof(PivotGridModel.Station)" Title="Station" />
</PivotGridRows>
<PivotGridColumns>
<PivotGridColumn Name="@nameof(PivotGridModel.Year)" Title="Year" HeaderClass="year-header" />
<PivotGridColumn Name="@nameof(PivotGridModel.MonthName)" Title="Month" />
</PivotGridColumns>
<PivotGridMeasures>
<PivotGridMeasure Name="@nameof(PivotGridModel.Rate)" Title="Total"
Aggregate="@PivotGridAggregateType.Sum" />
</PivotGridMeasures>
</TelerikPivotGrid>
</TelerikPivotGridContainer>
@code
{
private TelerikPivotGrid<PivotGridModel>? PivotGridRef { get; set; }
private List<PivotGridModel> PivotGridData { get; set; } = new();
protected override async Task OnInitializedAsync()
{
var dataItemCount = 10000;
var stationCount = 30;
var rnd = Random.Shared;
for (int i = 1; i <= dataItemCount; i++)
{
var stationNumber = rnd.Next(1, stationCount);
PivotGridData.Add(new PivotGridModel()
{
Station = $"Station {stationNumber}",
ContractMonth = DateTime.Today.AddMonths(-rnd.Next(0, 13)),
Rate = rnd.Next(123, 987) * 1.23m
});
}
PivotGridRef?.Rebind();
await base.OnInitializedAsync();
}
public class PivotGridModel
{
public DateTime ContractMonth { get; set; }
public int Year => ContractMonth.Year;
public int Month => ContractMonth.Month;
public string MonthName => $"{Month}-{ContractMonth.ToString("MMMM")}";
public string Station { get; set; } = string.Empty;
public decimal? Rate { get; set; }
}
}