Пример #1
0
 private static void SetPreferredSide(PreferredPlacementDescriptor newDescriptor,
                                      PreferredPlacementDescriptor oldDescriptor, ILabelModel model)
 {
     if (model is EdgeSegmentLabelModel)
     {
         var rotatedModel = model as EdgeSegmentLabelModel;
         var onEdge       = (rotatedModel.SideOfEdge & EdgeSides.OnEdge) == EdgeSides.OnEdge;
         newDescriptor.SideOfEdge     = onEdge ? LabelPlacements.OnEdge : LabelPlacements.RightOfEdge | LabelPlacements.LeftOfEdge;
         newDescriptor.DistanceToEdge = rotatedModel.Distance;
     }
 }
        private static void AddEdgeLabelPlacementDescriptors(LayoutGraphAdapter adapter)
        {
            var atSourceDescriptor = new PreferredPlacementDescriptor {
                PlaceAlongEdge = LabelPlacements.AtSourcePort,
                SideOfEdge     = LabelPlacements.LeftOfEdge | LabelPlacements.RightOfEdge,
            };

            adapter.AddDataProvider(LayoutGraphAdapter.EdgeLabelLayoutPreferredPlacementDescriptorDpKey,
                                    Mappers.FromDelegate((ILabel label) => {
                var edgeType = ((BpmnEdgeStyle)((IEdge)label.Owner).Style).Type;
                if (edgeType == EdgeType.SequenceFlow || edgeType == EdgeType.DefaultFlow || edgeType == EdgeType.ConditionalFlow)
                {
                    // labels on sequence, default and conditional flow edges should be placed at the source side.
                    return(atSourceDescriptor);
                }
                return(null);
            }));
        }
Пример #3
0
        /// <summary>
        /// Creates a new <see cref="PreferredPlacementDescriptor"/> that matches the given settings.
        /// </summary>
        public PreferredPlacementDescriptor CreatePreferredPlacementDescriptor(
            EnumLabelPlacementAlongEdge placeAlongEdge, EnumLabelPlacementSideOfEdge sideOfEdge,
            EnumLabelPlacementOrientation orientation, double distanceToEdge)
        {
            var descriptor = new PreferredPlacementDescriptor();

            switch (sideOfEdge)
            {
            case EnumLabelPlacementSideOfEdge.Anywhere:
                descriptor.SideOfEdge = LabelPlacements.Anywhere;
                break;

            case EnumLabelPlacementSideOfEdge.OnEdge:
                descriptor.SideOfEdge = LabelPlacements.OnEdge;
                break;

            case EnumLabelPlacementSideOfEdge.Left:
                descriptor.SideOfEdge = LabelPlacements.LeftOfEdge;
                break;

            case EnumLabelPlacementSideOfEdge.Right:
                descriptor.SideOfEdge = LabelPlacements.RightOfEdge;
                break;

            case EnumLabelPlacementSideOfEdge.LeftOrRight:
                descriptor.SideOfEdge = LabelPlacements.LeftOfEdge | LabelPlacements.RightOfEdge;
                break;
            }

            switch (placeAlongEdge)
            {
            case EnumLabelPlacementAlongEdge.Anywhere:
                descriptor.PlaceAlongEdge = LabelPlacements.Anywhere;
                break;

            case EnumLabelPlacementAlongEdge.AtSourcePort:
                descriptor.PlaceAlongEdge = LabelPlacements.AtSourcePort;
                break;

            case EnumLabelPlacementAlongEdge.AtTargetPort:
                descriptor.PlaceAlongEdge = LabelPlacements.AtTargetPort;
                break;

            case EnumLabelPlacementAlongEdge.AtSource:
                descriptor.PlaceAlongEdge = LabelPlacements.AtSource;
                break;

            case EnumLabelPlacementAlongEdge.AtTarget:
                descriptor.PlaceAlongEdge = LabelPlacements.AtTarget;
                break;

            case EnumLabelPlacementAlongEdge.Centered:
                descriptor.PlaceAlongEdge = LabelPlacements.AtCenter;
                break;
            }

            switch (orientation)
            {
            case EnumLabelPlacementOrientation.Parallel:
                descriptor.Angle          = 0.0d;
                descriptor.AngleReference = LabelAngleReferences.RelativeToEdgeFlow;
                break;

            case EnumLabelPlacementOrientation.Orthogonal:
                descriptor.Angle          = Math.PI / 2;
                descriptor.AngleReference = LabelAngleReferences.RelativeToEdgeFlow;
                break;

            case EnumLabelPlacementOrientation.Horizontal:
                descriptor.Angle          = 0.0d;
                descriptor.AngleReference = LabelAngleReferences.Absolute;
                break;

            case EnumLabelPlacementOrientation.Vertical:
                descriptor.Angle          = Math.PI / 2;
                descriptor.AngleReference = LabelAngleReferences.Absolute;
                break;
            }

            descriptor.DistanceToEdge = distanceToEdge;
            return(descriptor);
        }
