For .Net WPF XamPivotGrid:
Can you tell me if Calculated Measures are supported in FlatDataSource. Basically we will like to provide our own calculation for aggregating measures (e.g. weighted average instead of plain average).
I do see that Measures have aggregator which takes enum value and there are references to ByChildreen, ByAccount and Calculated.
I do not see any example and unable to determine how to use it.
Thanks
Thanks a lot.
I actually have same imports. I had to modify definitions for Funcs:
private
Func<object, object> _getValue;
private Func<object, object> _getWeight;
as well as specify data type for Cast() method and it runs:
IList dataItems = items.Cast<DataRowMetadata>().Select(drm => drm.DataObject).ToList();
Thanks a lot again,
Alex
If it helps, I am targeting framework 4 and my imports are
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Infragistics.Olap;
using Infragistics.Olap.FlatData;
I don't think there are any special libraries
Hi,
I am trying to achieve similar goal for my WA properties and hoped to steal your custom aggregator :-)
Not able to compile it though . Do you use some specific libs for Func and Linq ?
I am having the following comp. time errors :
Error 231 Using the generic type 'System.Func<TResult>' requires 1 type arguments
Error 236 The call is ambiguous between the following methods or properties: 'Stealth.Components.PivotGrid.Model.DerivedData.IgWeightedAverageAggregator.Evaluate(Infragistics.Olap.IAggregationResult, Infragistics.Olap.IAggregateable, System.Collections.IEnumerable)' and 'Stealth.Components.PivotGrid.Model.DerivedData.IgWeightedAverageAggregator.Evaluate(Infragistics.Olap.IAggregationResult, Infragistics.Olap.IAggregateable, System.Collections.IEnumerable)'
Error 233 'System.Linq.Queryable.Cast<TResult>(System.Linq.IQueryable)' is a 'method', which is not valid in the given context
Can you please help me to get your aggreagtor running ?
Thanks a lot in advance,
This works
public class IgWeightedAverageCache { /// /// sum(Weight * Value) /// private double _numerator = 0; /// /// sum(Weight) /// private double _denominator = 0; internal IgWeightedAverageCache() { } internal IgWeightedAverageCache(double numerator, double denominator) { _numerator = numerator; _denominator = denominator; } internal double WeightedAverage { get { return _numerator/_denominator; } } public void Add(double weight, double value) { _numerator += weight*value; _denominator += weight; } } public class IgWeightedAverageResult : IAggregationResult { private readonly IgWeightedAverageCache _cache; public IgWeightedAverageResult() { this._cache = new IgWeightedAverageCache(); } public IgWeightedAverageCache Cache { get { return this._cache; } } public double Value { get { return this.Cache.WeightedAverage; } set { throw new NotImplementedException(); } } object IAggregationResult.Value { get { return this.Value; } } object IAggregationResult.Cache { get { return this.Cache; } } } /// /// TODO: Flyweight? /// public class IgWeightedAverageAggregator : IAggregator { private readonly string _valuePropertyName; private readonly string _weightPropertyName; private Func _getValue; private Func _getWeight; public IgWeightedAverageAggregator(string valuePropName, string weightPropName) { _valuePropertyName = valuePropName; _weightPropertyName = weightPropName; } public string Identity { get; set; } private void InitReflection(object item) { if (_getValue == null) { lock (this) { if (_getValue == null) { Type itemsType = item.GetType(); var valuePropertyInfo = itemsType.GetProperty(_valuePropertyName); var weightPropertyInfo = itemsType.GetProperty(_weightPropertyName); _getValue = ReflectionHelper.CreatePropertyGetMethod(valuePropertyInfo); _getWeight = ReflectionHelper.CreatePropertyGetMethod(weightPropertyInfo); } } } } public IAggregationResult Evaluate(IAggregationResult oldResult, IAggregateable aggregateable, IEnumerable items) { var result = new IgWeightedAverageResult(); IList dataItems = items.Cast().Select(drm => drm.DataObject).ToList(); if (dataItems.Count > 0) { InitReflection(dataItems[0]); foreach (object dataItem in dataItems) { var weight = (double?) _getWeight(dataItem); var value = (double?)_getValue(dataItem); if (weight != null && value != null) { result.Cache.Add(weight.Value, value.Value); } } } return result; } public IAggregationResult Evaluate(IAggregationResult oldResult, IAggregateable aggregateable, IEnumerable items) { return this.Evaluate((oldResult as IgWeightedAverageResult), aggregateable, items); } public IAggregationResult Evaluate(IAggregationResult oldResult, double value) { throw new NotImplementedException(); } public IAggregationResult Evaluate(IAggregationResult oldResult, object value) { throw new NotImplementedException(); } }
I am looking at your examples. Is it actually possible to do a weighted average? For example, if I have a Value and Weight columns, the aggregation of Value should be sum(Value[i]*Weight[i])/sum(weight[i])? Can you give an example of that?