/// <summary>
        /// Creates a layout data suiting the <paramref name="resizeState"/>.
        /// </summary>
        /// <param name="resizeState">The current state of the gesture</param>
        /// <returns>A layout data suiting the <paramref name="resizeState"/>.</returns>
        private LayoutData CreateLayoutData(ResizeState resizeState)
        {
            var layoutData = new CompositeLayoutData(resetToOriginalGraphStageData);

            if (resizeState == ResizeState.Shrinking)
            {
                layoutData.Items.Add(new FillAreaLayoutData {
                    FixedNodes = { Items = nodes }
                });
                if (state == GestureState.Finishing)
                {
                    // only route edges for the final layout
                    layoutData.Items.Add(new EdgeRouterData {
                        AffectedNodes = { Items = nodes }
                    });
                }
            }
            else
            {
                if (resizeState == ResizeState.Both)
                {
                    layoutData.Items.Add(new FillAreaLayoutData {
                        FixedNodes = { Items = nodes }
                    });
                }
                layoutData.Items.Add(new ClearAreaLayoutData {
                    AreaNodes = { Items = nodes }
                });
            }
            return(layoutData);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// A <see cref="LayoutExecutor"/> that is used during the drag and drop operation.
        /// </summary>
        /// <remarks>
        /// First, all nodes and edges are pushed back into place before the drag started. Then space
        /// is made for the component at its current position. The animation morphs all elements to the
        /// calculated positions.
        /// </remarks>
        private LayoutExecutor CreateDraggingLayoutExecutor()
        {
            var layout = new GivenCoordinatesStage(
                clearAreaLayout = new ClearAreaLayout {
                ComponentAssignmentStrategy = ComponentAssignmentStrategy.Customized,
                ClearAreaStrategy           = ClearAreaStrategy.PreserveShapes
            });

            var layoutData = new CompositeLayoutData(
                resetToOriginalGraphStageData,
                new ClearAreaLayoutData {
                ComponentIds = { Mapper = components }
            });

            var items = new List <IModelItem>();

            items.AddRange(Component.Nodes);
            items.AddRange(Component.Edges);
            clearAreaLayout.ConfigureAreaOutline(items, 10);

            return(new LayoutExecutor(graphControl, layout)
            {
                LayoutData = layoutData,
                RunInThread = true,
                Duration = TimeSpan.FromMilliseconds(150)
            });
        }
        /// <summary>
        /// Invokes a layout specified by the current layout type.
        /// </summary>
        /// <remarks>
        /// If there is a fixed node, the layout is calculated incrementally.
        /// </remarks>
        /// <param name="fixedNode">If defined, the layout will be incrementally and this node remains at its location.</param>
        public async Task RunLayout(INode fixedNode = null)
        {
            if (layoutRunning)
            {
                return;
            }
            layoutRunning = true;
            var incremental = fixedNode != null;

            // configure layout
            var layout     = layoutType == LayoutHierarchic ? (ILayoutAlgorithm)GetHierarchicLayout(incremental) : GetOrthogonalLayout();
            var layoutData = layoutType == LayoutHierarchic ? (LayoutData)GetHierarchicLayoutData() : GetOrthogonalLayoutData();

            if (incremental)
            {
                // fixate the location of the given fixed node
                layout = new FixNodeLayoutStage(layout)
                {
                    FixPointPolicy = FixPointPolicy.LowerLeft
                };
                layoutData = new CompositeLayoutData(layoutData,
                                                     new FixNodeLayoutData {
                    FixedNodes = new ItemCollection <INode> {
                        Item = fixedNode
                    }
                }
                                                     );
            }

            EnableUI(false);

            // configure layout execution to not move the view port
            var executor = new LayoutExecutor(graphControl, layout)
            {
                LayoutData        = layoutData,
                AnimateViewport   = !incremental,
                Duration          = TimeSpan.FromMilliseconds(500),
                UpdateContentRect = true,
            };

            // start layout
            await executor.Start();

            layoutRunning = false;
            EnableUI(true);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// A <see cref="LayoutExecutor"/> that is used after the drag and drop operation is finished.
        /// </summary>
        /// <remarks>
        /// All nodes and edges are pushed back into place before the drag started. Then space is made
        /// for the component that has been dropped.
        /// </remarks>
        private LayoutExecutor CreateFinishedLayoutExecutor()
        {
            var layout = new GivenCoordinatesStage(
                new ClearAreaLayout {
                ComponentAssignmentStrategy = ComponentAssignmentStrategy.Customized,
                ClearAreaStrategy           = ClearAreaStrategy.PreserveShapes
            });

            var layoutData = new CompositeLayoutData(
                resetToOriginalGraphStageData,
                new ClearAreaLayoutData {
                AreaNodes    = { Source = Component.Nodes },
                ComponentIds = { Mapper = components }
            });

            return(new LayoutExecutor(graphControl, layout)
            {
                LayoutData = layoutData,
                RunInThread = true,
                Duration = TimeSpan.FromMilliseconds(150)
            });
        }
Ejemplo n.º 5
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;
        }