Contains information about one vertex group.
Inheritance: Object
示例#1
0
    TryGetGroups
    (
        IGraph graph,
        out GroupInfo [] groups
    )
    {
        Debug.Assert(graph != null);

        groups = ( GroupInfo[] )graph.GetValue(
            ReservedMetadataKeys.GroupInfo, typeof( GroupInfo[] ) );

        return (groups != null && groups.Length > 0);
    }
    GetTopGroups
    (
        GroupInfo [] groups,
        Int32 maximumGroups
    )
    {
        Debug.Assert(groups != null);
        Debug.Assert(maximumGroups > 0);

        return ( 
            (from oGroupInfo in groups
            orderby oGroupInfo.Vertices.Count descending
            select (ExcelTemplateGroupInfo)oGroupInfo).Take(maximumGroups)
            );
    }
    AddCollapsedGroupAttributesInternal
    (
        Microsoft.Office.Interop.Excel.Workbook oWorkbook,
        ReadWorkbookContext oReadWorkbookContext,
        ListObject oEdgeTable,
        ListObject oVertexTable,
        GroupInfo[] aoGroups
    )
    {
        Debug.Assert(oWorkbook != null);
        Debug.Assert(oReadWorkbookContext != null);
        Debug.Assert(oEdgeTable != null);
        Debug.Assert(oVertexTable != null);
        Debug.Assert(aoGroups != null);
        Debug.Assert(aoGroups.Length > 0);

        // Check whether relevant columns have been autofilled using numerical
        // source columns.

        PerWorkbookSettings oPerWorkbookSettings =
            new PerWorkbookSettings(oWorkbook);

        AutoFillColorColumnResults oVertexColorResults =
            oPerWorkbookSettings.AutoFillWorkbookResults.VertexColorResults;

        Boolean bVertexColorColumnAutoFilled =
            oVertexColorResults.ColumnAutoFilled &&
            !oVertexColorResults.ColumnAutoFilledWithCategories;

        AutoFillColorColumnResults oEdgeColorResults =
            oPerWorkbookSettings.AutoFillWorkbookResults.EdgeColorResults;

        Boolean bEdgeColorColumnAutoFilled =
            oEdgeColorResults.ColumnAutoFilled &&
            !oEdgeColorResults.ColumnAutoFilledWithCategories;

        AutoFillNumericRangeColumnResults oEdgeWidthResults =
            oPerWorkbookSettings.AutoFillWorkbookResults.EdgeWidthResults;

        Boolean bEdgeWidthColumnAutoFilled =
            oEdgeWidthResults.ColumnAutoFilled;

        // Some user settings for autofill may be needed.
        //
        // Note: This is a design bug.  The user's current settings should not
        // be required; everything needed here should come from the autofill
        // results.  The long-term fix is to add a UseLogs property to the
        // AutoFillColorColumnResults class.

        AutoFillUserSettings oAutoFillUserSettings =
            new AutoFillUserSettings();

        ColorColumnAutoFillUserSettings oVertexColorDetails =
            oAutoFillUserSettings.VertexColorDetails;

        ColorColumnAutoFillUserSettings oEdgeColorDetails =
            oAutoFillUserSettings.EdgeColorDetails;

        NumericRangeColumnAutoFillUserSettings oEdgeWidthDetails =
            oAutoFillUserSettings.EdgeWidthDetails;

        // The key is the row ID for each visible row in the vertex table and
        // the value is value of the source column cell in that row that was
        // used to autofill the vertex color column, if it was autofilled.

        Dictionary<Int32, Object> oVertexColorSourceDictionary =
            bVertexColorColumnAutoFilled ?

            GetRowIDDictionary(oVertexTable,
                oVertexColorResults.SourceColumnName)
            :
            null;

        // Ditto for edge colors and edge widths.

        Dictionary<Int32, Object> oEdgeColorSourceDictionary =
            bEdgeColorColumnAutoFilled ?

            GetRowIDDictionary(oEdgeTable, oEdgeColorResults.SourceColumnName)
            :
            null;

        Dictionary<Int32, Object> oEdgeWidthSourceDictionary =
            bEdgeWidthColumnAutoFilled ?

            GetRowIDDictionary(oEdgeTable, oEdgeWidthResults.SourceColumnName)
            :
            null;

        // Only motifs need to have attributes added to them.

        foreach ( ExcelTemplateGroupInfo oGroup in aoGroups.Where(
            oGroup => oGroup.CollapsedAttributes != null) )
        {
            CollapsedGroupAttributes oCollapsedGroupAttributes =
                CollapsedGroupAttributes.FromString(
                    oGroup.CollapsedAttributes);

            String sType = oCollapsedGroupAttributes.GetGroupType();

            if (
                sType == CollapsedGroupAttributeValues.FanMotifType
                ||
                sType == CollapsedGroupAttributeValues.DConnectorMotifType
                ||
                sType == CollapsedGroupAttributeValues.CliqueMotifType
                )
            {
                AddVertexColorAttributeToMotif(oGroup, sType,
                    bVertexColorColumnAutoFilled, oVertexColorResults,
                    oVertexColorDetails, oVertexColorSourceDictionary,
                    oReadWorkbookContext, oCollapsedGroupAttributes);
            }

            if (sType == CollapsedGroupAttributeValues.DConnectorMotifType)
            {
                Int32 iAnchorVertices;

                if ( oCollapsedGroupAttributes.TryGetValue(
                    CollapsedGroupAttributeKeys.AnchorVertices,
                    out iAnchorVertices) )
                {
                    AddEdgeColorAttributesToDConnectorMotif(oGroup, 
                        bEdgeColorColumnAutoFilled, oEdgeColorResults,
                        oEdgeColorDetails, oEdgeColorSourceDictionary,
                        oReadWorkbookContext, oCollapsedGroupAttributes,
                        iAnchorVertices);

                    AddEdgeWidthAttributesToDConnectorMotif(oGroup,
                        bEdgeWidthColumnAutoFilled, oEdgeWidthResults,
                        oEdgeWidthDetails, oEdgeWidthSourceDictionary,
                        oReadWorkbookContext, oCollapsedGroupAttributes,
                        iAnchorVertices);
                }
            }

            oGroup.CollapsedAttributes = oCollapsedGroupAttributes.ToString();
        }
    }
    EnumerateGroupsForCountingVertexTerms
    (
        IGraph oGraph
    )
    {
        Debug.Assert(oGraph != null);
        AssertValid();

        // Start with a dummy group that contains all the graph's vertices.
        // For consistency, use the same group name used by the GroupEdgeSorter
        // for such a group.

        GroupInfo oDummyGroupForEntireGraph = new GroupInfo();

        oDummyGroupForEntireGraph.Name =
            GroupEdgeSorter.DummyGroupNameForEntireGraph;

        foreach (IVertex oVertex in oGraph.Vertices)
        {
            oDummyGroupForEntireGraph.Vertices.AddLast(oVertex);
        }

        yield return oDummyGroupForEntireGraph;

        oDummyGroupForEntireGraph = null;

        // Get a list of the graph's groups, adding a dummy group if necessary
        // to contain any non-grouped vertices.

        foreach ( GroupInfo oGroup in GroupUtil.GetGroupsWithAllVertices(
            oGraph, false) )
        {
            if (oGroup.Name == null)
            {
                // This is the dummy group that contains non-grouped vertices.

                oGroup.Name = GroupEdgeSorter.DummyGroupNameForUngroupedEdges;
            }

            yield return oGroup;
        }
    }
    TryGetGroupRectangle
    (
        GroupInfo oGroupInfo,
        out Rect oGroupRectangle
    )
    {
        Debug.Assert(oGroupInfo != null);
        AssertValid();

        oGroupRectangle = WpfGraphicsUtil.RectangleToRect(
            oGroupInfo.Rectangle);

        return (oGroupRectangle.Width > 0 && oGroupRectangle.Height > 0);
    }
    GetReadColorAndShapeFlags
    (
        IVertex oVertex,
        GroupInfo oGroup,
        ReadWorkbookContext oReadWorkbookContext,
        out Boolean bReadColorFromGroup,
        out Boolean bReadShapeFromGroup
    )
    {
        Debug.Assert(oVertex != null);
        Debug.Assert(oReadWorkbookContext != null);
        AssertValid();

        // Assume that the settings specified in the context object will be
        // used.

        bReadColorFromGroup = oReadWorkbookContext.ReadVertexColorFromGroups;
        bReadShapeFromGroup = oReadWorkbookContext.ReadVertexShapeFromGroups;

        if (oGroup.CollapsedAttributes != null)
        {
            CollapsedGroupAttributes oCollapsedGroupAttributes =
                CollapsedGroupAttributes.FromString(
                    oGroup.CollapsedAttributes);

            String sHeadVertexName;

            if (
                oCollapsedGroupAttributes.GetGroupType() ==
                    CollapsedGroupAttributeValues.FanMotifType
                &&
                oCollapsedGroupAttributes.TryGetValue(
                    CollapsedGroupAttributeKeys.HeadVertexName,
                        out sHeadVertexName)
                &&
                oVertex.Name == sHeadVertexName
                )
            {
                // The shape of a fan motif's head vertex should never be
                // changed.  Do not get it from the group.

                bReadShapeFromGroup = false;
            }
        }
    }
    TestOnLayoutBegin()
    {
        // Draw rectangles, hide intergroup edges.

        const Double GroupRectanglePenWidth = 1.23;

        const IntergroupEdgeStyle IntergroupEdgeStyle =
            IntergroupEdgeStyle.Hide;

        IGraph oGraph = new Graph(GraphDirectedness.Undirected);

        IVertex[] aoVertices = TestGraphUtil.AddVertices(oGraph, 4);

        IEdgeCollection oEdges = oGraph.Edges;
        IEdge oEdge1 = oEdges.Add(aoVertices[0], aoVertices[1], false);
        IEdge oEdge2 = oEdges.Add(aoVertices[0], aoVertices[2], false);
        IEdge oEdge3 = oEdges.Add(aoVertices[2], aoVertices[3], false);
        IEdge oEdge4 = oEdges.Add(aoVertices[1], aoVertices[3], false);

        // oEdge2 is intergroup.  Give it an initial visibility. 

        oEdge2.SetValue(ReservedMetadataKeys.Visibility,
            VisibilityKeyValue.Filtered);

        // (oEdge4 is intergroup.  Don't give it an initial visibility.)

        GroupInfo oGroup1 = new GroupInfo();
        oGroup1.Vertices.AddLast( aoVertices[0] );
        oGroup1.Vertices.AddLast( aoVertices[1] );
        oGroup1.Rectangle = Rectangle.FromLTRB(1, 2, 3, 4);

        GroupInfo oGroup2 = new GroupInfo();
        oGroup2.Vertices.AddLast( aoVertices[2] );
        oGroup2.Vertices.AddLast( aoVertices[3] );
        oGroup2.Rectangle = Rectangle.FromLTRB(5, 6, 7, 8);

        GroupMetadataManager.OnLayoutBegin(oGraph);

        GroupMetadataManager.OnLayoutUsingGroupsEnd(oGraph,
            new GroupInfo[] {oGroup1, oGroup2},
            GroupRectanglePenWidth, IntergroupEdgeStyle);

        GroupLayoutDrawingInfo oGroupLayoutDrawingInfo;

        Assert.IsTrue( GroupMetadataManager.TryGetGroupLayoutDrawingInfo(
            oGraph, out oGroupLayoutDrawingInfo) );

        Assert.AreEqual(GroupRectanglePenWidth,
            oGroupLayoutDrawingInfo.PenWidth);

        IList<GroupInfo> oGroupInfo = oGroupLayoutDrawingInfo.GroupsToDraw;

        Assert.AreEqual(2, oGroupInfo.Count);
        Assert.AreEqual( oGroup1, oGroupInfo[0] );
        Assert.AreEqual( oGroup2, oGroupInfo[1] );

        Assert.IsTrue( oGraph.ContainsKey(
            ReservedMetadataKeys.IntergroupEdgesHidden) );

        Assert.IsFalse( oEdge1.ContainsKey(
            ReservedMetadataKeys.SavedVisibility) );

        Assert.IsTrue( oEdge2.ContainsKey(
            ReservedMetadataKeys.SavedVisibility) );

        Assert.AreEqual( VisibilityKeyValue.Filtered,
            oEdge2.GetValue(ReservedMetadataKeys.SavedVisibility) );

        Assert.IsTrue( oEdge2.ContainsKey(
            ReservedMetadataKeys.Visibility) );

        Assert.AreEqual( VisibilityKeyValue.Hidden,
            oEdge2.GetValue(ReservedMetadataKeys.Visibility) );

        Assert.IsFalse( oEdge3.ContainsKey(
            ReservedMetadataKeys.SavedVisibility) );

        Assert.IsTrue( oEdge4.ContainsKey(
            ReservedMetadataKeys.Visibility) );

        Assert.AreEqual( VisibilityKeyValue.Hidden,
            oEdge4.GetValue(ReservedMetadataKeys.Visibility) );

        // Verify that OnLayoutBegin() reverses the metadata changes.

        GroupMetadataManager.OnLayoutBegin(oGraph);

        VerifyOriginalMetadata(oGraph, oEdge1, oEdge2, oEdge3, oEdge4);
    }
    TestOnLayoutBegin6()
    {
        // Request that intergroup edges be combined, and there are some.

        const Double GroupRectanglePenWidth = 4.567;

        const IntergroupEdgeStyle IntergroupEdgeStyle =
            IntergroupEdgeStyle.Combine;

        IGraph oGraph = new Graph(GraphDirectedness.Undirected);

        IVertex[] aoVertices = TestGraphUtil.AddVertices(oGraph, 5);

        IEdgeCollection oEdges = oGraph.Edges;

        // Not intergroup.

        IEdge oEdge1 = oEdges.Add(aoVertices[0], aoVertices[1], false);
        IEdge oEdge2 = oEdges.Add(aoVertices[2], aoVertices[3], false);

        // Intergroup, between groups 1 and 2.

        IEdge oEdge3 = oEdges.Add(aoVertices[0], aoVertices[2], false);
        IEdge oEdge4 = oEdges.Add(aoVertices[1], aoVertices[2], false);
        IEdge oEdge5 = oEdges.Add(aoVertices[1], aoVertices[3], false);

        // Intergroup, between groups 2 and 3.

        IEdge oEdge6 = oEdges.Add(aoVertices[2], aoVertices[4], false);
        IEdge oEdge7 = oEdges.Add(aoVertices[3], aoVertices[4], false);

        // Intergroup, between groups 1 and 3.

        IEdge oEdge8 = oEdges.Add(aoVertices[1], aoVertices[4], false);

        GroupInfo oGroup1 = new GroupInfo();
        oGroup1.Vertices.AddLast( aoVertices[0] );
        oGroup1.Vertices.AddLast( aoVertices[1] );
        oGroup1.Rectangle = Rectangle.FromLTRB(1, 2, 3, 4);

        GroupInfo oGroup2 = new GroupInfo();
        oGroup2.Vertices.AddLast( aoVertices[2] );
        oGroup2.Vertices.AddLast( aoVertices[3] );
        oGroup2.Rectangle = Rectangle.FromLTRB(5, 6, 7, 8);

        GroupInfo oGroup3 = new GroupInfo();
        oGroup3.Vertices.AddLast( aoVertices[4] );
        oGroup3.Rectangle = Rectangle.FromLTRB(9, 10, 11, 12);

        GroupMetadataManager.OnLayoutBegin(oGraph);

        GroupMetadataManager.OnLayoutUsingGroupsEnd(oGraph,
            new GroupInfo[] {oGroup1, oGroup2, oGroup3},
            GroupRectanglePenWidth, IntergroupEdgeStyle);

        GroupLayoutDrawingInfo oGroupLayoutDrawingInfo;

        Assert.IsTrue( GroupMetadataManager.TryGetGroupLayoutDrawingInfo(
            oGraph, out oGroupLayoutDrawingInfo) );

        Assert.AreEqual(GroupRectanglePenWidth,
            oGroupLayoutDrawingInfo.PenWidth);

        IList<GroupInfo> oGroupInfo = oGroupLayoutDrawingInfo.GroupsToDraw;

        Assert.AreEqual(3, oGroupInfo.Count);
        Assert.AreEqual( oGroup1, oGroupInfo[0] );
        Assert.AreEqual( oGroup2, oGroupInfo[1] );
        Assert.AreEqual( oGroup3, oGroupInfo[2] );

        Assert.IsTrue( oGraph.ContainsKey(
            ReservedMetadataKeys.IntergroupEdgesHidden) );

        Assert.IsFalse( oEdge1.ContainsKey(
            ReservedMetadataKeys.SavedVisibility) );

        Assert.IsFalse( oEdge2.ContainsKey(
            ReservedMetadataKeys.SavedVisibility) );

        Assert.IsTrue( oEdge3.ContainsKey(
            ReservedMetadataKeys.SavedVisibility) );

        Assert.IsTrue( oEdge4.ContainsKey(
            ReservedMetadataKeys.SavedVisibility) );

        Assert.IsTrue( oEdge5.ContainsKey(
            ReservedMetadataKeys.SavedVisibility) );

        Assert.IsTrue( oEdge6.ContainsKey(
            ReservedMetadataKeys.SavedVisibility) );

        Assert.IsTrue( oEdge7.ContainsKey(
            ReservedMetadataKeys.SavedVisibility) );

        Assert.IsTrue( oEdge8.ContainsKey(
            ReservedMetadataKeys.SavedVisibility) );

        Assert.AreEqual( 3,
            oGroupLayoutDrawingInfo.CombinedIntergroupEdges.Count() );

        IntergroupEdgeInfo oCombinedIntergroupEdge;

        oCombinedIntergroupEdge =
            oGroupLayoutDrawingInfo.CombinedIntergroupEdges.Single(
                intergroupEdgeInfo =>
                intergroupEdgeInfo.Group1Index == 0
                &&
                intergroupEdgeInfo.Group2Index == 1
                );

        Assert.AreEqual(0, oCombinedIntergroupEdge.Group1Index);
        Assert.AreEqual(1, oCombinedIntergroupEdge.Group2Index);
        Assert.AreEqual(3, oCombinedIntergroupEdge.Edges);

        oCombinedIntergroupEdge =
            oGroupLayoutDrawingInfo.CombinedIntergroupEdges.Single(
                intergroupEdgeInfo =>
                intergroupEdgeInfo.Group1Index == 0
                &&
                intergroupEdgeInfo.Group2Index == 2
                );

        Assert.AreEqual(0, oCombinedIntergroupEdge.Group1Index);
        Assert.AreEqual(2, oCombinedIntergroupEdge.Group2Index);
        Assert.AreEqual(1, oCombinedIntergroupEdge.Edges);

        oCombinedIntergroupEdge =
            oGroupLayoutDrawingInfo.CombinedIntergroupEdges.Single(
                intergroupEdgeInfo =>
                intergroupEdgeInfo.Group1Index == 1
                &&
                intergroupEdgeInfo.Group2Index == 2
                );

        Assert.AreEqual(1, oCombinedIntergroupEdge.Group1Index);
        Assert.AreEqual(2, oCombinedIntergroupEdge.Group2Index);
        Assert.AreEqual(2, oCombinedIntergroupEdge.Edges);
    }
    TestCalculateGraphMetrics10()
    {
        // More complex case, undirected, check edge weight sum.

        Boolean bIsDirected = false;

        // Using directedness makes no difference in this case.

        foreach (Boolean bUseDirectedness in TestGraphUtil.AllBoolean)
        {
            CreateGraph(bIsDirected);

            IVertex oVertexA = m_oVertices.Add();
            IVertex oVertexB = m_oVertices.Add();

            IVertex oVertexC = m_oVertices.Add();
            IVertex oVertexD = m_oVertices.Add();

            IVertex oVertexE = m_oVertices.Add();
            IVertex oVertexF = m_oVertices.Add();

            IEdge oEdge;

            m_oEdges.Add(oVertexA, oVertexA, bIsDirected);

            oEdge = m_oEdges.Add(oVertexA, oVertexB, bIsDirected);
            oEdge.SetValue(ReservedMetadataKeys.EdgeWeight, 1.11);

            m_oEdges.Add(oVertexA, oVertexB, bIsDirected);
            m_oEdges.Add(oVertexA, oVertexC, bIsDirected);
            m_oEdges.Add(oVertexA, oVertexD, bIsDirected);
            m_oEdges.Add(oVertexC, oVertexD, bIsDirected);

            oEdge = m_oEdges.Add(oVertexE, oVertexC, bIsDirected);
            oEdge.SetValue(ReservedMetadataKeys.EdgeWeight, 123.0);

            // An edge weight of 0 is counted as 1.0.

            oEdge = m_oEdges.Add(oVertexD, oVertexE, bIsDirected);
            oEdge.SetValue(ReservedMetadataKeys.EdgeWeight, 0.0);

            m_oEdges.Add(oVertexA, oVertexE, bIsDirected);

            // A negative edge weight is counted as 1.0.

            oEdge = m_oEdges.Add(oVertexF, oVertexD, bIsDirected);
            oEdge.SetValue(ReservedMetadataKeys.EdgeWeight, -123.0);

            GroupInfo oGroup1 = new GroupInfo();
            oGroup1.Vertices.AddLast(oVertexA);
            oGroup1.Vertices.AddLast(oVertexB);

            GroupInfo oGroup2 = new GroupInfo();
            oGroup2.Vertices.AddLast(oVertexC);
            oGroup2.Vertices.AddLast(oVertexD);

            GroupInfo oGroup3 = new GroupInfo();
            oGroup3.Vertices.AddLast(oVertexE);
            oGroup3.Vertices.AddLast(oVertexF);

            IList<IntergroupEdgeInfo> oIntergroupEdges =
                m_oIntergroupEdgeCalculator.CalculateGraphMetrics(m_oGraph,
                    new GroupInfo[] {oGroup1, oGroup2, oGroup3},
                    bUseDirectedness);

            Assert.AreEqual(5, oIntergroupEdges.Count);

            Assert.AreEqual( 3, GetEdgeCount(oIntergroupEdges, 0, 0) );
            Assert.AreEqual( 2, GetEdgeCount(oIntergroupEdges, 0, 1) );
            Assert.AreEqual( 1, GetEdgeCount(oIntergroupEdges, 0, 2) );
            Assert.AreEqual( 1, GetEdgeCount(oIntergroupEdges, 1, 1) );
            Assert.AreEqual( 3, GetEdgeCount(oIntergroupEdges, 1, 2) );

            Assert.AreEqual( 3.11,
                Math.Round(GetEdgeWeightSum(oIntergroupEdges, 0, 0), 2 ) );

            Assert.AreEqual( 2.0, GetEdgeWeightSum(oIntergroupEdges, 0, 1) );
            Assert.AreEqual( 1.0, GetEdgeWeightSum(oIntergroupEdges, 0, 2) );
            Assert.AreEqual( 1.0, GetEdgeWeightSum(oIntergroupEdges, 1, 1) );
            Assert.AreEqual( 125.0, GetEdgeWeightSum(oIntergroupEdges, 1, 2) );
        }
    }
