/// <summary>
        /// Initializes the graph instance setting default styles
        /// and creating a small sample graph.
        /// </summary>
        protected virtual void InitializeGraph()
        {
            IGraph graph = Graph;

            // load a sample graph
            new GraphMLIOHandler().Read(graph, "Resources/sample.graphml");

            // set some defaults
            graph.NodeDefaults.Style = Enumerable.First(graph.Nodes).Style;
            graph.NodeDefaults.ShareStyleInstance = true;

            // we start with a simple run of OrganicLayout to get a good starting result
            // the algorithm is optimized to "unfold" graphs quicker than
            // interactive organic, so we use this result as a starting solution
            var initialLayout = new OrganicLayout {
                MinimumNodeDistance = 50
            };

            graph.ApplyLayout(initialLayout);

            // center the initial graph
            GraphControl.FitGraphBounds();

            movedNodes = new List <INode>();

            // we wrap the PositionHandler for nodes so that we always have the collection of nodes
            // that are currently being moved available in "movedNodes".
            // this way we do not need to know how the node is moved and do not have to guess
            // what elements are currently being moved based upon selection, etc.
            graph.GetDecorator().NodeDecorator.PositionHandlerDecorator.SetImplementationWrapper(
                (item, implementation) => new CollectingPositionHandlerWrapper(item, movedNodes, implementation));

            // create a copy of the graph for the layout algorithm
            LayoutGraphAdapter adapter = new LayoutGraphAdapter(graphControl.Graph);

            copiedLayoutGraph = adapter.CreateCopiedLayoutGraph();

            // create and start the layout algorithm
            layout = StartLayout();
            WakeUp();

            // register a listener so that structure updates are handled automatically
            graph.NodeCreated += delegate(object source, ItemEventArgs <INode> args) {
                if (layout != null)
                {
                    var center = args.Item.Layout.GetCenter();
                    layout.SyncStructure(true);
                    //we nail down all newly created nodes
                    var copiedNode = copiedLayoutGraph.GetCopiedNode(args.Item);
                    layout.SetCenter(copiedNode, center.X, center.Y);
                    layout.SetInertia(copiedNode, 1);
                    layout.SetStress(copiedNode, 0);
                    layout.WakeUp();
                }
            };
            graph.NodeRemoved += OnStructureChanged;
            graph.EdgeCreated += OnStructureChanged;
            graph.EdgeRemoved += OnStructureChanged;
        }
 static PartialLayoutForm()
 {
     SubGraphLayouts[LayoutIncremental] = new HierarchicLayout();
     SubGraphLayouts[LayoutOrganic]     = new OrganicLayout();
     SubGraphLayouts[LayoutOrthogonal]  = new OrthogonalLayout();
     SubGraphLayouts[LayoutCircular]    = new CircularLayout();
     SubGraphLayouts[LayoutUnchanged]   = null;
 }
 private void CreateOrganic()
 {
     if (organic == null)
     {
         organic = new OrganicLayout();
         organic.PrependStage(new PortCalculator());
     }
 }
Beispiel #4
0
        /// <summary>
        /// Gets the layout algorithm selected by the user.
        /// </summary>
        /// <returns></returns>
        private ILayoutAlgorithm GetLayoutAlgorithm()
        {
            var graph               = graphControl.Graph;
            var item                = layoutChooserBox.SelectedItem as ComboBoxItem;
            var layoutName          = item != null ? item.Tag as String: null;
            ILayoutAlgorithm layout = new HierarchicLayout();

            if (layoutName != null)
            {
                if (layoutName == "hierarchic")
                {
                    layout = new HierarchicLayout();
                }
                else if (layoutName == "organic")
                {
                    layout = new OrganicLayout {
                        PreferredEdgeLength = 1.5 * Math.Max(graph.NodeDefaults.Size.Width, graph.NodeDefaults.Size.Height)
                    };
                }
                else if (layoutName == "orthogonal")
                {
                    layout = new OrthogonalLayout();
                }
                else if (layoutName == "circular")
                {
                    layout = new CircularLayout();
                }
                else if (layoutName == "tree")
                {
                    layout = new TreeReductionStage(new TreeLayout())
                    {
                        NonTreeEdgeRouter = new OrganicEdgeRouter()
                    };
                }
                else if (layoutName == "balloon")
                {
                    layout = new TreeReductionStage(new BalloonLayout())
                    {
                        NonTreeEdgeRouter = new OrganicEdgeRouter()
                    };
                }
                else if (layoutName == "radial")
                {
                    layout = new RadialLayout();
                }
                else if (layoutName == "router-polyline")
                {
                    layout = new EdgeRouter();
                }
                else if (layoutName == "router-organic")
                {
                    layout = new OrganicEdgeRouter {
                        EdgeNodeOverlapAllowed = false
                    };
                }
            }
            return(layout);
        }
