GleePointToTransformedPointF ( Microsoft.Glee.Splines.Point oGleePoint, Matrix oTransformationMatrix ) { Debug.Assert(oGleePoint != null); Debug.Assert(oTransformationMatrix != null); AssertValid(); PointF oPointF = new PointF( (Single)oGleePoint.X, (Single)oGleePoint.Y ); return ( LayoutUtil.TransformPointF(oPointF, oTransformationMatrix) ); }
SaveGraphCore ( IGraph graph, Stream stream ) { Debug.Assert(graph != null); Debug.Assert(stream != null); AssertValid(); // The Pajek format requires coordinates to be between 0 and 1.0. Get // a Matrix that will transform the vertex locations to this range. RectangleF oCurrentBoundingRectangle = LayoutUtil.GetGraphBoundingRectangle(graph); RectangleF oNewBoundingRectangle = new RectangleF(PointF.Empty, new SizeF(1.0F, 1.0F)); Matrix oRectangleTransformation = LayoutUtil.GetRectangleTransformation( oCurrentBoundingRectangle, oNewBoundingRectangle ); // Create a dictionary to keep track of vertices. The keys are vertex // IDs and the values are the one-based vertex numbers used by the // Pajek format. Dictionary <Int32, Int32> oVertexIDToNumber = new Dictionary <Int32, Int32>(); IVertexCollection oVertices = graph.Vertices; StreamWriter oStreamWriter = new StreamWriter(stream, StreamEncoding); // Add the *vertices section. oStreamWriter.WriteLine( "*vertices {0}" , oVertices.Count ); Int32 iVertexNumber = 1; foreach (IVertex oVertex in oVertices) { // Format: // // 1 "vertex 1 name" x y z // Transform the vertex location. PointF oTransformedLocation = LayoutUtil.TransformPointF( oVertex.Location, oRectangleTransformation); // Limit the range in case of rounding errors. Single fX = Math.Max(0F, oTransformedLocation.X); fX = Math.Min(1F, fX); Single fY = Math.Max(0F, oTransformedLocation.Y); fY = Math.Min(1F, fY); oStreamWriter.WriteLine( "{0} \"{1}\" {2:N6} {3:N6} 0" , iVertexNumber, oVertex.Name, fX, fY ); oVertexIDToNumber.Add(oVertex.ID, iVertexNumber); iVertexNumber++; } IEdgeCollection oEdges = graph.Edges; GraphDirectedness eDirectedness = graph.Directedness; Boolean bSectionNameWritten = false; if (eDirectedness != GraphDirectedness.Directed) { // If appropriate, add the *edges section, which specifies // undirected edges. foreach (IEdge oEdge in oEdges) { // The graph could be mixed. if (oEdge.IsDirected) { continue; } if (!bSectionNameWritten) { oStreamWriter.WriteLine("*edges"); bSectionNameWritten = true; } WriteEdge(oEdge, oVertexIDToNumber, oStreamWriter); } } bSectionNameWritten = false; if (eDirectedness != GraphDirectedness.Undirected) { // If appropriate, add the *arcs section, which specifies // directed edges. foreach (IEdge oEdge in oEdges) { // The graph could be mixed. if (!oEdge.IsDirected) { continue; } if (!bSectionNameWritten) { oStreamWriter.WriteLine("*arcs"); bSectionNameWritten = true; } WriteEdge(oEdge, oVertexIDToNumber, oStreamWriter); } } oStreamWriter.Flush(); }
TransformLayoutCore ( IGraph graph, LayoutContext originalLayoutContext, LayoutContext newLayoutContext ) { Debug.Assert(graph != null); Debug.Assert(originalLayoutContext != null); Debug.Assert(newLayoutContext != null); AssertValid(); // Transform the graph's vertex locations. Matrix oTransformationMatrix = LayoutUtil.GetRectangleTransformation( originalLayoutContext.GraphRectangle, newLayoutContext.GraphRectangle ); base.TransformLayoutCore(graph, originalLayoutContext, newLayoutContext); // Tranform the geometry metadata added by LayOutGraphCore(). Object oValue; if ( graph.TryGetValue( ReservedMetadataKeys.SugiyamaComputedRadius, typeof(Single), out oValue) ) { // Transforming the radius in the x-direction only isn't ideal, but // doing the transform properly would involve drawing the vertex as // an ellipse. PointF oTransformedRadius = LayoutUtil.TransformPointF( new PointF( (Single)oValue, 0 ), oTransformationMatrix ); graph.SetValue( ReservedMetadataKeys.SugiyamaComputedRadius, oTransformedRadius.X ); } foreach (IEdge oEdge in graph.Edges) { if ( !oEdge.TryGetValue( ReservedMetadataKeys.SugiyamaCurvePoints, typeof( PointF [] ), out oValue ) ) { continue; } PointF [] aoCurvePoints = ( PointF [] )oValue; oTransformationMatrix.TransformPoints(aoCurvePoints); oEdge.SetValue(ReservedMetadataKeys.SugiyamaCurvePoints, aoCurvePoints); PointF oEndpoint = (PointF)oEdge.GetRequiredValue( ReservedMetadataKeys.SugiyamaEndpoint, typeof(PointF) ); oEdge.SetValue( ReservedMetadataKeys.SugiyamaEndpoint, LayoutUtil.TransformPointF(oEndpoint, oTransformationMatrix) ); } }