示例#10
0
    //*************************************************************************
    //  Method: getConnectivityBetween()
    //
    /// <summary>
    /// Get whether there is connectivity between two groups in a graph.
    /// </summary>
    /// 
    /// <param name="g1">
    /// Group 1
    /// </param>
    /// 
    /// <param name="g2">
    /// Group 2
    /// </param>
    /// 
    /// <param name="oGraph">
    /// The graph these groups are in
    /// </param>
    /// 
    /// <returns>
    /// True if there is connectivity, false otherwise.
    /// </returns>
    //*************************************************************************

    public bool getConnectivityBetween(GroupInfo g1, GroupInfo g2, IGraph oGraph)
    {

        IntergroupEdgeCalculator m_oIntergroupEdgeCalculator = new IntergroupEdgeCalculator();

        // Currently uses undirected graph
        IList<IntergroupEdgeInfo> oIntergroupEdges =
            m_oIntergroupEdgeCalculator.CalculateGraphMetrics(oGraph,
                new GroupInfo[] { g1, g2 }, false);

        foreach (IntergroupEdgeInfo e in oIntergroupEdges)
        {
            if (e.Group1Index == 0 && e.Group2Index == 1)
            {
                return e.Edges > 0;
        }
        }
        return false;
    }
示例#11
0
 public GroupVertex(GroupInfo groupInfo, Single areaPerVertex)
 {
     this.Name = groupInfo.Name;
     this.groupInfo = groupInfo;
     this.areaPerVertex = areaPerVertex;
 }
