示例#1
0
    GleeCurveToPointFArray
    (
        Microsoft.Glee.Splines.Curve oCurve
    )
    {
        Debug.Assert(oCurve != null);
        AssertValid();

        // This is based on code in Microsoft.Glee.GraphViewerGdi.GViewer.
        // TransferGeometryFromGleeGraphToGraph() in the GLEE source code,

        System.Collections.Generic.List<PointF> oPointFList =
            new System.Collections.Generic.List<PointF>();

        Microsoft.Glee.Splines.Point oGleePoint =
            (oCurve.Segs[0] as Microsoft.Glee.Splines.CubicBezierSeg).B(0);

        oPointFList.Add( GleePointToPointF(oGleePoint) );

        foreach (Microsoft.Glee.Splines.CubicBezierSeg oCubicBezierSeg in
            oCurve.Segs)
        {
            oPointFList.Add( GleePointToPointF(oCubicBezierSeg.B(1) ) );
            oPointFList.Add( GleePointToPointF(oCubicBezierSeg.B(2) ) );
            oPointFList.Add( GleePointToPointF(oCubicBezierSeg.B(3) ) );
        }

        return ( oPointFList.ToArray() );
    }
示例#2
0
    GleeCurveToTransformedPointFArray
    (
        Microsoft.Glee.Splines.Curve oCurve,
        Matrix oTransformationMatrix
    )
    {
        Debug.Assert(oCurve != null);
        Debug.Assert(oTransformationMatrix != null);
        AssertValid();

        // Load the curve points into a list.

        System.Collections.Generic.List<PointF> oPointFList =
            new System.Collections.Generic.List<PointF>();

        Microsoft.Glee.Splines.Point oGleePoint =
            (oCurve.Segs[0] as Microsoft.Glee.Splines.CubicBezierSeg).B(0);

        oPointFList.Add( GleePointToPointF(oGleePoint) );

        foreach (Microsoft.Glee.Splines.CubicBezierSeg oCubicBezierSeg in
            oCurve.Segs)
        {
            oPointFList.Add( GleePointToPointF(oCubicBezierSeg.B(1) ) );
            oPointFList.Add( GleePointToPointF(oCubicBezierSeg.B(2) ) );
            oPointFList.Add( GleePointToPointF(oCubicBezierSeg.B(3) ) );
        }

        // Convert the list to an array and transform it to NodeXL coordinates.

        PointF [] aoCurvePoints = oPointFList.ToArray();

        oTransformationMatrix.TransformPoints(aoCurvePoints);

        return (aoCurvePoints);
    }
