How do I add a summary that calculates a weighted average and handles when the group by columns gets changed? Do I need to create a custom summary? If so, are there examples of doing this? I have not ventured into creating my own summaries yet. thanks
I'm not exactly sure how a weighted average is calculated. I assume this would depend on two columns of the grid instead of just one, though.
If that's the case, then you would have to calculate this yourself using a custom summary. It's pretty simple. Create a class that implement ICustomSummaryCalculator and assign an instance of that class to the summary when you create it.
There are three methods on this interface, one that begins the calculation, one that ends it, and one that fires passing in the rows for which the summary is being calculated.
hey Mike, i'm trying to accomplish this exact task but having a bit of trouble. i am doing a weighted avg calc and i think i'm off in scope of what the custom class is doing. this is my weighted avg calc class. the field i'm avging is called price and its being weighted by cumqty.
daverage is not coming out as my weighted average. what am i missing? this class is called for every grouping/calculation right?
any help is appreciated.
Al
public class WeightAvgSummary:ICustomSummaryCalculator { decimal daverage = 0; decimal dweight = 0; decimal denominator = 0; public WeightAvgSummary () { }
//get total TOTALCUMQTY for denominator public void BeginCustomSummary (SummarySettings settings,RowsCollection rows) {
denominator = (from r in rows where r.IsDataRow == true select Convert.ToDecimal(r.Cells["CUMQTY"].Value)).Sum();
if (denominator == 0) denominator = 1; }
//per row get the weight of this row CUMQTY/TOTALCUMQTY gives me the weight for that row. and i sum it with a running total...(daverage).
//multiply that weight * PRICE public void AggregateCustomSummary(SummarySettings settings, UltraGridRow row) { dweight = Convert.ToDecimal(row.Cells["CUMQTY"].Value) / denominator; daverage += (dweight/100 * Convert.ToDecimal(row.Cells["PRICE"].Value)); } public object EndCustomSummary(SummarySettings settings, RowsCollection rows) { return daverage; } }
Hi Al,
The ICustomSummaryCalculator is pretty simple. It fires BeginCustomSummary once at the beginning, the AggregateCustomSummary fires for each row in the rows collection, and then it fires EndCustomSummary. If you are doing grouping in the grid, and displaying a summary in each group, then the calculation should be preformed separately for each rows collection under each GroupByRow.
I'm not clear on what might be wrong in your case. As I mentioned above, I'm not clear on how a weighted average is calculated. So I don't know why it's not working for you. Also, you don't mention exactly what the problem is, what results you are getting, or why they are wrong.
This post is from back in 2009, though. Since then, we added the ability to do external summaries. So that might be a better option than an ICustomSummaryCalculator if you are using a more recent version of the grid. When you add your summary to the band, specify External as the summary type. Then you handle the grid's ExternalSummaryValueRequested event. The event gives you the SummaryValue, from which you can get the RowsCollection and the SummarySettings. And then you just set the Value.
void ultraGrid1_ExternalSummaryValueRequested(object sender, ExternalSummaryValueEventArgs e) { decimal weightedAverage = // calculate the weighted average here. e.SummaryValue.SetExternalSummaryValue(weightedAverage); }
i think I'm definitely on the same page as you. for every level of grouping:
I imagine once instance of this SummaryCalculator class per grouping.
BeginCustomSummary() happens once in the beginning
AggregateCustomSummary() happens very every row in the group.
EndCustomSummary() happens once at the end returning object
my initial problem was the numbers were just wrong. ok I will try this solution since I am using a later version. 13.1
thanks mike
Hello to 10 months ago, Finally came back to fixing this with fresh eyes.Here's the info if anyone finds it useful.
was not setting allowrowsummaries=true
gridData.DisplayLayout.Bands[0].Columns["AVGPX"].AllowRowSummaries = AllowRowSummaries.True;
Also, i had SummaryType.External. should have been SummaryType.Custom
gridData.DisplayLayout.Bands[0].Summaries.Add(SummaryType.Custom, wavgprice, gridData.DisplayLayout.Bands[0].Columns["AVGPX"], SummaryPosition.UseSummaryPositionColumn, gridData.DisplayLayout.Bands[0].Columns["AVGPX"]);
..i am able to debug the custom summary and see it firing when i scroll throughout the grid.
FYI - SummaryType.Custom is for when you want to use an ICustomSummaryCalculator. This interface is useful because it tells you when the summary is about to be calculated, then it iterates the rows for you, then it tells you when the summary calculation is complete.
SummaryType.External has no interface. It's useful when you want to assign a literal value to a summary without any real calculation or dependency on the grid rows. For example if you want to display a label in the summary area with just a literal string that requires no calculation. Or you want to display some constant value from outside the grid.