示例#12
0
    GetGroupsWithAllVertices
    (
        IGraph graph,
        Boolean checkForCollapsedGroups
    )
    {
        Debug.Assert(graph != null);

        // This HashSet initially contains all the graph's vertices.  It will
        // eventually contain only vertices that aren't in a group, along with
        // each vertex that represents a collapsed group.

        HashSet<IVertex> oRemainingVertices =
            new HashSet<IVertex>(graph.Vertices);

        List<GroupInfo> oGroupList = new List<GroupInfo>();

        foreach ( GroupInfo oGroupInfo in GetGroups(graph) )
        {
            ICollection<IVertex> oVertices = oGroupInfo.Vertices;

            Debug.Assert(oVertices != null);

            if (oVertices.Count == 0)
            {
                continue;
            }

            if (checkForCollapsedGroups &&
                oVertices.First().ParentGraph == null)
            {
                // The group has been collapsed.  See
                // NodeXLControl.CollapseGroup() for information about how
                // groups are collapsed.

                continue;
            }

            oGroupList.Add(oGroupInfo);

            foreach (IVertex oVertex in oVertices)
            {
                oRemainingVertices.Remove(oVertex);
            }
        }

        if (oRemainingVertices.Count > 0)
        {
            // Add a GroupInfo object for the vertices that aren't in a group.

            GroupInfo oRemainingVertexInformation = new GroupInfo();

            foreach (IVertex oRemainingVertex in oRemainingVertices)
            {
                oRemainingVertexInformation.Vertices.AddLast(oRemainingVertex);
            }

            oGroupList.Add(oRemainingVertexInformation);
        }

        return (oGroupList);
    }