Пример #4
0
        private void UpdateLabelValues(IEnumerable <ILabel> labels)
        {
            if (descriptorMapper == null)
            {
                return;
            }

            var handler = Handler;

            foreach (var edgeLabel in labels)
            {
                if (edgeLabel.Owner is INode || edgeLabel.Owner is IPort)
                {
                    // this demo shouldn't have node or port labels but we make sure that nothing goes wrong
                    continue;
                }

                var prototype  = descriptorMapper[edgeLabel];
                var descriptor = new PreferredPlacementDescriptor(prototype);

                var item = handler.GetItemByName(LabelText);
                if (item.Value != OptionItem.VALUE_UNDEFINED)
                {
                    graphControl.Graph.SetLabelText(edgeLabel, (string)item.Value);
                }
                item = handler.GetItemByName(PlacementAlongEdge);
                if (item.Value != OptionItem.VALUE_UNDEFINED)
                {
                    descriptor.PlaceAlongEdge = (LabelPlacements)item.Value;
                }
                item = handler.GetItemByName(PlacementSideOfEdge);
                if (item.Value != OptionItem.VALUE_UNDEFINED)
                {
                    descriptor.SideOfEdge = (LabelPlacements)item.Value;
                }
                item = handler.GetItemByName(PlacementSideReference);
                if (item.Value != OptionItem.VALUE_UNDEFINED)
                {
                    descriptor.SideReference = (LabelSideReferences)item.Value;
                }
                item = handler.GetItemByName(Angle);
                if (item.Value != OptionItem.VALUE_UNDEFINED)
                {
                    descriptor.Angle = Geom.ToRadians((double)item.Value);
                }
                item = handler.GetItemByName(AngleReference);
                if (item.Value != OptionItem.VALUE_UNDEFINED)
                {
                    descriptor.AngleReference = (LabelAngleReferences)item.Value;
                }
                item = handler.GetItemByName(AngleRotation);
                if (item.Value != OptionItem.VALUE_UNDEFINED)
                {
                    descriptor.AngleRotationOnRightSide = (LabelAngleOnRightSideRotations)item.Value;
                }
                item = handler.GetItemByName(AngleAdd180Degree);
                if (item.Value != OptionItem.VALUE_UNDEFINED)
                {
                    descriptor.AngleOffsetOnRightSide = GetLabelAngleOnRightSideOffset((bool)item.Value);
                }
                item = handler.GetItemByName(PlacementDistance);
                if (item.Value != OptionItem.VALUE_UNDEFINED)
                {
                    descriptor.DistanceToEdge = (double)item.Value;
                }

                if (!descriptor.Equals(prototype))
                {
                    descriptorMapper[edgeLabel] = descriptor;
                }
            }
        }
