public static GroupTree <T> ParseGroups <T>(IList <T> paged, List <DynamicGroupBy <T> > groupBy, Func <T, object> uniqueKeyExpression) { var firstLevelGroups = paged.GroupBy(groupBy[0].Expression.Compile()); var groupsRoot = new GroupTree <T>(RootGroupString, GroupState.EXPANDED); foreach (var group in firstLevelGroups) { var groupItems = group.ToList(); var subGroup = new GroupTree <T>(group.Key == null? NullString : group.Key, groupBy[0].Column, groupBy[0].Expanded ? GroupState.EXPANDED : GroupState.COLLAPSED); if (groupBy.Count() > 1) { var nestedGroups = ParseNestedGroups(subGroup, groupItems, groupBy, 1, uniqueKeyExpression); groupsRoot.SubGroups.Add(nestedGroups); } else { subGroup.Parent = groupsRoot; subGroup.Items.AddRange(groupItems); subGroup.UniqueItemKeys = subGroup.Items.Select(uniqueKeyExpression).ToList(); groupsRoot.SubGroups.Add(subGroup); } } return(groupsRoot); }
public static GroupTree <T> ParseNestedGroups <T>(GroupTree <T> root, List <T> items, List <DynamicGroupBy <T> > groupBy, int counter, Func <T, object> uniqueKeyExpression) { if (counter == groupBy.Count()) { root.Items.AddRange(items); root.UniqueItemKeys = root.Items.Select(uniqueKeyExpression).ToList(); return(root); } var groups = items.GroupBy(groupBy[counter].Expression.Compile()); foreach (var group in groups) { var groupItems = group.ToList(); var nextCounter = counter + 1; var subGroup = new GroupTree <T>(group.Key, groupBy[counter].Column, groupBy[counter].Expanded ? GroupState.EXPANDED : GroupState.COLLAPSED); subGroup.Parent = root; root.SubGroups.Add(ParseNestedGroups(subGroup, groupItems, groupBy, nextCounter, uniqueKeyExpression)); } return(root); }
public static int GetTotalGroups <T>(GroupTree <T> group) { var totalGroups = group.SubGroups.Count; foreach (var subGroup in @group.SubGroups) { totalGroups += GetTotalGroups(subGroup); } return(totalGroups); }
public static void FormatGroupedAggregators <T>(GroupTree <T> group, Dictionary <string, string> formattings) { foreach (var aggregatorInfo in group.Aggregates) { var formatting = formattings.ContainsKey(aggregatorInfo.Column) ? formattings[aggregatorInfo.Column] : null; aggregatorInfo.FormatValue(formatting); foreach (var subGroup in group.SubGroups) { FormatGroupedAggregators(subGroup, formattings); } } }
private static GroupTree <T> RecreateHierarchicalGroupStructure <T>(List <LeafGroup> data, Dictionary <string, string> ColumnsToFormattings) { // Our root var groupsRoot = new GroupTree <T>(RootGroupString, GroupState.EXPANDED); // Maximum Nesting Level var maxLevel = data.Count > 0 ? data[0].Level : 0; // Start from level one and create tree level by level for (var level = 1; level <= maxLevel; level++) { // Find the distinct groups for this level var thisGroups = data.GroupBy(d => d.PathAtLevel(level)); // Iterate through these Level Groups foreach (var group in thisGroups.ToList()) { // Get the first Leaf Group in each Level Group // This leaf group always exists and is enough for this task var first = group.ToList()[0]; // Groupped by Column var column = first.ColumnsToKeys.ElementAt(level - 1).Key; // Column Value var value = first.ColumnsToKeys.ElementAt(level - 1).Value; // Column Formatting var formatting = ColumnsToFormattings.ContainsKey(column) ? ColumnsToFormattings[column] : null; // Group's Initial State // Last Level Groups must be Collapsed as there are no records var state = level < maxLevel && maxLevel > 1 ? GroupState.EXPANDED : GroupState.COLLAPSED; // Create the actual Group var groupTree = new GroupTree <T>(value, column, state); // For the last level Groups, include the aggregators we have retrieved if (level == maxLevel) { var aggList = new List <AggregatorInfo <T> >(); foreach (var agg in first.Aggregators) { aggList.Add(new AggregatorInfo <T>(agg.Column, agg.Type, agg.Value, formatting)); } groupTree.Aggregates = aggList; } // We now need to find were this Group belongs in the tree // If we are at first level, the Group belongs to the tree's root // For higher levels, we search for the parent Group var owner = level > 1 ? groupsRoot.FindSubGroup(first.PathAtLevel(level - 1)) : groupsRoot; // Add Group to Owner groupTree.Parent = owner; owner.SubGroups.Add(groupTree); } } // Calculate Aggregates and Count for all Groups based on the last level Groups groupsRoot.AggregateSubGroupAggregators(); // Special handle for the Average Aggregates which require Group Count to be available groupsRoot.AggregateSubGroupAggregators(true); return(groupsRoot); }