示例#13
0
    GetGroups
    (
        IGraph graph
    )
    {
        Debug.Assert(graph != null);

        GroupInfo [] aoGroups;

        if ( !TryGetGroups(graph, out aoGroups) )
        {
            aoGroups = new GroupInfo[0];
        }

        return (aoGroups);
    }
    GetRowIDsToAverageForEdges
    (
        GroupInfo oGroup,
        CollapsedGroupAttributes oCollapsedGroupAttributes,
        Int32 iAnchorVertexIndex
    )
    {
        Debug.Assert(oGroup != null);
        Debug.Assert(oCollapsedGroupAttributes != null);
        Debug.Assert(iAnchorVertexIndex >= 0);

        List<Int32> oRowIDsOfRowsToAverage = new List<Int32>();

        String sAnchorVertexName;

        if ( oCollapsedGroupAttributes.TryGetValue(

                CollapsedGroupAttributeKeys.GetAnchorVertexNameKey(
                    iAnchorVertexIndex),

                out sAnchorVertexName) )
        {
            // The group's vertices are the span vertices.  Loop through them.

            foreach (IVertex oVertex in oGroup.Vertices)
            {
                // We need to find the edge that is incident to the specified
                // anchor vertex.

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

                    if (oAdjacentVertex.Name == sAnchorVertexName)
                    {
                        // The row ID is stored in the edge's Tag, as long as
                        // the edge row isn't hidden.

                        if (oIncidentEdge.Tag is Int32)
                        {
                            oRowIDsOfRowsToAverage.Add(
                                (Int32)oIncidentEdge.Tag);
                        }

                        break;
                    }
                }
            }
        }

        return (oRowIDsOfRowsToAverage);
    }
    GetRowIDsToAverageForVertexColor
    (
        GroupInfo oGroup,
        CollapsedGroupAttributes oCollapsedGroupAttributes,
        String sType
    )
    {
        Debug.Assert(oGroup != null);
        Debug.Assert(oCollapsedGroupAttributes != null);
        Debug.Assert( !String.IsNullOrEmpty(sType) );

        List<Int32> oRowIDsOfRowsToAverage = new List<Int32>();
        IEnumerable<IVertex> oVerticesToAverage = null;

        switch (sType)
        {
            // Fan, Connector, and Clique fall through as each includes the proper vertices
            case CollapsedGroupAttributeValues.FanMotifType:

            case CollapsedGroupAttributeValues.DConnectorMotifType:

            case CollapsedGroupAttributeValues.CliqueMotifType:

                // All of the motif's vertices should be included.

                oVerticesToAverage = oGroup.Vertices;
                break;

            default:

                break;
        }

        if (oVerticesToAverage != null)
        {
            foreach (IVertex oVertex in oVerticesToAverage)
            {
                // The row ID is stored in the vertex's Tag, as long as the
                // vertex row isn't hidden.

                if (oVertex.Tag is Int32)
                {
                    oRowIDsOfRowsToAverage.Add( (Int32)oVertex.Tag );
                }
            }
        }

        return (oRowIDsOfRowsToAverage);
    }
    TestCalculateGraphMetrics7()
    {
        // Many parallel edges, undirected.

        Boolean bIsDirected = false;

        CreateGraph(bIsDirected);

        IVertex oVertexA = m_oVertices.Add();
        IVertex oVertexB = m_oVertices.Add();

        IVertex oVertexC = m_oVertices.Add();
        IVertex oVertexD = m_oVertices.Add();

        m_oEdges.Add(oVertexA, oVertexB, bIsDirected);
        m_oEdges.Add(oVertexB, oVertexA, bIsDirected);
        m_oEdges.Add(oVertexB, oVertexA, bIsDirected);

        m_oEdges.Add(oVertexB, oVertexC, bIsDirected);
        m_oEdges.Add(oVertexC, oVertexB, bIsDirected);

        m_oEdges.Add(oVertexA, oVertexD, bIsDirected);
        m_oEdges.Add(oVertexA, oVertexD, bIsDirected);
        m_oEdges.Add(oVertexA, oVertexD, bIsDirected);
        m_oEdges.Add(oVertexA, oVertexD, bIsDirected);

        m_oEdges.Add(oVertexD, oVertexC, bIsDirected);
        m_oEdges.Add(oVertexD, oVertexC, bIsDirected);

        m_oEdges.Add(oVertexD, oVertexD, bIsDirected);
        m_oEdges.Add(oVertexD, oVertexD, bIsDirected);

        GroupInfo oGroup1 = new GroupInfo();
        oGroup1.Vertices.AddLast(oVertexA);
        oGroup1.Vertices.AddLast(oVertexB);

        GroupInfo oGroup2 = new GroupInfo();
        oGroup2.Vertices.AddLast(oVertexC);
        oGroup2.Vertices.AddLast(oVertexD);

        // Using directedness makes no difference in this case.

        foreach (Boolean bUseDirectedness in TestGraphUtil.AllBoolean)
        {
            IList<IntergroupEdgeInfo> oIntergroupEdges =
                m_oIntergroupEdgeCalculator.CalculateGraphMetrics(m_oGraph,
                    new GroupInfo[] {oGroup1, oGroup2},
                    bUseDirectedness);

            Assert.AreEqual(3, oIntergroupEdges.Count);

            Assert.AreEqual( 3, GetEdgeCount(oIntergroupEdges, 0, 0) );
            Assert.AreEqual( 6, GetEdgeCount(oIntergroupEdges, 0, 1) );
            Assert.AreEqual( 4, GetEdgeCount(oIntergroupEdges, 1, 1) );
        }
    }
    TestCalculateGraphMetrics9()
    {
        // Many parallel edges, directed, use directedness.

        Boolean bIsDirected = true;
        Boolean bUseDirectedness = true;

        CreateGraph(bIsDirected);

        IVertex oVertexA = m_oVertices.Add();
        IVertex oVertexB = m_oVertices.Add();

        IVertex oVertexC = m_oVertices.Add();
        IVertex oVertexD = m_oVertices.Add();

        m_oEdges.Add(oVertexA, oVertexB, bIsDirected);
        m_oEdges.Add(oVertexB, oVertexA, bIsDirected);
        m_oEdges.Add(oVertexB, oVertexA, bIsDirected);

        m_oEdges.Add(oVertexB, oVertexC, bIsDirected);
        m_oEdges.Add(oVertexC, oVertexB, bIsDirected);

        m_oEdges.Add(oVertexA, oVertexD, bIsDirected);
        m_oEdges.Add(oVertexA, oVertexD, bIsDirected);
        m_oEdges.Add(oVertexA, oVertexD, bIsDirected);
        m_oEdges.Add(oVertexA, oVertexD, bIsDirected);

        m_oEdges.Add(oVertexD, oVertexC, bIsDirected);
        m_oEdges.Add(oVertexD, oVertexC, bIsDirected);

        m_oEdges.Add(oVertexD, oVertexD, bIsDirected);
        m_oEdges.Add(oVertexD, oVertexD, bIsDirected);

        GroupInfo oGroup1 = new GroupInfo();
        oGroup1.Vertices.AddLast(oVertexA);
        oGroup1.Vertices.AddLast(oVertexB);

        GroupInfo oGroup2 = new GroupInfo();
        oGroup2.Vertices.AddLast(oVertexC);
        oGroup2.Vertices.AddLast(oVertexD);

        IList<IntergroupEdgeInfo> oIntergroupEdges =
            m_oIntergroupEdgeCalculator.CalculateGraphMetrics(m_oGraph,
                new GroupInfo[] {oGroup1, oGroup2},
                bUseDirectedness);

        Assert.AreEqual(4, oIntergroupEdges.Count);

        Assert.AreEqual( 3, GetEdgeCount(oIntergroupEdges, 0, 0) );
        Assert.AreEqual( 5, GetEdgeCount(oIntergroupEdges, 0, 1) );
        Assert.AreEqual( 1, GetEdgeCount(oIntergroupEdges, 1, 0) );
        Assert.AreEqual( 4, GetEdgeCount(oIntergroupEdges, 1, 1) );
    }
 PlaceGroupInFreeBox
 (
     GroupInfo groupToBePlaced,
     double groupArea,
     FreeSpaceBox freeBox
 )
 {   double gLeft, gRight, gTop, gBottom, gHeight, gWidth;
     
     if (freeBox.orientation == FreeSpaceBox.Orientation.Vert)
     {
         gLeft = freeBox.boxRectangle.Left;
         gRight = freeBox.boxRectangle.Right;
         gTop = freeBox.boxRectangle.Top;
         gHeight = groupArea / ((double)(gRight - gLeft));
         gBottom = gTop + gHeight;
     }
     else
     {
         gLeft = freeBox.boxRectangle.Left;
         gTop = freeBox.boxRectangle.Top;
         gBottom = freeBox.boxRectangle.Bottom;
         gWidth = groupArea / ((double)Math.Abs(gTop - gBottom));
         gRight = gLeft + gWidth;
     }
     return RectangleF.FromLTRB((float)gLeft, (float)gTop, (float)gRight, (float)gBottom);
 }
    TestOnLayoutBegin5()
    {
        // Request that intergroup edges be combined, although there are none.

        const Double GroupRectanglePenWidth = 4.567;

        const IntergroupEdgeStyle IntergroupEdgeStyle =
            IntergroupEdgeStyle.Combine;

        IGraph oGraph = new Graph(GraphDirectedness.Undirected);

        IVertex[] aoVertices = TestGraphUtil.AddVertices(oGraph, 5);

        IEdgeCollection oEdges = oGraph.Edges;
        IEdge oEdge1 = oEdges.Add(aoVertices[0], aoVertices[1], false);
        IEdge oEdge2 = oEdges.Add(aoVertices[2], aoVertices[3], false);

        GroupInfo oGroup1 = new GroupInfo();
        oGroup1.Vertices.AddLast( aoVertices[0] );
        oGroup1.Vertices.AddLast( aoVertices[1] );
        oGroup1.Rectangle = Rectangle.FromLTRB(1, 2, 3, 4);

        GroupInfo oGroup2 = new GroupInfo();
        oGroup2.Vertices.AddLast( aoVertices[2] );
        oGroup2.Vertices.AddLast( aoVertices[3] );
        oGroup2.Rectangle = Rectangle.FromLTRB(5, 6, 7, 8);

        GroupInfo oGroup3 = new GroupInfo();
        oGroup3.Vertices.AddLast( aoVertices[4] );
        oGroup3.Rectangle = Rectangle.FromLTRB(9, 10, 11, 12);

        GroupMetadataManager.OnLayoutBegin(oGraph);

        GroupMetadataManager.OnLayoutUsingGroupsEnd(oGraph,
            new GroupInfo[] {oGroup1, oGroup2, oGroup3},
            GroupRectanglePenWidth, IntergroupEdgeStyle);

        GroupLayoutDrawingInfo oGroupLayoutDrawingInfo;

        Assert.IsTrue( GroupMetadataManager.TryGetGroupLayoutDrawingInfo(
            oGraph, out oGroupLayoutDrawingInfo) );

        Assert.AreEqual(GroupRectanglePenWidth,
            oGroupLayoutDrawingInfo.PenWidth);

        IList<GroupInfo> oGroupInfo = oGroupLayoutDrawingInfo.GroupsToDraw;

        Assert.AreEqual(3, oGroupInfo.Count);
        Assert.AreEqual( oGroup1, oGroupInfo[0] );
        Assert.AreEqual( oGroup2, oGroupInfo[1] );
        Assert.AreEqual( oGroup3, oGroupInfo[2] );

        Assert.IsFalse( oGraph.ContainsKey(
            ReservedMetadataKeys.IntergroupEdgesHidden) );

        Assert.IsFalse( oEdge1.ContainsKey(
            ReservedMetadataKeys.SavedVisibility) );

        Assert.IsFalse( oEdge2.ContainsKey(
            ReservedMetadataKeys.SavedVisibility) );

        Assert.AreEqual( 0,
            oGroupLayoutDrawingInfo.CombinedIntergroupEdges.Count() );
    }
    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);
    }
    TestTryTransformGroupRectangles()
    {
        // Graph has group drawing information.

        const Double GroupRectanglePenWidth = 4.567;

        IGraph oGraph = new Graph();

        GroupInfo oGroupInfo1 = new GroupInfo();
        oGroupInfo1.Rectangle = Rectangle.FromLTRB(0, 0, 1, 2);

        GroupInfo oGroupInfo2 = new GroupInfo();
        oGroupInfo2.Rectangle = Rectangle.FromLTRB(0, 0, 3, 4);

        oGraph.SetValue(ReservedMetadataKeys.GroupLayoutDrawingInfo,
            new GroupLayoutDrawingInfo(
                new GroupInfo[] {oGroupInfo1, oGroupInfo2},
                GroupRectanglePenWidth, null
            ) );

        GroupMetadataManager.TransformGroupRectangles(oGraph,
            new LayoutContext( Rectangle.FromLTRB(0, 0, 10, 20) ),
            new LayoutContext( Rectangle.FromLTRB(0, 0, 20, 60) )
            );

        GroupLayoutDrawingInfo oGroupLayoutDrawingInfo;

        Assert.IsTrue( GroupMetadataManager.TryGetGroupLayoutDrawingInfo(
            oGraph, out oGroupLayoutDrawingInfo) );

        Assert.AreEqual(2, oGroupLayoutDrawingInfo.GroupsToDraw.Count);

        Assert.AreEqual(Rectangle.FromLTRB(0, 0, 2, 6),
            oGroupLayoutDrawingInfo.GroupsToDraw[0].Rectangle);

        Assert.AreEqual(Rectangle.FromLTRB(0, 0, 6, 12),
            oGroupLayoutDrawingInfo.GroupsToDraw[1].Rectangle);
    }
    SetGroupVertexAttributes
    (
        GroupInfo oCollapsedGroup,
        IVertex oCollapsedGroupVertex,
        ICollection<IVertex> oVerticesToCollapse
    )
    {
        Debug.Assert(oCollapsedGroup != null);
        Debug.Assert(oCollapsedGroupVertex != null);
        Debug.Assert(oVerticesToCollapse != null);
        Debug.Assert(oVerticesToCollapse.Count > 0);
        AssertValid();

        // If the group has no collapsed location, arbitrarily use the location
        // of the first vertex in the group.

        oCollapsedGroupVertex.Location = 
            oCollapsedGroup.CollapsedLocation ??
            oVerticesToCollapse.First().Location;

        Boolean bAllVerticesSelected = true;
        Boolean bAllVerticesHidden = true;

        foreach (IVertex oVertex in oVerticesToCollapse)
        {
            if ( !VertexOrEdgeIsSelected(oVertex) )
            {
                bAllVerticesSelected = false;
            }

            if (VertexDrawer.GetVisibility(oVertex) !=
                VisibilityKeyValue.Hidden)
            {
                bAllVerticesHidden = false;
            }
        }

        // If all of the group's vertices are selected or hidden, select or
        // hide the collapsed group vertex.

        if (bAllVerticesSelected)
        {
            MarkVertexOrEdgeAsSelected(oCollapsedGroupVertex, true);
            m_oSelectedVertices.Add(oCollapsedGroupVertex);
        }

        if (bAllVerticesHidden)
        {
            oCollapsedGroupVertex.SetValue(ReservedMetadataKeys.Visibility,
                VisibilityKeyValue.Hidden);
        }

        // Store the group information on the collapsed group vertex.  This
        // gets used by VertexDrawer when the collapsed group vertex is drawn.

        oCollapsedGroupVertex.SetValue(
            ReservedMetadataKeys.CollapsedGroupInfo, oCollapsedGroup);

        // In case a sort order has been specified for the graph's vertices,
        // arbitrarily put the group vertex at the top of the sort order.
        //
        // This is only to avoid an exception that SortableLayoutBase throws
        // when it encounters a vertex that is missing the
        // SortableLayoutAndZOrder key.

        oCollapsedGroupVertex.SetValue(
            ReservedMetadataKeys.SortableLayoutAndZOrder, Single.MaxValue);
    }
    AddRows
    (
        GroupInfo [] oGroups,
        IList<IntergroupEdgeInfo> oIntergroupEdges
    )
    {
        Debug.Assert(oGroups != null);
        Debug.Assert(oIntergroupEdges != null);
        AssertValid();

        GroupEdgeRows oGroupEdgeRows = new GroupEdgeRows();

        foreach (IntergroupEdgeInfo oIntergroupEdge in oIntergroupEdges)
        {
            AddRow(oGroups[oIntergroupEdge.Group1Index].Name,
                oGroups[oIntergroupEdge.Group2Index].Name,
                oIntergroupEdge.Edges, oGroupEdgeRows);
        }

        return (oGroupEdgeRows);
    }
    TestCalculateGraphMetrics2()
    {
        // Self-loops only.

        // Directedness makes no difference in this case.

        foreach (Boolean bIsDirected in TestGraphUtil.AllBoolean)
        {
            CreateGraph(bIsDirected);

            IVertex oVertexA = m_oVertices.Add();
            IVertex oVertexB = m_oVertices.Add();
            IVertex oVertexC = m_oVertices.Add();
            IVertex oVertexD = m_oVertices.Add();

            m_oEdges.Add(oVertexA, oVertexA, bIsDirected);
            m_oEdges.Add(oVertexB, oVertexB, bIsDirected);
            m_oEdges.Add(oVertexC, oVertexC, bIsDirected);
            m_oEdges.Add(oVertexD, oVertexD, bIsDirected);

            GroupInfo oGroup1 = new GroupInfo();
            oGroup1.Vertices.AddLast(oVertexA);
            oGroup1.Vertices.AddLast(oVertexB);

            GroupInfo oGroup2 = new GroupInfo();
            oGroup2.Vertices.AddLast(oVertexC);

            GroupInfo oGroup3 = new GroupInfo();
            oGroup3.Vertices.AddLast(oVertexD);

            // Using directedness makes no difference in this case.

            foreach (Boolean bUseDirectedness in TestGraphUtil.AllBoolean)
            {
                IList<IntergroupEdgeInfo> oIntergroupEdges =
                    m_oIntergroupEdgeCalculator.CalculateGraphMetrics(m_oGraph,
                        new GroupInfo[] {oGroup1, oGroup2, oGroup3},
                        bUseDirectedness);

                Assert.AreEqual(3, oIntergroupEdges.Count);

                Assert.AreEqual( 2, GetEdgeCount(oIntergroupEdges, 0, 0) );
                Assert.AreEqual( 1, GetEdgeCount(oIntergroupEdges, 1, 1) );
                Assert.AreEqual( 1, GetEdgeCount(oIntergroupEdges, 2, 2) );
            }
        }
    }
