TestEdgeToVerticesBad8() { // Vertices not part of the same graph. try { MockVertex oVertex1 = new MockVertex(); MockVertex oVertex2 = new MockVertex(); IGraph oGraph1 = new Graph(GraphDirectedness.Mixed); IGraph oGraph2 = new Graph(GraphDirectedness.Mixed); oVertex1.ParentGraph = oGraph1; oVertex2.ParentGraph = oGraph2; IEdge oEdge = new MockEdge(oVertex1, oVertex2, false, false, 2); IVertex oVertexA, oVertexB; EdgeUtil.EdgeToVertices(oEdge, ClassName, MethodOrPropertyName, out oVertexA, out oVertexB); } catch (ApplicationException oApplicationException) { Assert.AreEqual( "TheClass.TheMethodOrProperty: The edge connects vertices not" + " in the same graph." , oApplicationException.Message ); throw oApplicationException; } }
TestEdgeToVerticesBad7() { // Second vertex has no parent. try { MockVertex oVertex1 = new MockVertex(); MockVertex oVertex2 = new MockVertex(); IGraph oGraph = new Graph(); oVertex1.ParentGraph = oGraph; // oVertex2.ParentGraph = oGraph; IEdge oEdge = new MockEdge(oVertex1, oVertex2, false, false, 2); IVertex oVertexA, oVertexB; EdgeUtil.EdgeToVertices(oEdge, ClassName, MethodOrPropertyName, out oVertexA, out oVertexB); } catch (ApplicationException oApplicationException) { Assert.AreEqual( "TheClass.TheMethodOrProperty: The edge's second vertex does" + " not belong to a graph." , oApplicationException.Message ); throw oApplicationException; } }
TestEdgeToVerticesBad5() { // Second vertex is null. try { IEdge oEdge = new MockEdge( new MockVertex(), null, false, false, 2); IVertex oVertexA, oVertexB; EdgeUtil.EdgeToVertices(oEdge, ClassName, MethodOrPropertyName, out oVertexA, out oVertexB); } catch (ApplicationException oApplicationException) { Assert.AreEqual( "TheClass.TheMethodOrProperty: The edge's second vertex is" + " null." , oApplicationException.Message ); throw oApplicationException; } }
TestEdgeToVerticesBad3() { // Edge.Vertices contains 1 vertex only. try { IEdge oEdge = new MockEdge(null, null, false, false, 1); IVertex oVertexA, oVertexB; EdgeUtil.EdgeToVertices(oEdge, ClassName, MethodOrPropertyName, out oVertexA, out oVertexB); } catch (ApplicationException oApplicationException) { Assert.AreEqual( "TheClass.TheMethodOrProperty: The edge does not connect two" + " vertices." , oApplicationException.Message ); throw oApplicationException; } }
TestEdgeToVerticesBad() { // Null Edge.Vertices. try { IEdge oEdge = new MockEdge(null, null, false, true, 0); IVertex oVertexA, oVertexB; EdgeUtil.EdgeToVertices(oEdge, ClassName, MethodOrPropertyName, out oVertexA, out oVertexB); } catch (ApplicationException ApplicationException) { Assert.AreEqual( "TheClass.TheMethodOrProperty: The edge's Vertices property is" + " null." , ApplicationException.Message ); throw ApplicationException; } }
SaveGraphCore ( IGraph graph, Stream stream ) { Debug.Assert(graph != null); Debug.Assert(graph.Directedness == GraphDirectedness.Directed); Debug.Assert(stream != null); AssertValid(); const String MethodName = "SaveGraph"; StreamWriter oStreamWriter = new StreamWriter(stream, StreamEncoding); // Loop through the graph's edges. foreach (IEdge oEdge in graph.Edges) { // Retrieve the edge's vertices. IVertex oVertex1, oVertex2; EdgeUtil.EdgeToVertices(oEdge, this.ClassName, MethodName, out oVertex1, out oVertex2); // Retrieve and format the edge names. String sVertex1Name = VertexToVertexName(oVertex1); String sVertex2Name = VertexToVertexName(oVertex2); oStreamWriter.WriteLine( "{0}\t{1}" , sVertex1Name, sVertex2Name ); } oStreamWriter.Flush(); }
TestEdgeToVertices() { // Valid vertices. MockVertex oVertex1 = new MockVertex(); MockVertex oVertex2 = new MockVertex(); IGraph oGraph = new Graph(); oVertex1.ParentGraph = oGraph; oVertex2.ParentGraph = oGraph; IEdge oEdge = new MockEdge(oVertex1, oVertex2, false, false, 2); IVertex oVertexA, oVertexB; EdgeUtil.EdgeToVertices(oEdge, ClassName, MethodOrPropertyName, out oVertexA, out oVertexB); Assert.AreEqual(oVertex1, oVertexA); Assert.AreEqual(oVertex2, oVertexB); }
WriteEdge ( IEdge oEdge, Dictionary <Int32, Int32> oVertexIDToNumber, StreamWriter oStreamWriter ) { Debug.Assert(oEdge != null); Debug.Assert(oVertexIDToNumber != null); Debug.Assert(oStreamWriter != null); AssertValid(); const String MethodName = "SaveGraph"; // Retrieve the edge's vertices. IVertex oVertex1, oVertex2; EdgeUtil.EdgeToVertices(oEdge, this.ClassName, MethodName, out oVertex1, out oVertex2); Int32 iVertex1ID = oVertex1.ID; Int32 iVertex2ID = oVertex2.ID; // Retrieve the vertex numbers. Int32 iVertex1Number, iVertex2Number; if (!oVertexIDToNumber.TryGetValue(iVertex1ID, out iVertex1Number) || !oVertexIDToNumber.TryGetValue(iVertex2ID, out iVertex2Number) ) { throw new InvalidOperationException(String.Format( "The edge with the ID {0} has a vertex that is not in the" + " graph's Vertices collection." , oEdge.ID.ToString(NodeXLBase.Int32Format) )); } // Retrieve the edge weight, if it exists. Object oWeight = null; Double dWeight = DefaultEdgeWeight; if (oEdge.TryGetValue( ReservedMetadataKeys.EdgeWeight, typeof(Double), out oWeight)) { dWeight = (Double)oWeight; } // Format: // // Vi Vj weight oStreamWriter.WriteLine( "{0} {1} {2}" , iVertex1Number, iVertex2Number, dWeight ); }
CalculateAttractiveForces ( ICollection <IEdge> edgesToLayOut, Single k ) { Debug.Assert(edgesToLayOut != null); Debug.Assert(k != 0); AssertValid(); const String MethodName = "CalculateAttractiveForces"; foreach (IEdge oEdge in edgesToLayOut) { if (oEdge.IsSelfLoop) { // A vertex isn't attracted to itself. continue; } // Get the edge's vertices. IVertex oVertexV, oVertexU; EdgeUtil.EdgeToVertices(oEdge, this.ClassName, MethodName, out oVertexV, out oVertexU); // Retrieve the objects that store calculated values for the // vertices. FruchtermanReingoldVertexInfo oVertexInfoV = (FruchtermanReingoldVertexInfo)oVertexV.Tag; FruchtermanReingoldVertexInfo oVertexInfoU = (FruchtermanReingoldVertexInfo)oVertexU.Tag; TMathType tDeltaX = (TMathType)oVertexInfoV.UnboundedLocationX - (TMathType)oVertexInfoU.UnboundedLocationX; TMathType tDeltaY = (TMathType)oVertexInfoV.UnboundedLocationY - (TMathType)oVertexInfoU.UnboundedLocationY; TMathType tDelta = (TMathType)Math.Sqrt( (tDeltaX * tDeltaX) + (tDeltaY * tDeltaY) ); // Use the edge weight, which InitializeMetadata() stored in the // Tag. tDelta *= (Single)oEdge.Tag; TMathType tDisplacementV_X = (TMathType)oVertexInfoV.DisplacementX; TMathType tDisplacementV_Y = (TMathType)oVertexInfoV.DisplacementY; TMathType tDisplacementU_X = (TMathType)oVertexInfoU.DisplacementX; TMathType tDisplacementU_Y = (TMathType)oVertexInfoU.DisplacementY; // (Note that there is an obvious typo in the Fruchterman-Reingold // paper for computing the attractive force. The function fa(z) at // the top of Figure 1 is defined as x squared over k. It should // read z squared over k.) TMathType fa = (tDelta * tDelta) / (TMathType)k; if (tDelta == 0) { // TODO: Is this the correct way to handle vertices in the same // location? See the notes in CalculateRepulsiveForces(). continue; } Debug.Assert(tDelta != 0); TMathType faOverDelta = fa / tDelta; TMathType tFactorX = tDeltaX * faOverDelta; TMathType tFactorY = tDeltaY * faOverDelta; tDisplacementV_X -= tFactorX; tDisplacementV_Y -= tFactorY; tDisplacementU_X += tFactorX; tDisplacementU_Y += tFactorY; oVertexInfoV.DisplacementX = (Single)tDisplacementV_X; oVertexInfoV.DisplacementY = (Single)tDisplacementV_Y; oVertexInfoU.DisplacementX = (Single)tDisplacementU_X; oVertexInfoU.DisplacementY = (Single)tDisplacementU_Y; } }