Пример #5
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);
        }
        /// <summary>
        /// Run a layout and an analysis algorithm if wanted.
        /// </summary>
        /// <param name="incremental">Whether to run in incremental mode, i.e. only moving new items.</param>
        /// <param name="clearUndo">Whether to clear the undo queue after the layout.</param>
        /// <param name="runAlgorithm">Whether to apply the <see cref="CurrentConfig">current analysis algorithm</see>, too.</param>
        /// <returns></returns>
        private async Task RunLayout(bool incremental, bool clearUndo, bool runAlgorithm)
        {
            // the actual organic layout
            var layout = new OrganicLayout {
                Deterministic       = true,
                ConsiderNodeSizes   = true,
                Scope               = incremental ? Scope.MainlySubset : Scope.All,
                LabelingEnabled     = false,
                PreferredEdgeLength = 100,
                MinimumNodeDistance = 10
            };

            ((ComponentLayout)layout.ComponentLayout).Style = ComponentArrangementStyles.None | ComponentArrangementStyles.ModifierNoOverlap;

            OrganicLayoutData layoutData = null;

            if (incremental && incrementalNodesMapper != null)
            {
                layoutData = new OrganicLayoutData();
                layoutData.AffectedNodes.Mapper = incrementalNodesMapper;
            }
            inLayout = true;
            SetUiDisabled(true);
            // run the layout in an asynchronous, animated fashion
            await graphControl.MorphLayout(layout, TimeSpan.FromSeconds(0.5), layoutData);

            // run algorithm
            if (runAlgorithm)
            {
                // apply graph algorithms after layout
                ApplyAlgorithm();
                var algorithm = algorithmComboBox.SelectedItem as Algorithm;
                if (algorithm != null && algorithm.DisplayName.EndsWith("Centrality"))
                {
                    // since centrality changes the node sizes, node overlaps need to be removed
                    await graphControl.MorphLayout(new OrganicRemoveOverlapsStage(), TimeSpan.FromSeconds(0.2));
                }
            }

            // labeling: place labels after the layout and the analysis (which might have generated or changed labels)
            var labeling = new GenericLabeling {
                PlaceEdgeLabels = true,
                PlaceNodeLabels = false,
                Deterministic   = true
            };
            var labelingData = new LabelingData {
                EdgeLabelPreferredPlacement =
                {
                    Delegate                                            = label => {
                        var preferredPlacementDescriptor                = new PreferredPlacementDescriptor();
                        if ("Centrality".Equals(label.Tag))
                        {
                            preferredPlacementDescriptor.SideOfEdge     = LabelPlacements.OnEdge;
                        }
                        else
                        {
                            preferredPlacementDescriptor.SideOfEdge     = LabelPlacements.RightOfEdge | LabelPlacements.LeftOfEdge;
                            preferredPlacementDescriptor.DistanceToEdge = 5;
                        }
                        preferredPlacementDescriptor.Freeze();
                        return(preferredPlacementDescriptor);
                    }
                }
            };
            await graphControl.MorphLayout(labeling, TimeSpan.FromSeconds(0.2), labelingData);

            // cleanup
            if (clearUndo)
            {
                graphControl.Graph.GetUndoEngine().Clear();
            }
            // clean up data provider
            incrementalNodesMapper.Clear();

            // enable the UI's buttons
            ReleaseLocks();
            SetUiDisabled(false);
            UpdateUiState();
        }