示例#25
0
    DrawGroupLabel
    (
        DrawingContext oDrawingContext,
        GraphDrawingContext oGraphDrawingContext,
        GroupInfo oGroupInfo
    )
    {
        Debug.Assert(oDrawingContext != null);
        Debug.Assert(oGraphDrawingContext != null);
        Debug.Assert(oGroupInfo != null);
        Debug.Assert(m_eLabelPosition != VertexLabelPosition.Nowhere);
        AssertValid();

        String sLabel = oGroupInfo.Label;
        Rect oGroupRectangle;

        if (
            String.IsNullOrEmpty(sLabel)
            ||
            !TryGetGroupRectangle(oGroupInfo, out oGroupRectangle)
            )
        {
            return;
        }

        FormattedText oFormattedText =
            m_oFormattedTextManager.CreateFormattedText(sLabel,
                m_oLabelTextColor, m_dLabelScale);

        oFormattedText.MaxTextWidth = oGroupRectangle.Width;
        oFormattedText.MaxTextHeight = oGroupRectangle.Height;

        // The alignment needs to be set before the width and height of the
        // FormattedText are obtained.

        SetTextAlignment(oFormattedText, m_eLabelPosition);

        // You can't use FormattedText.Width to get the width of the actual
        // text when text wrapping is enabled (FormattedText.MaxTextWidth > 0).
        // Instead, use a method that takes wrapping into account.

        Double dLabelWidth =
            WpfGraphicsUtil.GetFormattedTextSize(oFormattedText).Width;

        Double dLabelHeight = oFormattedText.Height;

        Double dGroupRectangleWidth = oGroupRectangle.Width;
        Double dGroupRectangleHeight = oGroupRectangle.Height;
        Double dMaxTextWidth = oFormattedText.MaxTextWidth;

        Double dTextOffsetXForCenter =
            (dGroupRectangleWidth - dMaxTextWidth) / 2.0;

        Double dTextOffsetYForMiddle =
            (dGroupRectangleHeight - dLabelHeight) / 2.0;

        Double dTextOffsetYForBottom =
            dGroupRectangleHeight - dLabelHeight - LabelVerticalMargin;

        Point oTextOrigin = oGroupRectangle.Location;
        Double dTextOffsetX = 0;
        Double dTextOffsetY = 0;

        switch (m_eLabelPosition)
        {
            case VertexLabelPosition.TopLeft:

                dTextOffsetX = LabelHorizontalMargin;
                dTextOffsetY = LabelVerticalMargin;
                break;

            case VertexLabelPosition.TopCenter:

                dTextOffsetX = dTextOffsetXForCenter;
                dTextOffsetY = LabelVerticalMargin;

                break;

            case VertexLabelPosition.TopRight:

                dTextOffsetX = -LabelHorizontalMargin;
                dTextOffsetY = LabelVerticalMargin;

                break;

            case VertexLabelPosition.MiddleLeft:

                dTextOffsetX = LabelHorizontalMargin;
                dTextOffsetY = dTextOffsetYForMiddle;

                break;

            case VertexLabelPosition.MiddleCenter:

                dTextOffsetX = dTextOffsetXForCenter;
                dTextOffsetY = dTextOffsetYForMiddle;

                break;

            case VertexLabelPosition.MiddleRight:

                dTextOffsetX = -LabelHorizontalMargin;
                dTextOffsetY = dTextOffsetYForMiddle;

                break;

            case VertexLabelPosition.BottomLeft:

                dTextOffsetX = LabelHorizontalMargin;
                dTextOffsetY = dTextOffsetYForBottom;

                break;

            case VertexLabelPosition.BottomCenter:


                dTextOffsetX = dTextOffsetXForCenter;
                dTextOffsetY = dTextOffsetYForBottom;

                break;

            case VertexLabelPosition.BottomRight:

                dTextOffsetX = -LabelHorizontalMargin;
                dTextOffsetY = dTextOffsetYForBottom;

                break;

            default:

                Debug.Assert(false);
                break;
        }

        oTextOrigin.Offset(dTextOffsetX, dTextOffsetY);

        DrawLabelBackground(oDrawingContext, oGraphDrawingContext,
            oFormattedText, m_oLabelTextColor, LabelBackgroundAlpha,
            oTextOrigin);

        oDrawingContext.DrawText(oFormattedText, oTextOrigin);
    }
    TestCalculateGraphMetrics4()
    {
        // More complex case, undirected.

        Boolean bIsDirected = false;

        // Using directedness makes no difference in this case.

        foreach (Boolean bUseDirectedness in TestGraphUtil.AllBoolean)
        {
            CreateGraph(bIsDirected);

            IVertex oVertexA = m_oVertices.Add();
            IVertex oVertexB = m_oVertices.Add();

            IVertex oVertexC = m_oVertices.Add();
            IVertex oVertexD = m_oVertices.Add();

            IVertex oVertexE = m_oVertices.Add();
            IVertex oVertexF = m_oVertices.Add();

            m_oEdges.Add(oVertexA, oVertexA, bIsDirected);
            m_oEdges.Add(oVertexA, oVertexB, bIsDirected);
            m_oEdges.Add(oVertexA, oVertexB, bIsDirected);
            m_oEdges.Add(oVertexA, oVertexC, bIsDirected);
            m_oEdges.Add(oVertexA, oVertexD, bIsDirected);
            m_oEdges.Add(oVertexC, oVertexD, bIsDirected);
            m_oEdges.Add(oVertexE, oVertexC, bIsDirected);
            m_oEdges.Add(oVertexD, oVertexE, bIsDirected);
            m_oEdges.Add(oVertexA, oVertexE, bIsDirected);
            m_oEdges.Add(oVertexF, oVertexD, bIsDirected);

            GroupInfo oGroup1 = new GroupInfo();
            oGroup1.Vertices.AddLast(oVertexA);
            oGroup1.Vertices.AddLast(oVertexB);

            GroupInfo oGroup2 = new GroupInfo();
            oGroup2.Vertices.AddLast(oVertexC);
            oGroup2.Vertices.AddLast(oVertexD);

            GroupInfo oGroup3 = new GroupInfo();
            oGroup3.Vertices.AddLast(oVertexE);
            oGroup3.Vertices.AddLast(oVertexF);

            IList<IntergroupEdgeInfo> oIntergroupEdges =
                m_oIntergroupEdgeCalculator.CalculateGraphMetrics(m_oGraph,
                    new GroupInfo[] {oGroup1, oGroup2, oGroup3},
                    bUseDirectedness);

            Assert.AreEqual(5, oIntergroupEdges.Count);

            Assert.AreEqual( 3, GetEdgeCount(oIntergroupEdges, 0, 0) );
            Assert.AreEqual( 2, GetEdgeCount(oIntergroupEdges, 0, 1) );
            Assert.AreEqual( 1, GetEdgeCount(oIntergroupEdges, 0, 2) );
            Assert.AreEqual( 1, GetEdgeCount(oIntergroupEdges, 1, 1) );
            Assert.AreEqual( 3, GetEdgeCount(oIntergroupEdges, 1, 2) );
        }
    }
