Smrf.NodeXL.Visualization.Wpf.GraphDrawer.DrawGraph C# (CSharp) Method

DrawGraph() public method

public DrawGraph ( IGraph graph, GraphDrawingContext graphDrawingContext ) : void
graph IGraph
graphDrawingContext GraphDrawingContext
return void
    DrawGraph
    (
        IGraph graph,
        GraphDrawingContext graphDrawingContext
    )
    {
        Debug.Assert(graph != null);
        Debug.Assert(graphDrawingContext != null);
        AssertValid();

        // Implementation note:
        //
        // In a previous GDI+ implementation of this graph drawer, the edges
        // had to be drawn first to allow the vertices to cover the ends of the
        // edges.  That required a complex three-step drawing process: 1) allow
        // the vertex drawer to move each vertex if necessary to prevent the
        // vertex from falling outside the graph rectangle; 2) draw the edges
        // using the moved vertex locations; and 3) draw the vertices.
        //
        // This WPF implementation is simpler, for two reasons:
        //
        // 1. WPF uses retained-mode graphics, so covering the ends of the
        //    edges can be accomplished simply by adding
        //    m_oUnselectedEdgeDrawingVisuals to m_oVisualCollection before
        //    adding m_oAllVertexDrawingVisuals.  That means that the vertices
        //    can be drawn onto m_oAllVertexDrawingVisuals first, and the
        //    vertex drawer can move the vertices as necessary before drawing
        //    them.  A three-step process is no longer required.
        //
        // 2. The edges in this implementation don't actually need to be
        //    covered, because they terminate at the vertex boundaries instead
        //    of the vertex centers, as in the GDI+ implementation.

        m_oVisualCollection.Clear();

        DrawBackground(graph, graphDrawingContext);

        Visual oGroupVisual;

        if ( m_oGroupDrawer.TryDrawGroupRectangles(graph, graphDrawingContext,
            out oGroupVisual) )
        {
            m_oVisualCollection.Add(oGroupVisual);
        }

        if ( m_oGroupDrawer.TryDrawCombinedIntergroupEdges(
            graph, graphDrawingContext, out oGroupVisual) )
        {
            m_oVisualCollection.Add(oGroupVisual);
        }

        m_oAllVertexDrawingVisuals = new DrawingVisual();
        m_oUnselectedEdgeDrawingVisuals = new DrawingVisual();
        m_oSelectedEdgeDrawingVisuals = new DrawingVisual();

        // Draw the vertices after moving them if necessary.  Each vertex needs
        // to be individually hit-tested and possibly redrawn by
        // RedrawVertex(), so each vertex is put into its own DrawingVisual
        // that becomes a child of m_oAllVertexDrawingVisuals.
        //
        // Selected vertices should always be on top of unselected vertices, so
        // draw them first.  Note that this could also be accomplished by using
        // two DrawingVisual objects, m_oUnselectedVertexDrawingVisuals and
        // m_oSelectedVertexDrawingVisuals, in a manner similar to what is done
        // for edges.  However, vertices have to be hit-tested, and having two
        // DrawingVisual objects for two sets of vertices would complicate and
        // slow down hit-testing, so this solution is the simpler one.

        LinkedList<IVertex> oSelectedVertices = new LinkedList<IVertex>();

        foreach ( IVertex oVertex in GetVerticesToDraw(graph) )
        {
            if ( m_oVertexDrawer.GetDrawAsSelected(oVertex) )
            {
                oSelectedVertices.AddLast(oVertex);
            }
            else
            {
                DrawVertex(oVertex, graphDrawingContext);
            }
        }

        foreach (IVertex oVertex in oSelectedVertices)
        {
            DrawVertex(oVertex, graphDrawingContext);
        }

        oSelectedVertices = null;

        // Draw the edges.  The edges don't need to be hit-tested, but they
        // might need to be redrawn by RedrawEdge(), so each edge is put into
        // its own DrawingVisual that becomes a child of either
        // m_oUnselectedEdgeDrawingVisuals or m_oSelectedEdgeDrawingVisuals.

        foreach (IEdge oEdge in graph.Edges)
        {
            DrawEdge(oEdge, graphDrawingContext);
        }

        // Selected edges need to be drawn on top of all the vertices
        // (including selected vertices) to guarantee that they will be
        // visible; hence the addition order seen here.

        m_oVisualCollection.Add(m_oUnselectedEdgeDrawingVisuals);
        m_oVisualCollection.Add(m_oAllVertexDrawingVisuals);
        m_oVisualCollection.Add(m_oSelectedEdgeDrawingVisuals);

        if ( m_oGroupDrawer.TryDrawGroupLabels(graph, graphDrawingContext,
            out oGroupVisual) )
        {
            m_oVisualCollection.Add(oGroupVisual);
        }
    }