GroupByVertexAttributeDateAndTime ( Microsoft.Office.Interop.Excel.Workbook workbook, String attributeColumnName, IEnumerable <DateTime> minimumValues ) { Debug.Assert(workbook != null); Debug.Assert(!String.IsNullOrEmpty(attributeColumnName)); Debug.Assert(minimumValues != null); TypeAdjuster <DateTime> oTypeAdjuster = (DateTime dateTime) => { // Set the seconds to 0. The DateTimePicker control doesn't show // seconds by default, but its value includes the seconds and that // can lead to confusing comparison results. return(new DateTime( dateTime.Year, dateTime.Month, dateTime.Day, dateTime.Hour, dateTime.Minute, 0, dateTime.Kind )); }; GroupByVertexAttributeGeneric <DateTime>(workbook, attributeColumnName, minimumValues, DateTime.MinValue, DateTime.TryParse, oTypeAdjuster); }
GroupByVertexAttributeTime ( Microsoft.Office.Interop.Excel.Workbook workbook, String attributeColumnName, IEnumerable <DateTime> minimumValues ) { Debug.Assert(workbook != null); Debug.Assert(!String.IsNullOrEmpty(attributeColumnName)); Debug.Assert(minimumValues != null); StringToTypeConverter <DateTime> oStringToTypeConverter = (String stringValue, out DateTime dateTime) => { // When an Excel cell is formatted as Time, the string read from // the cell is a Decimal. Sample: 39448.625. dateTime = DateTime.MinValue; Decimal decDateTime; if (!Decimal.TryParse(stringValue, out decDateTime)) { return(false); } dateTime = ExcelDateTimeUtil.ExcelDecimalToDateTime(decDateTime); return(true); }; TypeAdjuster <DateTime> oTypeAdjuster = (DateTime dateTime) => { // Set the date component to some arbitrary, constant value and set // the seconds to 0. The DateTimePicker control doesn't show // seconds by default, but its value includes the seconds and that // can lead to confusing comparison results. return(new DateTime( 2000, 1, 1, dateTime.Hour, dateTime.Minute, 0, dateTime.Kind )); }; GroupByVertexAttributeGeneric <DateTime>(workbook, attributeColumnName, minimumValues, DateTime.MinValue, oStringToTypeConverter, oTypeAdjuster); }
GroupByVertexAttributeGeneric <T> ( Microsoft.Office.Interop.Excel.Workbook oWorkbook, String sAttributeColumnName, IEnumerable <T> oMinimumValues, T oMinimumValueForType, StringToTypeConverter <T> oStringToTypeConverter, TypeAdjuster <T> oTypeAdjuster ) where T : IComparable <T> { Debug.Assert(oWorkbook != null); Debug.Assert(!String.IsNullOrEmpty(sAttributeColumnName)); Debug.Assert(oMinimumValues != null); IGraph oGraph = ReadWorkbook(oWorkbook); List <T> oMinimumValueList = new List <T>(oMinimumValues); // Add a group that will hold vertices whose values are less than the // first minimum value in oMinimumValueList. That way, every vertex // will end up in a group. oMinimumValueList.Insert(0, oMinimumValueForType); // For each group whose minimum value is stored in oMinimumValueList, // there is one LinkedList of vertices in oGroupList. Int32 iGroups = oMinimumValueList.Count; LinkedList <IVertex> [] oGroupList = new LinkedList <IVertex> [iGroups]; for (Int32 i = 0; i < iGroups; i++) { oMinimumValueList[i] = oTypeAdjuster(oMinimumValueList[i]); oGroupList[i] = new LinkedList <IVertex>(); } foreach (IVertex oVertex in oGraph.Vertices) { Object oAttributeValue; T tAttributeValue; if ( !oVertex.TryGetValue(sAttributeColumnName, typeof(String), out oAttributeValue) || !oStringToTypeConverter((String)oAttributeValue, out tAttributeValue) ) { continue; } tAttributeValue = oTypeAdjuster(tAttributeValue); // (This search technique is simple but slow. It should be // replaced with a binary search.) for (Int32 i = iGroups - 1; i >= 0; i--) { if (tAttributeValue.CompareTo(oMinimumValueList[i]) >= 0) { oGroupList[i].AddLast(oVertex); break; } } } // Convert the list of groups to an array of GraphMetricColumn objects, // then write the array to the workbook. GraphMetricColumn [] aoGraphMetricColumns = GroupsToGraphMetricColumnsConverter.Convert <LinkedList <IVertex> > (oGroupList, (oGroup) => oGroup); WriteGraphMetricsToWorkbook(oWorkbook, aoGraphMetricColumns); }