Beispiel #5
0
        /// <summary>
        /// Gets the layout algorithm selected by the user.
        /// </summary>
        /// <returns></returns>
        private ILayoutAlgorithm GetLayoutAlgorithm()
        {
            var graph               = graphControl.Graph;
            var layoutName          = layoutBox.SelectedItem as string;
            ILayoutAlgorithm layout = new HierarchicLayout();

            if (layoutName != null)
            {
                if (layoutName == "Layout: Hierarchic")
                {
                    layout = new HierarchicLayout();
                }
                else if (layoutName == "Layout: Organic")
                {
                    layout = new OrganicLayout {
                        PreferredEdgeLength = 1.5 * Math.Max(graph.NodeDefaults.Size.Width, graph.NodeDefaults.Size.Height)
                    };
                }
                else if (layoutName == "Layout: Orthogonal")
                {
                    layout = new OrthogonalLayout();
                }
                else if (layoutName == "Layout: Circular")
                {
                    layout = new CircularLayout();
                }
                else if (layoutName == "Layout: Tree")
                {
                    layout = new TreeReductionStage(new TreeLayout())
                    {
                        NonTreeEdgeRouter = new OrganicEdgeRouter()
                    };
                }
                else if (layoutName == "Layout: Balloon")
                {
                    layout = new TreeReductionStage(new BalloonLayout())
                    {
                        NonTreeEdgeRouter = new OrganicEdgeRouter()
                    };
                }
                else if (layoutName == "Layout: Radial")
                {
                    layout = new RadialLayout();
                }
                else if (layoutName == "Routing: Polyline")
                {
                    layout = new EdgeRouter();
                }
                else if (layoutName == "Routing: Organic")
                {
                    layout = new OrganicEdgeRouter {
                        EdgeNodeOverlapAllowed = false
                    };
                }
            }
            return(layout);
        }
        /// <summary>
        /// Populates the layout combo box.
        /// </summary>
        private void PopulateLayoutComboBox()
        {
            layouts["Hierarchic Layout"] = new HierarchicLayout();
            layouts["Organic Layout"]    = new OrganicLayout {
                MinimumNodeDistance = 40
            };
            layouts["Orthogonal Layout"] = new OrthogonalLayout();

            layoutComboBox.Items.AddRange(layouts.Keys.ToArray());
        }
        ///<inheritdoc/>
        protected override void ConfigureLayout()
        {
            OptionGroup layoutGroup   = Handler.GetGroupByName(GENERAL);
            var         partialLayout = new PartialLayout
            {
                MinimumNodeDistance   = (int)layoutGroup[MIN_NODE_DIST].Value,
                ConsiderNodeAlignment = (bool)layoutGroup[CONSIDER_SNAPLINES].Value,
                SubgraphPlacement     =
                    subgraphPlacementStrategies[
                        (string)layoutGroup[SUBGRAPH_POSITION_STRATEGY].Value]
            };

            string componentAssignmentStr = (string)layoutGroup[MODE_COMPONENT_ASSIGNMENT].Value;

            partialLayout.ComponentAssignmentStrategy =
                componentAssignment[componentAssignmentStr];

            partialLayout.LayoutOrientation =
                layoutOrientation[(string)layoutGroup[ORIENTATION_MAIN_GRAPH].Value];

            partialLayout.EdgeRoutingStrategy =
                routingStrategies[(string)layoutGroup[ROUTING_TO_SUBGRAPH].Value];

            ILayoutAlgorithm subgraphLayout = null;

            if (componentAssignmentStr != MODE_COMPONENT_SINGLE)
            {
                var subGraphLayoutStr = (string)layoutGroup[SUBGRAPH_LAYOUT].Value;
                switch (subGraphLayoutStr)
                {
                case SUBGRAPH_LAYOUT_IHL:
                    subgraphLayout = new HierarchicLayout();
                    break;

                case SUBGRAPH_LAYOUT_ORGANIC:
                    subgraphLayout = new OrganicLayout();
                    break;

                case SUBGRAPH_LAYOUT_CIRCULAR:
                    subgraphLayout = new CircularLayout();
                    break;

                case SUBGRAPH_LAYOUT_ORTHOGONAL:
                    subgraphLayout = new OrthogonalLayout();
                    break;

                default:
                    break;
                }
            }
            partialLayout.CoreLayout = subgraphLayout;

            LayoutAlgorithm = partialLayout;
        }
        private OrganicLayout CreateLayout()
        {
            OrganicLayout organicLayout = new OrganicLayout
            {
                PreferredEdgeLength = 100,
                MinimumNodeDistance = 30,
                Deterministic       = true
            };

            return(organicLayout);
        }
 /// <summary>
 /// Creates the core layouts and populates the layouts box
 /// </summary>
 private void InitializeCoreLayouts()
 {
     coreLayouts = new Dictionary <string, ILayoutAlgorithm>();
     coreLayouts["Hierarchic"] = new HierarchicLayout {
         ConsiderNodeLabels = true, IntegratedEdgeLabeling = true, OrthogonalRouting = true
     };
     coreLayouts["Circular"]           = new CircularLayout();
     coreLayouts["Compact Orthogonal"] = new CompactOrthogonalLayout();
     coreLayouts["Organic"]            = new OrganicLayout {
         MinimumNodeDistance = 10, Deterministic = true
     };
     coreLayouts["Orthogonal"]        = new OrthogonalLayout();
     coreLayoutComboBox.ItemsSource   = coreLayouts.Keys;
     coreLayoutComboBox.SelectedIndex = 0;
 }
