Example #1
0
        private void CollectSubtreeNodes(INode selectedNode, List <INode> nodesToDelete)
        {
            nodesToDelete.Add(selectedNode);
            IListEnumerable <IEdge> outEdges = graphControl.Graph.EdgesAt(selectedNode, AdjacencyTypes.Outgoing);

            foreach (IEdge outEdge in outEdges)
            {
                var target = (INode)outEdge.TargetPort.Owner;
                CollectSubtreeNodes(target, nodesToDelete);
            }
        }
Example #2
0
        private int GetLayer(INode n)
        {
            int   layer = 0;
            INode node  = n;

            while (true)
            {
                IListEnumerable <IEdge> inEdges = graphControl.Graph.EdgesAt(node, AdjacencyTypes.Incoming);
                if (inEdges.Count == 0)
                {
                    break;
                }
                else
                {
                    node = (INode)inEdges.First().SourcePort.Owner;
                    layer++;
                }
            }
            return(layer);
        }
Example #3
0
        /// <summary>
        /// Runs a balloon layout where the hierarchy edges are the tree edges and original edges are bundled.
        /// </summary>
        private async Task RunBalloonLayout(IListEnumerable <INode> affectedNodes = null)
        {
            // create the balloon layout
            var layout = new BalloonLayout {
                IntegratedNodeLabeling = true,
                NodeLabelingPolicy     = NodeLabelingPolicy.RayLikeLeaves,
                FromSketchMode         = true,
                CompactnessFactor      = 0.1,
                AllowOverlaps          = true
            };

            // prepend a TreeReduction stage with the hierarchy edges as tree edges
            layout.PrependStage(new TreeReductionStage());
            var nonTreeEdges = GraphControl.Graph.Edges.Where(e => !aggregationHelper.IsHierarchyEdge(e)).ToList();

            // mark all other edges to be bundled
            var bundleDescriptorMap = new ItemMapping <IEdge, EdgeBundleDescriptor>();

            foreach (var nonTreeEdge in nonTreeEdges)
            {
                bundleDescriptorMap.Mapper[nonTreeEdge] = new EdgeBundleDescriptor {
                    Bundled = true
                };
            }

            var treeReductionStageData = new TreeReductionStageData {
                NonTreeEdges = { Items = nonTreeEdges }, EdgeBundleDescriptors = bundleDescriptorMap
            };

            // create a layout executor that also zooms to all nodes that were affected by the last operation
            var layoutExecutor =
                new ZoomToNodesLayoutExecutor(affectedNodes ?? ListEnumerable <INode> .Empty, GraphControl, layout)
            {
                Duration        = TimeSpan.FromSeconds(0.5),
                AnimateViewport = true,
                EasedAnimation  = true,
                LayoutData      = treeReductionStageData
            };
            await layoutExecutor.Start();
        }
Example #4
0
        private static IBend CreateBends([NotNull] IGraph graph, [NotNull] IEdge edge, int segmentIndex, double ratio,
                                         [NotNull] IListEnumerable <IPoint> pathPoints)
        {
            //Create 3 bends and adjust the neighbors
            //The first bend we need to touch is at startIndex
            var startIndex = segmentIndex * 3;

            //This holds the new coordinates left and right of the split point
            //We don't actually need all of them, but this keeps the algorithm more straightforward.
            var left  = new PointD[4];
            var right = new PointD[4];

            //Determine the new control points to cleanly split the curve

            GetCubicSplitPoints(ratio,
                                new[] {
                pathPoints[startIndex].ToPointD(), pathPoints[startIndex + 1].ToPointD(),
                pathPoints[startIndex + 2].ToPointD(), pathPoints[startIndex + 3].ToPointD()
            }, left, right);

            //Previous control point - does always exist as a bend, given our precondition
            var previousBend = edge.Bends[startIndex];
            //Next control point - also always exists given the precondition for bend counts (i.e. there have to be at least two)
            var nextBend = edge.Bends[startIndex + 1];

            //We create the three new bends between previous bend and next bend and adjust these two.
            //We don't have to adjust more bends, since we just have a cubic curve.
            IBend bendToMove;
            var   engine = graph.GetUndoEngine();

            //Wrap everything into a single compound edit, so that everything can be undone in a single unit
            using (var edit = graph.BeginEdit("Create Bezier Bend", "Create Bezier Bend")) {
                try {
                    //Adjust the previous bend - given the split algorithm, its coordinate is in left[1]
                    //(left[0] is actually kept unchanged from the initial value)
                    var oldPrevLocation = previousBend.Location.ToPointD();
                    var newPrevLocation = left[1];
                    graph.SetBendLocation(previousBend, newPrevLocation);
                    // Add unit to engine
                    graph.AddUndoUnit("Set bend location", "Set bend location",
                                      () => graph.SetBendLocation(previousBend, oldPrevLocation),
                                      () => graph.SetBendLocation(previousBend, newPrevLocation));

                    //Insert the new triple, using the values from left and right in order
                    graph.AddBend(edge, left[2], startIndex + 1);
                    bendToMove = graph.AddBend(edge, left[3], startIndex + 2);
                    //right[0] == left[3], so right[1] is the next new control point
                    graph.AddBend(edge, right[1], startIndex + 3);

                    //Adjust the next bend
                    var oldNextLocation = nextBend.Location.ToPointD();
                    var newNextLocation = right[2];
                    graph.SetBendLocation(nextBend, newNextLocation);
                    // Add unit to engine
                    graph.AddUndoUnit("Set bend location", "Set bend location",
                                      () => graph.SetBendLocation(nextBend, oldNextLocation),
                                      () => graph.SetBendLocation(nextBend, newNextLocation));
                } catch {
                    //Cancel the edit in case anything goes wrong.
                    edit.Cancel();
                    throw;
                }
            }

            return(bendToMove);
        }
Example #5
0
 public ZoomToNodesLayoutExecutor(IListEnumerable <INode> nodes, GraphControl graphControl, ILayoutAlgorithm layout)
     : base(graphControl, layout)
 {
     this.nodes = nodes;
 }