/// <summary> /// Merge two pivot result. Useful for multiple nodes clusters /// </summary> /// <param name="other"></param> public void MergeWith(PivotLevel other) { if (!Equals(AxisValue, other.AxisValue)) { throw new NotSupportedException("Error in pivot merging. Mismatching axis"); } foreach (var aggregatedValue in other.AggregatedValues) { var myValue = AggregatedValues.FirstOrDefault(v => v.ColumnName == aggregatedValue.ColumnName); if (myValue == null) { AggregatedValues.Add(aggregatedValue); } else { myValue.Count += aggregatedValue.Count; myValue.Sum += aggregatedValue.Sum; } } foreach (var otherChild in other.Children) { if (!Children.TryGetValue(otherChild.Key, out var myChild)) { Children.Add(otherChild.Key, otherChild.Value); } else { myChild.MergeWith(otherChild.Value); } } }
public void AggregateOneObject(PackedObject @object, List <int> axisIndex, List <int> valuesIndex) { if (@object.Values.Length == 0) { throw new NotSupportedException($"At least one property of type {@object.CollectionName} must be declared as [ServerSideVisible]"); } var valuesForPivot = new List <KeyValue>(); foreach (var i in valuesIndex) { var val = @object.Values[i]; if (double.IsNaN(val.NumericValue)) { throw new NotSupportedException("Only numeric values can be used for pivot calculations"); } valuesForPivot.Add(val); } foreach (var value in valuesForPivot) { // first aggregate the root level var agg = AggregatedValues.FirstOrDefault(v => v.ColumnName == value.KeyName); if (agg == null) { agg = new AggregatedValue { ColumnName = value.KeyName }; AggregatedValues.Add(agg); } agg.Count++; agg.Sum += (decimal)value.NumericValue; } if (axisIndex.Count > 0) { var kv = @object[axisIndex[0]]; if (!Children.TryGetValue(kv, out var child)) { child = new PivotLevel { AxisValue = kv }; Children.Add(kv, child); } child.AggregateOneObject(@object, axisIndex.Skip(1).ToList(), valuesIndex); } }