private void Apply(TFact item, DimensionEntry <TDimension> entry, IDimensionEntryResult result) { var match = false; if (Dimension.Filter == null || Dimension.Filter(item)) { if (Dimension.EndSelector == null) { match = entry.InRange(Dimension.Selector(item)); } else { match = entry.InRange(Dimension.Selector(item), Dimension.EndSelector(item)); } } if (match) { // Do something foreach (var kvp in result.Values) { kvp.Key.Apply(kvp.Value, result, item); } // All other foreach (var otherDim in result.OtherDimensions) { otherDim.Key.Apply(item, otherDim.Value); } foreach (DimensionEntry <TDimension> child in entry.Children) { Apply(item, child, result.Entries[child]); } } }
private static List <DimensionEntry <T> > BuildPartition <T>(DimensionEntry <T> parent, T stepSize, T lowerLimit, T upperLimit, Func <T, T, T> add, T minValue, T maxValue, string lowerLabelFormat, string defaultLabelFormat, string upperLabelFormat) where T : IComparable { if (upperLimit.CompareTo(lowerLimit) <= 0) { throw new ArgumentOutOfRangeException("upperLimit", "Upper limit must be greater then lower limit"); } if (stepSize.CompareTo(default(T)) <= 0) { throw new ArgumentOutOfRangeException("stepSize", "Stepsize must be > 0"); } var prev = minValue; for (var limit = lowerLimit; limit.CompareTo(upperLimit) <= 0; limit = add(limit, stepSize)) { var label = prev.CompareTo(minValue) == 0 ? string.Format(lowerLabelFormat, limit) : string.Format(defaultLabelFormat, prev, limit); parent.Children.Add(new DimensionEntry <T>(label, parent) { Min = prev, Max = limit }); prev = limit; } parent.Children.Add(new DimensionEntry <T>(string.Format(upperLabelFormat, prev), parent) { Min = prev, Max = maxValue }); return(parent.Children); }
/// <summary> /// Builds an int partition dimension. /// </summary> /// <param name="parent"></param> /// <param name="stepSize"></param> /// <param name="lowerLimit"></param> /// <param name="upperLimit"></param> /// <param name="lowerLabelFormat"></param> /// <param name="defaultLabelFormat"></param> /// <param name="upperLabelFormat"></param> /// <returns></returns> public static List <DimensionEntry <int> > BuildPartition( this DimensionEntry <int> parent, int stepSize, int lowerLimit, int upperLimit, string lowerLabelFormat = "{0} - {1}", string defaultLabelFormat = "{0} - {1}", string upperLabelFormat = "{0} - {1}") { if (parent == null) { throw new ArgumentNullException(nameof(parent)); } return(parent.BuildPartition( stepSize, lowerLimit, upperLimit, int.MinValue, int.MaxValue, lowerLabelFormat, defaultLabelFormat, upperLabelFormat, (rangeTo, stepSize) => rangeTo + stepSize)); }
/// <summary> /// Builds a simple string bases enumeration dimension /// </summary> /// <param name="parent"></param> /// <param name="entries"></param> /// <returns></returns> public static List <DimensionEntry <string> > BuildEnum(this DimensionEntry <string> parent, params string[] entries) { foreach (var e in entries) { parent.Children.Add(new DimensionEntry <string>(e, parent) { Value = e }); } return(parent.Children); }
/// <summary> /// Builds a bool dimension. /// </summary> /// <param name="parent"></param> /// <returns></returns> public static List <DimensionEntry <bool> > BuildBool(this DimensionEntry <bool> parent) { if (parent == null) { throw new ArgumentNullException(nameof(parent)); } return(parent .AddBoolChild(false) .AddBoolChild(true) .Children); }
internal static List <DimensionEntry <T> > BuildPartition <T>( this DimensionEntry <T> parent, T stepSize, T lowerLimit, T upperLimit, T minValue, T maxValue, string lowerLabelFormat, string defaultLabelFormat, string upperLabelFormat, Func <T, T, T> add) where T : IComparable { if (upperLimit.CompareTo(lowerLimit) <= 0) { throw new ArgumentOutOfRangeException(nameof(upperLimit), $"{nameof(upperLimit)} must be greater than {nameof(lowerLimit)}."); } if (stepSize.CompareTo(default(T)) <= 0) { throw new ArgumentOutOfRangeException(nameof(stepSize), $"{nameof(stepSize)} must be greater than default."); } var rangeFrom = minValue; var rangeTo = lowerLimit; while (rangeTo.CompareTo(upperLimit) <= 0) { if (rangeTo.CompareTo(lowerLimit) == 0) { parent.AddChildHelper(minValue, rangeTo, lowerLabelFormat); } else { parent.AddChildHelper(rangeFrom, rangeTo, defaultLabelFormat); } rangeFrom = rangeTo; rangeTo = add(rangeTo, stepSize); if (rangeTo.CompareTo(upperLimit) > 0) { parent.AddChildHelper(rangeFrom, maxValue, upperLabelFormat); } } return(parent.Children); }
/// <summary> /// Builds a dimension representing Years /// </summary> /// <param name="parent"></param> /// <param name="fromYear"></param> /// <param name="thruYear"></param> /// <returns></returns> public static List <DimensionEntry <DateTime> > BuildYear(this DimensionEntry <DateTime> parent, int fromYear, int thruYear) { for (int year = fromYear; year <= thruYear; year++) { var dtFrom = new DateTime(year, 1, 1); var dtUntil = new DateTime(year + 1, 1, 1); parent.Children.Add(new DimensionEntry <DateTime>(year.ToString(), parent) { Min = dtFrom, Max = dtUntil }); } return(parent.Children); }
/// <summary> /// Builds a dimension representing Years in the given range. This method limits the years individual ends, e.g. 1.1. - 1.3. /// This makes part of years comparable. /// </summary> /// <param name="parent"></param> /// <param name="fromYear"></param> /// <param name="thruYear"></param> /// <param name="sliceFromMonth"></param> /// <param name="sliceFromDay"></param> /// <param name="sliceThruMonth"></param> /// <param name="sliceThruDay"></param> /// <returns></returns> public static List <DimensionEntry <DateTime> > BuildYearSlice(this DimensionEntry <DateTime> parent, int fromYear, int thruYear, int sliceFromMonth = 1, int?sliceFromDay = null, int sliceThruMonth = 1, int?sliceThruDay = null) { if (parent == null) { throw new ArgumentNullException(nameof(parent)); } for (int year = fromYear; year <= thruYear; year++) { parent.AddChild(year.ToStringInvariant(), new DateTime(year, sliceFromMonth, sliceFromDay ?? 1), new DateTime(year, sliceThruMonth, sliceThruDay ?? DateTime.DaysInMonth(year, sliceThruMonth))); } return(parent.Children); }
/// <summary> /// Builds a dimension representing Years /// </summary> /// <param name="parent"></param> /// <param name="fromYear"></param> /// <param name="thruYear"></param> /// <returns></returns> public static List <DimensionEntry <DateTime> > BuildYear(this DimensionEntry <DateTime> parent, int fromYear, int thruYear) { if (parent == null) { throw new ArgumentNullException(nameof(parent)); } for (int year = fromYear; year <= thruYear; year++) { parent.AddChild(year.ToStringInvariant(), new DateTime(year, 1, 1), new DateTime(year, 12, 31)); } return(parent.Children); }
/// <summary> /// Builds a dimension representing all Years in the the given range /// </summary> /// <param name="parent"></param> /// <param name="from"></param> /// <param name="thruDay"></param> /// <returns></returns> public static List <DimensionEntry <DateTime> > BuildYearRange(this DimensionEntry <DateTime> parent, DateTime from, DateTime thruDay) { if (from != from.Date) { throw new ArgumentOutOfRangeException("from", "contains time component"); } if (thruDay != thruDay.Date) { throw new ArgumentOutOfRangeException("thruDay", "contains time component"); } var children = BuildYear(parent, from.Year, thruDay.Year); children.First().Min = from; children.Last().Max = thruDay.AddDays(1); return(parent.Children); }
/// <summary> /// Builds a bool dimension. /// </summary> /// <param name="parent"></param> /// <returns></returns> public static List <DimensionEntry <bool> > BuildBool(this DimensionEntry <bool> parent) { parent.Children.Add(new DimensionEntry <bool>(false.ToString(), parent) { Value = false, Min = false, Max = false }); parent.Children.Add(new DimensionEntry <bool>(true.ToString(), parent) { Value = true, Min = true, Max = true }); return(parent.Children); }
/// <summary> /// Builds a enumeration dimension from the given Enum Type. /// </summary> /// <typeparam name="TEnum"></typeparam> /// <param name="parent"></param> /// <returns></returns> public static List <DimensionEntry <TEnum> > BuildEnum <TEnum>(this DimensionEntry <TEnum> parent) where TEnum : struct, IComparable { var enumType = typeof(TEnum); // TODO: Re-Support this // if (!enumType.IsEnum) throw new ArgumentOutOfRangeException("TEnum", "is no enumeration"); foreach (var e in Enum.GetValues(enumType)) { TEnum value = (TEnum)e; parent.Children.Add(new DimensionEntry <TEnum>(e.ToString(), parent) { Value = value }); } return(parent.Children); }
/// <summary> /// Builds a enumeration dimension from the given Enum Type. /// </summary> /// <typeparam name="TEnum"></typeparam> /// <param name="parent"></param> /// <remarks>As enum is non-nullable type then min and max are set to the same as value</remarks> /// <returns></returns> public static List <DimensionEntry <TEnum> > BuildEnum <TEnum>(this DimensionEntry <TEnum> parent) where TEnum : struct, IComparable, IConvertible, IFormattable { if (parent == null) { throw new ArgumentNullException(nameof(parent)); } if (!typeof(TEnum).IsEnum) { throw new InvalidOperationException("TEnum is not an enumeration."); } foreach (var value in Enum.GetValues(typeof(TEnum)).Cast <TEnum>()) { parent.AddChild(value.ToStringInvariant(), value); } return(parent.Children); }
/// <summary> /// Builds a simple string bases enumeration dimension /// </summary> /// <param name="parent"></param> /// <param name="entries"></param> /// <returns></returns> public static List <DimensionEntry <string> > BuildEnum(this DimensionEntry <string> parent, params string[] entries) { if (parent == null) { throw new ArgumentNullException(nameof(parent)); } if (entries == null) { throw new ArgumentNullException(nameof(entries)); } foreach (var entry in entries) { if (parent.Children.Any(x => x.Value == entry)) { throw new ArgumentException("Entries should be unique.", nameof(entries)); } parent.AddChild(entry, entry); } return(parent.Children); }
/// <summary> /// Builds a dimension representing Years in the given range. This method limits the years individual ends, e.g. 1.1. - 1.3. /// This makes part of years comparable. /// </summary> /// <param name="parent"></param> /// <param name="fromYear"></param> /// <param name="thruYear"></param> /// <param name="sliceFromMonth"></param> /// <param name="sliceFromDay"></param> /// <param name="sliceThruMonth"></param> /// <param name="sliceThruDay"></param> /// <returns></returns> public static List <DimensionEntry <DateTime> > BuildYearSlice(this DimensionEntry <DateTime> parent, int fromYear, int thruYear, int sliceFromMonth, int?sliceFromDay, int sliceThruMonth, int?sliceThruDay) { for (int year = fromYear; year <= thruYear; year++) { var dtFrom = new DateTime(year, sliceFromMonth, sliceFromDay ?? 1); var dtUntil = new DateTime(year, sliceThruMonth, 1); if (sliceThruDay.HasValue) { dtUntil = dtUntil.AddDays(sliceThruDay.Value - 1 + 1); // offset for starting on the first and adding one day for "thru" -> "max" transformation } else { dtUntil = dtUntil.AddMonths(1); } parent.Children.Add(new DimensionEntry <DateTime>(year.ToString(), parent) { Min = dtFrom, Max = dtUntil }); } return(parent.Children); }
private static void AddChildHelper <T>(this DimensionEntry <T> parent, T from, T to, string labelFormat) where T : IComparable => parent.AddChild(labelFormat.FormatInvariant(from, to), from, to);
/// <summary> /// Flattens a Dimensions hierarchie /// </summary> /// <typeparam name="T"></typeparam> /// <param name="dim"></param> /// <returns></returns> public static IEnumerable <DimensionEntry <TDimension> > FlattenHierarchy <TDimension>(this DimensionEntry <TDimension> dim) where TDimension : IComparable { var result = new List <DimensionEntry <TDimension> >(); foreach (DimensionEntry <TDimension> c in dim) { result.Add(c); result.AddRange(FlattenHierarchy(c)); } return(result); }
/// <summary> /// Builds a partition dimension /// </summary> /// <param name="parent"></param> /// <param name="stepSize"></param> /// <param name="lowerLimit"></param> /// <param name="upperLimit"></param> /// <param name="lowerLabelFormat"></param> /// <param name="defaultLabelFormat"></param> /// <param name="upperLabelFormat"></param> /// <returns></returns> public static List <DimensionEntry <int> > BuildPartition(this DimensionEntry <int> parent, int stepSize, int lowerLimit, int upperLimit, string lowerLabelFormat, string defaultLabelFormat, string upperLabelFormat) { return(BuildPartition(parent, stepSize, lowerLimit, upperLimit, (a, b) => a + b, int.MinValue, int.MaxValue, lowerLabelFormat, defaultLabelFormat, upperLabelFormat)); }
private static DimensionEntry <bool> AddBoolChild(this DimensionEntry <bool> parent, bool value) => parent.AddChild(value.ToStringInvariant(), value);
/// <summary> /// Builds a partition dimension. /// </summary> /// <param name="parent"></param> /// <param name="stepSize"></param> /// <param name="lowerLimit"></param> /// <param name="upperLimit"></param> /// <returns></returns> public static List <DimensionEntry <decimal> > BuildPartition(this DimensionEntry <decimal> parent, decimal stepSize, decimal lowerLimit, decimal upperLimit) { return(BuildPartition(parent, stepSize, lowerLimit, upperLimit, (a, b) => a + b, decimal.MinValue, decimal.MaxValue, "- {0}", "{0} - {1}", "{0} -")); }
/// <summary> /// Creats a new dimension entry /// </summary> /// <param name="label"></param> /// <param name="parent"></param> public DimensionEntry(string label, DimensionEntry <TDimension> parent) { this._parent = parent; this.Label = label; Children = new List <DimensionEntry <TDimension> >(); }
/// <summary> /// Flattens a Dimensions hierarchie /// </summary> /// <typeparam name="T"></typeparam> /// <param name="dim"></param> /// <returns></returns> public static IEnumerable <DimensionEntry <TDimension> > FlattenHierarchy <TDimension>(this DimensionEntry <TDimension> dim) where TDimension : IComparable { if (dim == null) { throw new ArgumentNullException(nameof(dim)); } var result = new List <DimensionEntry <TDimension> >(); foreach (DimensionEntry <TDimension> c in dim) { result.Add(c); result.AddRange(c.FlattenHierarchy()); } return(result); }
/// <summary> /// Builds a partition dimension /// </summary> /// <param name="parent"></param> /// <param name="stepSize"></param> /// <param name="lowerLimit"></param> /// <param name="upperLimit"></param> /// <returns></returns> public static List <DimensionEntry <int> > BuildPartition(this DimensionEntry <int> parent, int stepSize, int lowerLimit, int upperLimit) { return(BuildPartition(parent, stepSize, lowerLimit, upperLimit, (a, b) => a + b, int.MinValue, int.MaxValue, "- {0}", "{0} - {1}", "{0} -")); }