/// <inheritdoc /> protected override ILayoutAlgorithm CreateConfiguredLayout(GraphControl graphControl) { var layout = new HierarchicLayout(); // mark incremental elements if required var fromSketch = UseDrawingAsSketchItem; var incrementalLayout = SelectedElementsIncrementallyItem; var selectedElements = graphControl.Selection.SelectedEdges.Any() || graphControl.Selection.SelectedNodes.Any(); if (incrementalLayout && selectedElements) { layout.LayoutMode = LayoutMode.Incremental; } else if (fromSketch) { layout.LayoutMode = LayoutMode.Incremental; } else { layout.LayoutMode = LayoutMode.FromScratch; } ((SimplexNodePlacer)layout.NodePlacer).BarycenterMode = SymmetricPlacementItem; layout.ComponentLayoutEnabled = LayoutComponentsSeparatelyItem; layout.MinimumLayerDistance = MinimumLayerDistanceItem; layout.NodeToEdgeDistance = NodeToEdgeDistanceItem; layout.NodeToNodeDistance = NodeToNodeDistanceItem; layout.EdgeToEdgeDistance = EdgeToEdgeDistanceItem; var nld = layout.NodeLayoutDescriptor; var eld = layout.EdgeLayoutDescriptor; layout.AutomaticEdgeGrouping = AutomaticEdgeGroupingEnabledItem; eld.RoutingStyle = new RoutingStyle(EdgeRoutingItem); eld.RoutingStyle.CurveShortcuts = CurveShortcutsItem; eld.RoutingStyle.CurveUTurnSymmetry = CurveUTurnSymmetryItem; eld.MinimumFirstSegmentLength = MinimumFirstSegmentLengthItem; eld.MinimumLastSegmentLength = MinimumLastSegmentLengthItem; eld.MinimumDistance = MinimumEdgeDistanceItem; eld.MinimumLength = MinimumEdgeLengthItem; eld.MinimumSlope = MinimumSlopeItem; eld.SourcePortOptimization = PcOptimizationEnabledItem; eld.TargetPortOptimization = PcOptimizationEnabledItem; eld.RecursiveEdgeStyle = RecursiveEdgeStyleItem; nld.MinimumDistance = Math.Min(layout.NodeToNodeDistance, layout.NodeToEdgeDistance); nld.MinimumLayerHeight = 0; nld.LayerAlignment = LayerAlignmentItem; var ol = (OrientationLayout)layout.OrientationLayout; ol.Orientation = OrientationItem; if (ConsiderNodeLabelsItem) { layout.ConsiderNodeLabels = true; layout.NodeLayoutDescriptor.NodeLabelMode = NodeLabelMode.ConsiderForDrawing; } else { layout.ConsiderNodeLabels = false; } if (EdgeLabelingItem != EnumEdgeLabeling.None) { if (EdgeLabelingItem == EnumEdgeLabeling.Generic) { layout.IntegratedEdgeLabeling = false; var labeling = new GenericLabeling { PlaceNodeLabels = false, PlaceEdgeLabels = true, AutoFlipping = true, ReduceAmbiguity = ReduceAmbiguityItem, ProfitModel = new SimpleProfitModel(), }; layout.LabelingEnabled = true; layout.Labeling = labeling; } else if (EdgeLabelingItem == EnumEdgeLabeling.Integrated) { layout.IntegratedEdgeLabeling = true; ((SimplexNodePlacer)layout.NodePlacer).LabelCompaction = CompactEdgeLabelPlacementItem; } } else { layout.IntegratedEdgeLabeling = false; } layout.FromScratchLayeringStrategy = RankingPolicyItem; layout.ComponentArrangementPolicy = ComponentArrangementPolicyItem; ((SimplexNodePlacer)layout.NodePlacer).NodeCompaction = NodeCompactionItem; ((SimplexNodePlacer)layout.NodePlacer).StraightenEdges = StraightenEdgesItem; //configure AsIsLayerer var layerer = layout.LayoutMode == LayoutMode.FromScratch ? layout.FromScratchLayerer : layout.FixedElementsLayerer; var ail = layerer as AsIsLayerer; if (ail != null) { ail.NodeHalo = HaloItem; ail.NodeScalingFactor = ScaleItem; ail.MinimumNodeSize = MinimumSizeItem; ail.MaximumNodeSize = MaximumSizeItem; } //configure grouping ((SimplexNodePlacer)layout.NodePlacer).GroupCompactionStrategy = GroupHorizontalCompactionItem; if (!fromSketch && GroupLayeringStrategyItem == GroupLayeringStrategyOptions.LayoutGroups) { layout.GroupAlignmentPolicy = GroupAlignmentItem; layout.CompactGroups = GroupEnableCompactionItem; layout.RecursiveGroupLayering = true; } else { layout.RecursiveGroupLayering = false; } if (TreatRootGroupAsSwimlanesItem) { var stage = new TopLevelGroupToSwimlaneStage { OrderSwimlanesFromSketch = UseOrderFromSketchItem, Spacing = SwimlineSpacingItem }; layout.AppendStage(stage); } layout.BackLoopRouting = BackloopRoutingItem; layout.BackLoopRoutingForSelfLoops = BackloopRoutingForSelfLoopsItem; layout.MaximumDuration = MaximumDurationItem * 1000; if (GridEnabledItem) { layout.GridSpacing = GridSpacingItem; } return(layout); }
///<inheritdoc/> protected override void ConfigureLayout() { LayoutGraph graph = CurrentLayoutGraph; HierarchicLayout hl = new HierarchicLayout(); LayoutAlgorithm = hl; // mark incremental elements if required IDataMap incrementalElements; OptionGroup generalGroup = (OptionGroup)Handler.GetGroupByName(GENERAL); OptionGroup currentGroup = (OptionGroup)generalGroup.GetGroupByName(INTERACTION); OptionGroup groupingGroup = (OptionGroup)Handler.GetGroupByName(GROUPING); bool fromSketch = (bool)currentGroup[USE_DRAWING_AS_SKETCH].Value; bool incrementalLayout = (bool)currentGroup[SELECTED_ELEMENTS_INCREMENTALLY].Value; bool selectedElements = !IsEdgeSelectionEmpty() || !IsNodeSelectionEmpty(); if (incrementalLayout && selectedElements) { // create storage for both nodes and edges incrementalElements = Maps.CreateHashedDataMap(); // configure the mode hl.LayoutMode = LayoutMode.Incremental; IIncrementalHintsFactory ihf = hl.CreateIncrementalHintsFactory(); foreach (Node node in graph.Nodes) { if (IsSelected(node)) { incrementalElements.Set(node, ihf.CreateLayerIncrementallyHint(node)); } } foreach (Edge edge in graph.Edges) { if (IsSelected(edge)) { incrementalElements.Set(edge, ihf.CreateSequenceIncrementallyHint(edge)); } } graph.AddDataProvider(HierarchicLayout.IncrementalHintsDpKey, incrementalElements); } else if (fromSketch) { hl.LayoutMode = LayoutMode.Incremental; } else { hl.LayoutMode = LayoutMode.FromScratch; } // cast to implementation simplex var np = (SimplexNodePlacer)hl.NodePlacer; np.BarycenterMode = (bool)generalGroup[SYMMETRIC_PLACEMENT].Value; np.StraightenEdges = (bool)Handler.GetValue(EDGE_SETTINGS, EDGE_STRAIGHTENING_OPTIMIZATION_ENABLED); hl.ComponentLayoutEnabled = (bool)generalGroup[LAYOUT_COMPONENTS_SEPARATELY].Value; currentGroup = (OptionGroup)generalGroup.GetGroupByName(MINIMUM_DISTANCES); hl.MinimumLayerDistance = (double)currentGroup[MINIMUM_LAYER_DISTANCE].Value; hl.NodeToEdgeDistance = (double)currentGroup[NODE_TO_EDGE_DISTANCE].Value; hl.NodeToNodeDistance = (double)currentGroup[NODE_TO_NODE_DISTANCE].Value; hl.EdgeToEdgeDistance = (double)currentGroup[EDGE_TO_EDGE_DISTANCE].Value; NodeLayoutDescriptor nld = hl.NodeLayoutDescriptor; EdgeLayoutDescriptor eld = hl.EdgeLayoutDescriptor; currentGroup = (OptionGroup)Handler.GetGroupByName(EDGE_SETTINGS); hl.AutomaticEdgeGrouping = (bool)currentGroup[AUTOMATIC_EDGE_GROUPING_ENABLED].Value; string edgeRoutingChoice = (string)currentGroup[EDGE_ROUTING].Value; eld.RoutingStyle = edgeRoutingEnum[edgeRoutingChoice]; eld.MinimumFirstSegmentLength = (double)currentGroup[MINIMUM_FIRST_SEGMENT_LENGTH].Value; eld.MinimumLastSegmentLength = (double)currentGroup[MINIMUM_LAST_SEGMENT_LENGTH].Value; eld.MinimumDistance = (double)currentGroup[MINIMUM_EDGE_DISTANCE].Value; eld.MinimumLength = (double)currentGroup[MINIMUM_EDGE_LENGTH].Value; eld.MinimumSlope = (double)currentGroup[MINIMUM_SLOPE].Value; eld.SourcePortOptimization = (bool)currentGroup[PC_OPTIMIZATION_ENABLED].Value; eld.TargetPortOptimization = (bool)currentGroup[PC_OPTIMIZATION_ENABLED].Value; var isIncrementalModeEnabled = (fromSketch || (incrementalLayout && selectedElements)); var recursiveRoutingMode = Handler.GetValue(EDGE_SETTINGS, RECURSIVE_EDGE_ROUTING); if (!isIncrementalModeEnabled && recursiveRoutingMode == RECURSIVE_EDGE_ROUTING_DIRECTED) { eld.RecursiveEdgeStyle = RecursiveEdgeStyle.Directed; } else if (!isIncrementalModeEnabled && recursiveRoutingMode == RECURSIVE_EDGE_ROUTING_UNDIRECTED) { eld.RecursiveEdgeStyle = RecursiveEdgeStyle.Undirected; } else { eld.RecursiveEdgeStyle = RecursiveEdgeStyle.Off; } nld.MinimumDistance = Math.Min(hl.NodeToNodeDistance, hl.NodeToEdgeDistance); nld.MinimumLayerHeight = 0; OptionGroup rankGroup = (OptionGroup)Handler.GetGroupByName(RANKS); string layerAlignmentChoice = (string)rankGroup[LAYER_ALIGNMENT].Value; nld.LayerAlignment = alignmentEnum[layerAlignmentChoice]; ol = (OrientationLayout)hl.OrientationLayout; string orientationChoice = (string)generalGroup[ORIENTATION].Value; ol.Orientation = orientEnum[orientationChoice]; OptionGroup labelingGroup = (OptionGroup)Handler.GetGroupByName(LABELING); currentGroup = (OptionGroup)labelingGroup.GetGroupByName(LABELING_EDGE_PROPERTIES); string el = (string)currentGroup[EDGE_LABELING].Value; if (!el.Equals(EDGE_LABELING_NONE)) { if (el.Equals(EDGE_LABELING_GENERIC)) { var la = new GenericLabeling(); la.MaximumDuration = 0; la.PlaceNodeLabels = false; la.PlaceEdgeLabels = true; la.AutoFlipping = true; la.ProfitModel = new SimpleProfitModel(); hl.PrependStage(la); } else if (el.Equals(EDGE_LABELING_HIERARCHIC)) { bool copactEdgeLabelPlacement = (bool)currentGroup[COMPACT_EDGE_LABEL_PLACEMENT].Value; if (hl.NodePlacer is SimplexNodePlacer) { np.LabelCompaction = copactEdgeLabelPlacement; } hl.IntegratedEdgeLabeling = true; } } else { hl.IntegratedEdgeLabeling = false; } currentGroup = (OptionGroup)labelingGroup.GetGroupByName(NODE_PROPERTIES); if ((bool)currentGroup[CONSIDER_NODE_LABELS].Value) { hl.ConsiderNodeLabels = true; hl.NodeLayoutDescriptor.NodeLabelMode = NodeLabelMode.ConsiderForDrawing; } else { hl.ConsiderNodeLabels = false; } string rp = (string)rankGroup[RANKING_POLICY].Value; hl.FromScratchLayeringStrategy = rankingPolicies[rp]; if (rp.Equals(BFS_LAYERS)) { CurrentLayoutGraph.AddDataProvider(BFSLayerer.CoreNodesDpKey, new SelectedNodesDP(this)); } hl.ComponentArrangementPolicy = componentAlignmentEnum[(string)rankGroup[COMPONENT_ARRANGEMENT_POLICY].Value]; //configure AsIsLayerer Object layerer = (hl.LayoutMode == LayoutMode.FromScratch) ? hl.FromScratchLayerer : hl.FixedElementsLayerer; // if (layerer is OldLayererWrapper) { // layerer = ((OldLayererWrapper)layerer).OldLayerer; // } if (layerer is AsIsLayerer) { AsIsLayerer ail = (AsIsLayerer)layerer; currentGroup = (OptionGroup)rankGroup.GetGroupByName(FROM_SKETCH_PROPERTIES); ail.NodeHalo = (double)currentGroup[HALO].Value; ail.NodeScalingFactor = (double)currentGroup[SCALE].Value; ail.MinimumNodeSize = (double)currentGroup[MINIMUM_SIZE].Value; ail.MaximumNodeSize = (double)currentGroup[MAXIMUM_SIZE].Value; } //configure grouping np.GroupCompactionStrategy = groupHorizCompactionEnum[(string)groupingGroup[GROUP_HORIZONTAL_COMPACTION].Value]; if (!fromSketch && groupStrategyEnum[(string)groupingGroup[GROUP_LAYERING_STRATEGY].Value]) { GroupAlignmentPolicy alignmentPolicy = groupAlignmentEnum[(string)groupingGroup[GROUP_ALIGNMENT].Value]; hl.GroupAlignmentPolicy = alignmentPolicy; hl.CompactGroups = (bool)groupingGroup[GROUP_ENABLE_COMPACTION].Value; hl.RecursiveGroupLayering = true; } else { hl.RecursiveGroupLayering = false; } OptionGroup swimGroup = (OptionGroup)Handler.GetGroupByName(SWIMLANES); if ((bool)swimGroup[TREAT_ROOT_GROUPS_AS_SWIMLANES].Value) { TopLevelGroupToSwimlaneStage stage = new TopLevelGroupToSwimlaneStage(); stage.OrderSwimlanesFromSketch = (bool)swimGroup[USE_ORDER_FROM_SKETCH].Value; stage.Spacing = (double)swimGroup[SWIMLANE_SPACING].Value; hl.AppendStage(stage); } hl.BackLoopRouting = (bool)Handler.GetValue(EDGE_SETTINGS, BACKLOOP_ROUTING); hl.MaximumDuration = ((int)Handler.GetValue(GENERAL, MAXIMUM_DURATION)) * 1000; bool gridEnabled = (bool)Handler.GetValue(GRID, GRID_ENABLED); if (gridEnabled) { hl.GridSpacing = (double)Handler.GetValue(GRID, GRID_SPACING); String portAssignment = (string)Handler.GetValue(GRID, GRID_PORT_ASSIGNMENT); PortAssignmentMode gridPortAssignment; switch (portAssignment) { case GRID_PORT_ASSIGNMENT_ON_GRID: gridPortAssignment = PortAssignmentMode.OnGrid; break; case GRID_PORT_ASSIGNMENT_ON_SUBGRID: gridPortAssignment = PortAssignmentMode.OnSubgrid; break; default: gridPortAssignment = PortAssignmentMode.Default; break; } graph.AddDataProvider(HierarchicLayoutCore.NodeLayoutDescriptorDpKey, new NodeLayoutDescriptorAdapter(hl.NodeLayoutDescriptor, graph, gridPortAssignment)); } }