Beispiel #1
0
        /// <summary>
        /// Returns a new GraphComponents instance that represents connected nodes
        /// as partition nodes
        /// </summary>
        /// <param name="Scope">The scope of the graph data being partitioned</param>
        /// <returns>a GraphComponents instance</returns>
        public GraphComponents GetConnectedComponents(string _scope)
        {
            GraphComponents partitionedGraph = new GraphComponents(_scope);

            // Get all the node view models contained in the target scope
            List <NodeViewModelBase> nodeVMs = new List <NodeViewModelBase>(GetGraphComponents(_scope).GetNodeViewModels().Cast <NodeViewModelBase>().ToList());

            PartitionNode connectedComponent = GetNextConnectedComponent(nodeVMs, _scope);

            // Continue getting the next connected component
            // as long as the last connected component was
            // not null
            while (connectedComponent != null)
            {
                // Instruct the partition node to calculate its dimensions
                connectedComponent.RecalculateDimensions();

                // Add the partition node to the partion graph
                partitionedGraph.AddNodeViewModel(connectedComponent);
                //partitionedGraph.AddNode(connectedComponent);

                // Get the next connected component
                connectedComponent = GetNextConnectedComponent(nodeVMs, _scope);
            }

            return(partitionedGraph);
        }
Beispiel #2
0
        /// <summary>
        /// Returns a PartitionNode instance for the next connected
        /// component contained in the provided list.  The collection
        /// provided is altered and should not be changed between calls
        /// to this method.
        /// </summary>
        /// <param name="nodeVMs">The collection of node view models to be processed</param>
        /// <param name="partitionGraphScope">The scope for the paritioned graph</param>
        /// <param name="originalScope">The scope for the original graph</param>
        /// <returns>a PartitionNode containing a set of connected nodes</returns>
        private PartitionNode GetNextConnectedComponent(IList <NodeViewModelBase> nodeVMs, string scope)
        {
            // Make sure node view models were provided
            if (nodeVMs.Count == 0)
            {
                return(null);
            }

            // Create a new partition node to hold these components
            PartitionNode partitionNode = new PartitionNode(scope, "PN-" + nodeVMs.Count);

            // Start at the first nodeVMs
            List <NodeViewModelBase> visitedNodes = new List <NodeViewModelBase>();
            List <NodeViewModelBase> rootNodes    = new List <NodeViewModelBase>();

            // Add the first node view model to the root and visited lists
            rootNodes.Add(nodeVMs[0]);
            visitedNodes.Add(nodeVMs[0]);

            // Itterate over the root nodes
            while (rootNodes.Count > 0)
            {
                int currentNodeIndex = 0;

                // Add the current node view model to the
                // current PartitionNode
                partitionNode.AddNode(rootNodes[currentNodeIndex]);

                // Itterate over the node's neighbors
                foreach (Model.INode node in GetGraphComponents(rootNodes[currentNodeIndex].Scope).Data.Neighbors(rootNodes[currentNodeIndex].ParentNode))
                {
                    // Get the nodeVM for this node
                    NodeViewModelBase nodeVM = GetGraphComponents(rootNodes[currentNodeIndex].Scope).GetNodeViewModel(node) as NodeViewModelBase;

                    // Check if this node has already been visisted
                    if (!visitedNodes.Contains(nodeVM))
                    {
                        // Add this node to our two holder collections
                        rootNodes.Add(nodeVM);
                        visitedNodes.Add(nodeVM);
                    }
                }

                // Remove the current node since it has been processed
                nodeVMs.Remove(rootNodes[currentNodeIndex]);
                rootNodes.RemoveAt(currentNodeIndex);
            }

            return(partitionNode);
        }
Beispiel #3
0
        public ICollection<Point> CalculateConvexHullForCluster(PartitionNode pn)
        {
            double padding = 0;

            List<Point> points = new List<Point>();

            foreach (NodeViewModelBase nodeVM in pn.Nodes)
            {
                points.Add(new Point(nodeVM.Position.X - nodeVM.Width / 2 - padding, nodeVM.Position.Y - nodeVM.Height / 2 - padding));
                points.Add(new Point(nodeVM.Position.X - nodeVM.Width / 2 - padding, nodeVM.Position.Y + nodeVM.Height / 2 + padding));
                points.Add(new Point(nodeVM.Position.X + nodeVM.Width / 2 + padding, nodeVM.Position.Y + nodeVM.Height / 2 + padding));
                points.Add(new Point(nodeVM.Position.X + nodeVM.Width / 2 + padding, nodeVM.Position.Y - nodeVM.Height / 2 - padding));
            }

            return ConvexHull.CalculateConvexHull(points);
        }