Пример #7
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);

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

            //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));
            //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));
            tpc.Set(e2, PortConstraint.Create(PortSide.North));
            //e3 uses no port constraints, i.e. layout will choose best side
            graph.AddDataProvider(PortConstraintKeys.SourcePortConstraintDpKey, spc);
            graph.AddDataProvider(PortConstraintKeys.TargetPortConstraintDpKey, tpc);

            //setup two edge labels for edge e1. The size of the edge labels will be set to
            //80x20. Usually the size of the labels will be determined by
            //calculaing the bounding box of a piece text that is displayed
            //with a specific font.

            var labelFactory = LayoutGraphUtilities.GetLabelFactory(graph);

            graph.SetLabelLayout(e1, new[]
            {
                CreateEdgeLabelLayout(labelFactory, e1,
                                      new SliderEdgeLabelLayoutModel(SliderMode.Center),
                                      PreferredPlacementDescriptor.NewSharedInstance(LabelPlacements.AtCenter)),
                CreateEdgeLabelLayout(labelFactory, e1,
                                      new SliderEdgeLabelLayoutModel(SliderMode.Side),
                                      PreferredPlacementDescriptor.NewSharedInstance(LabelPlacements.LeftOfEdge))
            });

            var layout = new HierarchicLayout();

            layout.LabelingEnabled = true;
            layout.Labeling        = new GenericLabeling();

            new BufferedLayout(layout).ApplyLayout(graph);

            Console.WriteLine("\n\nGRAPH LAID OUT USING GENERIC EDGE LABELING");
            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));
            Console.WriteLine("e3 path = " + graph.GetPath(e3));
            Console.WriteLine("ell1 upper left location = " + GetEdgeLabelLocation(graph, e1, CreateEdgeLabelLayout(labelFactory, e1,
                                                                                                                    new SliderEdgeLabelLayoutModel(SliderMode.Center),
                                                                                                                    PreferredPlacementDescriptor.NewSharedInstance(LabelPlacements.AtCenter))));
            Console.WriteLine("ell2 upper left location = " + GetEdgeLabelLocation(graph, e1, graph.GetLabelLayout(e1)[1]));

            GraphViewer gv = new GraphViewer();

            gv.AddLayoutGraph(new CopiedLayoutGraph(graph), "Layout with Generic Labeling");

            var freeModel = new FreeEdgeLabelLayoutModel();

            graph.SetLabelLayout(e1, new[]
            {
                CreateEdgeLabelLayout(labelFactory, e1, freeModel,
                                      PreferredPlacementDescriptor.NewSharedInstance(LabelPlacements.AtCenter)),
                CreateEdgeLabelLayout(labelFactory, e1, freeModel,
                                      PreferredPlacementDescriptor.NewSharedInstance(LabelPlacements.LeftOfEdge))
            });

            layout.LabelingEnabled = true;
            layout.Labeling        = new LabelLayoutTranslator();

            new BufferedLayout(layout).ApplyLayout(graph);

            Console.WriteLine("\n\nGRAPH LAID OUT USING HIERACHIC LAYOUT SPECIFIC EDGE LABELING");
            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));
            Console.WriteLine("e3 path = " + graph.GetPath(e3));
            Console.WriteLine("ell1 upper left location = " + GetEdgeLabelLocation(graph, e1, CreateEdgeLabelLayout(labelFactory, e1,
                                                                                                                    new SliderEdgeLabelLayoutModel(SliderMode.Center),
                                                                                                                    PreferredPlacementDescriptor.NewSharedInstance(LabelPlacements.AtCenter))));
            Console.WriteLine("ell2 upper left location = " + GetEdgeLabelLocation(graph, e1, graph.GetLabelLayout(e1)[1]));

            //display the result in a simple viewer
            gv.AddLayoutGraph(graph, "Layout with Integrated Labeling");
            var application = new System.Windows.Application();

            application.Run(gv);
        }
Пример #8
0
        private static IEdgeLabelLayout CreateEdgeLabelLayout(ILabelLayoutFactory labelFactory, Edge edge,
                                                              IEdgeLabelLayoutModel edgeLabelModel, PreferredPlacementDescriptor preferredPlacementDescriptor)
        {
            var label = labelFactory.CreateLabelLayout(edge, new YOrientedRectangle(0, 0, 80, 20), edgeLabelModel,
                                                       preferredPlacementDescriptor);

            label.ModelParameter = edgeLabelModel.DefaultParameter;
            return(label);
        }