Support TimeSpan values for aggregation

Oct 29, 2009 at 12:57 AM

Hello Hans.

I tweaked one of your functions in InlineAggregateValue in order to support aggregation of TimeSpan values.

I would really like to see more aggregation options e.g. Standard deviation. I also think that the function should be rewritten from scratch without using a Decimal for the value holder.

Here's the resulting code:


        /// <summary>
        /// Computes an aggregate value and formats it
        /// </summary>
        /// <param name="values">list of values</param>
        /// <returns>calculated and formatted value</returns>
        /// <exception cref="NotSupportedException">The aggregate value type {0} is not supported yet!</exception>
        public string ComputeAndFormat(Dictionary<string, List<object>> values)
        {
            if ((values == null) || (values.Count <= 0)) return _emptyValue;
            if (!values.ContainsKey(_aggregateGroup)) return _emptyValue;

            decimal? result = null;
            bool isTimeSpan = false;
            long count = 0;
            foreach (object value in values[_aggregateGroup])
            {
                count++;
                if (_aggregateValueType == ReportAggregateValueType.Count) continue; // count needs no real calculation

                decimal thisValue;
                if (value == null) return _errorValue;
                if (value is TimeSpan)
                {
                    thisValue = Convert.ToDecimal(((TimeSpan)value).Ticks);
                    isTimeSpan = true;
                }
                else
                {
                    if (!Decimal.TryParse(value.ToString(), out thisValue)) return _errorValue;   
                }
                switch (_aggregateValueType)
                {
                    case ReportAggregateValueType.Average:
                    case ReportAggregateValueType.Sum:
                        if (result == null) { result = thisValue; break; }
                        result += thisValue;
                        break;
                    case ReportAggregateValueType.Maximum:
                        if (result == null) { result = thisValue; break; }
                        if (thisValue > result) result = thisValue;
                        break;
                    case ReportAggregateValueType.Minimum:
                        if (result == null) { result = thisValue; break; }
                        if (thisValue < result) result = thisValue;
                        break;
                    default:
                        throw new NotSupportedException(String.Format("The aggregate value type {0} is not supported yet!", _aggregateValueType.ToString()));
                }
            }
            if (_aggregateValueType == ReportAggregateValueType.Count) result = count;
            if (result == null) return _emptyValue;

            if (_aggregateValueType == ReportAggregateValueType.Average) result /= count; // calculate average

            if (isTimeSpan) return TimeSpan.FromTicks(Convert.ToInt64(result)).ToString();  //for timespans

            return InlineHasValue.FormatValue(result, Format);
        }
    }

Coordinator
Oct 31, 2009 at 11:57 AM

Thank you very much for your contribution, Theo. I added your code to InlineAggregateValue.cs.

Regards,

Hans