/// <inheritdoc />
        protected override ILayoutAlgorithm CreateConfiguredLayout(GraphControl graphControl)
        {
            var layout        = new CircularLayout();
            var balloonLayout = layout.BalloonLayout;

            layout.LayoutStyle       = LayoutStyleItem;
            layout.EdgeRoutingPolicy = EdgeRoutingPolicyItem;
            layout.ExteriorEdgeLayoutDescriptor.CircleDistance       = CircleDistanceItem;
            layout.ExteriorEdgeLayoutDescriptor.EdgeToEdgeDistance   = EdgeToEdgeDistanceItem;
            layout.ExteriorEdgeLayoutDescriptor.PreferredAngle       = PreferredAngleItem;
            layout.ExteriorEdgeLayoutDescriptor.PreferredCurveLength = PreferredCurveLengthItem;
            layout.ExteriorEdgeLayoutDescriptor.Smoothness           = SmoothnessItem;
            layout.SubgraphLayoutEnabled = ActOnSelectionOnlyItem;
            layout.MaximumDeviationAngle = MaximumDeviationAngleItem;
            layout.FromSketchMode        = FromSketchItem;
            layout.ConsiderNodeLabels    = HandleNodeLabelsItem;

            layout.PartitionStyle = PartitionStyleItem;

            layout.SingleCycleLayout.MinimumNodeDistance = MinimumNodeDistanceItem;
            layout.SingleCycleLayout.AutomaticRadius     = ChooseRadiusAutomaticallyItem;
            layout.SingleCycleLayout.FixedRadius         = FixedRadiusItem;

            balloonLayout.PreferredChildWedge  = PreferredChildWedgeItem;
            balloonLayout.MinimumEdgeLength    = MinimumEdgeLengthItem;
            balloonLayout.CompactnessFactor    = CompactnessFactorItem;
            balloonLayout.AllowOverlaps        = AllowOverlapsItem;
            layout.PlaceChildrenOnCommonRadius = PlaceChildrenOnCommonRadiusItem;
            balloonLayout.MinimumNodeDistance  = MinimumTreeNodeDistanceItem;

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

            var ebc = layout.EdgeBundling;
            var bundlingDescriptor = new EdgeBundleDescriptor();

            bundlingDescriptor.Bundled  = EdgeBundlingItem;
            ebc.BundlingStrength        = EdgeBundlingStrengthItem;
            ebc.DefaultBundleDescriptor = bundlingDescriptor;

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

            return(layout);
        }
        protected override void ConfigureLayout()
        {
            OptionGroup generalGroup = Handler.GetGroupByName(GENERAL);

            RadialLayout radialLayout = new RadialLayout();

            radialLayout.MinimumNodeToNodeDistance = (double)generalGroup[MINIMAL_NODE_DISTANCE].Value;
            String strategy = (string)generalGroup[EDGE_ROUTING_STRATEGY].Value;

            switch (strategy)
            {
            case EDGE_POLYLINE:
                radialLayout.EdgeRoutingStrategy = EdgeRoutingStrategy.Polyline;
                break;

            case EDGE_ARC:
                radialLayout.EdgeRoutingStrategy = EdgeRoutingStrategy.Arc;
                break;

            case EDGE_BUNDLES:
                EdgeBundling         ebc        = radialLayout.EdgeBundling;
                EdgeBundleDescriptor descriptor = new EdgeBundleDescriptor();
                descriptor.Bundled          = true;
                ebc.DefaultBundleDescriptor = descriptor;
                ebc.BundlingStrength        = (double)Handler.GetValue(GENERAL, EDGE_BUNDLING_STRENGTH);
                break;
            }

            double minimumBendAngle = 1 +
                                      (MAXIMUM_SMOOTHNESS - (int)generalGroup[EDGE_SMOOTHNESS].Value) *
                                      SMOOTHNESS_ANGLE_FACTOR;

            radialLayout.MinimumBendAngle        = minimumBendAngle;
            radialLayout.MinimumLayerDistance    = (double)generalGroup[MINIMAL_LAYER_DISTANCE].Value;
            radialLayout.MaximumChildSectorAngle = (double)generalGroup[MAXIMAL_CHILD_SECTOR_SIZE].Value;

            String centerStrategy = (string)generalGroup[CENTER_STRATEGY].Value;

            radialLayout.CenterNodesPolicy = centerNodeStrategies[centerStrategy];

            radialLayout.LayeringStrategy = layeringStrategies[(string)generalGroup[LAYERING_STRATEGY].Value];

            radialLayout.ConsiderNodeLabels = (bool)generalGroup[CONSIDER_NODE_LABELS].Value;

            LayoutAlgorithm = radialLayout;
        }
        /// <summary>
        /// configures tree reduction state and non-tree edge routing.
        /// </summary>
        protected override void PerformPreLayout()
        {
            if ((bool)Handler.GetValue(GENERAL, ALLOW_NON_TREE_EDGES))
            {
                additionalStage = new TreeReductionStage();
                multiStageLayout.AppendStage(additionalStage);
                string routingStyleChoice = (string)Handler.GetValue(GENERAL, ROUTING_STYLE_FOR_NON_TREE_EDGES);
                switch (routingStyleChoice)
                {
                case ROUTE_ORGANIC:
                    OrganicEdgeRouter organic = new OrganicEdgeRouter();
                    additionalStage.NonTreeEdgeRouter       = organic;
                    additionalStage.NonTreeEdgeSelectionKey = OrganicEdgeRouter.AffectedEdgesDpKey;
                    break;

                case ROUTE_ORTHOGONAL:
                    EdgeRouter orthogonal = new EdgeRouter {
                        Rerouting = true,
                        Scope     = Scope.RouteAffectedEdges
                    };

                    additionalStage.NonTreeEdgeSelectionKey = orthogonal.AffectedEdgesDpKey;
                    additionalStage.NonTreeEdgeRouter       = orthogonal;
                    break;

                case ROUTE_STRAIGHTLINE:
                    additionalStage.NonTreeEdgeRouter = additionalStage.CreateStraightLineRouter();
                    break;

                case ROUTE_BUNDLED:
                    EdgeBundling         ebc        = additionalStage.EdgeBundling;
                    EdgeBundleDescriptor descriptor = new EdgeBundleDescriptor();
                    descriptor.Bundled          = true;
                    ebc.DefaultBundleDescriptor = descriptor;
                    ebc.BundlingStrength        = (double)Handler.GetValue(GENERAL, EDGE_BUNDLING_STRENGTH);

                    // Sets a new straight-line router in case some edges are not bundled, e.g. self-loops
                    OrganicEdgeRouter oer = new OrganicEdgeRouter();
                    additionalStage.NonTreeEdgeRouter       = oer;
                    additionalStage.NonTreeEdgeSelectionKey = OrganicEdgeRouter.AffectedEdgesDpKey;
                    break;
                }
            }
        }
        ///<inheritdoc/>
        protected override void ConfigureLayout()
        {
            CircularLayout layout = new CircularLayout();

            ((ComponentLayout)layout.ComponentLayout).Style = ComponentArrangementStyles.MultiRows;

            BalloonLayout treeLayout = layout.BalloonLayout;

            layout.LayoutStyle           = globalLayoutStyles[(string)Handler.GetValue(GENERAL, LAYOUT_STYLE)];
            layout.SubgraphLayoutEnabled = (bool)Handler.GetValue(GENERAL, ACT_ON_SELECTION_ONLY);
            layout.MaximumDeviationAngle = (int)Handler.GetValue(TREE, MAXIMAL_DEVIATION_ANGLE);
            layout.FromSketchMode        = (bool)Handler.GetValue(GENERAL, FROM_SKETCH);
            layout.ConsiderNodeLabels    = (bool)Handler.GetValue(GENERAL, HANDLE_NODE_LABELS);

            layout.PartitionStyle = partitionLayoutStyles[(string)Handler.GetValue(CYCLE, PARTITION_LAYOUT_STYLE)];

            layout.SingleCycleLayout.MinimumNodeDistance = (int)Handler.GetValue(CYCLE, MINIMAL_NODE_DISTANCE);
            layout.SingleCycleLayout.AutomaticRadius     = (bool)Handler.GetValue(CYCLE, CHOOSE_RADIUS_AUTOMATICALLY);
            layout.SingleCycleLayout.FixedRadius         = (int)Handler.GetValue(CYCLE, FIXED_RADIUS);

            treeLayout.PreferredChildWedge     = ((int)Handler.GetValue(TREE, PREFERRED_CHILD_WEDGE));
            treeLayout.MinimumEdgeLength       = (int)Handler.GetValue(TREE, MINIMAL_EDGE_LENGTH);
            treeLayout.CompactnessFactor       = (double)Handler.GetValue(TREE, COMPACTNESS_FACTOR);
            treeLayout.AllowOverlaps           = (bool)Handler.GetValue(TREE, ALLOW_OVERLAPS);
            layout.PlaceChildrenOnCommonRadius = (bool)Handler.GetValue(TREE, PLACE_CHILDREN_ON_COMMON_RADIUS);
            treeLayout.MinimumNodeDistance     = (int)Handler.GetValue(TREE, MINIMAL_TREE_NODE_DISTANCE);

            // Edge Bundling
            EdgeBundling         ebc        = layout.EdgeBundling;
            EdgeBundleDescriptor descriptor = new EdgeBundleDescriptor();

            descriptor.Bundled          = (bool)Handler.GetValue(EDGE_BUNDLING, EDGE_BUNDLING_ENABLED);
            ebc.DefaultBundleDescriptor = descriptor;
            ebc.BundlingStrength        = (double)Handler.GetValue(EDGE_BUNDLING, EDGE_BUNDLING_STRENGTH);

            LayoutAlgorithm = layout;
        }
        /// <inheritdoc />
        protected override ILayoutAlgorithm CreateConfiguredLayout(GraphControl graphControl)
        {
            var layout = new BalloonLayout();

            ((ComponentLayout)layout.ComponentLayout).Style = ComponentArrangementStyles.MultiRows;

            layout.RootNodePolicy         = RootNodePolicyItem;
            layout.PreferredChildWedge    = PreferredChildWedgeItem;
            layout.PreferredRootWedge     = PreferredRootWedgeItem;
            layout.MinimumEdgeLength      = MinimumEdgeLengthItem;
            layout.CompactnessFactor      = 1 - CompactnessFactorItem;
            layout.AllowOverlaps          = AllowOverlapsItem;
            layout.FromSketchMode         = FromSketchItem;
            layout.ChainStraighteningMode = StraightenChainsItem;
            layout.InterleavedMode        = PlaceChildrenInterleavedItem ? InterleavedMode.AllNodes : InterleavedMode.Off;

            switch (NodeLabelingStyleItem)
            {
            case EnumNodeLabelingPolicies.None:
                layout.ConsiderNodeLabels = false;
                break;

            case EnumNodeLabelingPolicies.RaylikeLeaves:
                layout.IntegratedNodeLabeling = true;
                layout.NodeLabelingPolicy     = NodeLabelingPolicy.RayLikeLeaves;
                break;

            case EnumNodeLabelingPolicies.ConsiderCurrentPosition:
                layout.ConsiderNodeLabels = true;
                break;

            case EnumNodeLabelingPolicies.Horizontal:
                layout.IntegratedNodeLabeling = true;
                layout.NodeLabelingPolicy     = NodeLabelingPolicy.Horizontal;
                break;

            default:
                layout.ConsiderNodeLabels = false;
                break;
            }

            // configures tree reduction stage and non-tree edge routing.
            layout.SubgraphLayoutEnabled = ActOnSelectionOnlyItem;
            MultiStageLayout multiStageLayout = layout;

            var treeReductionStage = new TreeReductionStage();

            multiStageLayout.AppendStage(treeReductionStage);
            if (RoutingStyleForNonTreeEdgesItem == EnumRoute.Organic)
            {
                var organic = new OrganicEdgeRouter();
                treeReductionStage.NonTreeEdgeRouter       = organic;
                treeReductionStage.NonTreeEdgeSelectionKey = OrganicEdgeRouter.AffectedEdgesDpKey;
            }
            else if (RoutingStyleForNonTreeEdgesItem == EnumRoute.Orthogonal)
            {
                var edgeRouter = new EdgeRouter {
                    Rerouting = true,
                    Scope     = Scope.RouteAffectedEdges
                };
                treeReductionStage.NonTreeEdgeSelectionKey = edgeRouter.AffectedEdgesDpKey;
                treeReductionStage.NonTreeEdgeRouter       = edgeRouter;
            }
            else if (RoutingStyleForNonTreeEdgesItem == EnumRoute.StraightLine)
            {
                treeReductionStage.NonTreeEdgeRouter = treeReductionStage.CreateStraightLineRouter();
            }
            else if (RoutingStyleForNonTreeEdgesItem == EnumRoute.Bundled)
            {
                var ebc = treeReductionStage.EdgeBundling;
                var bundleDescriptor = new EdgeBundleDescriptor {
                    Bundled = true
                };
                ebc.BundlingStrength        = EdgeBundlingStrengthItem;
                ebc.DefaultBundleDescriptor = bundleDescriptor;
            }

            if (EdgeLabelingItem == EnumEdgeLabeling.Generic)
            {
                layout.IntegratedEdgeLabeling = false;
                var genericLabeling = new GenericLabeling {
                    PlaceEdgeLabels = true,
                    PlaceNodeLabels = false,
                    ReduceAmbiguity = ReduceAmbiguityItem
                };
                layout.LabelingEnabled = true;
                layout.Labeling        = genericLabeling;
            }
            else if (EdgeLabelingItem == EnumEdgeLabeling.Integrated)
            {
                layout.IntegratedEdgeLabeling = true;
                treeReductionStage.NonTreeEdgeLabelingAlgorithm = new GenericLabeling();
            }

            if (NodeLabelingStyleItem == EnumNodeLabelingPolicies.RaylikeLeaves || NodeLabelingStyleItem == EnumNodeLabelingPolicies.Horizontal)
            {
                foreach (var label in graphControl.Graph.GetNodeLabels())
                {
                    graphControl.Graph.SetLabelLayoutParameter(label, FreeNodeLabelModel.Instance.FindBestParameter(label, FreeNodeLabelModel.Instance, label.GetLayout()));
                }
            }

            return(layout);
        }