示例#27
0
    CompareConnectivity(GroupInfo other)
    {

        if (other.Connectivity != this.Connectivity)
        {
            return this.Connectivity.CompareTo(other.Connectivity);
        }
        else
        {
            return this.Vertices.Count.CompareTo(other.Vertices.Count);
        }
    }
    TestCalculateGraphMetrics6()
    {
        // More complex case, directed, use directedness.

        Boolean bIsDirected = true;
        Boolean bUseDirectedness = true;

        CreateGraph(bIsDirected);

        IVertex oVertexA = m_oVertices.Add();
        IVertex oVertexB = m_oVertices.Add();

        IVertex oVertexC = m_oVertices.Add();
        IVertex oVertexD = m_oVertices.Add();

        IVertex oVertexE = m_oVertices.Add();
        IVertex oVertexF = m_oVertices.Add();

        m_oEdges.Add(oVertexA, oVertexA, bIsDirected);
        m_oEdges.Add(oVertexA, oVertexB, bIsDirected);
        m_oEdges.Add(oVertexA, oVertexB, bIsDirected);
        m_oEdges.Add(oVertexA, oVertexC, bIsDirected);
        m_oEdges.Add(oVertexA, oVertexD, bIsDirected);
        m_oEdges.Add(oVertexC, oVertexD, bIsDirected);
        m_oEdges.Add(oVertexE, oVertexC, bIsDirected);
        m_oEdges.Add(oVertexD, oVertexE, bIsDirected);
        m_oEdges.Add(oVertexA, oVertexE, bIsDirected);
        m_oEdges.Add(oVertexF, oVertexD, bIsDirected);

        GroupInfo oGroup1 = new GroupInfo();
        oGroup1.Vertices.AddLast(oVertexA);
        oGroup1.Vertices.AddLast(oVertexB);

        GroupInfo oGroup2 = new GroupInfo();
        oGroup2.Vertices.AddLast(oVertexC);
        oGroup2.Vertices.AddLast(oVertexD);

        GroupInfo oGroup3 = new GroupInfo();
        oGroup3.Vertices.AddLast(oVertexE);
        oGroup3.Vertices.AddLast(oVertexF);

        IList<IntergroupEdgeInfo> oIntergroupEdges =
            m_oIntergroupEdgeCalculator.CalculateGraphMetrics(m_oGraph,
                new GroupInfo[] {oGroup1, oGroup2, oGroup3},
                bUseDirectedness);

        Assert.AreEqual(6, oIntergroupEdges.Count);

        Assert.AreEqual( 3, GetEdgeCount(oIntergroupEdges, 0, 0) );
        Assert.AreEqual( 2, GetEdgeCount(oIntergroupEdges, 0, 1) );
        Assert.AreEqual( 1, GetEdgeCount(oIntergroupEdges, 0, 2) );
        Assert.AreEqual( 1, GetEdgeCount(oIntergroupEdges, 1, 1) );
        Assert.AreEqual( 1, GetEdgeCount(oIntergroupEdges, 1, 2) );
        Assert.AreEqual( 2, GetEdgeCount(oIntergroupEdges, 2, 1) );
    }
    protected Boolean TryCalculateGraphMetricsForOneGroup
        (GroupInfo oGroupInfo, out OverallMetrics oOverallMetrics)
    {
        Debug.Assert(oGroupInfo != null);
        Debug.Assert(oGroupInfo.Vertices != null);
        Debug.Assert(oGroupInfo.Vertices.Count > 0);
        
        

        oOverallMetrics = null;

        ICollection<IVertex> oVertices = oGroupInfo.Vertices;

        // Create a new graph from the vertices in the group and the edges that
        // connect them.

        IGraph oNewGraph = SubgraphCalculator.GetSubgraphAsNewGraph(oVertices);

        // Calculate the overall metrics for the new graph using the
        // OverallMetricCalculator class in the Algorithms namespace, which
        // knows nothing about Excel.

        return ( (new OverallMetricCalculator() ).
            TryCalculateGraphMetrics(oNewGraph,
                null,
                out oOverallMetrics) );
    }
    TestConstructor()
    {
        // Has CombinedIntergroupEdges.

        GroupInfo [] aoGroupInfo = new GroupInfo [] {
            new GroupInfo(),
            new GroupInfo(),
            new GroupInfo()
            };

        const Double PenWidth = 1.234;

        IntergroupEdgeInfo[] aoCombinedIntergroupEdges =
            new IntergroupEdgeInfo[5];

        GroupLayoutDrawingInfo oGroupLayoutDrawingInfo =
            new GroupLayoutDrawingInfo(aoGroupInfo, PenWidth,
                aoCombinedIntergroupEdges);

        Assert.AreEqual(aoGroupInfo, oGroupLayoutDrawingInfo.GroupsToDraw);
        Assert.AreEqual(PenWidth, oGroupLayoutDrawingInfo.PenWidth);

        Assert.AreEqual(aoCombinedIntergroupEdges,
            oGroupLayoutDrawingInfo.CombinedIntergroupEdges);
    }