Beispiel #4
0
        private static object[] GetPartitionNodeDimensionAndPosition(GraphMapData graphMapData, PartitionNode partitionNode)
        {
            Point topLeft = new Point(double.MaxValue, double.MaxValue);
            Point bottomRight = new Point(double.MinValue, double.MinValue);

            // Loop through all node view models to get the bounding area
            foreach (NodeViewModelBase nodeViewModelBase in partitionNode.Nodes)
            {
                NodeMapData nodeMapData = graphMapData.Nodes[nodeViewModelBase.ParentNode.ID];

                topLeft.X = Math.Min(topLeft.X, nodeMapData.Position.X - nodeMapData.Dimension.Width / 2D);
                topLeft.Y = Math.Min(topLeft.Y, nodeMapData.Position.Y - nodeMapData.Dimension.Height / 2D);

                bottomRight.X = Math.Max(bottomRight.X, nodeMapData.Position.X + nodeMapData.Dimension.Width / 2D);
                bottomRight.Y = Math.Max(bottomRight.Y, nodeMapData.Position.Y + nodeMapData.Dimension.Height / 2D);
            }

            // Set the new dimensions based on the calculation performed
            double width = Math.Max(bottomRight.X - topLeft.X, 1D);
            double height = Math.Max(bottomRight.Y - topLeft.Y, 1D);

            Size dimension = new Size(width, height);

            // get the center of the partitionNode
            Point position = new Point(topLeft.X + width / 2D, topLeft.Y + height / 2D);

            object[] result = new object[] { dimension, position };
            return result;
        }
Beispiel #5
0
        /// <summary>
        /// Returns a PartitionNode instance for the next connected
        /// component contained in the provided list.  The collection
        /// provided is altered and should not be changed between calls
        /// to this method.
        /// </summary>
        /// <param name="nodeVMs">The collection of node view models to be processed</param>
        /// <param name="partitionGraphScope">The scope for the paritioned graph</param>
        /// <param name="originalScope">The scope for the original graph</param>
        /// <returns>a PartitionNode containing a set of connected nodes</returns>
        private PartitionNode GetNextConnectedComponent(IList<NodeViewModelBase> nodeVMs, string scope)
        {
            // Make sure node view models were provided
            if (nodeVMs.Count == 0) return null;

            // Create a new partition node to hold these components
            PartitionNode partitionNode = new PartitionNode(scope, "PN-" + nodeVMs.Count);

            // Start at the first nodeVMs
            List<NodeViewModelBase> visitedNodes = new List<NodeViewModelBase>();
            List<NodeViewModelBase> rootNodes = new List<NodeViewModelBase>();

            // Add the first node view model to the root and visited lists
            rootNodes.Add(nodeVMs[0]);
            visitedNodes.Add(nodeVMs[0]);

            // Itterate over the root nodes
            while (rootNodes.Count > 0)
            {
                int currentNodeIndex = 0;

                // Add the current node view model to the
                // current PartitionNode
                partitionNode.AddNode(rootNodes[currentNodeIndex]);

                // Itterate over the node's neighbors
                foreach (Model.INode node in GetGraphComponents(rootNodes[currentNodeIndex].Scope).Data.Neighbors(rootNodes[currentNodeIndex].ParentNode))
                {
                    // Get the nodeVM for this node
                    NodeViewModelBase nodeVM = GetGraphComponents(rootNodes[currentNodeIndex].Scope).GetNodeViewModel(node) as NodeViewModelBase;

                    // Check if this node has already been visisted
                    if (!visitedNodes.Contains(nodeVM))
                    {
                        // Add this node to our two holder collections
                        rootNodes.Add(nodeVM);
                        visitedNodes.Add(nodeVM);
                    }
                }

                // Remove the current node since it has been processed
                nodeVMs.Remove(rootNodes[currentNodeIndex]);
                rootNodes.RemoveAt(currentNodeIndex);
            }

            return partitionNode;
        }
Beispiel #6
0
        /// <summary>
        /// Creates the polygons that represent the highlights for clustered data
        /// </summary>
        /// <param name="pn">The partition node containing nodes in the cluster</param>
        /// <returns>The polygon created for the highlight</returns>
        private Polygon CreateHighlightPolygon(PartitionNode pn)
        {
            PointCollection convexHull = ConvertListOfPointsToPointCollection(_cluster.CalculateConvexHullForCluster(pn));

            return DrawHighlightPolygon(convexHull);
        }
Beispiel #7
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="initialNode"></param>
        /// <returns></returns>
        private PartitionNode GetClusterAsPartitionNode(INodeShape initialNode)
        {
            // Determine if the provided node is already
            // stored in our internal collection.  If it
            // is, return it.
            if (_nodeToPartition.ContainsKey(initialNode))
                return _nodeToPartition[initialNode];

            PartitionNode pn = new PartitionNode(_sourceGraph.Scope, "Partition" + (_currentId++).ToString());
            _partitionNodes.Add(pn);

            Dictionary<INodeShape, bool> nodesInCluster = new Dictionary<INodeShape, bool>();
            Queue<INodeShape> nodesToTriangulate = new Queue<INodeShape>();

            nodesInCluster[initialNode] = true;
            nodesToTriangulate.Enqueue(initialNode);

            while (nodesToTriangulate.Count > 0)
            {
                List<INodeShape> tempList = FindTrianglesToAdd(nodesToTriangulate.Dequeue(), nodesInCluster);

                foreach (INodeShape nodeVM in tempList)
                {
                    // Add the node view model to our queue
                    nodesToTriangulate.Enqueue(nodeVM);
                }
            }

            // Loop over all the node view models in the dictionary
            foreach (NodeViewModelBase nodeVM in nodesInCluster.Keys)
            {
                // Add the node to the partition
                pn.AddNode(nodeVM);

                // Save the updated partition node
                _nodeToPartition[nodeVM] = pn;
            }

            return pn;
        }