public PivotedRows GroupAndTotal(TickCounter tickCounter, PivotedRows pivotedRows) { IDictionary<IList<Tuple<PropertyPath, PivotKey, object>>, List<GroupedRow>> allReportRows = new Dictionary<IList<Tuple<PropertyPath, PivotKey, object>>, List<GroupedRow>>(); var groupColumns = ViewInfo.DisplayColumns .Where(col => TotalOperation.GroupBy == col.ColumnSpec.TotalOperation) .Select(col => col.ColumnDescriptor) .ToArray(); var pivotOnColumns = ViewInfo.DisplayColumns .Where(col => TotalOperation.PivotKey == col.ColumnSpec.TotalOperation) .Select(col => col.ColumnDescriptor) .ToArray(); var allInnerPivotKeys = new HashSet<PivotKey>(); var allPivotKeys = new Dictionary<PivotKey, PivotKey>(); foreach (var rowItem in pivotedRows.RowItems) { allInnerPivotKeys.UnionWith(rowItem.PivotKeys); IList<Tuple<PropertyPath, PivotKey, object>> groupKey = new List<Tuple<PropertyPath, PivotKey, object>>(); foreach (var column in groupColumns) { var pivotColumn = GetPivotColumn(column); if (null == pivotColumn) { groupKey.Add(new Tuple<PropertyPath, PivotKey, object>(column.PropertyPath, null, column.GetPropertyValue(rowItem, null))); } else { foreach (var pivotKey in GetPivotKeys(pivotColumn.PropertyPath, new []{rowItem})) { if (!pivotKey.Contains(pivotColumn.PropertyPath)) { continue; } groupKey.Add(new Tuple<PropertyPath, PivotKey, object>(column.PropertyPath, pivotKey, column.GetPropertyValue(rowItem, pivotKey))); } } } groupKey = ImmutableList.ValueOf(groupKey); var pivotOnKeyValues = new List<KeyValuePair<PropertyPath, object>>(); foreach (var column in pivotOnColumns) { var pivotColumn = GetPivotColumn(column); if (null == pivotColumn) { pivotOnKeyValues.Add(new KeyValuePair<PropertyPath, object>(column.PropertyPath, column.GetPropertyValue(rowItem, null))); } else { Trace.TraceWarning("Unable to pivot on column {0} because it is already pivoted.", pivotColumn.PropertyPath); // Not L10N } } var pivotOnKey = PivotKey.GetPivotKey(allPivotKeys, pivotOnKeyValues); List<GroupedRow> rowGroups; if (!allReportRows.TryGetValue(groupKey, out rowGroups)) { rowGroups = new List<GroupedRow>(); allReportRows.Add(groupKey, rowGroups); } var rowGroup = rowGroups.FirstOrDefault(rg => !rg.ContainsKey(pivotOnKey)); if (null == rowGroup) { rowGroup = new GroupedRow(); rowGroups.Add(rowGroup); } rowGroup.AddInnerRow(pivotOnKey, rowItem); } var outerPivotKeys = allPivotKeys.Keys.Where(key=>key.Length == pivotOnColumns.Length).ToArray(); var pivotKeyComparer = PivotKey.GetComparer(ViewInfo.DataSchema); Array.Sort(outerPivotKeys, pivotKeyComparer); var innerPivotKeys = allInnerPivotKeys.ToArray(); Array.Sort(innerPivotKeys, pivotKeyComparer); var reportItemProperties = new List<PropertyDescriptor>(); var propertyNames = new HashSet<string>(); foreach (var displayColumn in ViewInfo.DisplayColumns) { if (displayColumn.ColumnSpec.Hidden) { continue; } var totalOperation = displayColumn.ColumnSpec.TotalOperation; if (TotalOperation.GroupBy == totalOperation) { var pivotColumn = GetPivotColumn(displayColumn.ColumnDescriptor); if (null == pivotColumn) { string propertyName = MakeUniqueName(propertyNames, displayColumn.PropertyPath); reportItemProperties.Add(new GroupedPropertyDescriptor(propertyName, displayColumn, null)); } else { foreach (var innerPivotKey in innerPivotKeys) { string propertyName = MakeUniqueName(propertyNames, displayColumn.PropertyPath); reportItemProperties.Add(new GroupedPropertyDescriptor(propertyName, displayColumn, innerPivotKey)); } } } } foreach (var outerPivotKey in outerPivotKeys) { foreach (var displayColumn in ViewInfo.DisplayColumns) { if (displayColumn.ColumnSpec.Hidden) { continue; } if (TotalOperation.PivotValue == displayColumn.ColumnSpec.TotalOperation || TotalOperation.PivotKey == displayColumn.ColumnSpec.TotalOperation) { var pivotColumn = GetPivotColumn(displayColumn.ColumnDescriptor); if (null == pivotColumn) { string propertyName = MakeUniqueName(propertyNames, displayColumn.PropertyPath); reportItemProperties.Add(new GroupedPropertyDescriptor(propertyName, outerPivotKey, displayColumn, null)); } else { foreach (var innerPivotKey in allInnerPivotKeys) { string propertyName = MakeUniqueName(propertyNames, displayColumn.PropertyPath); reportItemProperties.Add(new GroupedPropertyDescriptor(propertyName, outerPivotKey, displayColumn, innerPivotKey)); } } } } } return new PivotedRows(allReportRows.SelectMany(entry=>entry.Value.Select( reportRow=>new RowItem(reportRow))), new PropertyDescriptorCollection(reportItemProperties.ToArray())); }
public ReportResults GroupAndTotal(CancellationToken cancellationToken, ReportResults pivotedRows) { IDictionary <IList <Tuple <PropertyPath, PivotKey, object> >, List <GroupedRow> > allReportRows = new Dictionary <IList <Tuple <PropertyPath, PivotKey, object> >, List <GroupedRow> >(); var groupColumns = ViewInfo.DisplayColumns .Where(col => TotalOperation.GroupBy == col.ColumnSpec.TotalOperation) .Select(col => col.ColumnDescriptor) .ToArray(); var pivotOnColumns = ViewInfo.DisplayColumns .Where(col => TotalOperation.PivotKey == col.ColumnSpec.TotalOperation) .Select(col => col.ColumnDescriptor) .ToArray(); var allInnerPivotKeys = new HashSet <PivotKey>(); var allPivotKeys = new Dictionary <PivotKey, PivotKey>(); foreach (var rowItem in pivotedRows.RowItems) { cancellationToken.ThrowIfCancellationRequested(); allInnerPivotKeys.UnionWith(rowItem.PivotKeys); IList <Tuple <PropertyPath, PivotKey, object> > groupKey = new List <Tuple <PropertyPath, PivotKey, object> >(); foreach (var column in groupColumns) { cancellationToken.ThrowIfCancellationRequested(); var pivotColumn = GetPivotColumn(column); if (null == pivotColumn) { groupKey.Add(new Tuple <PropertyPath, PivotKey, object>(column.PropertyPath, null, column.GetPropertyValue(rowItem, null))); } else { foreach (var pivotKey in GetPivotKeys(pivotColumn.PropertyPath, new [] { rowItem })) { cancellationToken.ThrowIfCancellationRequested(); if (!pivotKey.Contains(pivotColumn.PropertyPath)) { continue; } groupKey.Add(new Tuple <PropertyPath, PivotKey, object>(column.PropertyPath, pivotKey, column.GetPropertyValue(rowItem, pivotKey))); } } } groupKey = ImmutableList.ValueOf(groupKey); var pivotOnKeyValues = new List <KeyValuePair <PropertyPath, object> >(); foreach (var column in pivotOnColumns) { cancellationToken.ThrowIfCancellationRequested(); var pivotColumn = GetPivotColumn(column); if (null == pivotColumn) { pivotOnKeyValues.Add(new KeyValuePair <PropertyPath, object>(column.PropertyPath, column.GetPropertyValue(rowItem, null))); } else { Trace.TraceWarning(@"Unable to pivot on column {0} because it is already pivoted.", pivotColumn.PropertyPath); } } var pivotOnKey = PivotKey.GetPivotKey(allPivotKeys, pivotOnKeyValues); List <GroupedRow> rowGroups; if (!allReportRows.TryGetValue(groupKey, out rowGroups)) { rowGroups = new List <GroupedRow>(); allReportRows.Add(groupKey, rowGroups); } var rowGroup = rowGroups.FirstOrDefault(rg => !rg.ContainsKey(pivotOnKey)); if (null == rowGroup) { rowGroup = new GroupedRow(); rowGroups.Add(rowGroup); } rowGroup.AddInnerRow(pivotOnKey, rowItem); } var outerPivotKeys = allPivotKeys.Keys.Where(key => key.Length == pivotOnColumns.Length).ToArray(); var pivotKeyComparer = PivotKey.GetComparer(ViewInfo.DataSchema); Array.Sort(outerPivotKeys, pivotKeyComparer); var innerPivotKeys = allInnerPivotKeys.ToArray(); Array.Sort(innerPivotKeys, pivotKeyComparer); var reportItemProperties = new List <DataPropertyDescriptor>(); var propertyNames = new HashSet <string>(); foreach (var displayColumn in ViewInfo.DisplayColumns) { cancellationToken.ThrowIfCancellationRequested(); if (displayColumn.ColumnSpec.Hidden) { continue; } var totalOperation = displayColumn.ColumnSpec.TotalOperation; if (TotalOperation.GroupBy == totalOperation) { var pivotColumn = GetPivotColumn(displayColumn.ColumnDescriptor); if (null == pivotColumn) { string propertyName = MakeUniqueName(propertyNames, displayColumn.PropertyPath); reportItemProperties.Add(new GroupedPropertyDescriptor(propertyName, displayColumn, null)); } else { foreach (var innerPivotKey in innerPivotKeys) { cancellationToken.ThrowIfCancellationRequested(); string propertyName = MakeUniqueName(propertyNames, displayColumn.PropertyPath); reportItemProperties.Add(new GroupedPropertyDescriptor(propertyName, displayColumn, innerPivotKey)); } } } } foreach (var outerPivotKey in outerPivotKeys) { foreach (var displayColumn in ViewInfo.DisplayColumns) { cancellationToken.ThrowIfCancellationRequested(); if (displayColumn.ColumnSpec.Hidden) { continue; } if (TotalOperation.PivotValue == displayColumn.ColumnSpec.TotalOperation || TotalOperation.PivotKey == displayColumn.ColumnSpec.TotalOperation) { var pivotColumn = GetPivotColumn(displayColumn.ColumnDescriptor); if (null == pivotColumn) { string propertyName = MakeUniqueName(propertyNames, displayColumn.PropertyPath); reportItemProperties.Add(new GroupedPropertyDescriptor(propertyName, outerPivotKey, displayColumn, null)); } else { foreach (var innerPivotKey in allInnerPivotKeys) { string propertyName = MakeUniqueName(propertyNames, displayColumn.PropertyPath); reportItemProperties.Add(new GroupedPropertyDescriptor(propertyName, outerPivotKey, displayColumn, innerPivotKey)); } } } } } return(new ReportResults(allReportRows.SelectMany(entry => entry.Value.Select( reportRow => new RowItem(reportRow))), reportItemProperties)); }