ReadWorksheet ( Microsoft.Office.Interop.Excel.Workbook workbook, ReadWorkbookContext readWorkbookContext, IGraph graph ) { Debug.Assert(workbook != null); Debug.Assert(readWorkbookContext != null); Debug.Assert(graph != null); AssertValid(); // Get the required table that contains edge data, then add the edges // and vertices in the table to the graph. ListObject oEdgeTable = GetEdgeTable(workbook); // The code that reads the table can handle hidden rows, but not hidden // columns. Temporarily show all hidden columns in the table. ExcelHiddenColumns oHiddenColumns = ExcelColumnHider.ShowHiddenColumns(oEdgeTable); try { ReadEdgeTable(oEdgeTable, readWorkbookContext, graph); } finally { ExcelColumnHider.RestoreHiddenColumns(oEdgeTable, oHiddenColumns); } }
RemoveVertex ( IVertex oVertex, ReadWorkbookContext oReadWorkbookContext, IGraph oGraph ) { Debug.Assert(oVertex != null); Debug.Assert(oReadWorkbookContext != null); Debug.Assert(oGraph != null); AssertValid(); Dictionary <Int32, IIdentityProvider> oEdgeRowIDDictionary = oReadWorkbookContext.EdgeRowIDDictionary; foreach (IEdge oIncidentEdge in oVertex.IncidentEdges) { if (oIncidentEdge.Tag is Int32) { oEdgeRowIDDictionary.Remove((Int32)oIncidentEdge.Tag); } } oReadWorkbookContext.VertexNameDictionary.Remove(oVertex.Name); if (oVertex.Tag is Int32) { oReadWorkbookContext.VertexRowIDDictionary.Remove( (Int32)oVertex.Tag); } oGraph.Vertices.Remove(oVertex); }
AddCollapsedGroupAttributes ( Microsoft.Office.Interop.Excel.Workbook workbook, ReadWorkbookContext readWorkbookContext, IGraph graph ) { Debug.Assert(workbook != null); Debug.Assert(readWorkbookContext != null); Debug.Assert(graph != null); GroupInfo[] aoGroups; ListObject oEdgeTable, oVertexTable; if ( GroupUtil.TryGetGroups(graph, out aoGroups) && ExcelTableUtil.TryGetTable(workbook, WorksheetNames.Edges, TableNames.Edges, out oEdgeTable) && ExcelTableUtil.TryGetTable(workbook, WorksheetNames.Vertices, TableNames.Vertices, out oVertexTable) ) { AddCollapsedGroupAttributesInternal(workbook, readWorkbookContext, oEdgeTable, oVertexTable, aoGroups); } }
ReadWorkbook ( Microsoft.Office.Interop.Excel.Workbook oWorkbook ) { Debug.Assert(oWorkbook != null); WorkbookReader oWorkbookReader = new WorkbookReader(); ReadWorkbookContext oReadWorkbookContext = new ReadWorkbookContext(); // Read all columns in the vertex worksheet and store the cell values // as metadata on the graph's vertices. oReadWorkbookContext.ReadAllEdgeAndVertexColumns = true; // GroupsToGraphMetricColumnsConverter.Convert() copies the ID column // on the vertex worksheet to the group-vertex worksheet, so make sure // that the vertex ID column is filled in. oReadWorkbookContext.FillIDColumns = true; return(oWorkbookReader.ReadWorkbook(oWorkbook, oReadWorkbookContext)); }
RemoveUnwantedIsolates ( ReadWorkbookContext oReadWorkbookContext, IGraph oGraph ) { Debug.Assert(oReadWorkbookContext != null); Debug.Assert(oGraph != null); AssertValid(); List <IVertex> oIsolatedVertices = new List <IVertex>( from oVertex in oGraph.Vertices where oVertex.Degree == 0 select oVertex ); foreach (IVertex oIsolatedVertex in oIsolatedVertices) { // Don't remove the isolated vertex if it is supposed to be shown // regardless of whether it is part of an edge. if (!oIsolatedVertex.ContainsKey( ReservedMetadataKeys.VertexHasVisibilityOfShow)) { RemoveVertex(oIsolatedVertex, oReadWorkbookContext, oGraph); } } }
ReadWorkbook ( Microsoft.Office.Interop.Excel.Workbook oWorkbook, IGraphMetricCalculator2 [] oGraphMetricCalculators ) { Debug.Assert(oWorkbook != null); Debug.Assert(oGraphMetricCalculators != null); AssertValid(); ReadWorkbookContext oReadWorkbookContext = new ReadWorkbookContext(); oReadWorkbookContext.FillIDColumns = true; oReadWorkbookContext.PopulateVertexWorksheet = true; oReadWorkbookContext.ReadGroups = true; // Some of the graph metric calculators, such as // TopItemsCalculatorBase2, need to rank vertices or edges by values in // a specified column. Make those values available on the graph. oReadWorkbookContext.ReadAllEdgeAndVertexColumns = true; WorkbookReader oWorkbookReader = new WorkbookReader(); return(oWorkbookReader.ReadWorkbook( oWorkbook, oReadWorkbookContext)); }
AddCollapsedGroupAttributes ( Microsoft.Office.Interop.Excel.Workbook workbook, ReadWorkbookContext readWorkbookContext, IGraph graph ) { Debug.Assert(workbook != null); Debug.Assert(readWorkbookContext != null); Debug.Assert(graph != null); GroupInfo[] aoGroups; ListObject oEdgeTable,oVertexTable; if ( GroupUtil.TryGetGroups(graph, out aoGroups) && ExcelTableUtil.TryGetTable(workbook, WorksheetNames.Edges, TableNames.Edges, out oEdgeTable) && ExcelTableUtil.TryGetTable(workbook, WorksheetNames.Vertices, TableNames.Vertices, out oVertexTable) ) { AddCollapsedGroupAttributesInternal(workbook, readWorkbookContext, oEdgeTable, oVertexTable, aoGroups); } }
AddEdgeColorAttributesToDConnectorMotif ( ExcelTemplateGroupInfo oGroup, Boolean bEdgeColorColumnAutoFilled, AutoFillColorColumnResults oEdgeColorResults, ColorColumnAutoFillUserSettings oEdgeColorDetails, Dictionary <Int32, Object> oEdgeColorSourceDictionary, ReadWorkbookContext oReadWorkbookContext, CollapsedGroupAttributes oCollapsedGroupAttributes, Int32 iAnchorVertices ) { Debug.Assert(oGroup != null); Debug.Assert(oEdgeColorResults != null); Debug.Assert(oReadWorkbookContext != null); Debug.Assert(oCollapsedGroupAttributes != null); Debug.Assert(iAnchorVertices >= 0); // If the edge color column was autofilled, get the average color for // the edges incident to the D-connector motif's first anchor, then its // second anchor, and so on. Otherwise, don't do anything. if (!bEdgeColorColumnAutoFilled) { return; } for (Int32 iAnchorVertexIndex = 0; iAnchorVertexIndex < iAnchorVertices; iAnchorVertexIndex++) { Color oAverageColor; if (TableColumnMapper.TryMapAverageColor( GetRowIDsToAverageForEdges(oGroup, oCollapsedGroupAttributes, iAnchorVertexIndex), oEdgeColorSourceDictionary, oEdgeColorResults.SourceCalculationNumber1, oEdgeColorResults.SourceCalculationNumber2, oEdgeColorResults.DestinationColor1, oEdgeColorResults.DestinationColor2, oEdgeColorDetails.UseLogs, out oAverageColor) ) { oCollapsedGroupAttributes.Add( CollapsedGroupAttributeKeys.GetAnchorVertexEdgeColorKey( iAnchorVertexIndex), oReadWorkbookContext.ColorConverter2.GraphToWorkbook( oAverageColor) ); } } }
AddEdgeWidthAttributesToDConnectorMotif ( ExcelTemplateGroupInfo oGroup, Boolean bEdgeWidthColumnAutoFilled, AutoFillNumericRangeColumnResults oEdgeWidthResults, NumericRangeColumnAutoFillUserSettings oEdgeWidthDetails, Dictionary <Int32, Object> oEdgeWidthSourceDictionary, ReadWorkbookContext oReadWorkbookContext, CollapsedGroupAttributes oCollapsedGroupAttributes, Int32 iAnchorVertices ) { Debug.Assert(oGroup != null); Debug.Assert(oEdgeWidthResults != null); Debug.Assert(oReadWorkbookContext != null); Debug.Assert(oCollapsedGroupAttributes != null); Debug.Assert(iAnchorVertices >= 0); // If the edge width column was autofilled, get the average width for // the edges incident to the two-connector motif's first anchor, then // its second anchor. Otherwise, don't do anything. if (!bEdgeWidthColumnAutoFilled) { return; } for (Int32 iAnchorVertexIndex = 0; iAnchorVertexIndex < iAnchorVertices; iAnchorVertexIndex++) { Double dAverageEdgeWidth; if (TableColumnMapper.TryMapAverageNumber( GetRowIDsToAverageForEdges(oGroup, oCollapsedGroupAttributes, iAnchorVertexIndex), oEdgeWidthSourceDictionary, oEdgeWidthResults.SourceCalculationNumber1, oEdgeWidthResults.SourceCalculationNumber2, oEdgeWidthResults.DestinationNumber1, oEdgeWidthResults.DestinationNumber2, oEdgeWidthDetails.UseLogs, out dAverageEdgeWidth ) ) { oCollapsedGroupAttributes.Add( CollapsedGroupAttributeKeys.GetAnchorVertexEdgeWidthKey( iAnchorVertexIndex), dAverageEdgeWidth ); } } }
ReadWorkbook ( Microsoft.Office.Interop.Excel.Workbook workbook, ReadWorkbookContext readWorkbookContext ) { Debug.Assert(readWorkbookContext != null); Debug.Assert(workbook != null); AssertValid(); IGraph oGraph = null; // Turn off screen updating, for two reasons: // // 1. Reading the workbook can involve writing to edge and vertex ID // columns, which can be slow when updating is turned on. // // 2. Any hidden columns get temporarily shown as each worksheet is // read. Application oApplication = workbook.Application; Boolean bOldScreenUpdating = oApplication.ScreenUpdating; oApplication.ScreenUpdating = false; try { oGraph = ReadWorkbookInternal(workbook, readWorkbookContext); } catch (WorkbookFormatException oWorkbookFormatException) { Range oRangeToSelect = oWorkbookFormatException.RangeToSelect; if (oRangeToSelect != null) { // The user may have hidden the column group containing the // error. Make sure the column is visible. oRangeToSelect.EntireColumn.Hidden = false; } throw oWorkbookFormatException; } finally { oApplication.ScreenUpdating = bOldScreenUpdating; } return(oGraph); }
AddVertexColorAttributeToMotif ( ExcelTemplateGroupInfo oGroup, String sType, Boolean bVertexColorColumnAutoFilled, AutoFillColorColumnResults oVertexColorResults, ColorColumnAutoFillUserSettings oVertexColorDetails, Dictionary <Int32, Object> oVertexColorSourceDictionary, ReadWorkbookContext oReadWorkbookContext, CollapsedGroupAttributes oCollapsedGroupAttributes ) { Debug.Assert(oGroup != null); Debug.Assert(!String.IsNullOrEmpty(sType)); Debug.Assert(oVertexColorResults != null); Debug.Assert(oReadWorkbookContext != null); Debug.Assert(oCollapsedGroupAttributes != null); Color oColor; // If the vertex color column was autofilled, get the average color // for the vertices in the motif. if ( !bVertexColorColumnAutoFilled || !TableColumnMapper.TryMapAverageColor( GetRowIDsToAverageForVertexColor(oGroup, oCollapsedGroupAttributes, sType), oVertexColorSourceDictionary, oVertexColorResults.SourceCalculationNumber1, oVertexColorResults.SourceCalculationNumber2, oVertexColorResults.DestinationColor1, oVertexColorResults.DestinationColor2, oVertexColorDetails.UseLogs, out oColor) ) { // Default to the color that was assigned to the group. oColor = oGroup.VertexColor; } oCollapsedGroupAttributes.Add( CollapsedGroupAttributeKeys.VertexColor, oReadWorkbookContext.ColorConverter2.GraphToWorkbook(oColor) ); }
ReadWorksheet ( Microsoft.Office.Interop.Excel.Workbook workbook, ReadWorkbookContext readWorkbookContext, IGraph graph ) { Debug.Assert(workbook != null); Debug.Assert(readWorkbookContext != null); Debug.Assert(graph != null); AssertValid(); // Attempt to get the optional tables that contain group data. ListObject oGroupTable, oGroupVertexTable; if ( ExcelTableUtil.TryGetTable(workbook, WorksheetNames.Groups, TableNames.Groups, out oGroupTable) && ExcelTableUtil.TryGetTable(workbook, WorksheetNames.GroupVertices, TableNames.GroupVertices, out oGroupVertexTable) ) { // The code that reads the tables can handle hidden rows, but not // hidden columns. Temporarily show all hidden columns in the // table. ExcelHiddenColumns oHiddenGroupColumns = ExcelColumnHider.ShowHiddenColumns(oGroupTable); ExcelHiddenColumns oHiddenGroupVertexColumns = ExcelColumnHider.ShowHiddenColumns(oGroupVertexTable); try { ReadGroupTables(oGroupTable, oGroupVertexTable, readWorkbookContext, graph); } finally { ExcelColumnHider.RestoreHiddenColumns(oGroupTable, oHiddenGroupColumns); ExcelColumnHider.RestoreHiddenColumns(oGroupVertexTable, oHiddenGroupVertexColumns); } } }
ReadWorkbook ( Microsoft.Office.Interop.Excel.Workbook workbook, ReadWorkbookContext readWorkbookContext ) { Debug.Assert(readWorkbookContext != null); Debug.Assert(workbook != null); AssertValid(); IGraph oGraph = null; // Turn off screen updating, for two reasons: // // 1. Reading the workbook can involve writing to edge and vertex ID // columns, which can be slow when updating is turned on. // // 2. Any hidden columns get temporarily shown as each worksheet is // read. Application oApplication = workbook.Application; Boolean bOldScreenUpdating = oApplication.ScreenUpdating; oApplication.ScreenUpdating = false; try { oGraph = ReadWorkbookInternal(workbook, readWorkbookContext); } catch (WorkbookFormatException oWorkbookFormatException) { Range oRangeToSelect = oWorkbookFormatException.RangeToSelect; if (oRangeToSelect != null) { // The user may have hidden the column group containing the // error. Make sure the column is visible. oRangeToSelect.EntireColumn.Hidden = false; } throw oWorkbookFormatException; } finally { oApplication.ScreenUpdating = bOldScreenUpdating; } return (oGraph); }
ReadWorkbook ( Microsoft.Office.Interop.Excel.Workbook oWorkbook ) { Debug.Assert(oWorkbook != null); AssertValid(); ReadWorkbookContext oReadWorkbookContext = new ReadWorkbookContext(); WorkbookReader oWorkbookReader = new WorkbookReader(); // Convert the workbook contents to a Graph object. return(oWorkbookReader.ReadWorkbook( oWorkbook, oReadWorkbookContext)); }
GetReadColorAndShapeFlags ( IVertex oVertex, GroupInfo oGroup, ReadWorkbookContext oReadWorkbookContext, out Boolean bReadColorFromGroup, out Boolean bReadShapeFromGroup ) { Debug.Assert(oVertex != null); Debug.Assert(oReadWorkbookContext != null); AssertValid(); // Assume that the settings specified in the context object will be // used. bReadColorFromGroup = oReadWorkbookContext.ReadVertexColorFromGroups; bReadShapeFromGroup = oReadWorkbookContext.ReadVertexShapeFromGroups; if (oGroup.CollapsedAttributes != null) { CollapsedGroupAttributes oCollapsedGroupAttributes = CollapsedGroupAttributes.FromString( oGroup.CollapsedAttributes); String sHeadVertexName; if ( oCollapsedGroupAttributes.GetGroupType() == CollapsedGroupAttributeValues.FanMotifType && oCollapsedGroupAttributes.TryGetValue( CollapsedGroupAttributeKeys.HeadVertexName, out sHeadVertexName) && oVertex.Name == sHeadVertexName ) { // The shape of a fan motif's head vertex should never be // changed. Do not get it from the group. bReadShapeFromGroup = false; } } }
SkipAndHideGroups ( ReadWorkbookContext oReadWorkbookContext, Dictionary <String, ExcelTemplateGroupInfo> oGroupNameDictionary, HashSet <String> oSkippedGroupNames, HashSet <String> oHiddenGroupNames, IGraph oGraph ) { Debug.Assert(oReadWorkbookContext != null); Debug.Assert(oGroupNameDictionary != null); Debug.Assert(oSkippedGroupNames != null); Debug.Assert(oHiddenGroupNames != null); Debug.Assert(oGraph != null); AssertValid(); foreach (String sGroupName in oSkippedGroupNames) { // Remove the group's vertices and their incident edges from the // graph and dictionaries. foreach (IVertex oVertex in oGroupNameDictionary[sGroupName].Vertices) { RemoveVertex(oVertex, oReadWorkbookContext, oGraph); } oGroupNameDictionary.Remove(sGroupName); } foreach (String sGroupName in oHiddenGroupNames) { foreach (IVertex oVertex in oGroupNameDictionary[sGroupName].Vertices) { // Hide the group's vertices and their incident edges. HideVertex(oVertex); } } }
GetGraphML ( Microsoft.Office.Interop.Excel.Workbook oWorkbook ) { Debug.Assert(oWorkbook != null); String sGraphML = null; // The graph owned by the NodeXLControl can't be used, because it // doesn't include all the edge and vertex column data needed for // GraphML. Instead, read the graph from the workbook and include all // the necessary data. ReadWorkbookContext oReadWorkbookContext = new ReadWorkbookContext(); oReadWorkbookContext.ReadAllEdgeAndVertexColumns = true; WorkbookReader oWorkbookReader = new WorkbookReader(); IGraph oGraphForGraphML = oWorkbookReader.ReadWorkbook( oWorkbook, oReadWorkbookContext); GraphMLGraphAdapter oGraphMLGraphAdapter = new GraphMLGraphAdapter(); using (MemoryStream oMemoryStream = new MemoryStream()) { oGraphMLGraphAdapter.SaveGraph(oGraphForGraphML, oMemoryStream); oMemoryStream.Position = 0; using (StreamReader oStreamReader = new StreamReader(oMemoryStream)) { sGraphML = oStreamReader.ReadToEnd(); } } return(sGraphML); }
ReadGroupTables ( ListObject oGroupTable, ListObject oGroupVertexTable, ReadWorkbookContext oReadWorkbookContext, IGraph oGraph ) { Debug.Assert(oGroupTable != null); Debug.Assert(oGroupVertexTable != null); Debug.Assert(oReadWorkbookContext != null); Debug.Assert(oGraph != null); AssertValid(); // If a required column is missing, do nothing. ListColumn oColumn; if ( !ExcelTableUtil.TryGetTableColumn(oGroupTable, GroupTableColumnNames.Name, out oColumn) || !ExcelTableUtil.TryGetTableColumn(oGroupTable, GroupTableColumnNames.VertexColor, out oColumn) || !ExcelTableUtil.TryGetTableColumn(oGroupTable, GroupTableColumnNames.VertexShape, out oColumn) || !ExcelTableUtil.TryGetTableColumn(oGroupVertexTable, GroupVertexTableColumnNames.GroupName, out oColumn) || !ExcelTableUtil.TryGetTableColumn(oGroupVertexTable, GroupVertexTableColumnNames.VertexName, out oColumn) ) { return; } // These are the names of the groups that should be skipped or hidden. HashSet<String> oSkippedGroupNames = new HashSet<String>(); HashSet<String> oHiddenGroupNames = new HashSet<String>(); // Create a dictionary from the group table. The key is the group name // and the value is an ExcelTemplateGroupInfo object for the group. Dictionary<String, ExcelTemplateGroupInfo> oGroupNameDictionary = ReadGroupTable(oGroupTable, oReadWorkbookContext, oSkippedGroupNames, oHiddenGroupNames); // Read the group vertex table and set the color and shape of each // group vertex in the graph. ReadGroupVertexTable(oGroupVertexTable, oReadWorkbookContext, oGroupNameDictionary, oGraph); // Now that the groups and the vertices they contain are known, skip // and hide those groups that should be skipped or hidden. SkipAndHideGroups(oReadWorkbookContext, oGroupNameDictionary, oSkippedGroupNames, oHiddenGroupNames, oGraph); if (oGroupNameDictionary.Count > 0) { // Save the group information on the graph. Debug.Assert( oGroupNameDictionary.Values is ICollection<ExcelTemplateGroupInfo> ); oGraph.SetValue(ReservedMetadataKeys.GroupInfo, oGroupNameDictionary.Values.ToArray() ); } }
ReadEdgeTable ( ListObject oEdgeTable, ReadWorkbookContext oReadWorkbookContext, IGraph oGraph ) { Debug.Assert(oEdgeTable != null); Debug.Assert(oReadWorkbookContext != null); Debug.Assert(oGraph != null); AssertValid(); Boolean bReadAllEdgeAndVertexColumns = oReadWorkbookContext.ReadAllEdgeAndVertexColumns; if (oReadWorkbookContext.FillIDColumns) { FillIDColumn(oEdgeTable); } Dictionary <String, IVertex> oVertexNameDictionary = oReadWorkbookContext.VertexNameDictionary; EdgeVisibilityConverter oEdgeVisibilityConverter = new EdgeVisibilityConverter(); Boolean bGraphIsDirected = (oGraph.Directedness == GraphDirectedness.Directed); ExcelTableReader oExcelTableReader = new ExcelTableReader(oEdgeTable); IVertexCollection oVertices = oGraph.Vertices; IEdgeCollection oEdges = oGraph.Edges; HashSet <String> oColumnNamesToExclude = new HashSet <String>( new String[] { EdgeTableColumnNames.Vertex1Name, EdgeTableColumnNames.Vertex2Name }); foreach (ExcelTableReader.ExcelTableRow oRow in oExcelTableReader.GetRows()) { // Get the names of the edge's vertices. String sVertex1Name, sVertex2Name; Boolean bVertex1IsEmpty = !oRow.TryGetNonEmptyStringFromCell( EdgeTableColumnNames.Vertex1Name, out sVertex1Name); Boolean bVertex2IsEmpty = !oRow.TryGetNonEmptyStringFromCell( EdgeTableColumnNames.Vertex2Name, out sVertex2Name); if (bVertex1IsEmpty && bVertex2IsEmpty) { // Skip empty rows. continue; } if (bVertex1IsEmpty || bVertex2IsEmpty) { // A half-empty row is an error. OnHalfEmptyEdgeRow(oRow, bVertex1IsEmpty); } // Assume a default visibility. Visibility eVisibility = Visibility.Show; String sVisibility; if ( oRow.TryGetNonEmptyStringFromCell( CommonTableColumnNames.Visibility, out sVisibility) && !oEdgeVisibilityConverter.TryWorkbookToGraph( sVisibility, out eVisibility) ) { OnInvalidVisibility(oRow); } if (eVisibility == Visibility.Skip) { // Skip the edge an continue to the next edge. continue; } // Create the specified vertices or retrieve them from the // dictionary. IVertex oVertex1 = VertexNameToVertex( sVertex1Name, oVertices, oVertexNameDictionary); IVertex oVertex2 = VertexNameToVertex( sVertex2Name, oVertices, oVertexNameDictionary); // Add an edge connecting the vertices. IEdge oEdge = oEdges.Add(oVertex1, oVertex2, bGraphIsDirected); // If ReadWorkbookContext.FillIDColumns is true, add the edge to // the edge row ID dictionary and set the edge's Tag to the row ID. oReadWorkbookContext.AddToRowIDDictionary(oRow, oEdge, true); if (bReadAllEdgeAndVertexColumns) { // All columns except the vertex names should be read and // stored as metadata on the edge. ReadAllColumns(oExcelTableReader, oRow, oEdge, oColumnNamesToExclude); continue; } if (eVisibility == Visibility.Hide) { // Hide the edge and continue to the next edge. oEdge.SetValue(ReservedMetadataKeys.Visibility, VisibilityKeyValue.Hidden); continue; } // Alpha. Boolean bAlphaIsZero = ReadAlpha(oRow, oEdge); if (bAlphaIsZero) { continue; } // Color. ReadColor(oRow, EdgeTableColumnNames.Color, oEdge, ReservedMetadataKeys.PerColor, oReadWorkbookContext.ColorConverter2); // Width. ReadWidth(oRow, oReadWorkbookContext.EdgeWidthConverter, oEdge); // Style. ReadStyle(oRow, oReadWorkbookContext.EdgeStyleConverter, oEdge); // Label. if (oReadWorkbookContext.ReadEdgeLabels) { ReadCellAndSetMetadata(oRow, EdgeTableColumnNames.Label, oEdge, ReservedMetadataKeys.PerEdgeLabel); ReadColor(oRow, EdgeTableColumnNames.LabelTextColor, oEdge, ReservedMetadataKeys.PerEdgeLabelTextColor, oReadWorkbookContext.ColorConverter2); ReadLabelFontSize(oRow, oReadWorkbookContext.FontSizeConverter, oEdge); } // Weight. if (oReadWorkbookContext.ReadEdgeWeights) { ReadEdgeWeight(oRow, oEdge); } } if (bReadAllEdgeAndVertexColumns) { // Store the edge column names on the graph. oGraph.SetValue(ReservedMetadataKeys.AllEdgeMetadataKeys, FilterColumnNames(oExcelTableReader, oColumnNamesToExclude)); } }
RemoveVertex ( IVertex oVertex, ReadWorkbookContext oReadWorkbookContext, IGraph oGraph ) { Debug.Assert(oVertex != null); Debug.Assert(oReadWorkbookContext != null); Debug.Assert(oGraph != null); AssertValid(); Dictionary<Int32, IIdentityProvider> oEdgeRowIDDictionary = oReadWorkbookContext.EdgeRowIDDictionary; foreach (IEdge oIncidentEdge in oVertex.IncidentEdges) { if (oIncidentEdge.Tag is Int32) { oEdgeRowIDDictionary.Remove( (Int32)oIncidentEdge.Tag ); } } oReadWorkbookContext.VertexNameDictionary.Remove(oVertex.Name); if (oVertex.Tag is Int32) { oReadWorkbookContext.VertexRowIDDictionary.Remove( (Int32)oVertex.Tag ); } oGraph.Vertices.Remove(oVertex); }
AddCollapsedGroupAttributesInternal ( Microsoft.Office.Interop.Excel.Workbook oWorkbook, ReadWorkbookContext oReadWorkbookContext, ListObject oEdgeTable, ListObject oVertexTable, GroupInfo[] aoGroups ) { Debug.Assert(oWorkbook != null); Debug.Assert(oReadWorkbookContext != null); Debug.Assert(oEdgeTable != null); Debug.Assert(oVertexTable != null); Debug.Assert(aoGroups != null); Debug.Assert(aoGroups.Length > 0); // Check whether relevant columns have been autofilled using numerical // source columns. PerWorkbookSettings oPerWorkbookSettings = new PerWorkbookSettings(oWorkbook); AutoFillColorColumnResults oVertexColorResults = oPerWorkbookSettings.AutoFillWorkbookResults.VertexColorResults; Boolean bVertexColorColumnAutoFilled = oVertexColorResults.ColumnAutoFilled && !oVertexColorResults.ColumnAutoFilledWithCategories; AutoFillColorColumnResults oEdgeColorResults = oPerWorkbookSettings.AutoFillWorkbookResults.EdgeColorResults; Boolean bEdgeColorColumnAutoFilled = oEdgeColorResults.ColumnAutoFilled && !oEdgeColorResults.ColumnAutoFilledWithCategories; AutoFillNumericRangeColumnResults oEdgeWidthResults = oPerWorkbookSettings.AutoFillWorkbookResults.EdgeWidthResults; Boolean bEdgeWidthColumnAutoFilled = oEdgeWidthResults.ColumnAutoFilled; // Some user settings for autofill may be needed. // // Note: This is a design bug. The user's current settings should not // be required; everything needed here should come from the autofill // results. The long-term fix is to add a UseLogs property to the // AutoFillColorColumnResults class. AutoFillUserSettings oAutoFillUserSettings = new AutoFillUserSettings(); ColorColumnAutoFillUserSettings oVertexColorDetails = oAutoFillUserSettings.VertexColorDetails; ColorColumnAutoFillUserSettings oEdgeColorDetails = oAutoFillUserSettings.EdgeColorDetails; NumericRangeColumnAutoFillUserSettings oEdgeWidthDetails = oAutoFillUserSettings.EdgeWidthDetails; // The key is the row ID for each visible row in the vertex table and // the value is value of the source column cell in that row that was // used to autofill the vertex color column, if it was autofilled. Dictionary <Int32, Object> oVertexColorSourceDictionary = bVertexColorColumnAutoFilled ? GetRowIDDictionary(oVertexTable, oVertexColorResults.SourceColumnName) : null; // Ditto for edge colors and edge widths. Dictionary <Int32, Object> oEdgeColorSourceDictionary = bEdgeColorColumnAutoFilled ? GetRowIDDictionary(oEdgeTable, oEdgeColorResults.SourceColumnName) : null; Dictionary <Int32, Object> oEdgeWidthSourceDictionary = bEdgeWidthColumnAutoFilled ? GetRowIDDictionary(oEdgeTable, oEdgeWidthResults.SourceColumnName) : null; // Only motifs need to have attributes added to them. foreach (ExcelTemplateGroupInfo oGroup in aoGroups.Where( oGroup => oGroup.CollapsedAttributes != null)) { CollapsedGroupAttributes oCollapsedGroupAttributes = CollapsedGroupAttributes.FromString( oGroup.CollapsedAttributes); String sType = oCollapsedGroupAttributes.GetGroupType(); if ( sType == CollapsedGroupAttributeValues.FanMotifType || sType == CollapsedGroupAttributeValues.DConnectorMotifType || sType == CollapsedGroupAttributeValues.CliqueMotifType ) { AddVertexColorAttributeToMotif(oGroup, sType, bVertexColorColumnAutoFilled, oVertexColorResults, oVertexColorDetails, oVertexColorSourceDictionary, oReadWorkbookContext, oCollapsedGroupAttributes); } if (sType == CollapsedGroupAttributeValues.DConnectorMotifType) { Int32 iAnchorVertices; if (oCollapsedGroupAttributes.TryGetValue( CollapsedGroupAttributeKeys.AnchorVertices, out iAnchorVertices)) { AddEdgeColorAttributesToDConnectorMotif(oGroup, bEdgeColorColumnAutoFilled, oEdgeColorResults, oEdgeColorDetails, oEdgeColorSourceDictionary, oReadWorkbookContext, oCollapsedGroupAttributes, iAnchorVertices); AddEdgeWidthAttributesToDConnectorMotif(oGroup, bEdgeWidthColumnAutoFilled, oEdgeWidthResults, oEdgeWidthDetails, oEdgeWidthSourceDictionary, oReadWorkbookContext, oCollapsedGroupAttributes, iAnchorVertices); } } oGroup.CollapsedAttributes = oCollapsedGroupAttributes.ToString(); } }
RemoveUnwantedIsolates ( ReadWorkbookContext oReadWorkbookContext, IGraph oGraph ) { Debug.Assert(oReadWorkbookContext != null); Debug.Assert(oGraph != null); AssertValid(); List<IVertex> oIsolatedVertices = new List<IVertex>( from oVertex in oGraph.Vertices where oVertex.Degree == 0 select oVertex ); foreach (IVertex oIsolatedVertex in oIsolatedVertices) { // Don't remove the isolated vertex if it is supposed to be shown // regardless of whether it is part of an edge. if ( !oIsolatedVertex.ContainsKey( ReservedMetadataKeys.VertexHasVisibilityOfShow) ) { RemoveVertex(oIsolatedVertex, oReadWorkbookContext, oGraph); } } }
SetUp() { m_oReadWorkbookContext = new ReadWorkbookContext(); }
SkipAndHideGroups ( ReadWorkbookContext oReadWorkbookContext, Dictionary<String, ExcelTemplateGroupInfo> oGroupNameDictionary, HashSet<String> oSkippedGroupNames, HashSet<String> oHiddenGroupNames, IGraph oGraph ) { Debug.Assert(oReadWorkbookContext != null); Debug.Assert(oGroupNameDictionary != null); Debug.Assert(oSkippedGroupNames != null); Debug.Assert(oHiddenGroupNames != null); Debug.Assert(oGraph != null); AssertValid(); foreach (String sGroupName in oSkippedGroupNames) { // Remove the group's vertices and their incident edges from the // graph and dictionaries. foreach (IVertex oVertex in oGroupNameDictionary[sGroupName].Vertices) { RemoveVertex(oVertex, oReadWorkbookContext, oGraph); } oGroupNameDictionary.Remove(sGroupName); } foreach (String sGroupName in oHiddenGroupNames) { foreach (IVertex oVertex in oGroupNameDictionary[sGroupName].Vertices) { // Hide the group's vertices and their incident edges. HideVertex(oVertex); } } }
ReadWorkbookInternal ( Microsoft.Office.Interop.Excel.Workbook workbook, ReadWorkbookContext readWorkbookContext ) { Debug.Assert(readWorkbookContext != null); Debug.Assert(workbook != null); AssertValid(); if (readWorkbookContext.PopulateVertexWorksheet) { // Create and use the object that fills in the vertex worksheet. VertexWorksheetPopulator oVertexWorksheetPopulator = new VertexWorksheetPopulator(); try { oVertexWorksheetPopulator.PopulateVertexWorksheet( workbook, false); } catch (WorkbookFormatException) { // Ignore this type of error, which occurs when the vertex // worksheet is missing, for example. } } // Create a graph with the appropriate directedness. PerWorkbookSettings oPerWorkbookSettings = new PerWorkbookSettings(workbook); IGraph oGraph = new Graph(oPerWorkbookSettings.GraphDirectedness); // Read the edge worksheet. This adds data to oGraph, // ReadWorkbookContext.VertexNameDictionary, and // ReadWorkbookContext.EdgeIDDictionary. EdgeWorksheetReader oEdgeWorksheetReader = new EdgeWorksheetReader(); oEdgeWorksheetReader.ReadWorksheet(workbook, readWorkbookContext, oGraph); oEdgeWorksheetReader = null; // Read the vertex worksheet. This adds metadata to the vertices in // oGraph; adds any isolated vertices to oGraph and // ReadWorkbookContext.VertexNameDictionary; and removes any skipped // vertices (and their incident edges) from // ReadWorkbookContext.VertexNameDictionary, // ReadWorkbookContext.EdgeIDDictionary, and oGraph. VertexWorksheetReader oVertexWorksheetReader = new VertexWorksheetReader(); oVertexWorksheetReader.ReadWorksheet(workbook, readWorkbookContext, oGraph); oVertexWorksheetReader = null; if (readWorkbookContext.ReadGroups) { // Read the group worksheets. This adds metadata to the vertices // in oGraph and to oGraph itself. GroupWorksheetReader oGroupWorksheetReader = new GroupWorksheetReader(); oGroupWorksheetReader.ReadWorksheet(workbook, readWorkbookContext, oGraph); oGroupWorksheetReader = null; // Add to the graph any collapsed group attributes that can only be // added after the workbook is read. CollapsedGroupAttributeAdder.AddCollapsedGroupAttributes( workbook, readWorkbookContext, oGraph); } return(oGraph); }
ReadWorkbook ( Boolean bLayOutGraph ) { AssertValid(); if (oNodeXLControl.IsLayingOutGraph) { return; } RemoveSplashScreen(); if ( !this.NonEmptyWorkbookRead && this.LayoutIsNull && !ShowLayoutTypeIsNullNotification() ) { return; } // This is in case another open workbook has modified the user // settings. GeneralUserSettings oGeneralUserSettings = new GeneralUserSettings(); GroupUserSettings oGroupUserSettings = new GroupUserSettings(); ApplyGeneralUserSettings(oGeneralUserSettings); ApplyLayoutUserSettings( new LayoutUserSettings() ); ReadWorkbookContext oReadWorkbookContext = new ReadWorkbookContext(); oReadWorkbookContext.IgnoreVertexLocations = false; oReadWorkbookContext.GraphRectangle = this.GraphRectangle; oReadWorkbookContext.FillIDColumns = true; oReadWorkbookContext.ReadGroups = oGroupUserSettings.ReadGroups; oReadWorkbookContext.ReadEdgeWeights = true; oReadWorkbookContext.ReadVertexColorFromGroups = oGroupUserSettings.ReadVertexColorFromGroups; oReadWorkbookContext.ReadVertexShapeFromGroups = oGroupUserSettings.ReadVertexShapeFromGroups; oReadWorkbookContext.ReadVertexLabels = m_oRibbon.ReadVertexLabels; oReadWorkbookContext.ReadEdgeLabels = m_oRibbon.ReadEdgeLabels; oReadWorkbookContext.ReadGroupLabels = m_oRibbon.ReadGroupLabels; oReadWorkbookContext.ReadVertexImages = true; oReadWorkbookContext.DefaultVertexImageSize = oGeneralUserSettings.VertexImageSize; oReadWorkbookContext.DefaultVertexShape = oGeneralUserSettings.VertexShape; // Populate the vertex worksheet. This isn't strictly necessary, but // it does enable the vertex worksheet to be updated when the user // edits vertex attributes in the NodeXL graph. (If the vertex // worksheet is missing, vertex attributes can still be edited in the // graph; the edits just won't get saved in the workbook.) oReadWorkbookContext.PopulateVertexWorksheet = true; WorkbookReader oWorkbookReader = new WorkbookReader(); m_oEdgeRowIDDictionary = null; m_oVertexRowIDDictionary = null; EnableGraphControls(false); try { // Read the workbook into a Graph object. IGraph oGraph = oWorkbookReader.ReadWorkbook( m_oWorkbook, oReadWorkbookContext); // Save the edge and vertex dictionaries that were created by // WorkbookReader. m_oEdgeRowIDDictionary = oReadWorkbookContext.EdgeRowIDDictionary; m_oVertexRowIDDictionary = oReadWorkbookContext.VertexRowIDDictionary; // Load the NodeXLControl with the resulting graph. oNodeXLControl.Graph = oGraph; // Collapse any groups that are supposed to be collapsed. CollapseOrExpandGroups(GetGroupNamesToCollapse(oGraph), true, false); // Enable tooltips in case tooltips were specified in the workbook. oNodeXLControl.ShowVertexToolTips = true; // If the dynamic filter dialog is open, read the dynamic filter // columns it filled in. if (m_oDynamicFilterDialog != null) { ReadDynamicFilterColumns(false); DynamicFilterHandler.ReadFilteredAlpha(m_oDynamicFilterDialog, oNodeXLControl, false); } oNodeXLControl.DrawGraph(bLayOutGraph); PerWorkbookSettings oPerWorkbookSettings = this.PerWorkbookSettings; UpdateAutoFillResultsLegend(oPerWorkbookSettings); UpdateDynamicFiltersLegend(); UpdateAxes(oPerWorkbookSettings); UpdateGraphHistory(oPerWorkbookSettings); } catch (Exception oException) { // If exceptions aren't caught here, Excel consumes them without // indicating that anything is wrong. This can result in the graph // controls remaining disabled, among other problems. ErrorUtil.OnException(oException); } finally { EnableGraphControls(true); } // Change the button text to indicate that if any of the buttons is // clicked again, the graph will be read again. tsbReadWorkbook.Text = msiContextReadWorkbook.Text = m_oRibbon.ReadWorkbookButtonText = "Refresh Graph"; }
AddCollapsedGroupAttributesInternal ( Microsoft.Office.Interop.Excel.Workbook oWorkbook, ReadWorkbookContext oReadWorkbookContext, ListObject oEdgeTable, ListObject oVertexTable, GroupInfo[] aoGroups ) { Debug.Assert(oWorkbook != null); Debug.Assert(oReadWorkbookContext != null); Debug.Assert(oEdgeTable != null); Debug.Assert(oVertexTable != null); Debug.Assert(aoGroups != null); Debug.Assert(aoGroups.Length > 0); // Check whether relevant columns have been autofilled using numerical // source columns. PerWorkbookSettings oPerWorkbookSettings = new PerWorkbookSettings(oWorkbook); AutoFillColorColumnResults oVertexColorResults = oPerWorkbookSettings.AutoFillWorkbookResults.VertexColorResults; Boolean bVertexColorColumnAutoFilled = oVertexColorResults.ColumnAutoFilled && !oVertexColorResults.ColumnAutoFilledWithCategories; AutoFillColorColumnResults oEdgeColorResults = oPerWorkbookSettings.AutoFillWorkbookResults.EdgeColorResults; Boolean bEdgeColorColumnAutoFilled = oEdgeColorResults.ColumnAutoFilled && !oEdgeColorResults.ColumnAutoFilledWithCategories; AutoFillNumericRangeColumnResults oEdgeWidthResults = oPerWorkbookSettings.AutoFillWorkbookResults.EdgeWidthResults; Boolean bEdgeWidthColumnAutoFilled = oEdgeWidthResults.ColumnAutoFilled; // Some user settings for autofill may be needed. // // Note: This is a design bug. The user's current settings should not // be required; everything needed here should come from the autofill // results. The long-term fix is to add a UseLogs property to the // AutoFillColorColumnResults class. AutoFillUserSettings oAutoFillUserSettings = new AutoFillUserSettings(); ColorColumnAutoFillUserSettings oVertexColorDetails = oAutoFillUserSettings.VertexColorDetails; ColorColumnAutoFillUserSettings oEdgeColorDetails = oAutoFillUserSettings.EdgeColorDetails; NumericRangeColumnAutoFillUserSettings oEdgeWidthDetails = oAutoFillUserSettings.EdgeWidthDetails; // The key is the row ID for each visible row in the vertex table and // the value is value of the source column cell in that row that was // used to autofill the vertex color column, if it was autofilled. Dictionary<Int32, Object> oVertexColorSourceDictionary = bVertexColorColumnAutoFilled ? GetRowIDDictionary(oVertexTable, oVertexColorResults.SourceColumnName) : null; // Ditto for edge colors and edge widths. Dictionary<Int32, Object> oEdgeColorSourceDictionary = bEdgeColorColumnAutoFilled ? GetRowIDDictionary(oEdgeTable, oEdgeColorResults.SourceColumnName) : null; Dictionary<Int32, Object> oEdgeWidthSourceDictionary = bEdgeWidthColumnAutoFilled ? GetRowIDDictionary(oEdgeTable, oEdgeWidthResults.SourceColumnName) : null; // Only motifs need to have attributes added to them. foreach ( ExcelTemplateGroupInfo oGroup in aoGroups.Where( oGroup => oGroup.CollapsedAttributes != null) ) { CollapsedGroupAttributes oCollapsedGroupAttributes = CollapsedGroupAttributes.FromString( oGroup.CollapsedAttributes); String sType = oCollapsedGroupAttributes.GetGroupType(); if ( sType == CollapsedGroupAttributeValues.FanMotifType || sType == CollapsedGroupAttributeValues.DConnectorMotifType || sType == CollapsedGroupAttributeValues.CliqueMotifType ) { AddVertexColorAttributeToMotif(oGroup, sType, bVertexColorColumnAutoFilled, oVertexColorResults, oVertexColorDetails, oVertexColorSourceDictionary, oReadWorkbookContext, oCollapsedGroupAttributes); } if (sType == CollapsedGroupAttributeValues.DConnectorMotifType) { Int32 iAnchorVertices; if ( oCollapsedGroupAttributes.TryGetValue( CollapsedGroupAttributeKeys.AnchorVertices, out iAnchorVertices) ) { AddEdgeColorAttributesToDConnectorMotif(oGroup, bEdgeColorColumnAutoFilled, oEdgeColorResults, oEdgeColorDetails, oEdgeColorSourceDictionary, oReadWorkbookContext, oCollapsedGroupAttributes, iAnchorVertices); AddEdgeWidthAttributesToDConnectorMotif(oGroup, bEdgeWidthColumnAutoFilled, oEdgeWidthResults, oEdgeWidthDetails, oEdgeWidthSourceDictionary, oReadWorkbookContext, oCollapsedGroupAttributes, iAnchorVertices); } } oGroup.CollapsedAttributes = oCollapsedGroupAttributes.ToString(); } }
ReadWorkbook ( Microsoft.Office.Interop.Excel.Workbook oWorkbook ) { Debug.Assert(oWorkbook != null); AssertValid(); ReadWorkbookContext oReadWorkbookContext = new ReadWorkbookContext(); WorkbookReader oWorkbookReader = new WorkbookReader(); // Convert the workbook contents to a Graph object. return ( oWorkbookReader.ReadWorkbook( oWorkbook, oReadWorkbookContext) ); }
AddVertexColorAttributeToMotif ( ExcelTemplateGroupInfo oGroup, String sType, Boolean bVertexColorColumnAutoFilled, AutoFillColorColumnResults oVertexColorResults, ColorColumnAutoFillUserSettings oVertexColorDetails, Dictionary<Int32, Object> oVertexColorSourceDictionary, ReadWorkbookContext oReadWorkbookContext, CollapsedGroupAttributes oCollapsedGroupAttributes ) { Debug.Assert(oGroup != null); Debug.Assert( !String.IsNullOrEmpty(sType) ); Debug.Assert(oVertexColorResults != null); Debug.Assert(oReadWorkbookContext != null); Debug.Assert(oCollapsedGroupAttributes != null); Color oColor; // If the vertex color column was autofilled, get the average color // for the vertices in the motif. if ( !bVertexColorColumnAutoFilled || !TableColumnMapper.TryMapAverageColor( GetRowIDsToAverageForVertexColor(oGroup, oCollapsedGroupAttributes, sType), oVertexColorSourceDictionary, oVertexColorResults.SourceCalculationNumber1, oVertexColorResults.SourceCalculationNumber2, oVertexColorResults.DestinationColor1, oVertexColorResults.DestinationColor2, oVertexColorDetails.UseLogs, out oColor) ) { // Default to the color that was assigned to the group. oColor = oGroup.VertexColor; } oCollapsedGroupAttributes.Add( CollapsedGroupAttributeKeys.VertexColor, oReadWorkbookContext.ColorConverter2.GraphToWorkbook(oColor) ); }
ReadGroupTable ( ListObject oGroupTable, ReadWorkbookContext oReadWorkbookContext, HashSet<String> oSkippedGroupNames, HashSet<String> oHiddenGroupNames ) { Debug.Assert(oGroupTable != null); Debug.Assert(oReadWorkbookContext != null); Debug.Assert(oSkippedGroupNames != null); Debug.Assert(oHiddenGroupNames != null); AssertValid(); if (oReadWorkbookContext.FillIDColumns) { FillIDColumn(oGroupTable); } Dictionary<String, ExcelTemplateGroupInfo> oGroupNameDictionary = new Dictionary<String, ExcelTemplateGroupInfo>(); ColorConverter2 oColorConverter2 = oReadWorkbookContext.ColorConverter2; GroupVisibilityConverter oGroupVisibilityConverter = new GroupVisibilityConverter(); BooleanConverter oBooleanConverter = oReadWorkbookContext.BooleanConverter; ExcelTableReader oExcelTableReader = new ExcelTableReader(oGroupTable); foreach ( ExcelTableReader.ExcelTableRow oRow in oExcelTableReader.GetRows() ) { // Get the group information. String sGroupName; Color oVertexColor; VertexShape eVertexShape; if ( !oRow.TryGetNonEmptyStringFromCell(GroupTableColumnNames.Name, out sGroupName) || !TryGetColor(oRow, GroupTableColumnNames.VertexColor, oColorConverter2, out oVertexColor) || !TryGetVertexShape(oRow, GroupTableColumnNames.VertexShape, out eVertexShape) ) { continue; } ReadVisibility(oRow, oGroupVisibilityConverter, sGroupName, oSkippedGroupNames, oHiddenGroupNames); Boolean bCollapsed = false; Boolean bCollapsedCellValue; if ( TryGetBoolean(oRow, GroupTableColumnNames.Collapsed, oBooleanConverter, out bCollapsedCellValue) && bCollapsedCellValue ) { bCollapsed = true; } String sCollapsedAttributes; if ( !oRow.TryGetNonEmptyStringFromCell( GroupTableColumnNames.CollapsedAttributes, out sCollapsedAttributes) ) { sCollapsedAttributes = null; } Int32 iRowIDAsInt32; Nullable<Int32> iRowID = null; if ( oRow.TryGetInt32FromCell(CommonTableColumnNames.ID, out iRowIDAsInt32) ) { iRowID = iRowIDAsInt32; } ExcelTemplateGroupInfo oExcelTemplateGroupInfo = new ExcelTemplateGroupInfo(sGroupName, iRowID, oVertexColor, eVertexShape, bCollapsed, sCollapsedAttributes); if (oReadWorkbookContext.ReadGroupLabels) { String sLabel; if ( oRow.TryGetNonEmptyStringFromCell( GroupTableColumnNames.Label, out sLabel) ) { oExcelTemplateGroupInfo.Label = sLabel; } } if (!oReadWorkbookContext.IgnoreVertexLocations) { System.Drawing.PointF oCollapsedLocation; if ( TryGetLocation(oRow, GroupTableColumnNames.CollapsedX, GroupTableColumnNames.CollapsedY, oReadWorkbookContext.VertexLocationConverter, out oCollapsedLocation) ) { oExcelTemplateGroupInfo.CollapsedLocation = oCollapsedLocation; } } try { oGroupNameDictionary.Add(sGroupName, oExcelTemplateGroupInfo); } catch (ArgumentException) { Range oInvalidCell = oRow.GetRangeForCell( GroupTableColumnNames.Name); OnWorkbookFormatError( String.Format( "The cell {0} contains a duplicate group name. There" + " can't be two rows with the same group name." , ExcelUtil.GetRangeAddress(oInvalidCell) ), oInvalidCell ); } } return (oGroupNameDictionary); }
AddEdgeWidthAttributesToDConnectorMotif ( ExcelTemplateGroupInfo oGroup, Boolean bEdgeWidthColumnAutoFilled, AutoFillNumericRangeColumnResults oEdgeWidthResults, NumericRangeColumnAutoFillUserSettings oEdgeWidthDetails, Dictionary<Int32, Object> oEdgeWidthSourceDictionary, ReadWorkbookContext oReadWorkbookContext, CollapsedGroupAttributes oCollapsedGroupAttributes, Int32 iAnchorVertices ) { Debug.Assert(oGroup != null); Debug.Assert(oEdgeWidthResults != null); Debug.Assert(oReadWorkbookContext != null); Debug.Assert(oCollapsedGroupAttributes != null); Debug.Assert(iAnchorVertices >= 0); // If the edge width column was autofilled, get the average width for // the edges incident to the two-connector motif's first anchor, then // its second anchor. Otherwise, don't do anything. if (!bEdgeWidthColumnAutoFilled) { return; } for (Int32 iAnchorVertexIndex = 0; iAnchorVertexIndex < iAnchorVertices; iAnchorVertexIndex++) { Double dAverageEdgeWidth; if ( TableColumnMapper.TryMapAverageNumber( GetRowIDsToAverageForEdges(oGroup, oCollapsedGroupAttributes, iAnchorVertexIndex), oEdgeWidthSourceDictionary, oEdgeWidthResults.SourceCalculationNumber1, oEdgeWidthResults.SourceCalculationNumber2, oEdgeWidthResults.DestinationNumber1, oEdgeWidthResults.DestinationNumber2, oEdgeWidthDetails.UseLogs, out dAverageEdgeWidth ) ) { oCollapsedGroupAttributes.Add( CollapsedGroupAttributeKeys.GetAnchorVertexEdgeWidthKey( iAnchorVertexIndex), dAverageEdgeWidth ); } } }
ReadGroupVertexTable ( ListObject oGroupVertexTable, ReadWorkbookContext oReadWorkbookContext, Dictionary<String, ExcelTemplateGroupInfo> oGroupNameDictionary, IGraph oGraph ) { Debug.Assert(oGroupVertexTable != null); Debug.Assert(oReadWorkbookContext != null); Debug.Assert(oGroupNameDictionary != null); Debug.Assert(oGraph != null); AssertValid(); Dictionary<String, IVertex> oVertexNameDictionary = oReadWorkbookContext.VertexNameDictionary; ExcelTableReader oExcelTableReader = new ExcelTableReader(oGroupVertexTable); foreach ( ExcelTableReader.ExcelTableRow oRow in oExcelTableReader.GetRows() ) { // Get the group vertex information from the row. String sGroupName, sVertexName; if ( !oRow.TryGetNonEmptyStringFromCell( GroupVertexTableColumnNames.GroupName, out sGroupName) || !oRow.TryGetNonEmptyStringFromCell( GroupVertexTableColumnNames.VertexName, out sVertexName) ) { continue; } // Get the group information for the vertex. ExcelTemplateGroupInfo oExcelTemplateGroupInfo; IVertex oVertex; if ( !oGroupNameDictionary.TryGetValue(sGroupName, out oExcelTemplateGroupInfo) || !oVertexNameDictionary.TryGetValue(sVertexName, out oVertex) ) { continue; } // If the vertex should get its color or shape from the group, set // the vertex's color or shape. Boolean bReadColorFromGroup, bReadShapeFromGroup; GetReadColorAndShapeFlags(oVertex, oExcelTemplateGroupInfo, oReadWorkbookContext, out bReadColorFromGroup, out bReadShapeFromGroup); if (bReadColorFromGroup) { oVertex.SetValue(ReservedMetadataKeys.PerColor, oExcelTemplateGroupInfo.VertexColor); } if (bReadShapeFromGroup) { oVertex.SetValue(ReservedMetadataKeys.PerVertexShape, oExcelTemplateGroupInfo.VertexShape); } oExcelTemplateGroupInfo.Vertices.AddLast(oVertex); } }
ReadGroupTable ( ListObject oGroupTable, ReadWorkbookContext oReadWorkbookContext, HashSet <String> oSkippedGroupNames, HashSet <String> oHiddenGroupNames ) { Debug.Assert(oGroupTable != null); Debug.Assert(oReadWorkbookContext != null); Debug.Assert(oSkippedGroupNames != null); Debug.Assert(oHiddenGroupNames != null); AssertValid(); if (oReadWorkbookContext.FillIDColumns) { FillIDColumn(oGroupTable); } Dictionary <String, ExcelTemplateGroupInfo> oGroupNameDictionary = new Dictionary <String, ExcelTemplateGroupInfo>(); ColorConverter2 oColorConverter2 = oReadWorkbookContext.ColorConverter2; GroupVisibilityConverter oGroupVisibilityConverter = new GroupVisibilityConverter(); BooleanConverter oBooleanConverter = oReadWorkbookContext.BooleanConverter; ExcelTableReader oExcelTableReader = new ExcelTableReader(oGroupTable); foreach (ExcelTableReader.ExcelTableRow oRow in oExcelTableReader.GetRows()) { // Get the group information. String sGroupName; Color oVertexColor; VertexShape eVertexShape; if ( !oRow.TryGetNonEmptyStringFromCell(GroupTableColumnNames.Name, out sGroupName) || !TryGetColor(oRow, GroupTableColumnNames.VertexColor, oColorConverter2, out oVertexColor) || !TryGetVertexShape(oRow, GroupTableColumnNames.VertexShape, out eVertexShape) ) { continue; } ReadVisibility(oRow, oGroupVisibilityConverter, sGroupName, oSkippedGroupNames, oHiddenGroupNames); Boolean bCollapsed = false; Boolean bCollapsedCellValue; if ( TryGetBoolean(oRow, GroupTableColumnNames.Collapsed, oBooleanConverter, out bCollapsedCellValue) && bCollapsedCellValue ) { bCollapsed = true; } String sCollapsedAttributes; if (!oRow.TryGetNonEmptyStringFromCell( GroupTableColumnNames.CollapsedAttributes, out sCollapsedAttributes)) { sCollapsedAttributes = null; } Int32 iRowIDAsInt32; Nullable <Int32> iRowID = null; if (oRow.TryGetInt32FromCell(CommonTableColumnNames.ID, out iRowIDAsInt32)) { iRowID = iRowIDAsInt32; } ExcelTemplateGroupInfo oExcelTemplateGroupInfo = new ExcelTemplateGroupInfo(sGroupName, iRowID, oVertexColor, eVertexShape, bCollapsed, sCollapsedAttributes); if (oReadWorkbookContext.ReadGroupLabels) { String sLabel; if (oRow.TryGetNonEmptyStringFromCell( GroupTableColumnNames.Label, out sLabel)) { oExcelTemplateGroupInfo.Label = sLabel; } } if (!oReadWorkbookContext.IgnoreVertexLocations) { System.Drawing.PointF oCollapsedLocation; if (TryGetLocation(oRow, GroupTableColumnNames.CollapsedX, GroupTableColumnNames.CollapsedY, oReadWorkbookContext.VertexLocationConverter, out oCollapsedLocation)) { oExcelTemplateGroupInfo.CollapsedLocation = oCollapsedLocation; } } try { oGroupNameDictionary.Add(sGroupName, oExcelTemplateGroupInfo); } catch (ArgumentException) { Range oInvalidCell = oRow.GetRangeForCell( GroupTableColumnNames.Name); OnWorkbookFormatError(String.Format( "The cell {0} contains a duplicate group name. There" + " can't be two rows with the same group name." , ExcelUtil.GetRangeAddress(oInvalidCell) ), oInvalidCell ); } } return(oGroupNameDictionary); }
GetReadColorAndShapeFlags ( IVertex oVertex, GroupInfo oGroup, ReadWorkbookContext oReadWorkbookContext, out Boolean bReadColorFromGroup, out Boolean bReadShapeFromGroup ) { Debug.Assert(oVertex != null); Debug.Assert(oReadWorkbookContext != null); AssertValid(); // Assume that the settings specified in the context object will be // used. bReadColorFromGroup = oReadWorkbookContext.ReadVertexColorFromGroups; bReadShapeFromGroup = oReadWorkbookContext.ReadVertexShapeFromGroups; if (oGroup.CollapsedAttributes != null) { CollapsedGroupAttributes oCollapsedGroupAttributes = CollapsedGroupAttributes.FromString( oGroup.CollapsedAttributes); String sHeadVertexName; if ( oCollapsedGroupAttributes.GetGroupType() == CollapsedGroupAttributeValues.FanMotifType && oCollapsedGroupAttributes.TryGetValue( CollapsedGroupAttributeKeys.HeadVertexName, out sHeadVertexName) && oVertex.Name == sHeadVertexName ) { // The shape of a fan motif's head vertex should never be // changed. Do not get it from the group. bReadShapeFromGroup = false; } } }
ReadGroupVertexTable ( ListObject oGroupVertexTable, ReadWorkbookContext oReadWorkbookContext, Dictionary <String, ExcelTemplateGroupInfo> oGroupNameDictionary, IGraph oGraph ) { Debug.Assert(oGroupVertexTable != null); Debug.Assert(oReadWorkbookContext != null); Debug.Assert(oGroupNameDictionary != null); Debug.Assert(oGraph != null); AssertValid(); Dictionary <String, IVertex> oVertexNameDictionary = oReadWorkbookContext.VertexNameDictionary; ExcelTableReader oExcelTableReader = new ExcelTableReader(oGroupVertexTable); foreach (ExcelTableReader.ExcelTableRow oRow in oExcelTableReader.GetRows()) { // Get the group vertex information from the row. String sGroupName, sVertexName; if ( !oRow.TryGetNonEmptyStringFromCell( GroupVertexTableColumnNames.GroupName, out sGroupName) || !oRow.TryGetNonEmptyStringFromCell( GroupVertexTableColumnNames.VertexName, out sVertexName) ) { continue; } // Get the group information for the vertex. ExcelTemplateGroupInfo oExcelTemplateGroupInfo; IVertex oVertex; if ( !oGroupNameDictionary.TryGetValue(sGroupName, out oExcelTemplateGroupInfo) || !oVertexNameDictionary.TryGetValue(sVertexName, out oVertex) ) { continue; } // If the vertex should get its color or shape from the group, set // the vertex's color or shape. Boolean bReadColorFromGroup, bReadShapeFromGroup; GetReadColorAndShapeFlags(oVertex, oExcelTemplateGroupInfo, oReadWorkbookContext, out bReadColorFromGroup, out bReadShapeFromGroup); if (bReadColorFromGroup) { oVertex.SetValue(ReservedMetadataKeys.PerColor, oExcelTemplateGroupInfo.VertexColor); } if (bReadShapeFromGroup) { oVertex.SetValue(ReservedMetadataKeys.PerVertexShape, oExcelTemplateGroupInfo.VertexShape); } oExcelTemplateGroupInfo.Vertices.AddLast(oVertex); } }
ReadWorksheet ( Microsoft.Office.Interop.Excel.Workbook workbook, ReadWorkbookContext readWorkbookContext, IGraph graph ) { Debug.Assert(workbook != null); Debug.Assert(readWorkbookContext != null); Debug.Assert(graph != null); AssertValid(); // Attempt to get the optional table that contains vertex data. ListObject oVertexTable; if (ExcelTableUtil.TryGetTable(workbook, WorksheetNames.Vertices, TableNames.Vertices, out oVertexTable) ) { // The code that reads the table can handle hidden rows, but not // hidden columns. Temporarily show all hidden columns in the // table. ExcelHiddenColumns oHiddenColumns = ExcelColumnHider.ShowHiddenColumns(oVertexTable); Boolean bLayoutAndZOrderSet; try { ReadVertexTable(oVertexTable, readWorkbookContext, graph, out bLayoutAndZOrderSet); RemoveUnwantedIsolates(readWorkbookContext, graph); } finally { ExcelColumnHider.RestoreHiddenColumns(oVertexTable, oHiddenColumns); } if (bLayoutAndZOrderSet) { // The layout and z-orders were specified for at least one // vertex. The ByMetadataVertexSorter used by // SortableLayoutBase and GraphDrawer requires that if an order // is set on one vertex, it must be set on all vertices. This // isn't required in the Excel template, though, so set a // default order for each vertex that doesn't already specify // one. SetUnspecifiedVertexLayoutAndZOrders(graph); // The layout and z-orders are ignored unless this key is added // to the graph. graph.SetValue( ReservedMetadataKeys.SortableLayoutAndZOrderSet, null); } } }
ReadWorksheet ( Microsoft.Office.Interop.Excel.Workbook workbook, ReadWorkbookContext readWorkbookContext, IGraph graph ) { Debug.Assert(workbook != null); Debug.Assert(readWorkbookContext != null); Debug.Assert(graph != null); AssertValid(); // Get the required table that contains edge data, then add the edges // and vertices in the table to the graph. ListObject oEdgeTable = GetEdgeTable(workbook); // The code that reads the table can handle hidden rows, but not hidden // columns. Temporarily show all hidden columns in the table. ExcelHiddenColumns oHiddenColumns = ExcelColumnHider.ShowHiddenColumns(oEdgeTable); try { ReadEdgeTable(oEdgeTable, readWorkbookContext, graph); } finally { ExcelColumnHider.RestoreHiddenColumns(oEdgeTable, oHiddenColumns); } }
ReadVertexTable ( ListObject oVertexTable, ReadWorkbookContext oReadWorkbookContext, IGraph oGraph, out Boolean bLayoutAndZOrderSet ) { Debug.Assert(oVertexTable != null); Debug.Assert(oReadWorkbookContext != null); Debug.Assert(oGraph != null); AssertValid(); bLayoutAndZOrderSet = false; if (GetTableColumnIndex(oVertexTable, VertexTableColumnNames.VertexName, false) == NoSuchColumn) { // Nothing can be done without vertex names. return; } Boolean bReadAllEdgeAndVertexColumns = oReadWorkbookContext.ReadAllEdgeAndVertexColumns; if (oReadWorkbookContext.FillIDColumns) { FillIDColumn(oVertexTable); } // Get the names of all the column pairs that are used to add custom // menu items to the vertex context menu in the graph. TableColumnAdder oTableColumnAdder = new TableColumnAdder(); ICollection< KeyValuePair<String, String> > aoCustomMenuItemPairNames = oTableColumnAdder.GetColumnPairNames(oVertexTable, VertexTableColumnNames.CustomMenuItemTextBase, VertexTableColumnNames.CustomMenuItemActionBase); IVertexCollection oVertices = oGraph.Vertices; Dictionary<String, IVertex> oVertexNameDictionary = oReadWorkbookContext.VertexNameDictionary; Dictionary<Int32, IIdentityProvider> oEdgeRowIDDictionary = oReadWorkbookContext.EdgeRowIDDictionary; BooleanConverter oBooleanConverter = oReadWorkbookContext.BooleanConverter; VertexVisibilityConverter oVertexVisibilityConverter = new VertexVisibilityConverter(); VertexLabelPositionConverter oVertexLabelPositionConverter = new VertexLabelPositionConverter(); ExcelTableReader oExcelTableReader = new ExcelTableReader(oVertexTable); HashSet<String> oColumnNamesToExclude = new HashSet<String>( new String[] { VertexTableColumnNames.VertexName } ); foreach ( ExcelTableReader.ExcelTableRow oRow in oExcelTableReader.GetRows() ) { // Get the name of the vertex. String sVertexName; if ( !oRow.TryGetNonEmptyStringFromCell( VertexTableColumnNames.VertexName, out sVertexName) ) { continue; } // If the vertex was added to the graph as part of an edge, // retrieve the vertex. IVertex oVertex; if ( !oVertexNameDictionary.TryGetValue(sVertexName, out oVertex) ) { oVertex = null; } // Assume a default visibility. Visibility eVisibility = Visibility.ShowIfInAnEdge; String sVisibility; if ( oRow.TryGetNonEmptyStringFromCell( CommonTableColumnNames.Visibility, out sVisibility) ) { if ( !oVertexVisibilityConverter.TryWorkbookToGraph( sVisibility, out eVisibility) ) { OnInvalidVisibility(oRow); } } switch (eVisibility) { case Visibility.ShowIfInAnEdge: // If the vertex is part of an edge, show it using the // specified vertex attributes. Otherwise, skip the vertex // row. if (oVertex == null) { continue; } break; case Visibility.Skip: // Skip the vertex row and any edge rows that include the // vertex. Do not read them into the graph. if (oVertex != null) { // Remove the vertex and its incident edges from the // graph and dictionaries. RemoveVertex(oVertex, oReadWorkbookContext, oGraph); } continue; case Visibility.Hide: // If the vertex is part of an edge, hide it and its // incident edges. Otherwise, skip the vertex row. if (oVertex == null) { continue; } HideVertex(oVertex); break; case Visibility.Show: // Show the vertex using the specified attributes // regardless of whether it is part of an edge. if (oVertex == null) { oVertex = CreateVertex(sVertexName, oVertices, oVertexNameDictionary); } oVertex.SetValue( ReservedMetadataKeys.VertexHasVisibilityOfShow, null); break; default: Debug.Assert(false); break; } Debug.Assert(oVertex != null); // If ReadWorkbookContext.FillIDColumns is true, add the vertex to // the vertex row ID dictionary and set the vertex's Tag to the row // ID. oReadWorkbookContext.AddToRowIDDictionary(oRow, oVertex, false); if (bReadAllEdgeAndVertexColumns) { // All columns except the vertex name should be read and stored // as metadata on the vertex. ReadAllColumns( oExcelTableReader, oRow, oVertex, oColumnNamesToExclude); continue; } // Layout and z-order. if ( ReadLayoutAndZOrder(oRow, oVertex) ) { bLayoutAndZOrderSet = true; } // Location and Locked. if (!oReadWorkbookContext.IgnoreVertexLocations) { System.Drawing.PointF oLocation; Boolean bLocationSpecified = TryGetLocation(oRow, VertexTableColumnNames.X, VertexTableColumnNames.Y, oReadWorkbookContext.VertexLocationConverter, out oLocation); if (bLocationSpecified) { oVertex.Location = oLocation; } ReadLocked(oRow, oBooleanConverter, bLocationSpecified, oVertex); } // Polar coordinates. ReadPolarCoordinates(oRow, oVertex); // Marked. ReadMarked(oRow, oBooleanConverter, oVertex); // Custom menu items. if (aoCustomMenuItemPairNames.Count > 0) { ReadCustomMenuItems(oRow, aoCustomMenuItemPairNames, oVertex); } // Alpha. ReadAlpha(oRow, oVertex); // Tooltip. ReadCellAndSetMetadata(oRow, VertexTableColumnNames.ToolTip, oVertex, ReservedMetadataKeys.PerVertexToolTip); // Label. if (oReadWorkbookContext.ReadVertexLabels) { ReadCellAndSetMetadata(oRow, VertexTableColumnNames.Label, oVertex, ReservedMetadataKeys.PerVertexLabel); } // Label fill color. ReadColor(oRow, VertexTableColumnNames.LabelFillColor, oVertex, ReservedMetadataKeys.PerVertexLabelFillColor, oReadWorkbookContext.ColorConverter2); // Label position. ReadLabelPosition(oRow, oVertexLabelPositionConverter, oVertex); // Radius. Nullable<Single> oRadiusWorkbook = new Nullable<Single>(); oRadiusWorkbook = ReadRadius(oRow, oReadWorkbookContext.VertexRadiusConverter, oVertex); // Shape. VertexShape eVertexShape; if ( !ReadShape(oRow, oVertex, out eVertexShape) ) { eVertexShape = oReadWorkbookContext.DefaultVertexShape; } // Label font size. if (eVertexShape == VertexShape.Label && oRadiusWorkbook.HasValue) { // The vertex radius is used to specify font size when the // shape is Label. oVertex.SetValue( ReservedMetadataKeys.PerVertexLabelFontSize, oReadWorkbookContext.VertexRadiusConverter. WorkbookToLabelFontSize(oRadiusWorkbook.Value) ); } // Image URI. if (eVertexShape == VertexShape.Image && oReadWorkbookContext.ReadVertexImages) { ReadImageUri(oRow, oVertex, oReadWorkbookContext.VertexRadiusConverter, oRadiusWorkbook.HasValue ? oRadiusWorkbook : oReadWorkbookContext.DefaultVertexImageSize ); } // Color ReadColor(oRow, VertexTableColumnNames.Color, oVertex, ReservedMetadataKeys.PerColor, oReadWorkbookContext.ColorConverter2); } if (bReadAllEdgeAndVertexColumns) { // Store the vertex column names on the graph. oGraph.SetValue( ReservedMetadataKeys.AllVertexMetadataKeys, FilterColumnNames(oExcelTableReader, oColumnNamesToExclude) ); } }
ReadEdgeTable ( ListObject oEdgeTable, ReadWorkbookContext oReadWorkbookContext, IGraph oGraph ) { Debug.Assert(oEdgeTable != null); Debug.Assert(oReadWorkbookContext != null); Debug.Assert(oGraph != null); AssertValid(); Boolean bReadAllEdgeAndVertexColumns = oReadWorkbookContext.ReadAllEdgeAndVertexColumns; if (oReadWorkbookContext.FillIDColumns) { FillIDColumn(oEdgeTable); } Dictionary<String, IVertex> oVertexNameDictionary = oReadWorkbookContext.VertexNameDictionary; EdgeVisibilityConverter oEdgeVisibilityConverter = new EdgeVisibilityConverter(); Boolean bGraphIsDirected = (oGraph.Directedness == GraphDirectedness.Directed); ExcelTableReader oExcelTableReader = new ExcelTableReader(oEdgeTable); IVertexCollection oVertices = oGraph.Vertices; IEdgeCollection oEdges = oGraph.Edges; HashSet<String> oColumnNamesToExclude = new HashSet<String>( new String[] { EdgeTableColumnNames.Vertex1Name, EdgeTableColumnNames.Vertex2Name } ); foreach ( ExcelTableReader.ExcelTableRow oRow in oExcelTableReader.GetRows() ) { // Get the names of the edge's vertices. String sVertex1Name, sVertex2Name; Boolean bVertex1IsEmpty = !oRow.TryGetNonEmptyStringFromCell( EdgeTableColumnNames.Vertex1Name, out sVertex1Name); Boolean bVertex2IsEmpty = !oRow.TryGetNonEmptyStringFromCell( EdgeTableColumnNames.Vertex2Name, out sVertex2Name); if (bVertex1IsEmpty && bVertex2IsEmpty) { // Skip empty rows. continue; } if (bVertex1IsEmpty || bVertex2IsEmpty) { // A half-empty row is an error. OnHalfEmptyEdgeRow(oRow, bVertex1IsEmpty); } // Assume a default visibility. Visibility eVisibility = Visibility.Show; String sVisibility; if ( oRow.TryGetNonEmptyStringFromCell( CommonTableColumnNames.Visibility, out sVisibility) && !oEdgeVisibilityConverter.TryWorkbookToGraph( sVisibility, out eVisibility) ) { OnInvalidVisibility(oRow); } if (eVisibility == Visibility.Skip) { // Skip the edge an continue to the next edge. continue; } // Create the specified vertices or retrieve them from the // dictionary. IVertex oVertex1 = VertexNameToVertex( sVertex1Name, oVertices, oVertexNameDictionary); IVertex oVertex2 = VertexNameToVertex( sVertex2Name, oVertices, oVertexNameDictionary); // Add an edge connecting the vertices. IEdge oEdge = oEdges.Add(oVertex1, oVertex2, bGraphIsDirected); // If ReadWorkbookContext.FillIDColumns is true, add the edge to // the edge row ID dictionary and set the edge's Tag to the row ID. oReadWorkbookContext.AddToRowIDDictionary(oRow, oEdge, true); if (bReadAllEdgeAndVertexColumns) { // All columns except the vertex names should be read and // stored as metadata on the edge. ReadAllColumns(oExcelTableReader, oRow, oEdge, oColumnNamesToExclude); continue; } if (eVisibility == Visibility.Hide) { // Hide the edge and continue to the next edge. oEdge.SetValue(ReservedMetadataKeys.Visibility, VisibilityKeyValue.Hidden); continue; } // Alpha. Boolean bAlphaIsZero = ReadAlpha(oRow, oEdge); if (bAlphaIsZero) { continue; } // Color. ReadColor(oRow, EdgeTableColumnNames.Color, oEdge, ReservedMetadataKeys.PerColor, oReadWorkbookContext.ColorConverter2); // Width. ReadWidth(oRow, oReadWorkbookContext.EdgeWidthConverter, oEdge); // Style. ReadStyle(oRow, oReadWorkbookContext.EdgeStyleConverter, oEdge); // Label. if (oReadWorkbookContext.ReadEdgeLabels) { ReadCellAndSetMetadata(oRow, EdgeTableColumnNames.Label, oEdge, ReservedMetadataKeys.PerEdgeLabel); ReadColor(oRow, EdgeTableColumnNames.LabelTextColor, oEdge, ReservedMetadataKeys.PerEdgeLabelTextColor, oReadWorkbookContext.ColorConverter2); ReadLabelFontSize(oRow, oReadWorkbookContext.FontSizeConverter, oEdge); } // Weight. if (oReadWorkbookContext.ReadEdgeWeights) { ReadEdgeWeight(oRow, oEdge); } } if (bReadAllEdgeAndVertexColumns) { // Store the edge column names on the graph. oGraph.SetValue( ReservedMetadataKeys.AllEdgeMetadataKeys, FilterColumnNames(oExcelTableReader, oColumnNamesToExclude) ); } }
GetGraphML ( Microsoft.Office.Interop.Excel.Workbook oWorkbook ) { Debug.Assert(oWorkbook != null); String sGraphML = null; // The graph owned by the NodeXLControl can't be used, because it // doesn't include all the edge and vertex column data needed for // GraphML. Instead, read the graph from the workbook and include all // the necessary data. ReadWorkbookContext oReadWorkbookContext = new ReadWorkbookContext(); oReadWorkbookContext.ReadAllEdgeAndVertexColumns = true; WorkbookReader oWorkbookReader = new WorkbookReader(); IGraph oGraphForGraphML = oWorkbookReader.ReadWorkbook( oWorkbook, oReadWorkbookContext); GraphMLGraphAdapter oGraphMLGraphAdapter = new GraphMLGraphAdapter(); using ( MemoryStream oMemoryStream = new MemoryStream() ) { oGraphMLGraphAdapter.SaveGraph(oGraphForGraphML, oMemoryStream); oMemoryStream.Position = 0; using ( StreamReader oStreamReader = new StreamReader(oMemoryStream) ) { sGraphML = oStreamReader.ReadToEnd(); } } return (sGraphML); }
ReadWorksheet ( Microsoft.Office.Interop.Excel.Workbook workbook, ReadWorkbookContext readWorkbookContext, IGraph graph ) { Debug.Assert(workbook != null); Debug.Assert(readWorkbookContext != null); Debug.Assert(graph != null); AssertValid(); // Attempt to get the optional tables that contain group data. ListObject oGroupTable, oGroupVertexTable; if ( ExcelTableUtil.TryGetTable(workbook, WorksheetNames.Groups, TableNames.Groups, out oGroupTable) && ExcelTableUtil.TryGetTable(workbook, WorksheetNames.GroupVertices, TableNames.GroupVertices, out oGroupVertexTable) ) { // The code that reads the tables can handle hidden rows, but not // hidden columns. Temporarily show all hidden columns in the // table. ExcelHiddenColumns oHiddenGroupColumns = ExcelColumnHider.ShowHiddenColumns(oGroupTable); ExcelHiddenColumns oHiddenGroupVertexColumns = ExcelColumnHider.ShowHiddenColumns(oGroupVertexTable); try { ReadGroupTables(oGroupTable, oGroupVertexTable, readWorkbookContext, graph); } finally { ExcelColumnHider.RestoreHiddenColumns(oGroupTable, oHiddenGroupColumns); ExcelColumnHider.RestoreHiddenColumns(oGroupVertexTable, oHiddenGroupVertexColumns); } } }
ExportToNewMatrixWorkbook() { AssertValid(); // Merge duplicate edges and add an edge weight column. ( new DuplicateEdgeMerger() ).MergeDuplicateEdges(m_oWorkbookToExport); // Read the workbook, including the edge weight column. ReadWorkbookContext oReadWorkbookContext = new ReadWorkbookContext(); oReadWorkbookContext.ReadEdgeWeights = true; IGraph oGraph = ( new WorkbookReader() ).ReadWorkbook( m_oWorkbookToExport, oReadWorkbookContext); IVertexCollection oVertices = oGraph.Vertices; Int32 iVertices = oVertices.Count; if (iVertices == 0) { throw new ExportWorkbookException( "There are no vertices to export." ); } Workbook oNewWorkbook = m_oWorkbookToExport.Application.Workbooks.Add(Missing.Value); Worksheet oNewWorksheet = (Worksheet)oNewWorkbook.ActiveSheet; // Fill in row 1 and column A with the vertex names, starting at B1 and // A2, respectively. String [,] asVertexNamesForRow1 = ExcelUtil.GetSingleRow2DStringArray( iVertices); String [,] asVertexNamesForColumnA = ExcelUtil.GetSingleColumn2DStringArray(iVertices); Int32 i = 0; foreach (IVertex oVertexI in oVertices) { asVertexNamesForRow1[1, i + 1] = asVertexNamesForColumnA[i + 1, 1] = oVertexI.Name; i++; } ExcelUtil.SetRangeValues( (Range)oNewWorksheet.Cells[1, 2], asVertexNamesForRow1 ); ExcelUtil.SetRangeValues( (Range)oNewWorksheet.Cells[2, 1], asVertexNamesForColumnA ); asVertexNamesForRow1 = asVertexNamesForColumnA = null; // Now fill in the edge weights, row by row. Range oFirstColumnCell = (Range)oNewWorksheet.Cells[2, 2]; foreach (IVertex oVertexI in oVertices) { Object [,] aoEdgeWeights = ExcelUtil.GetSingleRow2DArray(iVertices); Int32 j = 0; foreach (IVertex oVertexJ in oVertices) { aoEdgeWeights[1, j + 1] = EdgeUtil.GetEdgeWeightSum(oVertexI, oVertexJ); j++; } ExcelUtil.SetRangeValues(oFirstColumnCell, aoEdgeWeights); oFirstColumnCell = oFirstColumnCell.get_Offset(1, 0); } return (oNewWorkbook); }
AddEdgeColorAttributesToDConnectorMotif ( ExcelTemplateGroupInfo oGroup, Boolean bEdgeColorColumnAutoFilled, AutoFillColorColumnResults oEdgeColorResults, ColorColumnAutoFillUserSettings oEdgeColorDetails, Dictionary<Int32, Object> oEdgeColorSourceDictionary, ReadWorkbookContext oReadWorkbookContext, CollapsedGroupAttributes oCollapsedGroupAttributes, Int32 iAnchorVertices ) { Debug.Assert(oGroup != null); Debug.Assert(oEdgeColorResults != null); Debug.Assert(oReadWorkbookContext != null); Debug.Assert(oCollapsedGroupAttributes != null); Debug.Assert(iAnchorVertices >= 0); // If the edge color column was autofilled, get the average color for // the edges incident to the D-connector motif's first anchor, then its // second anchor, and so on. Otherwise, don't do anything. if (!bEdgeColorColumnAutoFilled) { return; } for (Int32 iAnchorVertexIndex = 0; iAnchorVertexIndex < iAnchorVertices; iAnchorVertexIndex++) { Color oAverageColor; if ( TableColumnMapper.TryMapAverageColor( GetRowIDsToAverageForEdges(oGroup, oCollapsedGroupAttributes, iAnchorVertexIndex), oEdgeColorSourceDictionary, oEdgeColorResults.SourceCalculationNumber1, oEdgeColorResults.SourceCalculationNumber2, oEdgeColorResults.DestinationColor1, oEdgeColorResults.DestinationColor2, oEdgeColorDetails.UseLogs, out oAverageColor) ) { oCollapsedGroupAttributes.Add( CollapsedGroupAttributeKeys.GetAnchorVertexEdgeColorKey( iAnchorVertexIndex), oReadWorkbookContext.ColorConverter2.GraphToWorkbook( oAverageColor) ); } } }
ExportToNewMatrixWorkbook() { AssertValid(); // Merge duplicate edges and add an edge weight column. (new DuplicateEdgeMerger()).MergeDuplicateEdges(m_oWorkbookToExport); // Read the workbook, including the edge weight column. ReadWorkbookContext oReadWorkbookContext = new ReadWorkbookContext(); oReadWorkbookContext.ReadEdgeWeights = true; IGraph oGraph = (new WorkbookReader()).ReadWorkbook( m_oWorkbookToExport, oReadWorkbookContext); IVertexCollection oVertices = oGraph.Vertices; Int32 iVertices = oVertices.Count; if (iVertices == 0) { throw new ExportWorkbookException( "There are no vertices to export." ); } Workbook oNewWorkbook = m_oWorkbookToExport.Application.Workbooks.Add(Missing.Value); Worksheet oNewWorksheet = (Worksheet)oNewWorkbook.ActiveSheet; // Fill in row 1 and column A with the vertex names, starting at B1 and // A2, respectively. String [,] asVertexNamesForRow1 = ExcelUtil.GetSingleRow2DStringArray( iVertices); String [,] asVertexNamesForColumnA = ExcelUtil.GetSingleColumn2DStringArray(iVertices); Int32 i = 0; foreach (IVertex oVertexI in oVertices) { asVertexNamesForRow1[1, i + 1] = asVertexNamesForColumnA[i + 1, 1] = oVertexI.Name; i++; } ExcelUtil.SetRangeValues((Range)oNewWorksheet.Cells[1, 2], asVertexNamesForRow1); ExcelUtil.SetRangeValues((Range)oNewWorksheet.Cells[2, 1], asVertexNamesForColumnA); asVertexNamesForRow1 = asVertexNamesForColumnA = null; // Now fill in the edge weights, row by row. Range oFirstColumnCell = (Range)oNewWorksheet.Cells[2, 2]; foreach (IVertex oVertexI in oVertices) { Object [,] aoEdgeWeights = ExcelUtil.GetSingleRow2DArray(iVertices); Int32 j = 0; foreach (IVertex oVertexJ in oVertices) { aoEdgeWeights[1, j + 1] = EdgeUtil.GetEdgeWeightSum(oVertexI, oVertexJ); j++; } ExcelUtil.SetRangeValues(oFirstColumnCell, aoEdgeWeights); oFirstColumnCell = oFirstColumnCell.get_Offset(1, 0); } return(oNewWorkbook); }
ReadWorkbook ( Microsoft.Office.Interop.Excel.Workbook oWorkbook, IGraphMetricCalculator2 [] oGraphMetricCalculators ) { Debug.Assert(oWorkbook != null); Debug.Assert(oGraphMetricCalculators != null); AssertValid(); ReadWorkbookContext oReadWorkbookContext = new ReadWorkbookContext(); oReadWorkbookContext.FillIDColumns = true; oReadWorkbookContext.PopulateVertexWorksheet = true; oReadWorkbookContext.ReadGroups = true; // Some of the graph metric calculators, such as // TopItemsCalculatorBase2, need to rank vertices or edges by values in // a specified column. Make those values available on the graph. oReadWorkbookContext.ReadAllEdgeAndVertexColumns = true; WorkbookReader oWorkbookReader = new WorkbookReader(); return ( oWorkbookReader.ReadWorkbook( oWorkbook, oReadWorkbookContext) ); }
ReadWorksheet ( Microsoft.Office.Interop.Excel.Workbook workbook, ReadWorkbookContext readWorkbookContext, IGraph graph ) { Debug.Assert(workbook != null); Debug.Assert(readWorkbookContext != null); Debug.Assert(graph != null); AssertValid(); // Attempt to get the optional table that contains vertex data. ListObject oVertexTable; if (ExcelTableUtil.TryGetTable(workbook, WorksheetNames.Vertices, TableNames.Vertices, out oVertexTable)) { // The code that reads the table can handle hidden rows, but not // hidden columns. Temporarily show all hidden columns in the // table. ExcelHiddenColumns oHiddenColumns = ExcelColumnHider.ShowHiddenColumns(oVertexTable); Boolean bLayoutAndZOrderSet; try { ReadVertexTable(oVertexTable, readWorkbookContext, graph, out bLayoutAndZOrderSet); RemoveUnwantedIsolates(readWorkbookContext, graph); } finally { ExcelColumnHider.RestoreHiddenColumns(oVertexTable, oHiddenColumns); } if (bLayoutAndZOrderSet) { // The layout and z-orders were specified for at least one // vertex. The ByMetadataVertexSorter used by // SortableLayoutBase and GraphDrawer requires that if an order // is set on one vertex, it must be set on all vertices. This // isn't required in the Excel template, though, so set a // default order for each vertex that doesn't already specify // one. SetUnspecifiedVertexLayoutAndZOrders(graph); // The layout and z-orders are ignored unless this key is added // to the graph. graph.SetValue( ReservedMetadataKeys.SortableLayoutAndZOrderSet, null); } } }
ReadGroupTables ( ListObject oGroupTable, ListObject oGroupVertexTable, ReadWorkbookContext oReadWorkbookContext, IGraph oGraph ) { Debug.Assert(oGroupTable != null); Debug.Assert(oGroupVertexTable != null); Debug.Assert(oReadWorkbookContext != null); Debug.Assert(oGraph != null); AssertValid(); // If a required column is missing, do nothing. ListColumn oColumn; if ( !ExcelTableUtil.TryGetTableColumn(oGroupTable, GroupTableColumnNames.Name, out oColumn) || !ExcelTableUtil.TryGetTableColumn(oGroupTable, GroupTableColumnNames.VertexColor, out oColumn) || !ExcelTableUtil.TryGetTableColumn(oGroupTable, GroupTableColumnNames.VertexShape, out oColumn) || !ExcelTableUtil.TryGetTableColumn(oGroupVertexTable, GroupVertexTableColumnNames.GroupName, out oColumn) || !ExcelTableUtil.TryGetTableColumn(oGroupVertexTable, GroupVertexTableColumnNames.VertexName, out oColumn) ) { return; } // These are the names of the groups that should be skipped or hidden. HashSet <String> oSkippedGroupNames = new HashSet <String>(); HashSet <String> oHiddenGroupNames = new HashSet <String>(); // Create a dictionary from the group table. The key is the group name // and the value is an ExcelTemplateGroupInfo object for the group. Dictionary <String, ExcelTemplateGroupInfo> oGroupNameDictionary = ReadGroupTable(oGroupTable, oReadWorkbookContext, oSkippedGroupNames, oHiddenGroupNames); // Read the group vertex table and set the color and shape of each // group vertex in the graph. ReadGroupVertexTable(oGroupVertexTable, oReadWorkbookContext, oGroupNameDictionary, oGraph); // Now that the groups and the vertices they contain are known, skip // and hide those groups that should be skipped or hidden. SkipAndHideGroups(oReadWorkbookContext, oGroupNameDictionary, oSkippedGroupNames, oHiddenGroupNames, oGraph); if (oGroupNameDictionary.Count > 0) { // Save the group information on the graph. Debug.Assert(oGroupNameDictionary.Values is ICollection <ExcelTemplateGroupInfo>); oGraph.SetValue(ReservedMetadataKeys.GroupInfo, oGroupNameDictionary.Values.ToArray()); } }
ReadVertexTable ( ListObject oVertexTable, ReadWorkbookContext oReadWorkbookContext, IGraph oGraph, out Boolean bLayoutAndZOrderSet ) { Debug.Assert(oVertexTable != null); Debug.Assert(oReadWorkbookContext != null); Debug.Assert(oGraph != null); AssertValid(); bLayoutAndZOrderSet = false; if (GetTableColumnIndex(oVertexTable, VertexTableColumnNames.VertexName, false) == NoSuchColumn) { // Nothing can be done without vertex names. return; } Boolean bReadAllEdgeAndVertexColumns = oReadWorkbookContext.ReadAllEdgeAndVertexColumns; if (oReadWorkbookContext.FillIDColumns) { FillIDColumn(oVertexTable); } // Get the names of all the column pairs that are used to add custom // menu items to the vertex context menu in the graph. TableColumnAdder oTableColumnAdder = new TableColumnAdder(); ICollection <KeyValuePair <String, String> > aoCustomMenuItemPairNames = oTableColumnAdder.GetColumnPairNames(oVertexTable, VertexTableColumnNames.CustomMenuItemTextBase, VertexTableColumnNames.CustomMenuItemActionBase); IVertexCollection oVertices = oGraph.Vertices; Dictionary <String, IVertex> oVertexNameDictionary = oReadWorkbookContext.VertexNameDictionary; Dictionary <Int32, IIdentityProvider> oEdgeRowIDDictionary = oReadWorkbookContext.EdgeRowIDDictionary; BooleanConverter oBooleanConverter = oReadWorkbookContext.BooleanConverter; VertexVisibilityConverter oVertexVisibilityConverter = new VertexVisibilityConverter(); VertexLabelPositionConverter oVertexLabelPositionConverter = new VertexLabelPositionConverter(); ExcelTableReader oExcelTableReader = new ExcelTableReader(oVertexTable); HashSet <String> oColumnNamesToExclude = new HashSet <String>( new String[] { VertexTableColumnNames.VertexName }); foreach (ExcelTableReader.ExcelTableRow oRow in oExcelTableReader.GetRows()) { // Get the name of the vertex. String sVertexName; if (!oRow.TryGetNonEmptyStringFromCell( VertexTableColumnNames.VertexName, out sVertexName)) { continue; } // If the vertex was added to the graph as part of an edge, // retrieve the vertex. IVertex oVertex; if (!oVertexNameDictionary.TryGetValue(sVertexName, out oVertex)) { oVertex = null; } // Assume a default visibility. Visibility eVisibility = Visibility.ShowIfInAnEdge; String sVisibility; if (oRow.TryGetNonEmptyStringFromCell( CommonTableColumnNames.Visibility, out sVisibility)) { if (!oVertexVisibilityConverter.TryWorkbookToGraph( sVisibility, out eVisibility)) { OnInvalidVisibility(oRow); } } switch (eVisibility) { case Visibility.ShowIfInAnEdge: // If the vertex is part of an edge, show it using the // specified vertex attributes. Otherwise, skip the vertex // row. if (oVertex == null) { continue; } break; case Visibility.Skip: // Skip the vertex row and any edge rows that include the // vertex. Do not read them into the graph. if (oVertex != null) { // Remove the vertex and its incident edges from the // graph and dictionaries. RemoveVertex(oVertex, oReadWorkbookContext, oGraph); } continue; case Visibility.Hide: // If the vertex is part of an edge, hide it and its // incident edges. Otherwise, skip the vertex row. if (oVertex == null) { continue; } HideVertex(oVertex); break; case Visibility.Show: // Show the vertex using the specified attributes // regardless of whether it is part of an edge. if (oVertex == null) { oVertex = CreateVertex(sVertexName, oVertices, oVertexNameDictionary); } oVertex.SetValue( ReservedMetadataKeys.VertexHasVisibilityOfShow, null); break; default: Debug.Assert(false); break; } Debug.Assert(oVertex != null); // If ReadWorkbookContext.FillIDColumns is true, add the vertex to // the vertex row ID dictionary and set the vertex's Tag to the row // ID. oReadWorkbookContext.AddToRowIDDictionary(oRow, oVertex, false); if (bReadAllEdgeAndVertexColumns) { // All columns except the vertex name should be read and stored // as metadata on the vertex. ReadAllColumns(oExcelTableReader, oRow, oVertex, oColumnNamesToExclude); continue; } // Layout and z-order. if (ReadLayoutAndZOrder(oRow, oVertex)) { bLayoutAndZOrderSet = true; } // Location and Locked. if (!oReadWorkbookContext.IgnoreVertexLocations) { System.Drawing.PointF oLocation; Boolean bLocationSpecified = TryGetLocation(oRow, VertexTableColumnNames.X, VertexTableColumnNames.Y, oReadWorkbookContext.VertexLocationConverter, out oLocation); if (bLocationSpecified) { oVertex.Location = oLocation; } ReadLocked(oRow, oBooleanConverter, bLocationSpecified, oVertex); } // Polar coordinates. ReadPolarCoordinates(oRow, oVertex); // Marked. ReadMarked(oRow, oBooleanConverter, oVertex); // Custom menu items. if (aoCustomMenuItemPairNames.Count > 0) { ReadCustomMenuItems(oRow, aoCustomMenuItemPairNames, oVertex); } // Alpha. ReadAlpha(oRow, oVertex); // Tooltip. ReadCellAndSetMetadata(oRow, VertexTableColumnNames.ToolTip, oVertex, ReservedMetadataKeys.PerVertexToolTip); // Label. if (oReadWorkbookContext.ReadVertexLabels) { ReadCellAndSetMetadata(oRow, VertexTableColumnNames.Label, oVertex, ReservedMetadataKeys.PerVertexLabel); } // Label fill color. ReadColor(oRow, VertexTableColumnNames.LabelFillColor, oVertex, ReservedMetadataKeys.PerVertexLabelFillColor, oReadWorkbookContext.ColorConverter2); // Label position. ReadLabelPosition(oRow, oVertexLabelPositionConverter, oVertex); // Radius. Nullable <Single> oRadiusWorkbook = new Nullable <Single>(); oRadiusWorkbook = ReadRadius(oRow, oReadWorkbookContext.VertexRadiusConverter, oVertex); // Shape. VertexShape eVertexShape; if (!ReadShape(oRow, oVertex, out eVertexShape)) { eVertexShape = oReadWorkbookContext.DefaultVertexShape; } // Label font size. if (eVertexShape == VertexShape.Label && oRadiusWorkbook.HasValue) { // The vertex radius is used to specify font size when the // shape is Label. oVertex.SetValue(ReservedMetadataKeys.PerVertexLabelFontSize, oReadWorkbookContext.VertexRadiusConverter. WorkbookToLabelFontSize(oRadiusWorkbook.Value)); } // Image URI. if (eVertexShape == VertexShape.Image && oReadWorkbookContext.ReadVertexImages) { ReadImageUri(oRow, oVertex, oReadWorkbookContext.VertexRadiusConverter, oRadiusWorkbook.HasValue ? oRadiusWorkbook : oReadWorkbookContext.DefaultVertexImageSize ); } // Color ReadColor(oRow, VertexTableColumnNames.Color, oVertex, ReservedMetadataKeys.PerColor, oReadWorkbookContext.ColorConverter2); } if (bReadAllEdgeAndVertexColumns) { // Store the vertex column names on the graph. oGraph.SetValue(ReservedMetadataKeys.AllVertexMetadataKeys, FilterColumnNames(oExcelTableReader, oColumnNamesToExclude)); } }
ReadWorkbookInternal ( Microsoft.Office.Interop.Excel.Workbook workbook, ReadWorkbookContext readWorkbookContext ) { Debug.Assert(readWorkbookContext != null); Debug.Assert(workbook != null); AssertValid(); if (readWorkbookContext.PopulateVertexWorksheet) { // Create and use the object that fills in the vertex worksheet. VertexWorksheetPopulator oVertexWorksheetPopulator = new VertexWorksheetPopulator(); try { oVertexWorksheetPopulator.PopulateVertexWorksheet( workbook, false); } catch (WorkbookFormatException) { // Ignore this type of error, which occurs when the vertex // worksheet is missing, for example. } } // Create a graph with the appropriate directedness. PerWorkbookSettings oPerWorkbookSettings = new PerWorkbookSettings(workbook); IGraph oGraph = new Graph(oPerWorkbookSettings.GraphDirectedness); // Read the edge worksheet. This adds data to oGraph, // ReadWorkbookContext.VertexNameDictionary, and // ReadWorkbookContext.EdgeIDDictionary. EdgeWorksheetReader oEdgeWorksheetReader = new EdgeWorksheetReader(); oEdgeWorksheetReader.ReadWorksheet(workbook, readWorkbookContext, oGraph); oEdgeWorksheetReader = null; // Read the vertex worksheet. This adds metadata to the vertices in // oGraph; adds any isolated vertices to oGraph and // ReadWorkbookContext.VertexNameDictionary; and removes any skipped // vertices (and their incident edges) from // ReadWorkbookContext.VertexNameDictionary, // ReadWorkbookContext.EdgeIDDictionary, and oGraph. VertexWorksheetReader oVertexWorksheetReader = new VertexWorksheetReader(); oVertexWorksheetReader.ReadWorksheet(workbook, readWorkbookContext, oGraph); oVertexWorksheetReader = null; if (readWorkbookContext.ReadGroups) { // Read the group worksheets. This adds metadata to the vertices // in oGraph and to oGraph itself. GroupWorksheetReader oGroupWorksheetReader = new GroupWorksheetReader(); oGroupWorksheetReader.ReadWorksheet(workbook, readWorkbookContext, oGraph); oGroupWorksheetReader = null; // Add to the graph any collapsed group attributes that can only be // added after the workbook is read. CollapsedGroupAttributeAdder.AddCollapsedGroupAttributes( workbook, readWorkbookContext, oGraph); } return (oGraph); }