Ejemplo n.º 1
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);
        }
        ///<inheritdoc/>
        protected override void ConfigureLayout()
        {
            LayoutGraph      graph = CurrentLayoutGraph;
            HierarchicLayout hl    = new HierarchicLayout();

            LayoutAlgorithm = hl;

            //  mark incremental elements if required
            IDataMap    incrementalElements;
            OptionGroup generalGroup  = (OptionGroup)Handler.GetGroupByName(GENERAL);
            OptionGroup currentGroup  = (OptionGroup)generalGroup.GetGroupByName(INTERACTION);
            OptionGroup groupingGroup = (OptionGroup)Handler.GetGroupByName(GROUPING);

            bool fromSketch        = (bool)currentGroup[USE_DRAWING_AS_SKETCH].Value;
            bool incrementalLayout = (bool)currentGroup[SELECTED_ELEMENTS_INCREMENTALLY].Value;
            bool selectedElements  = !IsEdgeSelectionEmpty() || !IsNodeSelectionEmpty();

            if (incrementalLayout && selectedElements)
            {
                // create storage for both nodes and edges
                incrementalElements = Maps.CreateHashedDataMap();
                // configure the mode
                hl.LayoutMode = LayoutMode.Incremental;
                IIncrementalHintsFactory ihf = hl.CreateIncrementalHintsFactory();

                foreach (Node node in graph.Nodes)
                {
                    if (IsSelected(node))
                    {
                        incrementalElements.Set(node, ihf.CreateLayerIncrementallyHint(node));
                    }
                }

                foreach (Edge edge in graph.Edges)
                {
                    if (IsSelected(edge))
                    {
                        incrementalElements.Set(edge, ihf.CreateSequenceIncrementallyHint(edge));
                    }
                }
                graph.AddDataProvider(HierarchicLayout.IncrementalHintsDpKey, incrementalElements);
            }
            else if (fromSketch)
            {
                hl.LayoutMode = LayoutMode.Incremental;
            }
            else
            {
                hl.LayoutMode = LayoutMode.FromScratch;
            }


            // cast to implementation simplex
            var np = (SimplexNodePlacer)hl.NodePlacer;

            np.BarycenterMode  = (bool)generalGroup[SYMMETRIC_PLACEMENT].Value;
            np.StraightenEdges = (bool)Handler.GetValue(EDGE_SETTINGS, EDGE_STRAIGHTENING_OPTIMIZATION_ENABLED);

            hl.ComponentLayoutEnabled = (bool)generalGroup[LAYOUT_COMPONENTS_SEPARATELY].Value;

            currentGroup = (OptionGroup)generalGroup.GetGroupByName(MINIMUM_DISTANCES);

            hl.MinimumLayerDistance = (double)currentGroup[MINIMUM_LAYER_DISTANCE].Value;
            hl.NodeToEdgeDistance   = (double)currentGroup[NODE_TO_EDGE_DISTANCE].Value;
            hl.NodeToNodeDistance   = (double)currentGroup[NODE_TO_NODE_DISTANCE].Value;
            hl.EdgeToEdgeDistance   = (double)currentGroup[EDGE_TO_EDGE_DISTANCE].Value;

            NodeLayoutDescriptor nld = hl.NodeLayoutDescriptor;
            EdgeLayoutDescriptor eld = hl.EdgeLayoutDescriptor;

            currentGroup = (OptionGroup)Handler.GetGroupByName(EDGE_SETTINGS);

            hl.AutomaticEdgeGrouping = (bool)currentGroup[AUTOMATIC_EDGE_GROUPING_ENABLED].Value;

            string edgeRoutingChoice = (string)currentGroup[EDGE_ROUTING].Value;

            eld.RoutingStyle = edgeRoutingEnum[edgeRoutingChoice];
            eld.MinimumFirstSegmentLength = (double)currentGroup[MINIMUM_FIRST_SEGMENT_LENGTH].Value;
            eld.MinimumLastSegmentLength  = (double)currentGroup[MINIMUM_LAST_SEGMENT_LENGTH].Value;

            eld.MinimumDistance = (double)currentGroup[MINIMUM_EDGE_DISTANCE].Value;
            eld.MinimumLength   = (double)currentGroup[MINIMUM_EDGE_LENGTH].Value;

            eld.MinimumSlope = (double)currentGroup[MINIMUM_SLOPE].Value;

            eld.SourcePortOptimization = (bool)currentGroup[PC_OPTIMIZATION_ENABLED].Value;
            eld.TargetPortOptimization = (bool)currentGroup[PC_OPTIMIZATION_ENABLED].Value;

            var isIncrementalModeEnabled = (fromSketch || (incrementalLayout && selectedElements));
            var recursiveRoutingMode     = Handler.GetValue(EDGE_SETTINGS, RECURSIVE_EDGE_ROUTING);

            if (!isIncrementalModeEnabled && recursiveRoutingMode == RECURSIVE_EDGE_ROUTING_DIRECTED)
            {
                eld.RecursiveEdgeStyle = RecursiveEdgeStyle.Directed;
            }
            else if (!isIncrementalModeEnabled && recursiveRoutingMode == RECURSIVE_EDGE_ROUTING_UNDIRECTED)
            {
                eld.RecursiveEdgeStyle = RecursiveEdgeStyle.Undirected;
            }
            else
            {
                eld.RecursiveEdgeStyle = RecursiveEdgeStyle.Off;
            }

            nld.MinimumDistance    = Math.Min(hl.NodeToNodeDistance, hl.NodeToEdgeDistance);
            nld.MinimumLayerHeight = 0;

            OptionGroup rankGroup            = (OptionGroup)Handler.GetGroupByName(RANKS);
            string      layerAlignmentChoice = (string)rankGroup[LAYER_ALIGNMENT].Value;

            nld.LayerAlignment = alignmentEnum[layerAlignmentChoice];

            ol = (OrientationLayout)hl.OrientationLayout;
            string orientationChoice = (string)generalGroup[ORIENTATION].Value;

            ol.Orientation = orientEnum[orientationChoice];

            OptionGroup labelingGroup = (OptionGroup)Handler.GetGroupByName(LABELING);

            currentGroup = (OptionGroup)labelingGroup.GetGroupByName(LABELING_EDGE_PROPERTIES);
            string el = (string)currentGroup[EDGE_LABELING].Value;

            if (!el.Equals(EDGE_LABELING_NONE))
            {
                if (el.Equals(EDGE_LABELING_GENERIC))
                {
                    var la = new GenericLabeling();
                    la.MaximumDuration = 0;
                    la.PlaceNodeLabels = false;
                    la.PlaceEdgeLabels = true;
                    la.AutoFlipping    = true;
                    la.ProfitModel     = new SimpleProfitModel();
                    hl.PrependStage(la);
                }
                else if (el.Equals(EDGE_LABELING_HIERARCHIC))
                {
                    bool copactEdgeLabelPlacement = (bool)currentGroup[COMPACT_EDGE_LABEL_PLACEMENT].Value;
                    if (hl.NodePlacer is SimplexNodePlacer)
                    {
                        np.LabelCompaction = copactEdgeLabelPlacement;
                    }
                    hl.IntegratedEdgeLabeling = true;
                }
            }
            else
            {
                hl.IntegratedEdgeLabeling = false;
            }

            currentGroup = (OptionGroup)labelingGroup.GetGroupByName(NODE_PROPERTIES);
            if ((bool)currentGroup[CONSIDER_NODE_LABELS].Value)
            {
                hl.ConsiderNodeLabels = true;
                hl.NodeLayoutDescriptor.NodeLabelMode = NodeLabelMode.ConsiderForDrawing;
            }
            else
            {
                hl.ConsiderNodeLabels = false;
            }

            string rp = (string)rankGroup[RANKING_POLICY].Value;

            hl.FromScratchLayeringStrategy = rankingPolicies[rp];
            if (rp.Equals(BFS_LAYERS))
            {
                CurrentLayoutGraph.AddDataProvider(BFSLayerer.CoreNodesDpKey, new SelectedNodesDP(this));
            }

            hl.ComponentArrangementPolicy = componentAlignmentEnum[(string)rankGroup[COMPONENT_ARRANGEMENT_POLICY].Value];

            //configure AsIsLayerer
            Object layerer = (hl.LayoutMode == LayoutMode.FromScratch)
                         ? hl.FromScratchLayerer
                         : hl.FixedElementsLayerer;

//      if (layerer is OldLayererWrapper) {
//        layerer = ((OldLayererWrapper)layerer).OldLayerer;
//      }
            if (layerer is AsIsLayerer)
            {
                AsIsLayerer ail = (AsIsLayerer)layerer;
                currentGroup          = (OptionGroup)rankGroup.GetGroupByName(FROM_SKETCH_PROPERTIES);
                ail.NodeHalo          = (double)currentGroup[HALO].Value;
                ail.NodeScalingFactor = (double)currentGroup[SCALE].Value;
                ail.MinimumNodeSize   = (double)currentGroup[MINIMUM_SIZE].Value;
                ail.MaximumNodeSize   = (double)currentGroup[MAXIMUM_SIZE].Value;
            }

            //configure grouping
            np.GroupCompactionStrategy = groupHorizCompactionEnum[(string)groupingGroup[GROUP_HORIZONTAL_COMPACTION].Value];

            if (!fromSketch && groupStrategyEnum[(string)groupingGroup[GROUP_LAYERING_STRATEGY].Value])
            {
                GroupAlignmentPolicy alignmentPolicy = groupAlignmentEnum[(string)groupingGroup[GROUP_ALIGNMENT].Value];
                hl.GroupAlignmentPolicy   = alignmentPolicy;
                hl.CompactGroups          = (bool)groupingGroup[GROUP_ENABLE_COMPACTION].Value;
                hl.RecursiveGroupLayering = true;
            }
            else
            {
                hl.RecursiveGroupLayering = false;
            }

            OptionGroup swimGroup = (OptionGroup)Handler.GetGroupByName(SWIMLANES);

            if ((bool)swimGroup[TREAT_ROOT_GROUPS_AS_SWIMLANES].Value)
            {
                TopLevelGroupToSwimlaneStage stage = new TopLevelGroupToSwimlaneStage();
                stage.OrderSwimlanesFromSketch = (bool)swimGroup[USE_ORDER_FROM_SKETCH].Value;
                stage.Spacing = (double)swimGroup[SWIMLANE_SPACING].Value;
                hl.AppendStage(stage);
            }

            hl.BackLoopRouting = (bool)Handler.GetValue(EDGE_SETTINGS, BACKLOOP_ROUTING);
            hl.MaximumDuration = ((int)Handler.GetValue(GENERAL, MAXIMUM_DURATION)) * 1000;


            bool gridEnabled = (bool)Handler.GetValue(GRID, GRID_ENABLED);

            if (gridEnabled)
            {
                hl.GridSpacing = (double)Handler.GetValue(GRID, GRID_SPACING);
                String             portAssignment = (string)Handler.GetValue(GRID, GRID_PORT_ASSIGNMENT);
                PortAssignmentMode gridPortAssignment;
                switch (portAssignment)
                {
                case GRID_PORT_ASSIGNMENT_ON_GRID:
                    gridPortAssignment = PortAssignmentMode.OnGrid;
                    break;

                case GRID_PORT_ASSIGNMENT_ON_SUBGRID:
                    gridPortAssignment = PortAssignmentMode.OnSubgrid;
                    break;

                default:
                    gridPortAssignment = PortAssignmentMode.Default;
                    break;
                }
                graph.AddDataProvider(HierarchicLayoutCore.NodeLayoutDescriptorDpKey,
                                      new NodeLayoutDescriptorAdapter(hl.NodeLayoutDescriptor, graph, gridPortAssignment));
            }
        }