Beispiel #10
0
        private void SetupLayouts()
        {
            // create TreeLayout
            var treeLayout = new TreeLayout {
                LayoutOrientation = LayoutOrientation.LeftToRight
            };

            treeLayout.PrependStage(new FixNodeLayoutStage());
            layouts.Add(treeLayout);
            layoutMapper["Tree"] = treeLayout;
            layoutComboBox.Items.Add("Tree");

            // create BalloonLayout
            var balloonLayout = new BalloonLayout
            {
                FromSketchMode    = true,
                CompactnessFactor = 1.0,
                AllowOverlaps     = true
            };

            balloonLayout.PrependStage(new FixNodeLayoutStage());
            layouts.Add(balloonLayout);
            layoutMapper["Balloon"] = balloonLayout;
            layoutComboBox.Items.Add("Balloon");

            // create OrganicLayout
            var organicLayout = new OrganicLayout {
                MinimumNodeDistance = 40,
                Deterministic       = true
            };

            organicLayout.PrependStage(new FixNodeLayoutStage());
            layouts.Add(organicLayout);
            layoutMapper["Organic"] = organicLayout;
            layoutComboBox.Items.Add("Organic");

            // create OrthogonalLayout
            var orthogonalLayout = new OrthogonalLayout();

            orthogonalLayout.PrependStage(new FixNodeLayoutStage());
            layouts.Add(orthogonalLayout);
            layoutMapper["Orthogonal"] = orthogonalLayout;
            layoutComboBox.Items.Add("Orthogonal");

            // set it as initial value
            currentLayout = treeLayout;
            layoutComboBox.SelectedIndex = 0;
        }
        /// <summary>
        /// Runs an organic layout with edge labeling.
        /// </summary>
        private void RunLayout()
        {
            var genericLabeling = new GenericLabeling {
                PlaceEdgeLabels = true,
                PlaceNodeLabels = false,
                ReduceAmbiguity = true
            };
            var layout = new OrganicLayout {
                MinimumNodeDistance    = 60,
                NodeEdgeOverlapAvoided = true,
                LabelingEnabled        = true,
                Labeling = genericLabeling
            };

            graphControl.MorphLayout(layout, TimeSpan.FromSeconds(1));
        }
        /// <inheritdoc />
        protected override ILayoutAlgorithm CreateConfiguredLayout(GraphControl graphControl)
        {
            var layout = new OrganicLayout();

            layout.PreferredEdgeLength = PreferredEdgeLengthItem;
            layout.ConsiderNodeLabels  = ConsiderNodeLabelsItem;
            layout.NodeOverlapsAllowed = AllowNodeOverlapsItem;
            layout.MinimumNodeDistance = MinimumNodeDistanceItem;
            layout.Scope                  = ScopeItem;
            layout.CompactnessFactor      = CompactnessItem;
            layout.ConsiderNodeSizes      = true;
            layout.ClusterNodes           = UseAutoClusteringItem;
            layout.ClusteringQuality      = AutoClusteringQualityItem;
            layout.NodeEdgeOverlapAvoided = AvoidNodeEdgeOverlapsItem;
            layout.Deterministic          = ActivateDeterministicModeItem;
            layout.MaximumDuration        = 1000 * MaximumDurationItem;
            layout.QualityTimeRatio       = QualityTimeRatioItem;

            if (EdgeLabelingItem)
            {
                var genericLabeling = new GenericLabeling {
                    PlaceEdgeLabels = true,
                    PlaceNodeLabels = false,
                    ReduceAmbiguity = ReduceAmbiguityItem
                };
                layout.LabelingEnabled = true;
                layout.Labeling        = genericLabeling;
            }
            ((ComponentLayout)layout.ComponentLayout).Style = ComponentArrangementStyles.MultiRows;

            ConfigureOutputRestrictions(graphControl, layout);

            layout.ChainSubstructureStyle    = ChainSubstructureStyleItem;
            layout.CycleSubstructureStyle    = CycleSubstructureStyleItem;
            layout.StarSubstructureStyle     = StarSubstructureStyleItem;
            layout.ParallelSubstructureStyle = ParallelSubstructureStyleItem;

            if (UseEdgeGroupingItem)
            {
                graphControl.Graph.MapperRegistry.CreateConstantMapper <IEdge, object>(PortConstraintKeys.SourceGroupIdDpKey, "Group");
                graphControl.Graph.MapperRegistry.CreateConstantMapper <IEdge, object>(PortConstraintKeys.TargetGroupIdDpKey, "Group");
            }

            AddPreferredPlacementDescriptor(graphControl.Graph, LabelPlacementAlongEdgeItem, LabelPlacementSideOfEdgeItem, LabelPlacementOrientationItem, LabelPlacementDistanceItem);

            return(layout);
        }
Beispiel #13
0
        /// <summary>
        /// Setup default values for various configuration parameters.
        /// </summary>
        public OrganicLayoutConfig()
        {
            var layout = new OrganicLayout();

            ScopeItem = Scope.All;
            PreferredEdgeLengthItem   = layout.PreferredEdgeLength;
            AllowNodeOverlapsItem     = layout.NodeOverlapsAllowed;
            MinimumNodeDistanceItem   = 10;
            AvoidNodeEdgeOverlapsItem = layout.NodeEdgeOverlapAvoided;
            CompactnessItem           = layout.CompactnessFactor;
            ClusteringPolicyItem      = layout.ClusteringPolicy;
            ClusteringQualityItem     = layout.ClusteringQuality;

            RestrictOutputItem  = EnumOutputRestrictions.None;
            RectCageUseViewItem = true;
            CageXItem           = 0;
            CageYItem           = 0;
            CageWidthItem       = 1000;
            CageHeightItem      = 1000;
            ArCageUseViewItem   = true;
            CageRatioItem       = 1;

            GroupLayoutPolicyItem = EnumGroupLayoutPolicy.LayoutGroups;

            QualityTimeRatioItem          = layout.QualityTimeRatio;
            MaximumDurationItem           = (int)(layout.MaximumDuration / 1000);
            ActivateDeterministicModeItem = layout.Deterministic;

            CycleSubstructureStyleItem    = CycleSubstructureStyle.None;
            CycleSubstructureSizeItem     = layout.CycleSubstructureSize;
            ChainSubstructureStyleItem    = ChainSubstructureStyle.None;
            ChainSubstructureSizeItem     = layout.ChainSubstructureSize;
            StarSubstructureStyleItem     = StarSubstructureStyle.None;
            StarSubstructureSizeItem      = layout.StarSubstructureSize;
            ParallelSubstructureStyleItem = ParallelSubstructureStyle.None;
            ParallelSubstructureSizeItem  = layout.ParallelSubstructureSize;

            ConsiderNodeLabelsItem        = layout.ConsiderNodeLabels;
            EdgeLabelingItem              = false;
            LabelPlacementAlongEdgeItem   = EnumLabelPlacementAlongEdge.Centered;
            LabelPlacementSideOfEdgeItem  = EnumLabelPlacementSideOfEdge.OnEdge;
            LabelPlacementOrientationItem = EnumLabelPlacementOrientation.Horizontal;
            LabelPlacementDistanceItem    = 10;
        }
