TestTryGetGroupLayoutDrawingInfo()
        {
            // Graph has group drawing information.

            const Double GroupRectanglePenWidth = 4.567;

            const IntergroupEdgeStyle IntergroupEdgeStyle =
                IntergroupEdgeStyle.Show;

            IGraph oGraph = new Graph();

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

            GroupLayoutDrawingInfo oGroupLayoutDrawingInfo;

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

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

            Assert.AreEqual(GroupRectanglePenWidth,
                            oGroupLayoutDrawingInfo.PenWidth);

            Assert.IsNull(oGroupLayoutDrawingInfo.CombinedIntergroupEdges);
        }
    OnLayoutUsingGroupsEnd
    (
        IGraph graph,
        IList<GroupInfo> laidOutGroups,
        Double groupRectanglePenWidth,
        IntergroupEdgeStyle intergroupEdgeStyle
    )
    {
        Debug.Assert(graph != null);
        Debug.Assert(laidOutGroups != null);
        Debug.Assert(groupRectanglePenWidth >= 0);

        List<IntergroupEdgeInfo> oCombinedIntergroupEdges = null;

        if (intergroupEdgeStyle == IntergroupEdgeStyle.Combine)
        {
            // Get a collection of IntergroupEdgeInfo objects, one for the
            // edges between each pair of groups and one for the edges within
            // each group.

            IEnumerable<IntergroupEdgeInfo> oAllIntergroupEdges =
                ( new IntergroupEdgeCalculator() ).CalculateGraphMetrics(
                    graph, laidOutGroups, false);

            // Filter out the objects for the edges within each group.

            oCombinedIntergroupEdges = new List<IntergroupEdgeInfo>(
                oAllIntergroupEdges.Where(
                    oIntergroupEdge =>
                    oIntergroupEdge.Group1Index != oIntergroupEdge.Group2Index
                    ) );
        }

        if (intergroupEdgeStyle == IntergroupEdgeStyle.Hide ||
            intergroupEdgeStyle == IntergroupEdgeStyle.Combine)
        {
            // Intergroup edges need to be hidden.

            Boolean bEdgeHidden = false;
            Int32 iLaidOutGroups = laidOutGroups.Count;

            // The key is an IVertex.ID and the value is the zero-based index
            // of the laid-out group the vertex belongs to.

            Dictionary<Int32, Int32> oGroupIndexDictionary =
                GroupUtil.GetGroupIndexDictionary(laidOutGroups);

            for (Int32 iGroupIndex = 0; iGroupIndex < iLaidOutGroups;
                iGroupIndex++)
            {
                GroupInfo oGroup = laidOutGroups[iGroupIndex];

                foreach (IVertex oVertex in oGroup.Vertices)
                {
                    foreach (IEdge oIncidentEdge in oVertex.IncidentEdges)
                    {
                        if ( IncidentEdgeShouldBeHidden(oIncidentEdge, oVertex,
                            iGroupIndex, oGroupIndexDictionary) )
                        {
                            HideEdge(oIncidentEdge);
                            bEdgeHidden = true;
                        }
                    }
                }
            }

            if (bEdgeHidden)
            {
                graph.SetValue(ReservedMetadataKeys.IntergroupEdgesHidden,
                    null);
            }
        }

        graph.SetValue( ReservedMetadataKeys.GroupLayoutDrawingInfo,
            new GroupLayoutDrawingInfo(laidOutGroups, groupRectanglePenWidth,
                oCombinedIntergroupEdges) );
    }
        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);
        }
        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());
        }
Beispiel #6
0
        OnLayoutUsingGroupsEnd
        (
            IGraph graph,
            IList <GroupInfo> laidOutGroups,
            Double groupRectanglePenWidth,
            IntergroupEdgeStyle intergroupEdgeStyle
        )
        {
            Debug.Assert(graph != null);
            Debug.Assert(laidOutGroups != null);
            Debug.Assert(groupRectanglePenWidth >= 0);

            List <IntergroupEdgeInfo> oCombinedIntergroupEdges = null;

            if (intergroupEdgeStyle == IntergroupEdgeStyle.Combine)
            {
                // Get a collection of IntergroupEdgeInfo objects, one for the
                // edges between each pair of groups and one for the edges within
                // each group.

                IEnumerable <IntergroupEdgeInfo> oAllIntergroupEdges =
                    (new IntergroupEdgeCalculator()).CalculateGraphMetrics(
                        graph, laidOutGroups, false);

                // Filter out the objects for the edges within each group.

                oCombinedIntergroupEdges = new List <IntergroupEdgeInfo>(
                    oAllIntergroupEdges.Where(
                        oIntergroupEdge =>
                        oIntergroupEdge.Group1Index != oIntergroupEdge.Group2Index
                        ));
            }

            if (intergroupEdgeStyle == IntergroupEdgeStyle.Hide ||
                intergroupEdgeStyle == IntergroupEdgeStyle.Combine)
            {
                // Intergroup edges need to be hidden.

                Boolean bEdgeHidden    = false;
                Int32   iLaidOutGroups = laidOutGroups.Count;

                // The key is an IVertex.ID and the value is the zero-based index
                // of the laid-out group the vertex belongs to.

                Dictionary <Int32, Int32> oGroupIndexDictionary =
                    GroupUtil.GetGroupIndexDictionary(laidOutGroups);

                for (Int32 iGroupIndex = 0; iGroupIndex < iLaidOutGroups;
                     iGroupIndex++)
                {
                    GroupInfo oGroup = laidOutGroups[iGroupIndex];

                    foreach (IVertex oVertex in oGroup.Vertices)
                    {
                        foreach (IEdge oIncidentEdge in oVertex.IncidentEdges)
                        {
                            if (IncidentEdgeShouldBeHidden(oIncidentEdge, oVertex,
                                                           iGroupIndex, oGroupIndexDictionary))
                            {
                                HideEdge(oIncidentEdge);
                                bEdgeHidden = true;
                            }
                        }
                    }
                }

                if (bEdgeHidden)
                {
                    graph.SetValue(ReservedMetadataKeys.IntergroupEdgesHidden,
                                   null);
                }
            }

            graph.SetValue(ReservedMetadataKeys.GroupLayoutDrawingInfo,
                           new GroupLayoutDrawingInfo(laidOutGroups, groupRectanglePenWidth,
                                                      oCombinedIntergroupEdges));
        }