Smrf.NodeXL.Visualization.Wpf.NodeXLControl.CollapseGroupInternal C# (CSharp) Method

CollapseGroupInternal() protected method

protected CollapseGroupInternal ( GroupInfo oGroupToCollapse, System.Boolean bRedrawGroupImmediately ) : void
oGroupToCollapse Smrf.NodeXL.Core.GroupInfo
bRedrawGroupImmediately System.Boolean
return void
    CollapseGroupInternal
    (
        GroupInfo oGroupToCollapse,
        Boolean bRedrawGroupImmediately
    )
    {
        Debug.Assert(oGroupToCollapse != null);
        AssertValid();

        String groupName = oGroupToCollapse.Name;
        ICollection<IVertex> oVerticesInGroup = oGroupToCollapse.Vertices;

        if (IsCollapsedGroup(groupName) || oVerticesInGroup.Count == 0)
        {
            return;
        }

        // Create a vertex that will represent the collapsed group.

        IVertex oCollapsedGroupVertex = m_oGraph.Vertices.Add();

        SetGroupVertexAttributes(oGroupToCollapse, oCollapsedGroupVertex,
            oVerticesInGroup);

        // Save the collapsed vertices on the new group vertex.  These will be
        // used by ExpandGroup() if the group is later expanded.

        oCollapsedGroupVertex.SetValue(ReservedMetadataKeys.CollapsedVertices,
            oVerticesInGroup);

        // Store the vertices in a HashSet that will allow the code below to
        // quickly determine whether an edge is an internal edge, meaning that
        // both its vertices are in the group.

        HashSet<IVertex> oVerticesToCollapse =
            new HashSet<IVertex>(oVerticesInGroup);

        LinkedList<IEdge> oCollapsedInternalEdges = new LinkedList<IEdge>();
        LinkedList<IEdge> oExternalEdgeClones = new LinkedList<IEdge>();

        Boolean bGraphIsDirected =
            (m_oGraph.Directedness == GraphDirectedness.Directed);

        foreach (IVertex oVertexToCollapse in oVerticesInGroup)
        {
            foreach (IEdge oIncidentEdge in oVertexToCollapse.IncidentEdges)
            {
                IVertex oAdjacentVertex = oIncidentEdge.GetAdjacentVertex(
                    oVertexToCollapse);

                if ( oVerticesToCollapse.Contains(oAdjacentVertex) )
                {
                    // The incident edge is internal.  Save the edge in
                    // metadata on the group vertex so that ExpandGroup() can
                    // restore the edge by adding it back to the graph.

                    oCollapsedInternalEdges.AddLast(oIncidentEdge);
                }
                else
                {
                    // The incident edge connects to a vertex not in the group.
                    // In NodeXL, an edge can't be given new vertices.
                    // Instead, draw a cloned edge between the adjacent vertex
                    // and oCollapsedGroupVertex.

                    IEdge oExternalEdgeClone = null;

                    if ( oAdjacentVertex == oIncidentEdge.Vertices[0] )
                    {
                        oExternalEdgeClone = oIncidentEdge.Clone(true, true,
                            oAdjacentVertex, oCollapsedGroupVertex,
                            bGraphIsDirected);

                        // Save the collapsed vertex as metadata on the cloned
                        // edge.  ExpandGroup() will use this to connect to
                        // the collapsed vertex again.

                        oExternalEdgeClone.SetValue(
                            ReservedMetadataKeys.OriginalVertex2InEdge
                                + groupName,
                            oVertexToCollapse);
                    }
                    else
                    {
                        oExternalEdgeClone = oIncidentEdge.Clone(true, true,
                            oCollapsedGroupVertex, oAdjacentVertex,
                            bGraphIsDirected);

                        oExternalEdgeClone.SetValue(
                            ReservedMetadataKeys.OriginalVertex1InEdge
                                + groupName,
                            oVertexToCollapse);
                    }

                    oExternalEdgeClones.AddLast(oExternalEdgeClone);
                }

                RemoveEdgeDuringGroupCollapseOrExpand(oIncidentEdge,
                    bRedrawGroupImmediately);
            }

            RemoveVertexDuringGroupCollapseOrExpand(oVertexToCollapse,
                bRedrawGroupImmediately);
        }

        // The drawing of the new vertices and edges must be done in a
        // particular order to satisfy the needs of the
        // CollapsedGroupDrawingManager class, which the drawing code uses to
        // modify the appearance of a collapsed group and its external edges.
        //
        // First, add the cloned external edges to the graph, but don't draw
        // them yet.

        foreach (IEdge oExternalEdgeClone in oExternalEdgeClones)
        {
            AddEdgeDuringGroupCollapseOrExpand(oExternalEdgeClone, false);
        }

        // Now draw the collapsed group vertex.  Before the vertex is drawn,
        // CollapsedGroupDrawingManager.PreDrawVertex() might add metadata to
        // the vertex and its incident edges to change their appearance.
        // That's why the cloned external edges can't be drawn yet.

        if (bRedrawGroupImmediately && m_oLastGraphDrawingContext != null)
        {
            m_oGraphDrawer.DrawNewVertex(oCollapsedGroupVertex,
                m_oLastGraphDrawingContext);
        }

        // Now draw the cloned external edges.

        foreach (IEdge oExternalEdgeClone in oExternalEdgeClones)
        {
            if (m_oLastGraphDrawingContext != null)
            {
                m_oGraphDrawer.DrawNewEdge(
                    oExternalEdgeClone, m_oLastGraphDrawingContext);
            }
        }

        // Save the collapsed internal edges on the new group vertex.  These
        // will be used by ExpandGroup() if the group is later expanded.

        oCollapsedGroupVertex.SetValue(
            ReservedMetadataKeys.CollapsedInternalEdges,
            oCollapsedInternalEdges);

        m_oCollapsedGroups.Add(groupName, oCollapsedGroupVertex);
    }
NodeXLControl