Beispiel #14
0
        /// <inheritdoc />
        protected override ILayoutAlgorithm CreateConfiguredLayout(GraphControl graphControl)
        {
            var layout = new OrganicLayout();

            layout.PreferredEdgeLength = PreferredEdgeLengthItem;
            layout.ConsiderNodeLabels  = ConsiderNodeLabelsItem;
            layout.NodeOverlapsAllowed = AllowNodeOverlapsItem;
            layout.MinimumNodeDistance = MinimumNodeDistanceItem;
            layout.Scope                  = ScopeItem;
            layout.CompactnessFactor      = CompactnessItem;
            layout.ConsiderNodeSizes      = true;
            layout.ClusteringPolicy       = ClusteringPolicyItem;
            layout.ClusteringQuality      = ClusteringQualityItem;
            layout.NodeEdgeOverlapAvoided = AvoidNodeEdgeOverlapsItem;
            layout.Deterministic          = ActivateDeterministicModeItem;
            layout.MaximumDuration        = 1000 * MaximumDurationItem;
            layout.QualityTimeRatio       = QualityTimeRatioItem;

            if (EdgeLabelingItem)
            {
                var genericLabeling = new GenericLabeling {
                    PlaceEdgeLabels = true,
                    PlaceNodeLabels = false,
                    ReduceAmbiguity = ReduceAmbiguityItem
                };
                layout.LabelingEnabled = true;
                layout.Labeling        = genericLabeling;
            }
            ((ComponentLayout)layout.ComponentLayout).Style = ComponentArrangementStyles.MultiRows;

            ConfigureOutputRestrictions(graphControl, layout);

            layout.ChainSubstructureStyle    = ChainSubstructureStyleItem;
            layout.CycleSubstructureSize     = CycleSubstructureSizeItem;
            layout.CycleSubstructureStyle    = CycleSubstructureStyleItem;
            layout.ChainSubstructureSize     = ChainSubstructureSizeItem;
            layout.StarSubstructureStyle     = StarSubstructureStyleItem;
            layout.StarSubstructureSize      = StarSubstructureSizeItem;
            layout.ParallelSubstructureStyle = ParallelSubstructureStyleItem;
            layout.ParallelSubstructureSize  = ParallelSubstructureSizeItem;

            return(layout);
        }
Beispiel #15
0
        /// <inheritdoc />
        protected override ILayoutAlgorithm CreateConfiguredLayout(GraphControl graphControl)
        {
            var layout = new PartialLayout();

            layout.ConsiderNodeAlignment       = AlignNodesItem;
            layout.MinimumNodeDistance         = MinimumNodeDistanceItem;
            layout.SubgraphPlacement           = SubgraphPlacementItem;
            layout.ComponentAssignmentStrategy = ComponentAssignmentStrategyItem;
            layout.LayoutOrientation           = OrientationItem;
            layout.EdgeRoutingStrategy         = RoutingToSubgraphItem;
            layout.AllowMovingFixedElements    = MoveFixedElementsItem;

            ILayoutAlgorithm subgraphLayout = null;

            if (ComponentAssignmentStrategyItem != ComponentAssignmentStrategy.Single)
            {
                switch (SubgraphLayoutItem)
                {
                case EnumSubgraphLayouts.Hierarchic:
                    subgraphLayout = new HierarchicLayout();
                    break;

                case EnumSubgraphLayouts.Organic:
                    subgraphLayout = new OrganicLayout();
                    break;

                case EnumSubgraphLayouts.Circular:
                    subgraphLayout = new CircularLayout();
                    break;

                case EnumSubgraphLayouts.Orthogonal:
                    subgraphLayout = new OrthogonalLayout();
                    break;
                }
            }
            layout.CoreLayout = subgraphLayout;

            return(layout);
        }