示例#3
0
    LayOutGraphCore
    (
        IGraph graph,
        ICollection<IVertex> verticesToLayOut,
        LayoutContext layoutContext,
        BackgroundWorker backgroundWorker
    )
    {
        Debug.Assert(graph != null);
        Debug.Assert(verticesToLayOut != null);
        Debug.Assert(verticesToLayOut.Count > 0);
        Debug.Assert(layoutContext != null);
        AssertValid();

        // This class does not incorporate GLEE source code to implement the
        // layout.  Instead, it transfers the NodeXL graph to a GLEE graph,
        // tells GLEE to lay out the GLEE graph, then reads the resulting
        // layout geometry from the GLEE graph and stores it as metadata in the
        // NodeXL graph.  Although this involves several copy operations, it
        // uses only the GLEE public interfaces and bypasses all the
        // maintenance headaches that would arise if the GLEE source code were
        // used.
        //
        // Note:
        //
        // This class was written when the NodeXL visualization layer used
        // GDI+.  There were complex families of vertex and edge drawers,
        // including SugiyamaVertexDrawer and EdgeVertexDrawer.  This class
        // stores vertex and edge metadata meant for use by those
        // Sugiyama-specific drawers, which were eliminated when the
        // visualization layer was changed to WPF and the vertex- and edge-
        // drawing code was vastly simplified.  Therefore, the vertex radius
        // and edge curve information stored by this class is currently ignored
        // in the WPF layer.  Vertices are of constant size, and edges are
        // drawn as straight lines.
        // 
        // This could be fixed by modifying the WPF layer to be Sugiyama-aware,
        // but as of June 2009 no one has complained about these problems and
        // so the fix is postponed.

        // Create a GLEE graph.

        Microsoft.Glee.GleeGraph oGleeGraph = new Microsoft.Glee.GleeGraph();

        // Get the vertex radius specified by the SugiyamaVertexDrawer.

        Single fNodeXLVertexRadius = GetNodeXLVertexRadius(layoutContext);

        // Loop through the NodeXL vertices.

        foreach (IVertex oVertex in verticesToLayOut)
        {
            // Create a circle that defines the GLEE node's boundary.  GLEE's
            // layout code does not modify the node's boundary, it just shifts
            // the node's center.

            Microsoft.Glee.Splines.ICurve oCurve =
                Microsoft.Glee.Splines.CurveFactory.CreateEllipse(
                    fNodeXLVertexRadius, fNodeXLVertexRadius,
                    new Microsoft.Glee.Splines.Point(0, 0)
                    );

            // Create a GLEE node that corresponds to the NodeXL node.

            Microsoft.Glee.Node oGleeNode =
                new Microsoft.Glee.Node(oVertex.ID.ToString(), oCurve);

            oGleeGraph.AddNode(oGleeNode);

            // Store the GLEE node as temporary metadata in the NodeXL node.

            oVertex.SetValue(ReservedMetadataKeys.SugiyamaGleeNode, oGleeNode);
        }

        // Loop through the NodeXL edges.

        ICollection<IEdge> oEdgesToLayOut =
            GetEdgesToLayOut(graph, verticesToLayOut);

        foreach (IEdge oEdge in oEdgesToLayOut)
        {
            // Retrieve the NodeXL edge's vertices.

            IVertex [] aoVertices = oEdge.Vertices;

            // Retrieve the corresponding GLEE node for the NodeXL edge's
            // vertices.

            Microsoft.Glee.Node oGleeNode0 =
                NodeXLVertexToGleeNode( aoVertices[0] );

            Microsoft.Glee.Node oGleeNode1 =
                NodeXLVertexToGleeNode( aoVertices[1] );

            // Create a GLEE edge using the two GLEE nodes.

            Microsoft.Glee.Edge oGleeEdge =
                new Microsoft.Glee.Edge(oGleeNode0, oGleeNode1);

            oGleeGraph.AddEdge(oGleeEdge);

            // Store the GLEE edge as temporary metadata in the NodeXL edge.

            oEdge.SetValue(
                ReservedMetadataKeys.SugiyamaGleeEdge, oGleeEdge);
        }

        // Tell GLEE to lay out the GLEE graph.  This shifts the node centers,
        // connects the nodes with lines, and computes the smallest rectangle
        // that contains all the nodes and edges.

        oGleeGraph.CalculateLayout();

        // The rectangle computed by GLEE does not have the dimensions
        // specified by layoutContext.GraphRectangle.  Get a transformation
        // that will map coordinates in the GLEE rectangle to coordinates in
        // the specified NodeXL rectangle.

        Matrix oTransformationMatrix =
            GetTransformationMatrix(oGleeGraph, layoutContext.GraphRectangle);

        // Because of the transformation, the radius of the vertices is no
        // longer the original fNodeXLVertexRadius.  Compute the transformed
        // radius.

        PointF [] aoRadiusPoints = new PointF [] {
            PointF.Empty,
            new PointF(0, fNodeXLVertexRadius)
            };

        oTransformationMatrix.TransformPoints(aoRadiusPoints);

        Double dX = aoRadiusPoints[1].X - aoRadiusPoints[0].X;
        Double dY = aoRadiusPoints[1].Y - aoRadiusPoints[0].Y;

        Single fTransformedNodeXLVertexRadius =
            (Single)Math.Sqrt(dX * dX + dY * dY);

        // Store the computed radius as metadata on the graph, to be retrieved
        // by SugiyamaVertexDrawer.DrawVertex().

        graph.SetValue(ReservedMetadataKeys.SugiyamaComputedRadius,
            fTransformedNodeXLVertexRadius);

        // Loop through the NodeXL vertices again.

        foreach (IVertex oVertex in verticesToLayOut)
        {
            // Retrieve the corresponding GLEE node.

            Microsoft.Glee.Node oGleeNode =
                NodeXLVertexToGleeNode(oVertex);

            oVertex.RemoveKey(ReservedMetadataKeys.SugiyamaGleeNode);

            // Get the shifted node center and transform it to NodeXL
            // coordinates.

            if ( !VertexIsLocked(oVertex) )
            {
                oVertex.Location = GleePointToTransformedPointF(
                    oGleeNode.Center, oTransformationMatrix);
            }
        }

        // Loop through the NodeXL edges again.

        foreach (IEdge oEdge in oEdgesToLayOut)
        {
            // Retrieve the corresponding GLEE edge.

            Microsoft.Glee.Edge oGleeEdge = NodeXLEdgeToGleeEdge(oEdge);

            oEdge.RemoveKey(ReservedMetadataKeys.SugiyamaGleeEdge);

            // Get the GLEE curve that describes most (but not all) of the
            // edge.

            Microsoft.Glee.Splines.Curve oCurve =
                (Microsoft.Glee.Splines.Curve)oGleeEdge.Curve;

            // TODO: In Microsoft.Glee.GraphViewerGdi.GViewer.
            // TransferGeometryFromGleeGraphToGraph() in the GLEE source code,
            // oCurve can apparently be null.  Can it be null here?  For now,
            // assume that the answer is no.

            Debug.Assert(oCurve != null);

            // Convert the curve to an array of PointF objects in NodeXL
            // coordinates.

            PointF [] aoCurvePoints = GleeCurveToTransformedPointFArray(
                oCurve, oTransformationMatrix);

            // Store the array as metadata in the edge, to be retrieved by
            // SugiyamaEdgeDrawer.DrawEdge().

            oEdge.SetValue(
                ReservedMetadataKeys.SugiyamaCurvePoints, aoCurvePoints);

            // Get the endpoint of the curve and transform it to NodeXL
            // coordinates.

            PointF oEndpoint = GleePointToTransformedPointF(
                oGleeEdge.ArrowHeadAtTargetPosition, oTransformationMatrix);

            // Store the endpoint as metadata in the edge, to be retrieved by
            // SugiyamaEdgeDrawer.DrawEdge().

            oEdge.SetValue(ReservedMetadataKeys.SugiyamaEndpoint, oEndpoint);
        }

        return (true);
    }