/// <summary> /// Creates and configures the <see cref="OrganicLayout"/> and the <see cref="OrganicLayoutData"/> /// such that node types are considered. /// </summary> private Sample CreateOrganicSample() { // create an organic layout wrapped by an organic edge router var layout = new OrganicEdgeRouter( // to consider node types, substructures handling (stars, parallel structures and cycles) // on the organic layout is enabled - otherwise types have no influence new OrganicLayout { Deterministic = true, ConsiderNodeSizes = true, MinimumNodeDistance = 30, StarSubstructureStyle = StarSubstructureStyle.Circular, StarSubstructureTypeSeparation = false, ParallelSubstructureStyle = ParallelSubstructureStyle.Rectangular, ParallelSubstructureTypeSeparation = false, CycleSubstructureStyle = CycleSubstructureStyle.Circular }); // the node types are specified as delegate on the nodeTypes property of the layout data var layoutData = new OrganicLayoutData { NodeTypes = { Delegate = node => GetNodeType(node) } }; return(new Sample { Name = "Organic", File = "organic", Layout = layout, LayoutData = layoutData, IsDirected = false }); }
private void createRouter() { if (router != null) { return; } router = new OrganicEdgeRouter(); }
/// <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); }
/// <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> /// Setup default values for various configuration parameters. /// </summary> public OrganicEdgeRouterConfig() { var router = new OrganicEdgeRouter(); SelectionOnlyItem = false; MinimumNodeDistanceItem = router.MinimumDistance; KeepExistingBendsItem = router.KeepExistingBends; RouteOnlyNecessaryItem = !router.RouteAllEdges; AllowMovingNodesItem = false; }
/// <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 ILayoutAlgorithm CreateConfiguredLayout(GraphControl graphControl) { var router = new OrganicEdgeRouter(); router.MinimumDistance = MinimumNodeDistanceItem; router.KeepExistingBends = KeepExistingBendsItem; router.RouteAllEdges = !RouteOnlyNecessaryItem; var layout = new SequentialLayout(); if (AllowMovingNodesItem) { //if we are allowed to move nodes, we can improve the routing results by temporarily enlarging nodes and removing overlaps //(this strategy ensures that there is enough space for the edges) var cls = new CompositeLayoutStage(); cls.AppendStage(router.CreateNodeEnlargementStage()); cls.AppendStage(new RemoveOverlapsStage(0)); layout.AppendLayout(cls); } if (router.KeepExistingBends) { //we want to keep the original bends var bendConverter = new BendConverter { AffectedEdgesDpKey = OrganicEdgeRouter.AffectedEdgesDpKey, AdoptAffectedEdges = SelectionOnlyItem, CoreLayout = router }; layout.AppendLayout(bendConverter); } else { layout.AppendLayout(router); } return(layout); }
/// <inheritdoc /> protected override ILayoutAlgorithm CreateConfiguredLayout(GraphControl graphControl) { var layout = new SeriesParallelLayout(); layout.GeneralGraphHandling = true; layout.LayoutOrientation = OrientationItem; layout.VerticalAlignment = VerticalAlignmentItem; layout.FromSketchMode = UseDrawingAsSketchItem; layout.MinimumNodeToNodeDistance = MinimumNodeToNodeDistanceItem; layout.MinimumNodeToEdgeDistance = MinimumNodeToEdgeDistanceItem; layout.MinimumEdgeToEdgeDistance = MinimumEdgeToEdgeDistanceItem; layout.ConsiderNodeLabels = ConsiderNodeLabelsItem; layout.IntegratedEdgeLabeling = PlaceEdgeLabelsItem; var portAssignment = (DefaultPortAssignment)layout.DefaultPortAssignment; portAssignment.Mode = PortStyleItem; portAssignment.ForkStyle = RouteEdgesInFlowDirectionItem ? ForkStyle.OutsideNode : ForkStyle.AtNode; layout.RoutingStyle = RoutingStyleItem; if (RoutingStyleItem == RoutingStyle.Octilinear) { layout.PreferredOctilinearSegmentLength = PreferredOctilinearSegmentLengthItem; } else if (RoutingStyleItem == RoutingStyle.Polyline) { layout.MinimumPolylineSegmentLength = MinimumPolylineSegmentLengthItem; layout.MinimumSlope = MinimumSlopeItem; } if (RoutingStyleNonSeriesParallelItem == NonSeriesParallelRoutingStyle.Orthogonal) { var edgeRouter = new EdgeRouter { Rerouting = true, Scope = Scope.RouteAffectedEdges }; layout.NonSeriesParallelEdgeRouter = edgeRouter; layout.NonSeriesParallelEdgesDpKey = edgeRouter.AffectedEdgesDpKey; } else if (RoutingStyleNonSeriesParallelItem == NonSeriesParallelRoutingStyle.Organic) { var edgeRouter = new OrganicEdgeRouter(); layout.NonSeriesParallelEdgeRouter = edgeRouter; layout.NonSeriesParallelEdgesDpKey = OrganicEdgeRouter.AffectedEdgesDpKey; } else if (RoutingStyleNonSeriesParallelItem == NonSeriesParallelRoutingStyle.Straight) { var edgeRouter = new StraightLineEdgeRouter { Scope = Scope.RouteAffectedEdges }; layout.NonSeriesParallelEdgeRouter = edgeRouter; layout.NonSeriesParallelEdgesDpKey = edgeRouter.AffectedEdgesDpKey; } var edgeLayoutDescriptor = layout.DefaultEdgeLayoutDescriptor; edgeLayoutDescriptor.MinimumFirstSegmentLength = MinimumFirstSegmentLengthItem; edgeLayoutDescriptor.MinimumLastSegmentLength = MinimumLastSegmentLengthItem; edgeLayoutDescriptor.MinimumLength = MinimumEdgeLengthItem; return(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); }