Beispiel #16
0
        private void SetupLayouts()
        {
            //using hierarchical layout style
            HierarchicLayout hierarchicLayout = new HierarchicLayout();

            hierarchicLayout.EdgeLayoutDescriptor.RoutingStyle = new yWorks.Layout.Hierarchic.RoutingStyle(
                yWorks.Layout.Hierarchic.EdgeRoutingStyle.Orthogonal);

            CurrentLayout = hierarchicLayout;
            layouts.Add("Hierarchic", hierarchicLayout);

            //using organic layout style
            OrganicLayout organic = new OrganicLayout
            {
                QualityTimeRatio       = 1.0,
                NodeOverlapsAllowed    = false,
                NodeEdgeOverlapAvoided = true,
                MinimumNodeDistance    = 10,
                PreferredEdgeLength    = 50,
            };

            layouts.Add("Organic", organic);

            //using orthogonal layout style
            OrthogonalLayout orthogonal = new OrthogonalLayout
            {
                GridSpacing            = 15,
                OptimizePerceivedBends = true
            };

            layouts.Add("Orthogonal", orthogonal);

            //using circular layout style
            CircularLayout circular = new CircularLayout();

            circular.BalloonLayout.MinimumEdgeLength = 50;
            circular.BalloonLayout.CompactnessFactor = 0.1;
            layouts.Add("Circular", circular);

            // a tree layout algorithm
            TreeLayout treeLayout = new TreeLayout {
                ConsiderNodeLabels = true
            };

            treeLayout.AppendStage(new TreeReductionStage()
            {
                NonTreeEdgeRouter       = new OrganicEdgeRouter(),
                NonTreeEdgeSelectionKey = OrganicEdgeRouter.AffectedEdgesDpKey,
            });
            layouts.Add("Tree", treeLayout);

            //using Polyline Router
            var polylineRouter = new EdgeRouter
            {
                Grid            = new Grid(0, 0, 10),
                PolylineRouting = true,
                Rerouting       = true
            };

            polylineRouter.DefaultEdgeLayoutDescriptor.PenaltySettings.BendPenalty         = 3;
            polylineRouter.DefaultEdgeLayoutDescriptor.PenaltySettings.EdgeCrossingPenalty = 5;
            layouts.Add("Polyline Edge Router", polylineRouter);
        }
        private void ConfigureOutputRestrictions(GraphControl graphControl, OrganicLayout layout)
        {
            var    viewInfoIsAvailable = false;
            var    visibleRect = GetVisibleRectangle(graphControl);
            double x = 0, y = 0, w = 0, h = 0;

            if (visibleRect != null)
            {
                viewInfoIsAvailable = true;
                x = visibleRect[0];
                y = visibleRect[1];
                w = visibleRect[2];
                h = visibleRect[3];
            }
            switch (RestrictOutputItem)
            {
            case EnumOutputRestrictions.None:
                layout.ComponentLayoutEnabled = true;
                layout.OutputRestriction      = OutputRestriction.None;
                break;

            case EnumOutputRestrictions.OutputCage:
                if (!viewInfoIsAvailable || !RectCageUseViewItem)
                {
                    x = CageXItem;
                    y = CageYItem;
                    w = CageWidthItem;
                    h = CageHeightItem;
                }
                layout.OutputRestriction      = OutputRestriction.CreateRectangularCageRestriction(x, y, w, h);
                layout.ComponentLayoutEnabled = false;
                break;

            case EnumOutputRestrictions.OutputAr:
                double ratio;
                if (viewInfoIsAvailable && ArCageUseViewItem)
                {
                    ratio = w / h;
                }
                else
                {
                    ratio = CageRatioItem;
                }
                layout.OutputRestriction      = OutputRestriction.CreateAspectRatioRestriction(ratio);
                layout.ComponentLayoutEnabled = true;
                ((ComponentLayout)layout.ComponentLayout).PreferredSize = new YDimension(ratio * 100, 100);
                break;

            case EnumOutputRestrictions.OutputEllipticalCage:
                if (!viewInfoIsAvailable || !RectCageUseViewItem)
                {
                    x = CageXItem;
                    y = CageYItem;
                    w = CageWidthItem;
                    h = CageHeightItem;
                }
                layout.OutputRestriction      = OutputRestriction.CreateEllipticalCageRestriction(x, y, w, h);
                layout.ComponentLayoutEnabled = false;
                break;
            }
        }
