Beispiel #1
0
        /// <summary>
        /// Creates a large random graph to give the layout algorithms something to chew.
        /// </summary>
        private static void BuildGraph(IGraph graph)
        {
            graph.Clear();
            // Create 400 nodes
            INode[] nodes = new INode[400];
            for (int i = 0; i < nodes.Length; i++)
            {
                nodes[i] = graph.CreateNode();
            }
            // Connect the nodes randomly
            Random random = new Random(0);

            for (int i = 0; i < nodes.Length; i++)
            {
                int edgeCount;
                if (random.Next(10) == 0)
                {
                    edgeCount = 4 + random.Next(5);
                }
                else
                {
                    edgeCount = random.Next(3);
                }
                for (int j = 0; j < edgeCount; j++)
                {
                    graph.CreateEdge(nodes[i], nodes[random.Next(nodes.Length)]);
                }
            }

            // remove all components except the largest one
            var adapter = new YGraphAdapter(graph);

            NodeList[] components = GraphConnectivity.ConnectedComponents(adapter.YGraph);

            Array.Sort(components, (o1, o2) => o2.Count - o1.Count);

            for (int i = components.Length - 1; i > 0; i--)
            {
                foreach (var node in components[i])
                {
                    graph.Remove(adapter.GetOriginalNode(node));
                }
            }

            // add labels
            int count = 0;

            foreach (var node in graph.Nodes)
            {
                graph.AddLabel(node, count++.ToString());
            }
            RandomizeGraph(graph);
        }
        /// <summary>
        /// Called once the move operation has been initialized
        /// </summary>
        /// <remarks>
        /// Calculates which components stay fixed and which nodes will be moved by the user.
        /// </remarks>
        private void OnMoveInitialized(object sender, EventArgs eventArgs)
        {
            if (layout != null)
            {
                CopiedLayoutGraph copy = this.copiedLayoutGraph;
                var componentNumber    = copy.CreateNodeMap();
                GraphConnectivity.ConnectedComponents(copy, componentNumber);
                System.Collections.Generic.HashSet <int>  movedComponents = new System.Collections.Generic.HashSet <int>();
                System.Collections.Generic.HashSet <Node> selectedNodes   = new System.Collections.Generic.HashSet <Node>();
                foreach (INode node in movedNodes)
                {
                    Node copiedNode = copy.GetCopiedNode(node);
                    if (copiedNode != null)
                    {
                        // remember that we nailed down this node
                        selectedNodes.Add(copiedNode);
                        // remember that we are moving this component
                        movedComponents.Add(componentNumber.GetInt(copiedNode));
                        //Update the position of the node in the CLG to match the one in the IGraph
                        layout.SetCenter(copiedNode, node.Layout.X + node.Layout.Width * 0.5, node.Layout.Y + node.Layout.Height * 0.5);
                        //Actually, the node itself is fixed at the start of a drag gesture
                        layout.SetInertia(copiedNode, 1.0);
                        //Increasing has the effect that the layout will consider this node as not completely placed...
                        // In this case, the node itself is fixed, but it's neighbors will wake up
                        IncreaseHeat(copiedNode, layout, 0.5);
                    }
                }

                // there are components that won't be moved - nail the nodes down so that they don't spread apart infinitely
                foreach (var copiedNode in copy.Nodes)
                {
                    if (!movedComponents.Contains(componentNumber.GetInt(copiedNode)))
                    {
                        layout.SetInertia(copiedNode, 1);
                    }
                    else
                    {
                        if (!selectedNodes.Contains(copiedNode))
                        {
                            // make it float freely
                            layout.SetInertia(copiedNode, 0);
                        }
                    }
                }

                // dispose the map
                copy.DisposeNodeMap(componentNumber);

                //Notify the layout algorithm that there is new work to do...
                layout.WakeUp();
            }
        }