TestIsParallelTo ( GraphDirectedness eDirectedness, Int32 iEdge1Vertex1, Int32 iEdge1Vertex2, Boolean bEdge1IsDirected, Int32 iEdge2Vertex1, Int32 iEdge2Vertex2, Boolean bEdge2IsDirected, Boolean bExpectedEdge1IsParallelToEdge2 ) { const Int32 Vertices = 100; CreateGraph(eDirectedness, Vertices); IVertex oEdge1Vertex1 = m_aoVertices[iEdge1Vertex1]; IVertex oEdge1Vertex2 = m_aoVertices[iEdge1Vertex2]; IVertex oEdge2Vertex1 = m_aoVertices[iEdge2Vertex1]; IVertex oEdge2Vertex2 = m_aoVertices[iEdge2Vertex2]; IEdge oEdge1 = CreateEdge(oEdge1Vertex1, oEdge1Vertex2, bEdge1IsDirected); IEdge oEdge2 = CreateEdge(oEdge2Vertex1, oEdge2Vertex2, bEdge2IsDirected); IEdgeCollection oEdgeCollection = m_oGraph.Edges; oEdgeCollection.Add(oEdge1); oEdgeCollection.Add(oEdge2); Boolean bActualEdge1IsParallelToEdge2 = oEdge1.IsParallelTo(oEdge2); Assert.AreEqual( bExpectedEdge1IsParallelToEdge2, bActualEdge1IsParallelToEdge2); Boolean bActualEdge2IsParallelToEdge1 = oEdge2.IsParallelTo(oEdge1); Assert.AreEqual( bExpectedEdge1IsParallelToEdge2, bActualEdge2IsParallelToEdge1); Boolean bActualEdge1IsAntiparallelToEdge2 = oEdge1.IsAntiparallelTo(oEdge2); Assert.AreEqual( !bExpectedEdge1IsParallelToEdge2, bActualEdge1IsAntiparallelToEdge2 ); Boolean bActualEdge2IsAntiparallelToEdge1 = oEdge2.IsAntiparallelTo(oEdge1); Assert.AreEqual( !bExpectedEdge1IsParallelToEdge2, bActualEdge2IsAntiparallelToEdge1 ); }
TestGraphContainsDuplicateEdges13() { // Undirected graph, many duplicates. m_oDuplicateEdgeDetector = new DuplicateEdgeDetector(m_oUndirectedGraph); IEdgeCollection oEdges = m_oUndirectedGraph.Edges; oEdges.Add(m_oUndirectedVertexB, m_oUndirectedVertexA, false); oEdges.Add(m_oUndirectedVertexC, m_oUndirectedVertexD, false); oEdges.Add(m_oUndirectedVertexA, m_oUndirectedVertexA, false); oEdges.Add(m_oUndirectedVertexB, m_oUndirectedVertexB, false); oEdges.Add(m_oUndirectedVertexC, m_oUndirectedVertexD, false); oEdges.Add(m_oUndirectedVertexA, m_oUndirectedVertexB, false); oEdges.Add(m_oUndirectedVertexA, m_oUndirectedVertexB, false); oEdges.Add(m_oUndirectedVertexB, m_oUndirectedVertexA, false); oEdges.Add(m_oUndirectedVertexC, m_oUndirectedVertexD, false); Assert.IsTrue(m_oDuplicateEdgeDetector.GraphContainsDuplicateEdges); Assert.AreEqual(2, m_oDuplicateEdgeDetector.UniqueEdges); Assert.AreEqual(7, m_oDuplicateEdgeDetector.EdgesWithDuplicates); Assert.AreEqual(2, m_oDuplicateEdgeDetector. TotalEdgesAfterMergingDuplicatesNoSelfLoops); }
private void add_edges(DataRowCollection edge_rows, IVertexCollection oVertices, IEdgeCollection oEdges) { String from; String to; foreach (DataRow row in edge_rows) { //Notice: "EdgeFromid" and "EdgeToid" should be edited from = row["FromID"].ToString(); to = row["ToID"].ToString(); // Add an edge IVertex oFrom = null; IVertex oTo = null; foreach (IVertex oVertex in oVertices) { if (oVertex.Tag.ToString() == from) { oFrom = oVertex; } if (oVertex.Tag.ToString() == to) { oTo = oVertex; } } IEdge oEdge1 = oEdges.Add(oFrom, oTo, true); } }
AddEdgeToGraph ( PajekEdgeData oEdgeData, IEdgeCollection oEdges, IVertex [] aoVertices, Boolean bDirected ) { Debug.Assert(oEdges != null); Debug.Assert(aoVertices != null); Int32 iVertices = aoVertices.Length; Int32 iFirstVertexNumber = oEdgeData.FirstVertexNumber; Int32 iSecondVertexNumber = oEdgeData.SecondVertexNumber; Debug.Assert(iFirstVertexNumber >= 1); Debug.Assert(iFirstVertexNumber <= iVertices); Debug.Assert(aoVertices[iFirstVertexNumber - 1] != null); Debug.Assert(iSecondVertexNumber >= 1); Debug.Assert(iSecondVertexNumber <= iVertices); Debug.Assert(aoVertices[iSecondVertexNumber - 1] != null); IEdge oEdge = oEdges.Add(aoVertices[iFirstVertexNumber - 1], aoVertices[iSecondVertexNumber - 1], bDirected); oEdge.SetValue(ReservedMetadataKeys.EdgeWeight, oEdgeData.Weight); }
TestGetVertexIDPair6() { // Undirected graph, useDirectedness = false. IGraph oUndirectedGraph = new Graph(GraphDirectedness.Undirected); IVertexCollection oUndirectedVertices = oUndirectedGraph.Vertices; IVertex oUndirectedVertexA = oUndirectedVertices.Add(); IVertex oUndirectedVertexB = oUndirectedVertices.Add(); IVertex oUndirectedVertexC = oUndirectedVertices.Add(); IVertex oUndirectedVertexD = oUndirectedVertices.Add(); IEdgeCollection oEdges = oUndirectedGraph.Edges; IEdge oEdge1 = oEdges.Add(oUndirectedVertexA, oUndirectedVertexB, false); IEdge oEdge2 = oEdges.Add(oUndirectedVertexA, oUndirectedVertexB, false); IEdge oEdge3 = oEdges.Add(oUndirectedVertexB, oUndirectedVertexA, false); IEdge oEdge4 = oEdges.Add(oUndirectedVertexA, oUndirectedVertexC, false); Int64 i64VertexIDPair1 = EdgeUtil.GetVertexIDPair(oEdge1, false); Int64 i64VertexIDPair2 = EdgeUtil.GetVertexIDPair(oEdge2, false); Int64 i64VertexIDPair3 = EdgeUtil.GetVertexIDPair(oEdge3, false); Int64 i64VertexIDPair4 = EdgeUtil.GetVertexIDPair(oEdge4, false); // Make sure that the left-shift worked. Assert.IsTrue(i64VertexIDPair1 > Int32.MaxValue); Assert.IsTrue(i64VertexIDPair2 > Int32.MaxValue); Assert.IsTrue(i64VertexIDPair3 > Int32.MaxValue); Assert.IsTrue(i64VertexIDPair4 > Int32.MaxValue); Assert.AreEqual(i64VertexIDPair1, i64VertexIDPair2); Assert.AreEqual(i64VertexIDPair1, i64VertexIDPair3); Assert.AreNotEqual(i64VertexIDPair1, i64VertexIDPair4); Assert.AreEqual(i64VertexIDPair2, i64VertexIDPair3); Assert.AreNotEqual(i64VertexIDPair2, i64VertexIDPair4); Assert.AreNotEqual(i64VertexIDPair3, i64VertexIDPair4); }
ParseEdges ( IGraph oGraph, XmlNode oGraphXmlNode, XmlNamespaceManager oXmlNamespaceManager, Dictionary <String, IVertex> oVertexDictionary, Dictionary <String, GraphMLAttribute> oGraphMLAttributeDictionary ) { Debug.Assert(oGraph != null); Debug.Assert(oGraphXmlNode != null); Debug.Assert(oXmlNamespaceManager != null); Debug.Assert(oVertexDictionary != null); Debug.Assert(oGraphMLAttributeDictionary != null); AssertValid(); IEdgeCollection oEdges = oGraph.Edges; Boolean bGraphIsDirected = (oGraph.Directedness == GraphDirectedness.Directed); foreach (XmlNode oEdgeXmlNode in oGraphXmlNode.SelectNodes( GraphMLPrefix + ":edge", oXmlNamespaceManager)) { IVertex oVertex1, oVertex2; if ( !TryGraphMLNodeIDToVertex(oEdgeXmlNode, "source", oVertexDictionary, out oVertex1) || !TryGraphMLNodeIDToVertex(oEdgeXmlNode, "target", oVertexDictionary, out oVertex2) ) { // From the GraphML Primer: // // For applications which can not handle nested graphs the // fall-back behaviour is to ignore nodes which are not // contained in the top-level graph and to ignore edges which // have do not have both endpoints in the top-level graph. continue; } IEdge oEdge = oEdges.Add(oVertex1, oVertex2, bGraphIsDirected); String sID; if (XmlUtil2.TrySelectSingleNodeAsString(oEdgeXmlNode, "@id", null, out sID)) { oEdge.Name = sID; } ParseGraphMLAttributeValues(oEdgeXmlNode, oXmlNamespaceManager, oEdge, false, oGraphMLAttributeDictionary); } }
TestGetVertexIDPair() { // Directed graph. IGraph oDirectedGraph = new Graph(GraphDirectedness.Directed); IVertexCollection oDirectedVertices = oDirectedGraph.Vertices; IVertex oDirectedVertexA = oDirectedVertices.Add(); IVertex oDirectedVertexB = oDirectedVertices.Add(); IVertex oDirectedVertexC = oDirectedVertices.Add(); IVertex oDirectedVertexD = oDirectedVertices.Add(); IEdgeCollection oEdges = oDirectedGraph.Edges; IEdge oEdge1 = oEdges.Add(oDirectedVertexA, oDirectedVertexB, true); IEdge oEdge2 = oEdges.Add(oDirectedVertexA, oDirectedVertexB, true); IEdge oEdge3 = oEdges.Add(oDirectedVertexB, oDirectedVertexA, true); IEdge oEdge4 = oEdges.Add(oDirectedVertexA, oDirectedVertexC, true); Int64 i64VertexIDPair1 = EdgeUtil.GetVertexIDPair(oEdge1); Int64 i64VertexIDPair2 = EdgeUtil.GetVertexIDPair(oEdge2); Int64 i64VertexIDPair3 = EdgeUtil.GetVertexIDPair(oEdge3); Int64 i64VertexIDPair4 = EdgeUtil.GetVertexIDPair(oEdge4); // Make sure that the left-shift worked. Assert.IsTrue(i64VertexIDPair1 > Int32.MaxValue); Assert.IsTrue(i64VertexIDPair2 > Int32.MaxValue); Assert.IsTrue(i64VertexIDPair3 > Int32.MaxValue); Assert.IsTrue(i64VertexIDPair4 > Int32.MaxValue); Assert.AreEqual(i64VertexIDPair1, i64VertexIDPair2); Assert.AreNotEqual(i64VertexIDPair1, i64VertexIDPair3); Assert.AreNotEqual(i64VertexIDPair1, i64VertexIDPair4); Assert.AreNotEqual(i64VertexIDPair2, i64VertexIDPair3); Assert.AreNotEqual(i64VertexIDPair2, i64VertexIDPair4); Assert.AreNotEqual(i64VertexIDPair3, i64VertexIDPair4); }
TestGraphContainsDuplicateEdges12() { // Undirected graph, duplicate null name, C. m_oDuplicateEdgeDetector = new DuplicateEdgeDetector(m_oUndirectedGraph); IEdgeCollection oEdges = m_oUndirectedGraph.Edges; oEdges.Add(m_oUndirectedVertexA, m_oUndirectedVertexB, false); oEdges.Add(m_oUndirectedVertexA, m_oUndirectedVertexA, false); oEdges.Add(m_oUndirectedVertexB, m_oUndirectedVertexB, false); oEdges.Add(m_oUndirectedVertexC, m_oUndirectedVertexD, false); oEdges.Add(m_oUndirectedVertexC, m_oUndirectedVertexWithNullName, false); oEdges.Add(m_oUndirectedVertexWithNullName, m_oUndirectedVertexC, false); Assert.IsFalse(m_oDuplicateEdgeDetector.GraphContainsDuplicateEdges); Assert.AreEqual(4, m_oDuplicateEdgeDetector.UniqueEdges); Assert.AreEqual(0, m_oDuplicateEdgeDetector.EdgesWithDuplicates); Assert.AreEqual(2, m_oDuplicateEdgeDetector. TotalEdgesAfterMergingDuplicatesNoSelfLoops); }
TestMoveNext4() { // N vertices, connect last vertex to all other vertices. const Int32 Vertices = 2000; // Add the vertices. IVertex[] aoVertices = AddVertices(Vertices); // Connect the first vertex to all other vertices. Int32 iEdges = Vertices - 1; IEdge[] aoAddedEdges = new IEdge[iEdges]; IVertex oVertex1 = aoVertices[Vertices - 1]; IEdgeCollection oEdgeCollection = m_oGraph.Edges; Int32 i; for (i = 0; i < Vertices - 1; i++) { IVertex oVertex2 = aoVertices[i]; IEdge oEdge = new Edge(oVertex1, oVertex2, false); oEdge.Name = oEdge.ID.ToString(); aoAddedEdges[i] = oEdge; oEdgeCollection.Add(oEdge); } // Enumerate the edges using m_oEnumerator and compare the enumerated // edges with the edges that were added to the edge collection. EnumerateAndCompare(aoAddedEdges); // Reset the enumerator and repeat. m_oEnumerator.Reset(); EnumerateAndCompare(aoAddedEdges); }
MakeGraphComplete ( IGraph oGraph, IVertex [] aoVertices, Boolean bDirected ) { Debug.Assert(oGraph != null); Debug.Assert(aoVertices != null); Int32 iVertices = aoVertices.Length; Int32 iEdges = GetEdgeCountForCompleteGraph(iVertices); IEdge[] aoAddedEdges = new IEdge[iEdges]; IEdgeCollection oEdgeCollection = oGraph.Edges; Int32 iEdge = 0; for (Int32 i = 0; i < iVertices; i++) { for (Int32 j = i + 1; j < iVertices; j++) { IEdge oEdge = oEdgeCollection.Add( aoVertices[i], aoVertices[j], bDirected); oEdge.Name = oEdge.ID.ToString(); aoAddedEdges[iEdge] = oEdge; iEdge++; } } Debug.Assert(oEdgeCollection.Count == iEdges); return(aoAddedEdges); }
TestLargeGraph() { // Create a large graph, make sure there are no exceptions or // assertions. const Int32 Vertices = 1000000; const Int32 Edges = 100000; IVertex [] aoVertices = TestGraphUtil.AddVertices(m_oGraph, Vertices); Random oRandom = new Random(1); for (Int32 i = 0; i < Edges; i++) { IVertex oVertex1 = aoVertices[oRandom.Next(Vertices)]; IVertex oVertex2 = aoVertices[oRandom.Next(Vertices)]; IEdgeCollection oEdgeCollection = m_oGraph.Edges; oEdgeCollection.Add(oVertex1, oVertex2); } Assert.AreEqual(Vertices, m_oGraph.Vertices.Count); Assert.AreEqual(Edges, m_oGraph.Edges.Count); m_oGraph.Edges.Clear(); Assert.AreEqual(Vertices, m_oGraph.Vertices.Count); Assert.AreEqual(0, m_oGraph.Edges.Count); m_oGraph.Vertices.Clear(); Assert.AreEqual(0, m_oGraph.Vertices.Count); Assert.AreEqual(0, m_oGraph.Edges.Count); }
TestGraphContainsDuplicateEdges6() { // Directed graph, non-duplicate null name, C. m_oDuplicateEdgeDetector = new DuplicateEdgeDetector(m_oDirectedGraph); IEdgeCollection oEdges = m_oDirectedGraph.Edges; oEdges.Add(m_oDirectedVertexA, m_oDirectedVertexB, true); oEdges.Add(m_oDirectedVertexB, m_oDirectedVertexA, true); oEdges.Add(m_oDirectedVertexA, m_oDirectedVertexA, true); oEdges.Add(m_oDirectedVertexB, m_oDirectedVertexB, true); oEdges.Add(m_oDirectedVertexC, m_oDirectedVertexD, true); oEdges.Add(m_oDirectedVertexC, m_oDirectedVertexWithNullName, true); oEdges.Add(m_oDirectedVertexWithNullName, m_oDirectedVertexC, true); Assert.IsFalse(m_oDuplicateEdgeDetector.GraphContainsDuplicateEdges); Assert.AreEqual(7, m_oDuplicateEdgeDetector.UniqueEdges); Assert.AreEqual(0, m_oDuplicateEdgeDetector.EdgesWithDuplicates); Assert.AreEqual(5, m_oDuplicateEdgeDetector. TotalEdgesAfterMergingDuplicatesNoSelfLoops); }
TestGraphContainsDuplicateEdges4() { // Directed graph, duplicate A,A. m_oDuplicateEdgeDetector = new DuplicateEdgeDetector(m_oDirectedGraph); IEdgeCollection oEdges = m_oDirectedGraph.Edges; oEdges.Add(m_oDirectedVertexA, m_oDirectedVertexB, true); oEdges.Add(m_oDirectedVertexB, m_oDirectedVertexA, true); oEdges.Add(m_oDirectedVertexA, m_oDirectedVertexA, true); oEdges.Add(m_oDirectedVertexB, m_oDirectedVertexB, true); oEdges.Add(m_oDirectedVertexC, m_oDirectedVertexD, true); oEdges.Add(m_oDirectedVertexC, m_oDirectedVertexWithNullName, true); oEdges.Add(m_oDirectedVertexA, m_oDirectedVertexA, true); Assert.IsTrue(m_oDuplicateEdgeDetector.GraphContainsDuplicateEdges); Assert.AreEqual(4, m_oDuplicateEdgeDetector.UniqueEdges); Assert.AreEqual(2, m_oDuplicateEdgeDetector.EdgesWithDuplicates); Assert.AreEqual(3, m_oDuplicateEdgeDetector. TotalEdgesAfterMergingDuplicatesNoSelfLoops); }
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); }
LoadGraphCore ( Stream stream ) { Debug.Assert(stream != null); AssertValid(); // For now, support only directed graphs. IGraph oGraph = new Graph(GraphDirectedness.Directed); IVertexCollection oVertices = oGraph.Vertices; IEdgeCollection oEdges = oGraph.Edges; StreamReader oStreamReader = new StreamReader(stream, StreamEncoding); // Create a dictionary to keep track of the vertices that have been // added to the graph. The key is the vertex name and the value is the // vertex. Dictionary <String, IVertex> oDictionary = new Dictionary <String, IVertex>(); Int32 iLineNumber = 1; while (true) { String sLine = oStreamReader.ReadLine(); if (sLine == null) { break; } // Skip empty lines. if (sLine.Trim().Length > 0) { // Parse the line. String [] asTokens = sLine.Split('\t'); if (asTokens.Length != 2) { OnLoadFormatError(sLine, iLineNumber, ExpectedFormat); } String sVertex1Name = asTokens[0]; String sVertex2Name = asTokens[1]; if (!VertexNameIsValid(sVertex1Name) || !VertexNameIsValid(sVertex2Name)) { OnLoadFormatError(sLine, iLineNumber, ExpectedFormat); } // Retrieve or create the specified vertices. IVertex oVertex1 = VertexNameToVertex(sVertex1Name, oVertices, oDictionary); IVertex oVertex2 = VertexNameToVertex(sVertex2Name, oVertices, oDictionary); // Add an edge connecting the vertices. oEdges.Add(oVertex1, oVertex2, true); } iLineNumber++; } oDictionary.Clear(); return(oGraph); }
ReadEdges ( Microsoft.Office.Interop.Excel.Worksheet oSourceWorksheet, Int32 iFirstEdgeWeightRowOneBased, Int32 iFirstEdgeWeightColumnOneBased, IGraph oGraph, IVertex [] aoOrderedVertices ) { Debug.Assert(oSourceWorksheet != null); Debug.Assert(iFirstEdgeWeightRowOneBased >= 1); Debug.Assert(iFirstEdgeWeightColumnOneBased >= 1); Debug.Assert(oGraph != null); Debug.Assert(aoOrderedVertices != null); Debug.Assert(oGraph.Vertices.Count == aoOrderedVertices.Length); Boolean bGraphIsDirected = (oGraph.Directedness == GraphDirectedness.Directed); Int32 iVertices = aoOrderedVertices.Length; IEdgeCollection oEdges = oGraph.Edges; for (Int32 i = 0; i < iVertices; i++) { Int32 iRowOneBased = iFirstEdgeWeightRowOneBased + i; Object [,] oRowOfEdgeWeightValues = ExcelUtil.GetValuesInRow( oSourceWorksheet, iRowOneBased, iFirstEdgeWeightColumnOneBased, iVertices); // In a directed graph, look at the whole row. In an undirected // graph, look only at the cell on the diagonal and the cells to // the right. for (Int32 j = (bGraphIsDirected ? 0 : i); j < iVertices; j++) { Double dEdgeWeight = 0; Int32 iColumnOneBased = iFirstEdgeWeightColumnOneBased + j; if (!ExcelUtil.TryGetDoubleFromCell(oRowOfEdgeWeightValues, 1, j + 1, out dEdgeWeight)) { OnInvalidSourceWorkbook(String.Format( "The edge weight in {0} must be a number." , ExcelUtil.GetCellAddress(oSourceWorksheet, iRowOneBased, iColumnOneBased) ), oSourceWorksheet, iRowOneBased, iColumnOneBased ); } if (dEdgeWeight != 0) { IEdge oEdge = oEdges.Add(aoOrderedVertices[i], aoOrderedVertices[j], bGraphIsDirected); oEdge.SetValue(ReservedMetadataKeys.EdgeWeight, dEdgeWeight); } } } }
GetSubgraphAsNewGraph ( ICollection <IVertex> verticesToInclude ) { Debug.Assert(verticesToInclude != null); Debug.Assert(verticesToInclude.Count > 0); IVertex oFirstVertex = verticesToInclude.First(); IGraph oParentGraph = oFirstVertex.ParentGraph; IGraph oNewGraph = new Graph(oParentGraph.Directedness); IEdgeCollection oNewEdges = oNewGraph.Edges; IVertexCollection oNewVertices = oNewGraph.Vertices; // This maps vertex IDs in the original graph to the corresponding new // vertices in the new graph. Dictionary <Int32, IVertex> oVertexIDToNewVertexDictionary = new Dictionary <Int32, IVertex>(verticesToInclude.Count); // Copy the vertices into the new graph. foreach (IVertex oVertex in verticesToInclude) { IVertex oNewVertex = oNewVertices.Add(); oNewVertex.Name = oVertex.Name; oVertexIDToNewVertexDictionary.Add(oVertex.ID, oNewVertex); } // This contains the IDs of the original edges that have been copied // into the new graph. HashSet <Int32> oIDsOfCopiedEdges = new HashSet <Int32>(); // Copy the edges connecting the vertices into the new graph. foreach (IVertex oVertex in verticesToInclude) { foreach (IEdge oIncidentEdge in oVertex.IncidentEdges) { IVertex oAdjacentVertex = oIncidentEdge.GetAdjacentVertex( oVertex); IVertex oNewAdjacentVertex; if ( !oVertexIDToNewVertexDictionary.TryGetValue( oAdjacentVertex.ID, out oNewAdjacentVertex) || oIDsOfCopiedEdges.Contains(oIncidentEdge.ID) ) { // The adjacent vertex is not in the set of vertices to // include, or the edge has already been copied into the // new graph. continue; } IVertex oNewVertex = oVertexIDToNewVertexDictionary[oVertex.ID]; IEdge oNewEdge; Boolean bIncidentEdgeIsDirected = oIncidentEdge.IsDirected; if (oVertex == oIncidentEdge.Vertices[0]) { oNewEdge = oNewEdges.Add(oNewVertex, oNewAdjacentVertex, bIncidentEdgeIsDirected); } else { oNewEdge = oNewEdges.Add(oNewAdjacentVertex, oNewVertex, bIncidentEdgeIsDirected); } oIDsOfCopiedEdges.Add(oIncidentEdge.ID); } } return(oNewGraph); }
TestSaveGraph2() { // Undirected graph. IGraph oGraph = new Graph(GraphDirectedness.Undirected); IVertexCollection oVertices = oGraph.Vertices; IEdgeCollection oEdges = oGraph.Edges; IVertex oVertexA = oVertices.Add(); oVertexA.Name = "a"; IVertex oVertexB = oVertices.Add(); oVertexB.Name = "b"; IVertex oVertexC = oVertices.Add(); oVertexC.Name = "c"; IVertex oVertexD = oVertices.Add(); oVertexD.Name = "d"; IEdge oEdge; oEdge = oEdges.Add(oVertexD, oVertexB, false); oEdge.SetValue(ReservedMetadataKeys.EdgeWeight, 1.0); oEdge = oEdges.Add(oVertexB, oVertexC, false); oEdge.SetValue(ReservedMetadataKeys.EdgeWeight, 3.0); oEdge = oEdges.Add(oVertexC, oVertexC, false); oEdge.SetValue(ReservedMetadataKeys.EdgeWeight, 4.12); m_oGraphAdapter.SaveGraph(oGraph, m_sTempFileName); String sFileContents = FileUtil.ReadTextFile(m_sTempFileName); const String ExpectedFileContents = "DL\r\n" + "N=4\r\n" + "FORMAT = FULLMATRIX DIAGONAL PRESENT\r\n" + "ROW LABELS:\r\n" + "\"a\"\r\n" + "\"b\"\r\n" + "\"c\"\r\n" + "\"d\"\r\n" + "COLUMN LABELS:\r\n" + "\"a\"\r\n" + "\"b\"\r\n" + "\"c\"\r\n" + "\"d\"\r\n" + "DATA:\r\n" + "0 0 0 0 \r\n" + "0 0 3 1 \r\n" + "0 3 4.12 0 \r\n" + "0 1 0 0 \r\n" ; Assert.AreEqual(ExpectedFileContents, sFileContents); }
TestOnLayoutBegin() { // Draw rectangles, hide intergroup edges. const Double GroupRectanglePenWidth = 1.23; const IntergroupEdgeStyle IntergroupEdgeStyle = IntergroupEdgeStyle.Hide; IGraph oGraph = new Graph(GraphDirectedness.Undirected); IVertex[] aoVertices = TestGraphUtil.AddVertices(oGraph, 4); IEdgeCollection oEdges = oGraph.Edges; IEdge oEdge1 = oEdges.Add(aoVertices[0], aoVertices[1], false); IEdge oEdge2 = oEdges.Add(aoVertices[0], aoVertices[2], false); IEdge oEdge3 = oEdges.Add(aoVertices[2], aoVertices[3], false); IEdge oEdge4 = oEdges.Add(aoVertices[1], aoVertices[3], false); // oEdge2 is intergroup. Give it an initial visibility. oEdge2.SetValue(ReservedMetadataKeys.Visibility, VisibilityKeyValue.Filtered); // (oEdge4 is intergroup. Don't give it an initial visibility.) GroupInfo oGroup1 = new GroupInfo(); oGroup1.Vertices.AddLast(aoVertices[0]); oGroup1.Vertices.AddLast(aoVertices[1]); oGroup1.Rectangle = Rectangle.FromLTRB(1, 2, 3, 4); GroupInfo oGroup2 = new GroupInfo(); oGroup2.Vertices.AddLast(aoVertices[2]); oGroup2.Vertices.AddLast(aoVertices[3]); oGroup2.Rectangle = Rectangle.FromLTRB(5, 6, 7, 8); GroupMetadataManager.OnLayoutBegin(oGraph); GroupMetadataManager.OnLayoutUsingGroupsEnd(oGraph, new GroupInfo[] { oGroup1, oGroup2 }, GroupRectanglePenWidth, IntergroupEdgeStyle); GroupLayoutDrawingInfo oGroupLayoutDrawingInfo; Assert.IsTrue(GroupMetadataManager.TryGetGroupLayoutDrawingInfo( oGraph, out oGroupLayoutDrawingInfo)); Assert.AreEqual(GroupRectanglePenWidth, oGroupLayoutDrawingInfo.PenWidth); IList <GroupInfo> oGroupInfo = oGroupLayoutDrawingInfo.GroupsToDraw; Assert.AreEqual(2, oGroupInfo.Count); Assert.AreEqual(oGroup1, oGroupInfo[0]); Assert.AreEqual(oGroup2, oGroupInfo[1]); Assert.IsTrue(oGraph.ContainsKey( ReservedMetadataKeys.IntergroupEdgesHidden)); Assert.IsFalse(oEdge1.ContainsKey( ReservedMetadataKeys.SavedVisibility)); Assert.IsTrue(oEdge2.ContainsKey( ReservedMetadataKeys.SavedVisibility)); Assert.AreEqual(VisibilityKeyValue.Filtered, oEdge2.GetValue(ReservedMetadataKeys.SavedVisibility)); Assert.IsTrue(oEdge2.ContainsKey( ReservedMetadataKeys.Visibility)); Assert.AreEqual(VisibilityKeyValue.Hidden, oEdge2.GetValue(ReservedMetadataKeys.Visibility)); Assert.IsFalse(oEdge3.ContainsKey( ReservedMetadataKeys.SavedVisibility)); Assert.IsTrue(oEdge4.ContainsKey( ReservedMetadataKeys.Visibility)); Assert.AreEqual(VisibilityKeyValue.Hidden, oEdge4.GetValue(ReservedMetadataKeys.Visibility)); // Verify that OnLayoutBegin() reverses the metadata changes. GroupMetadataManager.OnLayoutBegin(oGraph); VerifyOriginalMetadata(oGraph, oEdge1, oEdge2, oEdge3, oEdge4); }
TestOnLayoutBegin6() { // Request that intergroup edges be combined, and there are some. const Double GroupRectanglePenWidth = 4.567; const IntergroupEdgeStyle IntergroupEdgeStyle = IntergroupEdgeStyle.Combine; IGraph oGraph = new Graph(GraphDirectedness.Undirected); IVertex[] aoVertices = TestGraphUtil.AddVertices(oGraph, 5); IEdgeCollection oEdges = oGraph.Edges; // Not intergroup. IEdge oEdge1 = oEdges.Add(aoVertices[0], aoVertices[1], false); IEdge oEdge2 = oEdges.Add(aoVertices[2], aoVertices[3], false); // Intergroup, between groups 1 and 2. IEdge oEdge3 = oEdges.Add(aoVertices[0], aoVertices[2], false); IEdge oEdge4 = oEdges.Add(aoVertices[1], aoVertices[2], false); IEdge oEdge5 = oEdges.Add(aoVertices[1], aoVertices[3], false); // Intergroup, between groups 2 and 3. IEdge oEdge6 = oEdges.Add(aoVertices[2], aoVertices[4], false); IEdge oEdge7 = oEdges.Add(aoVertices[3], aoVertices[4], false); // Intergroup, between groups 1 and 3. IEdge oEdge8 = oEdges.Add(aoVertices[1], aoVertices[4], false); GroupInfo oGroup1 = new GroupInfo(); oGroup1.Vertices.AddLast(aoVertices[0]); oGroup1.Vertices.AddLast(aoVertices[1]); oGroup1.Rectangle = Rectangle.FromLTRB(1, 2, 3, 4); GroupInfo oGroup2 = new GroupInfo(); oGroup2.Vertices.AddLast(aoVertices[2]); oGroup2.Vertices.AddLast(aoVertices[3]); oGroup2.Rectangle = Rectangle.FromLTRB(5, 6, 7, 8); GroupInfo oGroup3 = new GroupInfo(); oGroup3.Vertices.AddLast(aoVertices[4]); oGroup3.Rectangle = Rectangle.FromLTRB(9, 10, 11, 12); GroupMetadataManager.OnLayoutBegin(oGraph); GroupMetadataManager.OnLayoutUsingGroupsEnd(oGraph, new GroupInfo[] { oGroup1, oGroup2, oGroup3 }, GroupRectanglePenWidth, IntergroupEdgeStyle); GroupLayoutDrawingInfo oGroupLayoutDrawingInfo; Assert.IsTrue(GroupMetadataManager.TryGetGroupLayoutDrawingInfo( oGraph, out oGroupLayoutDrawingInfo)); Assert.AreEqual(GroupRectanglePenWidth, oGroupLayoutDrawingInfo.PenWidth); IList <GroupInfo> oGroupInfo = oGroupLayoutDrawingInfo.GroupsToDraw; Assert.AreEqual(3, oGroupInfo.Count); Assert.AreEqual(oGroup1, oGroupInfo[0]); Assert.AreEqual(oGroup2, oGroupInfo[1]); Assert.AreEqual(oGroup3, oGroupInfo[2]); Assert.IsTrue(oGraph.ContainsKey( ReservedMetadataKeys.IntergroupEdgesHidden)); Assert.IsFalse(oEdge1.ContainsKey( ReservedMetadataKeys.SavedVisibility)); Assert.IsFalse(oEdge2.ContainsKey( ReservedMetadataKeys.SavedVisibility)); Assert.IsTrue(oEdge3.ContainsKey( ReservedMetadataKeys.SavedVisibility)); Assert.IsTrue(oEdge4.ContainsKey( ReservedMetadataKeys.SavedVisibility)); Assert.IsTrue(oEdge5.ContainsKey( ReservedMetadataKeys.SavedVisibility)); Assert.IsTrue(oEdge6.ContainsKey( ReservedMetadataKeys.SavedVisibility)); Assert.IsTrue(oEdge7.ContainsKey( ReservedMetadataKeys.SavedVisibility)); Assert.IsTrue(oEdge8.ContainsKey( ReservedMetadataKeys.SavedVisibility)); Assert.AreEqual(3, oGroupLayoutDrawingInfo.CombinedIntergroupEdges.Count()); IntergroupEdgeInfo oCombinedIntergroupEdge; oCombinedIntergroupEdge = oGroupLayoutDrawingInfo.CombinedIntergroupEdges.Single( intergroupEdgeInfo => intergroupEdgeInfo.Group1Index == 0 && intergroupEdgeInfo.Group2Index == 1 ); Assert.AreEqual(0, oCombinedIntergroupEdge.Group1Index); Assert.AreEqual(1, oCombinedIntergroupEdge.Group2Index); Assert.AreEqual(3, oCombinedIntergroupEdge.Edges); oCombinedIntergroupEdge = oGroupLayoutDrawingInfo.CombinedIntergroupEdges.Single( intergroupEdgeInfo => intergroupEdgeInfo.Group1Index == 0 && intergroupEdgeInfo.Group2Index == 2 ); Assert.AreEqual(0, oCombinedIntergroupEdge.Group1Index); Assert.AreEqual(2, oCombinedIntergroupEdge.Group2Index); Assert.AreEqual(1, oCombinedIntergroupEdge.Edges); oCombinedIntergroupEdge = oGroupLayoutDrawingInfo.CombinedIntergroupEdges.Single( intergroupEdgeInfo => intergroupEdgeInfo.Group1Index == 1 && intergroupEdgeInfo.Group2Index == 2 ); Assert.AreEqual(1, oCombinedIntergroupEdge.Group1Index); Assert.AreEqual(2, oCombinedIntergroupEdge.Group2Index); Assert.AreEqual(2, oCombinedIntergroupEdge.Edges); }
TestOnLayoutBegin5() { // Request that intergroup edges be combined, although there are none. const Double GroupRectanglePenWidth = 4.567; const IntergroupEdgeStyle IntergroupEdgeStyle = IntergroupEdgeStyle.Combine; IGraph oGraph = new Graph(GraphDirectedness.Undirected); IVertex[] aoVertices = TestGraphUtil.AddVertices(oGraph, 5); IEdgeCollection oEdges = oGraph.Edges; IEdge oEdge1 = oEdges.Add(aoVertices[0], aoVertices[1], false); IEdge oEdge2 = oEdges.Add(aoVertices[2], aoVertices[3], false); GroupInfo oGroup1 = new GroupInfo(); oGroup1.Vertices.AddLast(aoVertices[0]); oGroup1.Vertices.AddLast(aoVertices[1]); oGroup1.Rectangle = Rectangle.FromLTRB(1, 2, 3, 4); GroupInfo oGroup2 = new GroupInfo(); oGroup2.Vertices.AddLast(aoVertices[2]); oGroup2.Vertices.AddLast(aoVertices[3]); oGroup2.Rectangle = Rectangle.FromLTRB(5, 6, 7, 8); GroupInfo oGroup3 = new GroupInfo(); oGroup3.Vertices.AddLast(aoVertices[4]); oGroup3.Rectangle = Rectangle.FromLTRB(9, 10, 11, 12); GroupMetadataManager.OnLayoutBegin(oGraph); GroupMetadataManager.OnLayoutUsingGroupsEnd(oGraph, new GroupInfo[] { oGroup1, oGroup2, oGroup3 }, GroupRectanglePenWidth, IntergroupEdgeStyle); GroupLayoutDrawingInfo oGroupLayoutDrawingInfo; Assert.IsTrue(GroupMetadataManager.TryGetGroupLayoutDrawingInfo( oGraph, out oGroupLayoutDrawingInfo)); Assert.AreEqual(GroupRectanglePenWidth, oGroupLayoutDrawingInfo.PenWidth); IList <GroupInfo> oGroupInfo = oGroupLayoutDrawingInfo.GroupsToDraw; Assert.AreEqual(3, oGroupInfo.Count); Assert.AreEqual(oGroup1, oGroupInfo[0]); Assert.AreEqual(oGroup2, oGroupInfo[1]); Assert.AreEqual(oGroup3, oGroupInfo[2]); Assert.IsFalse(oGraph.ContainsKey( ReservedMetadataKeys.IntergroupEdgesHidden)); Assert.IsFalse(oEdge1.ContainsKey( ReservedMetadataKeys.SavedVisibility)); Assert.IsFalse(oEdge2.ContainsKey( ReservedMetadataKeys.SavedVisibility)); Assert.AreEqual(0, oGroupLayoutDrawingInfo.CombinedIntergroupEdges.Count()); }
Clone ( Boolean copyMetadataValues, Boolean copyTag ) { AssertValid(); const String MethodName = "Clone"; IGraph oNewGraph = new Graph(m_eDirectedness); // Copy the base-class fields to the new edge. this.CopyTo(oNewGraph, copyMetadataValues, copyTag); // The vertices need to be copied to the new graph. Loop through the // vertices in this original graph. IVertexCollection oNewVertices = oNewGraph.Vertices; foreach (IVertex oOriginalVertex in m_oVertexCollection) { IVertex oNewVertex = oOriginalVertex.Clone( copyMetadataValues, copyTag); // To make it easier to copy the edges in this original graph, // temporarily store the ID of the new vertex in the Tag of the // original vertex. Save the Tag so it can be restored later. oOriginalVertex.Tag = new VertexMapper(oOriginalVertex.Tag, oNewVertex); oNewVertices.Add(oNewVertex); } // The edges need to be copied to the new graph. Loop through the // edges in this original graph. IEdgeCollection oNewEdges = oNewGraph.Edges; foreach (IEdge oOriginalEdge in m_oEdgeCollection) { // Get the original edge's vertices. IVertex oOriginalVertex1, oOriginalVertex2; EdgeUtil.EdgeToVertices(oOriginalEdge, this.ClassName, MethodName, out oOriginalVertex1, out oOriginalVertex2); // Retrieve the VertexMapper objects that were temporarily stored // in the vertices' Tags. Debug.Assert(oOriginalVertex1.Tag is VertexMapper); Debug.Assert(oOriginalVertex2.Tag is VertexMapper); VertexMapper oVertexMapper1 = (VertexMapper)oOriginalVertex1.Tag; VertexMapper oVertexMapper2 = (VertexMapper)oOriginalVertex2.Tag; // Get the new vertices that correspond to the original edge's // vertices. IVertex oNewVertex1 = oVertexMapper1.NewVertex; IVertex oNewVertex2 = oVertexMapper2.NewVertex; // Copy the original edge, connecting the new vertices in the // process. IEdge oNewEdge = oOriginalEdge.Clone(copyMetadataValues, copyTag, oNewVertex1, oNewVertex2, oOriginalEdge.IsDirected); oNewEdges.Add(oNewEdge); } // Restore the original vertices' Tags. foreach (IVertex oOriginalVertex in m_oVertexCollection) { Debug.Assert(oOriginalVertex.Tag is VertexMapper); VertexMapper oVertexMapper = (VertexMapper)oOriginalVertex.Tag; oOriginalVertex.Tag = oVertexMapper.OriginalVertexTag; } return(oNewGraph); }
LoadGraphEdges ( IGraph oGraph, StreamReader oStreamReader, Dictionary <Int32, IVertex> oVertexDictionary, ref Int32 iLineNumber ) { Debug.Assert(oGraph != null); Debug.Assert(oStreamReader != null); Debug.Assert(oVertexDictionary != null); AssertValid(); IVertexCollection oVertices = oGraph.Vertices; Int32 iVertices = oVertices.Count; IEdgeCollection oEdges = oGraph.Edges; Boolean bGraphIsDirected = (m_eLoadedGraphDirectedness == GraphDirectedness.Directed); String sLine; for (Int32 i = 0; i < iVertices; i++) { if (!TryReadLine(oStreamReader, out sLine, ref iLineNumber)) { OnLoadFormatError(String.Format( "The \"DATA:\" section must contain {0} {1}." , iVertices, StringUtil.MakePlural("line", iVertices) )); } // This will remove any leading and trailing spaces from the line, // and it handles any number of spaces and tabs between the edge // weights. String [] asEdgeWeights = sLine.Split(new Char [] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); if (asEdgeWeights.Length != iVertices) { OnLoadFormatError(String.Format( "Expected number of edge weights on line {0}: {1}. Actual" + " number of edge weights: {2}." , iLineNumber, iVertices, asEdgeWeights.Length )); } // For directed graphs, read all edge weights. For undirected // graphs, read only the diagonal and above. for (Int32 j = (bGraphIsDirected ? 0 : i); j < iVertices; j++) { Double dEdgeWeight; if (!MathUtil.TryParseCultureInvariantDouble( asEdgeWeights[j], out dEdgeWeight)) { OnLoadFormatError(String.Format( "Line {0} contains an invalid edge weight." , iLineNumber )); } if (dEdgeWeight != 0) { IEdge oEdge = oEdges.Add(oVertexDictionary[i], oVertexDictionary[j], bGraphIsDirected); oEdge.SetValue(ReservedMetadataKeys.EdgeWeight, dEdgeWeight); } } } }
PopulateGraph() { IGraph oGraph = m_oNodeXLControl.Graph; IVertexCollection oVertices = oGraph.Vertices; IEdgeCollection oEdges = oGraph.Edges; Double dWidth = this.Width; Double dHeight = this.Height; Random oRandom = new Random(); // m_oNodeXLControl.Layout.Margin = 0; { #if false // Two shapes only. IVertex oVertex1 = oVertices.Add(); oVertex1.SetValue(ReservedMetadataKeys.PerVertexShape, VertexShape.Circle); oVertex1.SetValue(ReservedMetadataKeys.PerVertexRadius, 5.0F); oVertex1.SetValue(ReservedMetadataKeys.LockVertexLocation, true); oVertex1.Location = new System.Drawing.PointF(300, 300); oVertex1.SetValue(ReservedMetadataKeys.PerVertexLabel, "This is A: " + oVertex1.Location); IVertex oVertex2 = oVertices.Add(); oVertex2.SetValue(ReservedMetadataKeys.PerVertexShape, VertexShape.Circle); oVertex2.SetValue(ReservedMetadataKeys.PerVertexRadius, 5.0F); oVertex2.SetValue(ReservedMetadataKeys.LockVertexLocation, true); oVertex2.Location = new System.Drawing.PointF(500, 300); oVertex2.SetValue(ReservedMetadataKeys.PerVertexLabel, "This is B: " + oVertex2.Location); IEdge oEdge = oEdges.Add(oVertex1, oVertex2, true); // oEdge.SetValue(ReservedMetadataKeys.PerEdgeWidth, 20F); m_oNodeXLControl.DrawGraph(true); return; #endif } { #if false // Two labels only. IVertex oVertex1 = oVertices.Add(); oVertex1.SetValue(ReservedMetadataKeys.PerVertexShape, VertexShape.Label); oVertex1.SetValue(ReservedMetadataKeys.PerVertexLabel, "This is a label."); oVertex1.SetValue(ReservedMetadataKeys.LockVertexLocation, true); oVertex1.Location = new System.Drawing.PointF(300, 300); IVertex oVertex2 = oVertices.Add(); oVertex2.SetValue(ReservedMetadataKeys.PerVertexShape, VertexShape.Label); oVertex2.SetValue(ReservedMetadataKeys.PerVertexLabel, "This is another label."); oVertex2.SetValue(ReservedMetadataKeys.LockVertexLocation, true); oVertex2.Location = new System.Drawing.PointF(500, 100); oEdges.Add(oVertex1, oVertex2, true); m_oNodeXLControl.DrawGraph(true); return; #endif } Smrf.NodeXL.Visualization.Wpf.VertexShape[] aeShapes = (Smrf.NodeXL.Visualization.Wpf.VertexShape[]) Enum.GetValues(typeof(Smrf.NodeXL.Visualization.Wpf. VertexShape)); Int32 iShapes = aeShapes.Length; Int32 Vertices = 100; IVertex oFirstVertex = oVertices.Add(); oFirstVertex.SetValue(ReservedMetadataKeys.PerVertexRadius, 4.0F); IVertex oPreviousVertex = oFirstVertex; for (Int32 i = 1; i < Vertices; i++) { IVertex oVertex = oVertices.Add(); VertexShape eShape = aeShapes[oRandom.Next(iShapes)]; oVertex.SetValue(ReservedMetadataKeys.PerVertexShape, eShape); #if false // Hard-coded vertex shape. oVertex.SetValue(ReservedMetadataKeys.PerVertexShape, VertexDrawer.VertexShape.Diamond); #endif #if true // Vertex color. oVertex.SetValue(ReservedMetadataKeys.PerColor, System.Windows.Media.Color.FromArgb(255, (Byte)oRandom.Next(256), (Byte)oRandom.Next(256), (Byte)oRandom.Next(256)) ); #endif #if true // Vertex radius. Single fRadius = (Single)( Smrf.NodeXL.Visualization.Wpf.VertexDrawer.MinimumRadius + (0.1 * Smrf.NodeXL.Visualization.Wpf.VertexDrawer.MaximumRadius - Smrf.NodeXL.Visualization.Wpf.VertexDrawer.MinimumRadius) * oRandom.NextDouble()); oVertex.SetValue(ReservedMetadataKeys.PerVertexRadius, fRadius); #endif if (true && oRandom.Next(20) == 0) // Image { oVertex.SetValue(ReservedMetadataKeys.PerVertexShape, VertexShape.Image); oVertex.SetValue(ReservedMetadataKeys.PerVertexImage, new System.Windows.Media.Imaging.BitmapImage( new Uri(oRandom.Next(2) == 1 ? "..\\..\\Images\\TestImage1.gif" : "..\\..\\Images\\TestImage2.jpg", UriKind.Relative))); } if (eShape == VertexShape.Label) { String sLabel = "This is a label"; if (oRandom.Next(2) == 0) { sLabel = LongLabel; } oVertex.SetValue(ReservedMetadataKeys.PerVertexLabel, sLabel); /* * oVertex.SetValue( ReservedMetadataKeys.PerColor, * System.Windows.Media.Color.FromArgb(255, 0, 0, 0) ); * * oVertex.SetValue( * * ReservedMetadataKeys.PerVertexLabelFillColor, * System.Windows.Media.Color.FromArgb(255, 200, 200, * 200) ); * * oVertex.SetValue(ReservedMetadataKeys.PerAlpha, (Single)128); */ } else { String sAnnotation = "This is an annotation."; oVertex.SetValue(ReservedMetadataKeys.PerVertexLabel, sAnnotation); } if (true && oRandom.Next(1) == 1) // Vertex visibility. { oVertex.SetValue(ReservedMetadataKeys.Visibility, VisibilityKeyValue.Filtered); } #if false // Vertex alpha. oVertex.SetValue( ReservedMetadataKeys.PerAlpha, (Single)oRandom.Next(256)); #endif #if false // Vertex IsSelected. oVertex.SetValue(ReservedMetadataKeys.IsSelected, null); #endif oVertex.Location = new System.Drawing.PointF( (Single)(dWidth * oRandom.NextDouble()), (Single)(dHeight * oRandom.NextDouble()) ); IEdge oEdge = oEdges.Add(oFirstVertex, oVertex, true); oEdge.SetValue(ReservedMetadataKeys.PerEdgeLabel, "This is an edge label"); #if false // Edge color. oEdge.SetValue(ReservedMetadataKeys.PerColor, System.Windows.Media.Color.FromArgb(255, (Byte)oRandom.Next(256), (Byte)oRandom.Next(256), (Byte)oRandom.Next(256)) ); #endif #if false // Edge width. Double dEdgeWidth = EdgeDrawer.MinimumWidth + (EdgeDrawer.MaximumWidth - EdgeDrawer.MinimumWidth) * oRandom.NextDouble(); oEdge.SetValue(ReservedMetadataKeys.PerEdgeWidth, dEdgeWidth); #endif #if true // Edge visibility. oEdge.SetValue(ReservedMetadataKeys.Visibility, VisibilityKeyValue.Visible); #endif #if true // Edge alpha. oEdge.SetValue(ReservedMetadataKeys.PerAlpha, (Single)oRandom.Next(256)); #endif #if false // Edge IsSelected. oEdge.SetValue(ReservedMetadataKeys.IsSelected, null); #endif #if true if (oRandom.Next(1) == 0) { IEdge oRandomEdge = oEdges.Add(oPreviousVertex, oVertex, true); #if true // Edge label. oRandomEdge.SetValue(ReservedMetadataKeys.PerEdgeLabel, "This is a random edge label"); #endif } #endif oPreviousVertex = oVertex; } AddToolTipsToVertices(); SetBackgroundImage(); m_oNodeXLControl.DrawGraph(true); }
public MiRNADataReader(string sourcefile) { // Create a graph with mixed directedness. graph = new Graph(); vertexes = new Dictionary <string, Vertex>(); // Add vertices to the graph. IVertexCollection oVertices = graph.Vertices; IEdgeCollection oEdges = graph.Edges; using (StreamReader sr = new StreamReader(sourcefile)) { while (sr.Peek() != -1) { string line = sr.ReadLine().Trim(); if (line.Equals("")) { continue; } string[] tks = line.Split('\t'); string[] miRNAs = tks[2].Split('|'); string[] diseases = tks[6].Split('|'); for (int i = 0; i < miRNAs.Length; i++) { Vertex s = new Vertex(); s.Name = miRNAs[i].ToLower(); if (!vertexes.ContainsKey(s.Name)) { vertexes.Add(s.Name, s); oVertices.Add(s); } else { s = vertexes[s.Name]; } for (int j = 0; j < diseases.Length; j++) { Vertex t = new Vertex(); t.Name = diseases[j].ToLower(); t.SetValue(MeSH, tks[7]); //MeSHDictionaryTagger mesh = MeSHDictionaryTagger.GetInstance(@"D:\Resources\Models\NCBI\MeSH\desc2014.xml", @"D:\Resources\Models\ThirdParty\TsujiiLab\GENIATagger"); //string name = mesh.GetMeSHTrees(tks[7]).First().ToString(); if (!vertexes.ContainsKey(t.GetValue(MeSH).ToString())) { vertexes.Add(t.GetValue(MeSH).ToString(), t); oVertices.Add(t); } else { t = vertexes[t.GetValue(MeSH).ToString()]; } Smrf.NodeXL.Core.Edge e = new Smrf.NodeXL.Core.Edge(s, t, false); e.Tag = tks[5]; e.SetValue(SENTENCE, tks[1]); e.Name = tks[4]; oEdges.Add(e); } } } } }
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)); } }
TestRemoveIsolatesFromGroups() { IGraph oGraph = new Graph(); IEdgeCollection oEdges = oGraph.Edges; IVertexCollection oVertices = oGraph.Vertices; // Non-isolates. IVertex oVertexA = oVertices.Add(); IVertex oVertexB = oVertices.Add(); IVertex oVertexC = oVertices.Add(); IVertex oVertexD = oVertices.Add(); // Isolates. IVertex oVertexE = oVertices.Add(); IVertex oVertexF = oVertices.Add(); IVertex oVertexG = oVertices.Add(); oEdges.Add(oVertexA, oVertexB); oEdges.Add(oVertexB, oVertexC); oEdges.Add(oVertexD, oVertexA); // Group1 contains all non-isolate vertices. GroupInfo oGroup1 = new GroupInfo(); oGroup1.Vertices.AddLast(oVertexA); oGroup1.Vertices.AddLast(oVertexB); oGroup1.Vertices.AddLast(oVertexC); // Group2 contains a mix of isolate and non-isolate vertices. GroupInfo oGroup2 = new GroupInfo(); oGroup2.Vertices.AddLast(oVertexD); oGroup2.Vertices.AddLast(oVertexE); // Group3 contains all isolate vertices. GroupInfo oGroup3 = new GroupInfo(); oGroup3.Vertices.AddLast(oVertexF); oGroup3.Vertices.AddLast(oVertexG); // Group4 is empty. GroupInfo oGroup4 = new GroupInfo(); List <GroupInfo> oGroups = new List <GroupInfo>(); oGroups.Add(oGroup1); oGroups.Add(oGroup2); oGroups.Add(oGroup3); oGroups.Add(oGroup4); GroupUtil.RemoveIsolatesFromGroups(oGroups); Assert.AreEqual(2, oGroups.Count); Assert.AreEqual(3, oGroups[0].Vertices.Count); Assert.IsNotNull(oGroups[0].Vertices.Find(oVertexA)); Assert.IsNotNull(oGroups[0].Vertices.Find(oVertexB)); Assert.IsNotNull(oGroups[0].Vertices.Find(oVertexC)); Assert.AreEqual(1, oGroups[1].Vertices.Count); Assert.IsNotNull(oGroups[1].Vertices.Find(oVertexD)); }
TestRandomGraph ( Int32 iVertices, Random oRandom ) { Debug.Assert(iVertices >= 0); Debug.Assert(oRandom != null); // Stores the edges actually added to the graph. List <IEdge> oActualEdges = new List <IEdge>(); // Create a graph with random directedness. GraphDirectedness eDirectedness = TestGraphUtil.AllGraphDirectedness[ oRandom.Next(TestGraphUtil.AllGraphDirectedness.Length)]; InitializeGraph(eDirectedness); // Add random vertices. IVertex [] aoVertices = TestGraphUtil.AddVertices(m_oGraph, iVertices); Assert.AreEqual(iVertices, m_oGraph.Vertices.Count); Assert.AreEqual(0, m_oGraph.Edges.Count); // Add random edges. Int32 iAttemptedEdges = oRandom.Next(iVertices); IEdgeCollection oEdgeCollection = m_oGraph.Edges; for (Int32 i = 0; i < iAttemptedEdges; i++) { Boolean bIsDirected = false; switch (eDirectedness) { case GraphDirectedness.Undirected: bIsDirected = false; break; case GraphDirectedness.Directed: bIsDirected = true; break; case GraphDirectedness.Mixed: bIsDirected = (oRandom.Next(2) % 2 == 0); break; default: Debug.Assert(false); break; } IVertex oVertex1 = aoVertices[oRandom.Next(iVertices)]; IVertex oVertex2 = aoVertices[oRandom.Next(iVertices)]; IEdge oEdge = oEdgeCollection.Add(oVertex1, oVertex2, bIsDirected); oActualEdges.Add(oEdge); } Assert.AreEqual(iVertices, m_oGraph.Vertices.Count); Assert.AreEqual(oActualEdges.Count, m_oGraph.Edges.Count); // Set random metadata. foreach (IVertex oVertex in m_oGraph.Vertices) { String sName = null; if (oRandom.Next(3) % 3 == 0) { MetadataUtil.SetRandomMetadata( oVertex, true, true, oVertex.ID); // Mark the vertex as having metadata. sName = MetadataMarker; } oVertex.Name = sName; } foreach (IEdge oEdge in m_oGraph.Edges) { String sName = null; if (oRandom.Next(4) % 4 == 0) { MetadataUtil.SetRandomMetadata(oEdge, true, true, oEdge.ID); sName = MetadataMarker; } oEdge.Name = sName; } MetadataUtil.SetRandomMetadata(m_oGraph, true, true, m_oGraph.ID); // Check the random metadata. CheckRandomMetadataOnRandomGraph(); // Remove random edges. Int32 iRemovedEdges = 0; if (oRandom.Next(2) % 2 == 0) { foreach (IEdge oEdge in oActualEdges) { if (oRandom.Next(5) % 5 == 0) { m_oGraph.Edges.Remove(oEdge); iRemovedEdges++; } } } Assert.AreEqual(iVertices, m_oGraph.Vertices.Count); Assert.AreEqual(oActualEdges.Count - iRemovedEdges, m_oGraph.Edges.Count); // Remove random vertices. Int32 iRemovedVertices = 0; if (oRandom.Next(2) % 2 == 0) { foreach (IVertex oVertex in aoVertices) { if (oRandom.Next(3) % 3 == 0) { m_oGraph.Vertices.Remove(oVertex); iRemovedVertices++; } } } Assert.AreEqual(iVertices - iRemovedVertices, m_oGraph.Vertices.Count); // Note: Can't test m_oGraph.Edges.Count here, because removing // vertices probably removed some edges as well. // Check the random metadata on the remaining objects. CheckRandomMetadataOnRandomGraph(); // Check all the vertices, including the ones that were removed. // First, store all the non-removed vertex IDs in a dictionary to avoid // having to repeatedly call Vertices.Contains(), which is slow. Dictionary <Int32, Byte> oContainedVertexIDs = new Dictionary <Int32, Byte>(); foreach (IVertex oVertex in m_oGraph.Vertices) { oContainedVertexIDs.Add(oVertex.ID, 0); } foreach (IVertex oVertex in aoVertices) { Boolean bContainedInGraph = oContainedVertexIDs.ContainsKey(oVertex.ID); Assert.AreEqual(bContainedInGraph, oVertex.ParentGraph != null); if (oVertex.Name == MetadataMarker) { MetadataUtil.CheckRandomMetadata( oVertex, true, true, oVertex.ID); } else { Assert.IsNull(oVertex.Tag); } } oContainedVertexIDs.Clear(); // Remove all edges. m_oGraph.Edges.Clear(); Assert.AreEqual(iVertices - iRemovedVertices, m_oGraph.Vertices.Count); Assert.AreEqual(0, m_oGraph.Edges.Count); // Remove all vertices. m_oGraph.Vertices.Clear(); Assert.AreEqual(0, m_oGraph.Vertices.Count); Assert.AreEqual(0, m_oGraph.Edges.Count); // Check all the vertices. foreach (IVertex oVertex in aoVertices) { Boolean bContainedInGraph = m_oGraph.Vertices.Contains(oVertex); Assert.IsFalse(bContainedInGraph); if (oVertex.Name == MetadataMarker) { MetadataUtil.CheckRandomMetadata( oVertex, true, true, oVertex.ID); } else { Assert.IsNull(oVertex.Tag); } } }
protected void PopulateAndDrawGraph() { // Get the graph's vertex collection. IVertexCollection oVertices = Graph.Graph.Vertices; // Add three vertices. IVertex oVertexA = oVertices.Add(); IVertex oVertexB = oVertices.Add(); IVertex oVertexC = oVertices.Add(); // Change the color, radius, and shape of vertex A. oVertexA.SetValue(ReservedMetadataKeys.PerColor, Color.FromArgb(255, 255, 0, 255)); oVertexA.SetValue(ReservedMetadataKeys.PerVertexRadius, 20F); oVertexA.SetValue(ReservedMetadataKeys.PerVertexShape, VertexShape.Sphere); // Draw vertex B as a Label, which is a rectangle containing text. oVertexB.SetValue(ReservedMetadataKeys.PerVertexShape, VertexShape.Label); oVertexB.SetValue(ReservedMetadataKeys.PerVertexLabel, "Label"); // Set the label's text and fill colors. oVertexB.SetValue(ReservedMetadataKeys.PerColor, Color.FromArgb(255, 220, 220, 220)); oVertexB.SetValue(ReservedMetadataKeys.PerVertexLabelFillColor, Color.FromArgb(255, 0, 0, 0)); // Annotate vertex C with text that is drawn outside the vertex. All // shapes except Label can be annotated. oVertexC.SetValue(ReservedMetadataKeys.PerVertexLabel, "Annotation"); // Get the graph's edge collection. IEdgeCollection oEdges = Graph.Graph.Edges; // Connect the vertices with directed edges. IEdge oEdge1 = oEdges.Add(oVertexA, oVertexB, true); IEdge oEdge2 = oEdges.Add(oVertexB, oVertexC, true); IEdge oEdge3 = oEdges.Add(oVertexC, oVertexA, true); // Customize their appearance. oEdge1.SetValue(ReservedMetadataKeys.PerColor, Color.FromArgb(255, 55, 125, 98)); oEdge1.SetValue(ReservedMetadataKeys.PerEdgeWidth, 3F); oEdge1.SetValue(ReservedMetadataKeys.PerEdgeLabel, "This is edge 1"); oEdge2.SetValue(ReservedMetadataKeys.PerEdgeWidth, 5F); oEdge2.SetValue(ReservedMetadataKeys.PerEdgeLabel, "This is edge 2"); oEdge3.SetValue(ReservedMetadataKeys.PerColor, Color.FromArgb(255, 0, 255, 0)); Graph.DrawGraph(true); }
CloneVertexIntoSubgraph ( IVertex oOriginalVertex, IGraph oSubgraph, Decimal decLevels ) { Debug.Assert(oOriginalVertex != null); Debug.Assert(oSubgraph != null); Debug.Assert(decLevels >= 0); AssertValid(); // Get the original vertices and edges to clone. For the vertex // dictionary, the key is the IVertex and the value is the vertex's // level, which is the distance of the vertex from oOriginalVertex. // For the edge HashSet, the key is the IEdge. Dictionary <IVertex, Int32> oOriginalVerticesToClone; HashSet <IEdge> oOriginalEdgesToClone; SubgraphCalculator.GetSubgraph(oOriginalVertex, decLevels, true, out oOriginalVerticesToClone, out oOriginalEdgesToClone); // Clone the vertices. This dictionary maps the IDs of the original // vertices to their clones. Dictionary <Int32, IVertex> oOriginalToSubgraphVertexMapper = new Dictionary <Int32, IVertex>(); IVertexCollection oSubgraphVertices = oSubgraph.Vertices; foreach (IVertex oOriginalVertexToClone in oOriginalVerticesToClone.Keys) { IVertex oSubgraphVertex = oOriginalVertexToClone.Clone(false, false); oSubgraphVertices.Add(oSubgraphVertex); oOriginalToSubgraphVertexMapper.Add(oOriginalVertexToClone.ID, oSubgraphVertex); } // This dictionary is no longer needed. oOriginalVerticesToClone.Clear(); oOriginalVerticesToClone = null; // Clone the edges. IEdgeCollection oSubgraphEdges = oSubgraph.Edges; foreach (IEdge oOriginalEdgeToClone in oOriginalEdgesToClone) { IVertex [] aoOriginalVertices = oOriginalEdgeToClone.Vertices; IVertex oSubgraphVertex1 = oOriginalToSubgraphVertexMapper[aoOriginalVertices[0].ID]; IVertex oSubgraphVertex2 = oOriginalToSubgraphVertexMapper[aoOriginalVertices[1].ID]; oSubgraphEdges.Add(oSubgraphVertex1, oSubgraphVertex2, oOriginalEdgeToClone.IsDirected); } Debug.Assert(oOriginalToSubgraphVertexMapper.ContainsKey( oOriginalVertex.ID)); return(oOriginalToSubgraphVertexMapper[oOriginalVertex.ID]); }
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; using (StreamReader oStreamReader = new StreamReader(m_sTempFileName)) { sFileContents = oStreamReader.ReadToEnd(); } XmlDocument oXmlDocument = new XmlDocument(); oXmlDocument.LoadXml(sFileContents); XmlNamespaceManager oXmlNamespaceManager = new XmlNamespaceManager( oXmlDocument.NameTable); oXmlNamespaceManager.AddNamespace("g", GraphMLGraphAdapter.GraphMLUri); 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); } } }