Beispiel #18
0
        protected override LayoutData CreateConfiguredLayoutData(GraphControl graphControl, ILayoutAlgorithm layout)
        {
            var layoutData = new HierarchicLayoutData();

            var incrementalLayout = SelectedElementsIncrementallyItem;
            var selection         = graphControl.Selection;
            var selectedElements  = selection.SelectedEdges.Any() || selection.SelectedNodes.Any();

            if (incrementalLayout && selectedElements)
            {
                // configure the mode
                var ihf = ((HierarchicLayout)layout).CreateIncrementalHintsFactory();
                layoutData.IncrementalHints.Delegate = item => {
                    // Return the correct hint type for each model item that appears in one of these sets
                    if (item is INode && selection.IsSelected(item))
                    {
                        return(ihf.CreateLayerIncrementallyHint(item));
                    }
                    if (item is IEdge && selection.IsSelected(item))
                    {
                        return(ihf.CreateSequenceIncrementallyHint(item));
                    }
                    return(null);
                };
            }

            if (RankingPolicyItem == LayeringStrategy.Bfs)
            {
                layoutData.BfsLayererCoreNodes.Delegate = selection.IsSelected;
            }

            if (GridEnabledItem)
            {
                var nld = ((HierarchicLayout)layout).NodeLayoutDescriptor;
                layoutData.NodeLayoutDescriptors.Delegate = node => {
                    var descriptor = new NodeLayoutDescriptor();
                    descriptor.LayerAlignment     = nld.LayerAlignment;
                    descriptor.MinimumDistance    = nld.MinimumDistance;
                    descriptor.MinimumLayerHeight = nld.MinimumLayerHeight;
                    descriptor.NodeLabelMode      = nld.NodeLabelMode;
                    // anchor nodes on grid according to their alignment within the layer
                    descriptor.GridReference  = new YPoint(0.0, (nld.LayerAlignment - 0.5) * node.Layout.Height);
                    descriptor.PortAssignment = this.GridPortAssignmentItem;
                    return(descriptor);
                };
            }

            if (EdgeDirectednessItem)
            {
                layoutData.EdgeDirectedness.Delegate = edge => {
                    if (edge.Style is IArrowOwner && !Equals(((IArrowOwner)edge.Style).TargetArrow, Arrows.None))
                    {
                        return(1);
                    }
                    return(0);
                };
            }

            if (EdgeThicknessItem)
            {
                layoutData.EdgeThickness.Delegate = edge => {
                    var style = edge.Style as PolylineEdgeStyle;
                    if (style != null)
                    {
                        return(style.Pen.Thickness);
                    }
                    return(1);
                };
            }

            if (SubComponentsItem)
            {
                // layout all siblings with label 'TL' separately with tree layout
                var treeLayout = new TreeLayout {
                    DefaultNodePlacer = new LeftRightNodePlacer()
                };
                foreach (var listOfNodes in FindSubComponents(graphControl.Graph, "TL"))
                {
                    layoutData.SubComponents.Add(treeLayout).Items = listOfNodes;
                }
                // layout all siblings with label 'HL' separately with hierarchical layout
                var hierarchicLayout = new HierarchicLayout {
                    LayoutOrientation = LayoutOrientation.LeftToRight
                };
                foreach (var listOfNodes in FindSubComponents(graphControl.Graph, "HL"))
                {
                    layoutData.SubComponents.Add(hierarchicLayout).Items = listOfNodes;
                }
                // layout all siblings with label 'OL' separately with organic layout
                var organicLayout = new OrganicLayout {
                    PreferredEdgeLength = 100, Deterministic = true
                };
                foreach (var listOfNodes in FindSubComponents(graphControl.Graph, "OL"))
                {
                    layoutData.SubComponents.Add(organicLayout).Items = listOfNodes;
                }
            }

            if (HighlightCriticalPath)
            {
                // highlight the longest path in the graph as critical path
                // since the longest path algorithm only works for acyclic graphs,
                // feedback edges and self loops have to be excluded here
                var feedbackEdgeSetResult = new FeedbackEdgeSet().Run(graphControl.Graph);
                var longestPath           = new LongestPath {
                    SubgraphEdges =
                    {
                        Excludes     =
                        {
                            Delegate = edge => feedbackEdgeSetResult.FeedbackEdgeSet.Contains(edge) || edge.IsSelfloop()
                        }
                    }
                }.Run(graphControl.Graph);
                if (longestPath.Edges.Any())
                {
                    layoutData.CriticalEdgePriorities.Delegate = edge => {
                        if (longestPath.Edges.Contains(edge))
                        {
                            return(10);
                        }
                        return(1);
                    };
                }
            }

            if (AutomaticBusRouting)
            {
                var allBusNodes = new HashSet <INode>();
                foreach (var node in graphControl.Graph.Nodes)
                {
                    if (!graphControl.Graph.IsGroupNode(node) && !allBusNodes.Contains(node))
                    {
                        // search for good opportunities for bus structures rooted at this node
                        if (graphControl.Graph.InDegree(node) >= 4)
                        {
                            var busDescriptor = new BusDescriptor();
                            var busEdges      = GetBusEdges(graphControl.Graph, node, allBusNodes,
                                                            graphControl.Graph.InEdgesAt(node));
                            if (busEdges.Any())
                            {
                                layoutData.Buses.Add(busDescriptor).Items = busEdges;
                            }
                        }
                        if (graphControl.Graph.OutDegree(node) >= 4)
                        {
                            var busDescriptor = new BusDescriptor();
                            var busEdges      = GetBusEdges(graphControl.Graph, node, allBusNodes, graphControl.Graph.OutEdgesAt(node));
                            if (busEdges.Any())
                            {
                                layoutData.Buses.Add(busDescriptor).Items = busEdges;
                            }
                        }
                    }
                }
            }

            return(layoutData.CombineWith(
                       CreateLabelingLayoutData(
                           graphControl.Graph,
                           LabelPlacementAlongEdgeItem,
                           LabelPlacementSideOfEdgeItem,
                           LabelPlacementOrientationItem,
                           LabelPlacementDistanceItem
                           )
                       ));
        }
        /// <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();
        }
