Example #1
0
        /// <summary>
        /// Calculate the total of a specified data field for a row/columnn header for custom sorting.
        /// </summary>
        /// <param name="node">The current node that is being evaluated.</param>
        /// <param name="dataFieldIndex">The index of the referenced data field.</param>
        /// <returns>The calculated total.</returns>
        public double CalculateSortingValues(PivotItemTreeNode node, int dataFieldIndex)
        {
            double sortingTotal = 0;

            foreach (var record in node.CacheRecordIndices)
            {
                string dataFieldValue = this.Records[record].Items[dataFieldIndex].Value;
                sortingTotal += double.Parse(dataFieldValue);
            }
            return(sortingTotal);
        }
Example #2
0
        /// <summary>
        /// Adds a new child with the specified values to this node.
        /// </summary>
        /// <param name="value">The cache record item node "v" index of the new child.</param>
        /// <param name="pivotFieldIndex">The index of the pivot field referenced by the new child.</param>
        /// <param name="pivotFieldItemIndex">The index of the pivot field item referenced by the new child.</param>
        /// <param name="sharedItemValue">The shared item "v" value. (Only used for date groupings).</param>
        /// <param name="isTabularForm">A value indicating if this node's pivot field is set as tabular form.</param>
        public PivotItemTreeNode AddChild(int value, int pivotFieldIndex = -2, int pivotFieldItemIndex = -2, string sharedItemValue = null, bool isTabularForm = false)
        {
            var child = new PivotItemTreeNode(value)
            {
                PivotFieldIndex     = pivotFieldIndex,
                PivotFieldItemIndex = pivotFieldItemIndex,
                SharedItemValue     = sharedItemValue,
                IsTabularForm       = isTabularForm
            };

            this.Children.Add(child);
            return(child);
        }
Example #3
0
        /// <summary>
        /// Creates a deep copy of this node.
        /// </summary>
        /// <returns>The newly created node.</returns>
        public PivotItemTreeNode Clone()
        {
            var clone = new PivotItemTreeNode(this.Value);

            clone.DataFieldIndex      = this.DataFieldIndex;
            clone.PivotFieldIndex     = this.PivotFieldIndex;
            clone.PivotFieldItemIndex = this.PivotFieldItemIndex;
            clone.SubtotalTop         = this.SubtotalTop;
            clone.IsTabularForm       = this.IsTabularForm;
            clone.CacheRecordIndices  = this.CacheRecordIndices;

            foreach (var child in this.Children)
            {
                clone.Children.Add(child.Clone());
            }
            return(clone);
        }
Example #4
0
        private double?GetCalculatedFieldTotal(PivotItemTreeNode node, ExcelPivotTable pivotTable, CacheFieldNode cacheField)
        {
            var totalsFunction   = new TotalsFunctionHelper();
            var calculatedFields = pivotTable.CacheDefinition.CacheFields.Where(f => !string.IsNullOrEmpty(f.Formula));

            PivotTableDataManager.ConfigureCalculatedFields(calculatedFields, totalsFunction, pivotTable);
            var fieldNameToValues = new Dictionary <string, List <object> >();

            foreach (var cacheFieldName in cacheField.ReferencedCacheFieldsToIndex.Keys)
            {
                var values = pivotTable.CacheDefinition.CacheRecords.GetChildDataFieldValues(node.CacheRecordIndices, cacheField.ReferencedCacheFieldsToIndex[cacheFieldName]);
                fieldNameToValues.Add(cacheFieldName, values);
            }
            var total = totalsFunction.EvaluateCalculatedFieldFormula(fieldNameToValues, cacheField.ResolvedFormula);

            if (double.TryParse(total.ToString(), out var result))
            {
                return(result);
            }
            return(null);
        }
Example #5
0
        private void SortWithDataFields(ExcelPivotTable pivotTable, ExcelPivotTableField pivotField, PivotItemTreeNode root)
        {
            int autoScopeIndex          = int.Parse(pivotField.AutoSortScopeReferences[0].Value);
            var referenceDataFieldIndex = pivotTable.DataFields[autoScopeIndex].Index;
            var orderedList             = new List <Tuple <int, double?> >();

            // Get the total value for every child at the given data field index.
            foreach (var child in root.Children.ToList())
            {
                double?sortingTotal = 0;
                var    cacheField   = pivotTable.CacheDefinition.CacheFields[referenceDataFieldIndex];
                if (!string.IsNullOrEmpty(cacheField.Formula))
                {
                    sortingTotal = this.GetCalculatedFieldTotal(child, pivotTable, cacheField);
                }
                else
                {
                    sortingTotal = pivotTable.CacheDefinition.CacheRecords.CalculateSortingValues(child, referenceDataFieldIndex);
                }
                orderedList.Add(new Tuple <int, double?>(child.Value, sortingTotal));
            }

            bool sortDescending = pivotField.Sort == eSortType.Descending;

            // Sort the list of total values accordingly.
            orderedList = sortDescending ? orderedList.OrderByDescending(i => i.Item2).ToList() : orderedList.OrderBy(i => i.Item2).ToList();

            // If there are duplicated sortingTotal values, sort it based on the value of the first tuple.
            var duplicates = orderedList.GroupBy(x => x.Item2).Where(g => g.Count() > 1).Select(k => k.Key);

            if (duplicates.Count() > 0)
            {
                for (int i = 0; i < duplicates.ToList().Count(); i++)
                {
                    var duplicatedList = orderedList.FindAll(j => j.Item2 == duplicates.ElementAt(i));
                    int startingIndex  = orderedList.FindIndex(y => y == duplicatedList.ElementAt(0));
                    duplicatedList = sortDescending ? duplicatedList.OrderByDescending(w => w.Item1).ToList() : duplicatedList.OrderBy(w => w.Item1).ToList();
                    orderedList.RemoveRange(startingIndex, duplicatedList.Count());
                    orderedList.InsertRange(startingIndex, duplicatedList);
                }
            }

            // Add children back to the root node in sorted order.
            var newChildList = root.Children.ToList();

            root.Children.Clear();
            for (int i = 0; i < orderedList.Count(); i++)
            {
                int index = newChildList.FindIndex(x => x.Value == orderedList.ElementAt(i).Item1);
                root.Children.Add(newChildList[index]);
            }
        }