Ejemplo n.º 1
0
        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();
        }