Beispiel #20
0
        protected override LayoutData CreateConfiguredLayoutData(GraphControl graphControl, ILayoutAlgorithm layout)
        {
            var layoutData = new HierarchicLayoutData();

            var incrementalLayout = SelectedElementsIncrementallyItem;
            var selection         = graphControl.Selection;
            var selectedElements  = selection.SelectedEdges.Any() || selection.SelectedNodes.Any();

            if (incrementalLayout && selectedElements)
            {
                // configure the mode
                var ihf = ((HierarchicLayout)layout).CreateIncrementalHintsFactory();
                layoutData.IncrementalHints.Delegate = item => {
                    // Return the correct hint type for each model item that appears in one of these sets
                    if (item is INode && selection.IsSelected(item))
                    {
                        return(ihf.CreateLayerIncrementallyHint(item));
                    }
                    if (item is IEdge && selection.IsSelected(item))
                    {
                        return(ihf.CreateSequenceIncrementallyHint(item));
                    }
                    return(null);
                };
            }

            if (RankingPolicyItem == LayeringStrategy.Bfs)
            {
                layoutData.BfsLayererCoreNodes.Delegate = selection.IsSelected;
            }

            if (GridEnabledItem)
            {
                var nld = ((HierarchicLayout)layout).NodeLayoutDescriptor;
                layoutData.NodeLayoutDescriptors.Delegate = node => {
                    var descriptor = new NodeLayoutDescriptor();
                    descriptor.LayerAlignment     = nld.LayerAlignment;
                    descriptor.MinimumDistance    = nld.MinimumDistance;
                    descriptor.MinimumLayerHeight = nld.MinimumLayerHeight;
                    descriptor.NodeLabelMode      = nld.NodeLabelMode;
                    // anchor nodes on grid according to their alignment within the layer
                    descriptor.GridReference  = new YPoint(0.0, (nld.LayerAlignment - 0.5) * node.Layout.Height);
                    descriptor.PortAssignment = this.GridPortAssignmentItem;
                    return(descriptor);
                };
            }

            if (EdgeDirectednessItem)
            {
                layoutData.EdgeDirectedness.Delegate = edge => {
                    if (edge.Style is IArrowOwner && !Equals(((IArrowOwner)edge.Style).TargetArrow, Arrows.None))
                    {
                        return(1);
                    }
                    return(0);
                };
            }

            if (EdgeThicknessItem)
            {
                layoutData.EdgeThickness.Delegate = edge => {
                    var style = edge.Style as PolylineEdgeStyle;
                    if (style != null)
                    {
                        return(style.Pen.Width);
                    }
                    return(1);
                };
            }

            if (SubComponentsItem)
            {
                var treeLayout = new TreeLayout {
                    DefaultNodePlacer = new LeftRightNodePlacer()
                };
                layoutData.SubComponents.Add(treeLayout).Delegate =
                    node => node.Labels.Any() && node.Labels.First().Text == "TL";
                var hierarchicLayout = new HierarchicLayout {
                    LayoutOrientation = LayoutOrientation.LeftToRight
                };
                layoutData.SubComponents.Add(hierarchicLayout).Delegate =
                    node => node.Labels.Any() && node.Labels.First().Text == "HL";
                var organicLayout = new OrganicLayout {
                    PreferredEdgeLength = 100, Deterministic = true
                };
                layoutData.SubComponents.Add(organicLayout).Delegate =
                    node => node.Labels.Any() && node.Labels.First().Text == "OL";
            }

            if (BusesItem)
            {
                // Group edges ending at a node with the label "Bus" into a bus
                layoutData.Buses.Add(new BusDescriptor()).Delegate =
                    edge => edge.GetTargetNode().Labels.Count > 0 && edge.GetTargetNode().Labels[0].Text == "Bus";
            }

            return(layoutData);
        }
Beispiel #21
0
        /// <summary>
        /// Lays out the graph with nodes that are laid out incrementally.
        /// </summary>
        /// <param name="incrementalNodes">Nodes that should be inserted into the graph incrementally.</param>
        private async Task ApplyLayout(HashSet <INode> incrementalNodes)
        {
            toolStrip.Enabled = false;

            // We'll use an OrganicLayout with OrganicEdgeRouter to get a pleasing image for most databases
            var layout = new OrganicLayout
            {
                NodeEdgeOverlapAvoided         = true,
                NodeOverlapsAllowed            = false,
                PreferredEdgeLength            = 180,
                MinimumNodeDistance            = 80,
                StarSubstructureStyle          = StarSubstructureStyle.Radial,
                StarSubstructureSize           = 3,
                ConsiderNodeSizes              = true,
                CycleSubstructureStyle         = CycleSubstructureStyle.Circular,
                StarSubstructureTypeSeparation = false,
                LabelingEnabled           = true,
                ParallelEdgeRouterEnabled = true,
                Scope = incrementalNodes.Count > 0 ? Scope.MainlySubset : Scope.All
            };

            layout.PrependStage(new OrganicEdgeRouter()
            {
                ConsiderExistingBends  = false,
                KeepExistingBends      = false,
                EdgeNodeOverlapAllowed = false,
                RouteAllEdges          = false,
                MinimumDistance        = 10
            });

            // GenericLabeling ensures that labels don't overlap
            layout.PrependStage(new GenericLabeling {
                RemoveNodeOverlaps = true
            });

            // CurveFittingLayoutStage adds Bezier control points so we can use BezierEdgeStyle to render the edges
            layout.PrependStage(new CurveFittingLayoutStage());

            var layoutData = new CompositeLayoutData(
                new OrganicLayoutData
            {
                NodeTypes     = { Delegate = node => ((INeo4jNode)node.Tag).Labels[0] },
                AffectedNodes = { Source = incrementalNodes },
            },
                new LabelingData
            {
                EdgeLabelPreferredPlacement =
                {
                    Constant           = new PreferredPlacementDescriptor
                    {
                        AngleReference = LabelAngleReferences.RelativeToEdgeFlow,
                        PlaceAlongEdge = LabelPlacements.AtSource,
                        SideOfEdge     = LabelPlacements.RightOfEdge | LabelPlacements.LeftOfEdge
                    }
                }
            }
                );

            await graphControl.MorphLayout(layout, TimeSpan.FromMilliseconds(700), layoutData);

            toolStrip.Enabled = true;
        }
        public BusinessModelAdapterWindow()
        {
            InitializeComponent();

            // create a sample list of customers
            // create the template Customer
            dummyCustomer = new Customer("Enter A Name", 0);

            customers = new ObservableCollection <Customer>();

            this.Resources.Add("DummyCustomer", dummyCustomer);


            Customer customer1 = new Customer("Mr. Tester", 42);
            Customer customer2 = new Customer("Mrs. Tester", 43);
            Customer customer3 = new Customer("Baby Tester", 2);
            Customer customer4 = new Customer("Aunt Tester", 34);

            this.customers.Add(customer1);
            this.customers.Add(customer2);
            this.customers.Add(customer3);
            this.customers.Add(customer4);

            // add some relationships between customers
            customer2.RelatedCustomers.Add(customer3);
            customer2.RelatedCustomers.Add(customer4);

            customer1.RelatedCustomers.Add(customer2);
            customer2.RelatedCustomers.Add(customer1);

            // publish the list so that the listview can pick it up
            this.Resources.Add("Customers", this.customers);

            // configure the GraphControl
            GraphEditorInputMode editorInputMode = new GraphEditorInputMode();

            // configure some structural edits
            editorInputMode.CreateBendInputMode.Enabled = false;
            editorInputMode.ShowHandleItems             = GraphItemTypes.Edge;
            editorInputMode.DeletableItems = GraphItemTypes.None;
            editorInputMode.CreateEdgeInputMode.Enabled     = true;
            editorInputMode.CreateEdgeInputMode.EdgeCreator = EdgeCreator;

            // register custom code for the creation of new entities
            editorInputMode.NodeCreator = NodeCreator;

            // set the mode
            graphControl.InputMode = editorInputMode;

            // define the default edge style
            ArcEdgeStyle style = new ArcEdgeStyle {
                Pen = new Pen(Brushes.Black, 2), Height = 30, TargetArrow = Arrows.Default, ProvideHeightHandle = false
            };

            Graph.EdgeDefaults.Style = style;

            // fetch the node style from the xaml templates
            customerNodeStyle = new NodeControlNodeStyle("CustomerNodeStyle")
            {
                OutlineShape = new System.Windows.Shapes.Rectangle {
                    RadiusX = 3, RadiusY = 3
                }
            };

            // now create the graph from the bindinglist
            CreateGraph(this.customers);

            // register for change notification
            ((INotifyCollectionChanged)customers).CollectionChanged += customers_CollectionChanged;

            layout = CreateLayout();
        }
