/// <summary>
      /// Removes all edges that are incident to group nodes and passes it to the core layout algorithm.
      /// </summary>
      /// <remarks>
      /// This stage removes some edges from the graph such that no edges incident to group nodes
      /// exist. Then, it applies the core layout algorithm to the reduced graph.
      /// After it produces the result, it re-inserts the previously removed edges and routes them.
      /// </remarks>
      public override void ApplyLayout(LayoutGraph graph) {
        var groupingSupport = new yWorks.Layout.Grouping.GroupingSupport(graph);

        if (!GroupingSupport.IsGrouped(graph)) {
          ApplyLayoutCore(graph);
        } else {
          var hiddenEdgesMap = Maps.CreateHashedEdgeMap();

          var edgeHider = new LayoutGraphHider(graph);

          var existHiddenEdges = false;
          foreach (var edge in graph.Edges) {
            if (groupingSupport.IsGroupNode(edge.Source) || groupingSupport.IsGroupNode(edge.Target)) {
              hiddenEdgesMap.Set(edge, true);
              edgeHider.Hide(edge);
              existHiddenEdges = true;
            } else {
              hiddenEdgesMap.Set(edge, false);
            }
          }

          ApplyLayoutCore(graph);

          if (existHiddenEdges) {
            edgeHider.UnhideAll();

            // routes the marked edges
            RouteMarkedEdges(graph, hiddenEdgesMap);

            if (ConsiderEdgeLabels) {
              // all labels of hidden edges should be marked
              var affectedLabelsDpKey = "affectedLabelsDpKey";
              var nonTreeLabelsMap = Maps.CreateHashedDataMap();

              foreach (var edge in graph.Edges) {
                var ell = graph.GetLabelLayout(edge);
                foreach (var labelLayout in ell) {
                  nonTreeLabelsMap.Set(labelLayout, hiddenEdgesMap.Get(edge));
                }
              }

              // add selection marker
              graph.AddDataProvider(affectedLabelsDpKey, nonTreeLabelsMap);

              // place marked labels
              var labeling = new GenericLabeling {
                  PlaceNodeLabels = false,
                  PlaceEdgeLabels = true,
                  AffectedLabelsDpKey = affectedLabelsDpKey,
              };
              labeling.ApplyLayout(graph);

              // dispose selection key
              graph.RemoveDataProvider(affectedLabelsDpKey);
            }
          }
        }
      }
