ImportWorkbookIntoGraph ( Worksheet oSourceWorksheet, Range oNonEmptySourceRange, Int32 iColumnNumberToUseForVertex1OneBased, Int32 iColumnNumberToUseForVertex2OneBased, ICollection<Int32> oEdgeColumnNumbersToImportOneBased, ICollection<Int32> oVertex1ColumnNumbersToImportOneBased, ICollection<Int32> oVertex2ColumnNumbersToImportOneBased, Boolean bSourceColumnsHaveHeaders ) { Debug.Assert(oSourceWorksheet != null); Debug.Assert(oNonEmptySourceRange != null); Debug.Assert(iColumnNumberToUseForVertex1OneBased >= 1); Debug.Assert(iColumnNumberToUseForVertex2OneBased >= 1); Debug.Assert(oEdgeColumnNumbersToImportOneBased != null); Debug.Assert(oVertex1ColumnNumbersToImportOneBased != null); Debug.Assert(oVertex2ColumnNumbersToImportOneBased != null); AssertValid(); String [] asWorkbookColumnNames = GetWorkbookColumnNames( oSourceWorksheet, oNonEmptySourceRange, bSourceColumnsHaveHeaders); Int32 iColumns = oNonEmptySourceRange.Columns.Count; Int32 iFirstNonEmptyColumnOneBased = oNonEmptySourceRange.Columns.Column; if (bSourceColumnsHaveHeaders) { // Skip the header row. if (oNonEmptySourceRange.Rows.Count < 2) { OnInvalidSourceWorkbook( "If the columns in the other workbook have headers, then" + " there must be at least two rows.", oSourceWorksheet, 1, 1 ); } ExcelUtil.OffsetRange(ref oNonEmptySourceRange, 1, 0); ExcelUtil.ResizeRange(ref oNonEmptySourceRange, oNonEmptySourceRange.Rows.Count - 1, iColumns); } IGraph oGraph = new Graph(GraphDirectedness.Undirected); IVertexCollection oVertices = oGraph.Vertices; IEdgeCollection oEdges = oGraph.Edges; // The key is a vertex name and the value is the corresponding IVertex // object. Dictionary<String, IVertex> oVertexNameDictionary = new Dictionary<String, IVertex>(); foreach ( Range oSubrange in ExcelRangeSplitter.SplitRange(oNonEmptySourceRange, 500) ) { Object [,] oSubrangeValues = ExcelUtil.GetRangeValues(oSubrange); Int32 iSubrangeRows = oSubrangeValues.GetUpperBound(0); for (Int32 iRowOneBased = 1; iRowOneBased <= iSubrangeRows; iRowOneBased++) { String sVertex1Name, sVertex2Name; if ( !ExcelUtil.TryGetNonEmptyStringFromCell(oSubrangeValues, iRowOneBased, iColumnNumberToUseForVertex1OneBased - iFirstNonEmptyColumnOneBased + 1, out sVertex1Name) || !ExcelUtil.TryGetNonEmptyStringFromCell(oSubrangeValues, iRowOneBased, iColumnNumberToUseForVertex2OneBased - iFirstNonEmptyColumnOneBased + 1, out sVertex2Name) ) { continue; } IVertex oVertex1 = WorksheetReaderBase.VertexNameToVertex( sVertex1Name, oVertices, oVertexNameDictionary); IVertex oVertex2 = WorksheetReaderBase.VertexNameToVertex( sVertex2Name, oVertices, oVertexNameDictionary); IEdge oEdge = oEdges.Add(oVertex1, oVertex2); // Add the edge and vertex attributes. AddAttributeValuesToEdgeOrVertex(asWorkbookColumnNames, oSubrangeValues, iRowOneBased, iFirstNonEmptyColumnOneBased, oEdgeColumnNumbersToImportOneBased, oEdge); AddAttributeValuesToEdgeOrVertex(asWorkbookColumnNames, oSubrangeValues, iRowOneBased, iFirstNonEmptyColumnOneBased, oVertex1ColumnNumbersToImportOneBased, oVertex1); AddAttributeValuesToEdgeOrVertex(asWorkbookColumnNames, oSubrangeValues, iRowOneBased, iFirstNonEmptyColumnOneBased, oVertex2ColumnNumbersToImportOneBased, oVertex2); } } // Store metadata on the graph indicating the sets of keys that may be // present on the graph's edges and vertices. oGraph.SetValue(ReservedMetadataKeys.AllEdgeMetadataKeys, GetColumnNamesToImport(oNonEmptySourceRange, asWorkbookColumnNames, oEdgeColumnNumbersToImportOneBased) ); List<Int32> oVertexColumnNumbersToImportOneBased = new List<Int32>(); oVertexColumnNumbersToImportOneBased.AddRange( oVertex1ColumnNumbersToImportOneBased); oVertexColumnNumbersToImportOneBased.AddRange( oVertex2ColumnNumbersToImportOneBased); oGraph.SetValue( ReservedMetadataKeys.AllVertexMetadataKeys, GetColumnNamesToImport(oNonEmptySourceRange, asWorkbookColumnNames, oVertexColumnNumbersToImportOneBased) ); return (oGraph); }
TestTryGetGroupLayoutDrawingInfo() { // Graph has group drawing information. const Double GroupRectanglePenWidth = 4.567; const IntergroupEdgeStyle IntergroupEdgeStyle = IntergroupEdgeStyle.Show; IGraph oGraph = new Graph(); oGraph.SetValue(ReservedMetadataKeys.GroupLayoutDrawingInfo, new GroupLayoutDrawingInfo( new GroupInfo[] { new GroupInfo(), new GroupInfo() }, GroupRectanglePenWidth, null ) ); GroupLayoutDrawingInfo oGroupLayoutDrawingInfo; Assert.IsTrue( GroupMetadataManager.TryGetGroupLayoutDrawingInfo( oGraph, out oGroupLayoutDrawingInfo) ); Assert.AreEqual(2, oGroupLayoutDrawingInfo.GroupsToDraw.Count); Assert.AreEqual(GroupRectanglePenWidth, oGroupLayoutDrawingInfo.PenWidth); Assert.IsNull(oGroupLayoutDrawingInfo.CombinedIntergroupEdges); }
TestTryTransformGroupRectangles() { // Graph has group drawing information. const Double GroupRectanglePenWidth = 4.567; IGraph oGraph = new Graph(); GroupInfo oGroupInfo1 = new GroupInfo(); oGroupInfo1.Rectangle = Rectangle.FromLTRB(0, 0, 1, 2); GroupInfo oGroupInfo2 = new GroupInfo(); oGroupInfo2.Rectangle = Rectangle.FromLTRB(0, 0, 3, 4); oGraph.SetValue(ReservedMetadataKeys.GroupLayoutDrawingInfo, new GroupLayoutDrawingInfo( new GroupInfo[] {oGroupInfo1, oGroupInfo2}, GroupRectanglePenWidth, null ) ); GroupMetadataManager.TransformGroupRectangles(oGraph, new LayoutContext( Rectangle.FromLTRB(0, 0, 10, 20) ), new LayoutContext( Rectangle.FromLTRB(0, 0, 20, 60) ) ); GroupLayoutDrawingInfo oGroupLayoutDrawingInfo; Assert.IsTrue( GroupMetadataManager.TryGetGroupLayoutDrawingInfo( oGraph, out oGroupLayoutDrawingInfo) ); Assert.AreEqual(2, oGroupLayoutDrawingInfo.GroupsToDraw.Count); Assert.AreEqual(Rectangle.FromLTRB(0, 0, 2, 6), oGroupLayoutDrawingInfo.GroupsToDraw[0].Rectangle); Assert.AreEqual(Rectangle.FromLTRB(0, 0, 6, 12), oGroupLayoutDrawingInfo.GroupsToDraw[1].Rectangle); }
TestSaveGraph() { // Directed and undirected graphs. foreach (Boolean bDirected in TestGraphUtil.AllBoolean) { IGraph oGraph = new Graph(bDirected ? GraphDirectedness.Directed : GraphDirectedness.Undirected); IVertexCollection oVertices = oGraph.Vertices; IEdgeCollection oEdges = oGraph.Edges; IVertex oVertex1 = oVertices.Add(); oVertex1.Name = "Vertex1"; oVertex1.SetValue("VertexAttribute1", 123); // Int32 IVertex oVertex2 = oVertices.Add(); oVertex2.Name = "Vertex2"; oVertex2.SetValue("VertexAttribute2", "abc"); // String IVertex oVertex3 = oVertices.Add(); oVertex3.Name = "Vertex3"; oVertex3.SetValue("VertexAttribute1", 4.0); // Double oVertex3.SetValue("VertexAttribute2", 23456.0F); // Single IVertex oVertex4 = oVertices.Add(); oVertex4.Name = "Vertex4"; IVertex oVertex5 = oVertices.Add(); oVertex5.Name = "Vertex5"; IEdge oEdge; oEdge = oEdges.Add(oVertex1, oVertex2, bDirected); oEdge.SetValue("EdgeAttribute1", "ea1"); oEdge = oEdges.Add(oVertex3, oVertex4, bDirected); oEdge.SetValue("EdgeAttribute2", "ea2"); oGraph.SetValue( ReservedMetadataKeys.AllVertexMetadataKeys, new String [] { "VertexAttribute1", "VertexAttribute2", } ); oGraph.SetValue(ReservedMetadataKeys.AllEdgeMetadataKeys, new String [] { "EdgeAttribute1", "EdgeAttribute2", } ); m_oGraphAdapter.SaveGraph(oGraph, m_sTempFileName); String sFileContents = FileUtil.ReadTextFile(m_sTempFileName); XmlDocument oXmlDocument = new XmlDocument(); oXmlDocument.LoadXml(sFileContents); XmlNamespaceManager oXmlNamespaceManager = new XmlNamespaceManager( oXmlDocument.NameTable); oXmlNamespaceManager.AddNamespace("g", GraphMLGraphAdapter.GraphMLNamespaceUri); String [] asRequiredXPaths = new String [] { // Graph node. String.Format("/g:graphml/g:graph[@edgedefault='{0}']", bDirected ? "directed" : "undirected"), "/g:graphml/g:key[@id='V-VertexAttribute1' and @for='node'" + " and @attr.name='VertexAttribute1'" + " and @attr.type='string']", // Vertex nodes. "/g:graphml/g:key[@id='V-VertexAttribute2' and @for='node'" + " and @attr.name='VertexAttribute2'" + " and @attr.type='string']", "/g:graphml/g:key[@id='E-EdgeAttribute1' and @for='edge'" + " and @attr.name='EdgeAttribute1'" + " and @attr.type='string']", "/g:graphml/g:key[@id='E-EdgeAttribute2' and @for='edge'" + " and @attr.name='EdgeAttribute2'" + " and @attr.type='string']", "/g:graphml/g:graph/g:node[@id='Vertex1']/" + "g:data[@key='V-VertexAttribute1' and .='123']", "/g:graphml/g:graph/g:node[@id='Vertex2']/" + "g:data[@key='V-VertexAttribute2' and .='abc']", "/g:graphml/g:graph/g:node[@id='Vertex3']/" + "g:data[@key='V-VertexAttribute1' and .='4']", "/g:graphml/g:graph/g:node[@id='Vertex3']/" + "g:data[@key='V-VertexAttribute2' and .='23456']", "/g:graphml/g:graph/g:node[@id='Vertex4']", "/g:graphml/g:graph/g:node[@id='Vertex5']", // Edge nodes. "/g:graphml/g:graph/g:edge[@source='Vertex1' and" + " @target='Vertex2']/" + "g:data[@key='E-EdgeAttribute1' and .='ea1']", "/g:graphml/g:graph/g:edge[@source='Vertex3' and" + " @target='Vertex4']/" + "g:data[@key='E-EdgeAttribute2' and .='ea2']", }; foreach (String sRequiredXPath in asRequiredXPaths) { XmlNode oXmlNode = oXmlDocument.SelectSingleNode( sRequiredXPath, oXmlNamespaceManager); Assert.IsNotNull(oXmlNode); } } }