Beispiel #23
0
        public static void Main()
        {
            DefaultLayoutGraph graph = new DefaultLayoutGraph();

            //construct graph and assign sizes to its nodes
            Node[] nodes = new Node[16];
            for (int i = 0; i < 16; i++)
            {
                nodes[i] = graph.CreateNode();
                graph.SetSize(nodes[i], 30, 30);
            }
            graph.CreateEdge(nodes[0], nodes[1]);
            graph.CreateEdge(nodes[0], nodes[2]);
            graph.CreateEdge(nodes[0], nodes[3]);
            graph.CreateEdge(nodes[0], nodes[14]);
            graph.CreateEdge(nodes[2], nodes[4]);
            graph.CreateEdge(nodes[3], nodes[5]);
            graph.CreateEdge(nodes[3], nodes[6]);
            graph.CreateEdge(nodes[3], nodes[9]);
            graph.CreateEdge(nodes[4], nodes[7]);
            graph.CreateEdge(nodes[4], nodes[8]);
            graph.CreateEdge(nodes[5], nodes[9]);
            graph.CreateEdge(nodes[6], nodes[10]);
            graph.CreateEdge(nodes[7], nodes[11]);
            graph.CreateEdge(nodes[8], nodes[12]);
            graph.CreateEdge(nodes[8], nodes[15]);
            graph.CreateEdge(nodes[9], nodes[13]);
            graph.CreateEdge(nodes[10], nodes[13]);
            graph.CreateEdge(nodes[10], nodes[14]);
            graph.CreateEdge(nodes[12], nodes[15]);

            GraphViewer gv = new GraphViewer();

            //using organic layout style
            OrganicLayout organic = new OrganicLayout();

            organic.QualityTimeRatio    = 1.0;
            organic.NodeOverlapsAllowed = false;
            organic.MinimumNodeDistance = 10;
            organic.PreferredEdgeLength = 40;
            new BufferedLayout(organic).ApplyLayout(graph);
            LayoutGraphUtilities.ClipEdgesOnBounds(graph);
            gv.AddLayoutGraph(new CopiedLayoutGraph(graph), "Organic Layout Style");

            //using orthogonal edge router (node positions stay fixed)
            EdgeRouter router = new EdgeRouter();

            new BufferedLayout(router).ApplyLayout(graph);
            gv.AddLayoutGraph(new CopiedLayoutGraph(graph), "Polyline Edge Router");


            //using orthogonal layout style
            OrthogonalLayout orthogonal = new OrthogonalLayout();

            orthogonal.GridSpacing            = 15;
            orthogonal.OptimizePerceivedBends = true;
            new BufferedLayout(orthogonal).ApplyLayout(graph);
            gv.AddLayoutGraph(new CopiedLayoutGraph(graph), "Orthogonal Layout Style");


            //using circular layout style
            CircularLayout circular = new CircularLayout();

            circular.BalloonLayout.MinimumEdgeLength = 20;
            circular.BalloonLayout.CompactnessFactor = 0.1;
            new BufferedLayout(circular).ApplyLayout(graph);
            LayoutGraphUtilities.ClipEdgesOnBounds(graph);
            gv.AddLayoutGraph(new CopiedLayoutGraph(graph), "Circular Layout Style");

            //using hierarchical layout style
            var hierarchic = new HierarchicLayout();

            new BufferedLayout(hierarchic).ApplyLayout(graph);
            gv.AddLayoutGraph(graph, "Hierarchical Layout Style");

            var application = new System.Windows.Application();

            application.Run(gv);
        }