Esempio n. 2
0
        public static void Main()
        {
            DefaultLayoutGraph graph = new DefaultLayoutGraph();

            //construct graph. assign sizes to nodes
            Node v1 = graph.CreateNode();

            graph.SetSize(v1, 30, 30);
            Node v2 = graph.CreateNode();

            graph.SetSize(v2, 30, 30);
            Node v3 = graph.CreateNode();

            graph.SetSize(v3, 30, 30);

            // add a label to one node
            var nodeLabelLayoutModel = new DiscreteNodeLabelLayoutModel(DiscreteNodeLabelPositions.InternalMask, 4);
            var labelLayoutFactory   = LayoutGraphUtilities.GetLabelFactory(graph);

            labelLayoutFactory.AddLabelLayout(v1, labelLayoutFactory.CreateLabelLayout(v1,
                                                                                       new YOrientedRectangle(0, 0, 80, 20), nodeLabelLayoutModel));

            Edge e1 = graph.CreateEdge(v1, v2);
            Edge e2 = graph.CreateEdge(v1, v3);

            // add a label to an edge
            var edgeLabelLayoutModel = new SliderEdgeLabelLayoutModel(SliderMode.Side);

            labelLayoutFactory.AddLabelLayout(e1, labelLayoutFactory.CreateLabelLayout(e1,
                                                                                       new YOrientedRectangle(0, 0, 80, 20), edgeLabelLayoutModel,
                                                                                       PreferredPlacementDescriptor.NewSharedInstance(LabelPlacements.LeftOfEdge)));

            //optionally setup some port constraints for HierarchicLayout
            IEdgeMap spc = graph.CreateEdgeMap();
            IEdgeMap tpc = graph.CreateEdgeMap();

            //e1 shall leave and enter the node on the right side
            spc.Set(e1, PortConstraint.Create(PortSide.East, false));
            //additionally set a strong port constraint on the target side.
            tpc.Set(e1, PortConstraint.Create(PortSide.East, true));
            //ports with strong port constraints will not be reset by the
            //layout algorithm.  So we specify the target port right now to connect
            //to the upper left corner of the node
            graph.SetTargetPointRel(e1, new YPoint(15, -15));

            //e2 shall leave and enter the node on the top side
            spc.Set(e2, PortConstraint.Create(PortSide.North, false));
            tpc.Set(e2, PortConstraint.Create(PortSide.North, false));

            graph.AddDataProvider(PortConstraintKeys.SourcePortConstraintDpKey, spc);
            graph.AddDataProvider(PortConstraintKeys.TargetPortConstraintDpKey, tpc);

            HierarchicLayout layout = new HierarchicLayout();

            layout.IntegratedEdgeLabeling = true;
            layout.ConsiderNodeLabels     = true;
            layout.LayoutMode             = LayoutMode.FromScratch;

            new BufferedLayout(layout).ApplyLayout(graph);

            Console.WriteLine("\n\nGRAPH LAID OUT HIERARCHICALLY FROM SCRATCH");
            Console.WriteLine("v1 center position = " + graph.GetCenter(v1));
            Console.WriteLine("v2 center position = " + graph.GetCenter(v2));
            Console.WriteLine("v3 center position = " + graph.GetCenter(v3));
            Console.WriteLine("e1 path = " + graph.GetPath(e1));
            Console.WriteLine("e2 path = " + graph.GetPath(e2));

            //display the graph in a simple viewer
            GraphViewer gv = new GraphViewer();

            gv.AddLayoutGraph(new CopiedLayoutGraph(graph), "Before Addition");

            // now add a node and two edges incrementally...
            Node v4 = graph.CreateNode();

            graph.SetSize(v4, 30, 30);

            Edge e4 = graph.CreateEdge(v4, v2);
            Edge e3 = graph.CreateEdge(v1, v4);

            //mark elements as newly added so that the layout algorithm can place
            //them nicely.
            IIncrementalHintsFactory ihf = layout.CreateIncrementalHintsFactory();
            IDataMap map = Maps.CreateHashedDataMap();

            map.Set(v4, ihf.CreateLayerIncrementallyHint(v4));
            map.Set(e3, ihf.CreateSequenceIncrementallyHint(e3));
            map.Set(e4, ihf.CreateSequenceIncrementallyHint(e4));
            graph.AddDataProvider(HierarchicLayout.IncrementalHintsDpKey, map);
            layout.LayoutMode = LayoutMode.Incremental;

            new BufferedLayout(layout).ApplyLayout(graph);

            Console.WriteLine("\n\nGRAPH AFTER ELEMENTS HAVE BEEN ADDED INCREMENTALLY");
            Console.WriteLine("v1 center position = " + graph.GetCenter(v1));
            Console.WriteLine("v2 center position = " + graph.GetCenter(v2));
            Console.WriteLine("v3 center position = " + graph.GetCenter(v3));
            Console.WriteLine("v4 center position = " + graph.GetCenter(v4));
            Console.WriteLine("e1 path = " + graph.GetPath(e1));
            Console.WriteLine("e2 path = " + graph.GetPath(e2));
            Console.WriteLine("e3 path = " + graph.GetPath(e3));
            Console.WriteLine("e4 path = " + graph.GetPath(e4));

            //clean up data maps
            graph.RemoveDataProvider(HierarchicLayout.IncrementalHintsDpKey);

            //display the graph in a simple viewer
            gv.AddLayoutGraph(new CopiedLayoutGraph(graph), "After Addition");
            Application.Run(gv);
        }