示例#1
0
        /// <summary>
        /// Collapse all children (outgoing nodes) for the target node
        /// </summary>
        /// <param name="targetNode"></param>
        private void CollapseNode(NodeViewModelBase targetNode)
        {
            List <INode>             childNodes       = new List <INode>();
            List <IEdgeViewModel>    edgesToBeRemoved = new List <IEdgeViewModel>();
            List <IEdgeViewModel>    edgesToBeAdded   = new List <IEdgeViewModel>();
            List <NodeViewModelBase> nodesToBeRemoved = new List <NodeViewModelBase>();

            graph = Data.GraphManager.Instance.GetGraphComponents(targetNode.Scope);

            // Get all the chidren for the target node
            childNodes = GetChildren(targetNode.ParentNode);

            // Ensure we have any child nodes before continuing
            if (childNodes.Count > 0)
            {
                foreach (INode childNode in childNodes)
                {
                    NodeViewModelBase nodeVM = graph.GetNodeViewModel(childNode) as NodeViewModelBase;

                    foreach (IEdge edge in graph.GetEdges(childNode))
                    {
                        IEdgeViewModel edgeVM = graph.GetEdgeViewModel(edge);

                        // Determine if this is an incoming edge
                        if (edge.Target == childNode)
                        {
                            // Existing incoming edges need to be removed
                            // and new ones need to be added
                            edgesToBeRemoved.Add(edgeVM);

                            // Determine if this edge's source node is inside
                            // of the child nodes being collapsed
                            if (!childNodes.Contains(edge.Source) && edge.Source != targetNode.ParentNode)
                            {
                                IEdgeViewModel newEdgeVM = (edgeVM as EdgeViewModelBase).Copy(edge.Source, targetNode.ParentNode);

                                edgesToBeAdded.Add(newEdgeVM);
                            }
                        }
                        else // Handle the outgoing edges
                        {
                            // Outgoing edges need to be saved and removed
                            edgesToBeRemoved.Add(edgeVM);
                        }
                    }

                    // Remove (hide) the node
                    //nodeVM.IsHidden = true;
                    nodesToBeRemoved.Add(nodeVM);
                }

                graph.RemoveNodeViewModels(nodesToBeRemoved);

                // Remove (hide) the edges
                RemoveEdges(edgesToBeRemoved, targetNode);

                // Add new edges
                AddEdges(edgesToBeAdded, targetNode);
            }
        }
示例#2
0
        private static GraphMapData GetClusteredGraph(GraphMapData graphMapData, GraphComponents graphComponents)
        {
            GraphMapData graphComponentsMapData = new GraphMapData();

            IEnumerable <INodeShape> clusteredComponents = graphComponents.GetNodeViewModels();

            foreach (PartitionNode clusteredComponent in clusteredComponents)
            {
                NodeMapData nodeMapData = new TextNodeMapData(clusteredComponent.ID);
                graphComponentsMapData.Add(nodeMapData);

                // Properties
                object[] dimensionAndPosition = GetPartitionNodeDimensionAndPosition(graphMapData, clusteredComponent);
                nodeMapData.Dimension = (Size)dimensionAndPosition[0];
                nodeMapData.Position  = (Point)dimensionAndPosition[1];

                nodeMapData.IsHidden = clusteredComponent.IsHidden;

                IEnumerable <IEdge> clusteredComponentEdges = graphComponents.GetEdges(clusteredComponent);
                foreach (IEdge clusteredComponentEdge in clusteredComponentEdges)
                {
                    EdgeMapData edgeMapData = new EdgeMapData(clusteredComponentEdge.Source.ID, clusteredComponentEdge.Target.ID);
                    graphComponentsMapData.Add(edgeMapData);
                }
            }

            return(graphComponentsMapData);
        }
示例#3
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);
        }
示例#4
0
        public GraphComponents GetClusteredGraph()
        {
            IEnumerable <INodeShape> nodes = _sourceGraph.GetNodeViewModels();

            _partitionedGraph = new GraphComponents(_sourceGraph.Scope);

            // Loop over all the nodes in the list
            foreach (NodeViewModelBase nodeVM in nodes)
            {
                // Create a partition node for clusters
                PartitionNode pn = GetClusterAsPartitionNode(nodeVM);

                // Add the partition node to the graph
                _partitionedGraph.AddNodeViewModel(pn);
            }

            // Loop over all of the partition nodes in our partition graph
            foreach (PartitionNode pn in _partitionNodes)
            {
                // Loop over all the external connections
                foreach (Edge edge in pn.ExternalConnections)
                {
                    INodeShape targetNodeVM = GraphManager.Instance.GetGraphComponents(_sourceGraph.Scope).GetNodeViewModel(edge.Target);

                    // Check if the edge's target node is in our partition collection
                    if (_nodeToPartition.ContainsKey(targetNodeVM))
                    {
                        IEdge newEdge = edge.Copy(pn, _nodeToPartition[targetNodeVM]);
                        _partitionedGraph.Data.AddEdge(newEdge);
                    }
                }
            }

            return(_partitionedGraph);
        }
示例#5
0
        /// <summary>
        /// Converts a GraphMapData instance, with data from an import operation,
        /// to a Graph (GraphComponents)
        /// </summary>
        /// <param name="graph">The mapping data to be imported into the Graph</param>
        /// <param name="graphComponents">The Graph that data is being imported into</param>
        /// <param name="creationType">The specified CreationType</param>
        public static void ImportGraph(this GraphMapData graph, GraphComponents graphComponents, CreationType creationType)
        {
            // Ensure that valid mapping data was provided
            if (graph == null)
            {
                throw new ArgumentNullException("graph", "No mapping data was provided");
            }

            graphComponents.NodeType = NodeTypes.Text;
            foreach (NodeMapData objNode in graph.GetNodes())
            {
                if (objNode is IconNodeMapData)
                {
                    graphComponents.NodeType = NodeTypes.Icon;
                    break;
                }
            }

            // TODO edgedefault?

            // Loop over the node mapping objects
            foreach (NodeMapData objNode in graph.GetNodes())
            {
                AddNode(graphComponents, creationType, objNode);
            }

            // Edges
            foreach (EdgeMapData objEdge in graph.GetEdges())
            {
                AddEdge(graphComponents, creationType, objEdge);
            }
        }
示例#6
0
        /// <summary>
        /// Calculates the rank for the graph specified by the provided scope.
        /// For ranks normalized between 0 and 1, use the CalculateNormalizedRank
        /// method.
        /// </summary>
        /// <param name="scope">The scope for the graph to be ranked</param>
        /// <returns>the ranking for the nodes on the graph in the form
        /// of a dictionary of nodes and their scores.  The ranking is
        /// normalized between 0 and 1.</returns>
        public override Dictionary <INode, double> CalculateRank(string scope)
        {
            // Valid the scope parameter
            if (string.IsNullOrEmpty(scope))
            {
                throw new ArgumentNullException("Scope", "No scope was provided");
            }

            // Initialize the results dictionary
            Dictionary <INode, double> results = new Dictionary <INode, double>();

            // Get the graph data using the provided scope
            _graph = GraphManager.Instance.GetGraphComponents(scope);

            // Iterate over the algorithm multiple times in order
            // to hone the results to the 'true' value
            for (int i = 0; i < NumIterations; i++)
            {
                // Loop over all the nodes in the graph
                foreach (INode node in _graph.Nodes)
                {
                    // Get the degree for the current node
                    results[node] = DetermineNodeRank(node, results);
                }
            }

            return(results);
        }
示例#7
0
        public void Directed_graph_components_cycle()
        {
            var nodes = new List <GraphNode <int> >()
            {
                new GraphNode <int>(0),
                new GraphNode <int>(1),
                new GraphNode <int>(2)
            };

            var edges = new List <DirectedEdge <int> >()
            {
                new DirectedEdge <int>(nodes[0], nodes[1]),
                new DirectedEdge <int>(nodes[1], nodes[2]),
                new DirectedEdge <int>(nodes[2], nodes[0])
            };

            var graph = new DirectedGraph <int>(nodes, edges);
            var componentAlgorithms = new GraphComponents <int>();

            var connectedComponents = componentAlgorithms.KosarajuScc(graph);

            Assert.Equal(0, connectedComponents[nodes[0]]);
            Assert.Equal(0, connectedComponents[nodes[1]]);
            Assert.Equal(0, connectedComponents[nodes[2]]);
        }
示例#8
0
        /// <summary>
        /// Positions the nodes
        /// </summary>
        /// <param name="isAnimated">Indicates whether or not the layout should be animated</param>
        /// <param name="graphComponents">The object containing the graph data</param>
        /// <param name="rootNode">Root node</param>
        public void ComputeLayout(bool isAnimated, GraphComponents graphComponents, INode rootNode)
        {
            nodeVMs       = graphComponents.GetNodeViewModels().Where(node => !node.IsHidden).ToArray();
            positions     = new Point[nodeVMs.Length];
            edgeCounts    = new int[nodeVMs.Length];
            nodeIDToIndex = new Dictionary <string, int>();

            for (int i = 0; i < nodeVMs.Length; i++)
            {
                // Save this nodes position
                positions[i] = nodeVMs[i].Position;

                if (nodeVMs[i] is PartitionNode)
                {
                    nodeIDToIndex[(nodeVMs[i] as PartitionNode).ID] = i;
                }
                else
                {
                    nodeIDToIndex[(nodeVMs[i] as NodeViewModelBase).ParentNode.ID] = i;
                }

                // Get a count of all the edges for this node

                //testcount += GraphComponents.GetNumberOfEdges(nodeVMs[i].ParentNode);

                List <INodeShape> visitedNeighbors = new List <INodeShape>();
                Model.INode       currentNode      = null;

                if (nodeVMs[i] is PartitionNode)
                {
                    currentNode = nodeVMs[i] as Model.INode;
                }
                else
                {
                    currentNode = (nodeVMs[i] as NodeViewModelBase).ParentNode;
                }

                // Loop over all the edges for this node
                foreach (Model.IEdge edge in graphComponents.GetEdges(currentNode))
                {
                    // Get the node at the opposite end of this edge
                    INodeShape oppositeNode = graphComponents.GetOppositeNode(edge, currentNode);

                    // Ensure that this edge is not a similarity edge and that
                    // the opposite node has not been visited already
                    if (!(edge is Model.SimilarityDataEdge) && !visitedNeighbors.Contains(oppositeNode))
                    {
                        edgeCounts[i]++;
                        visitedNeighbors.Add(oppositeNode);
                    }
                }
            }

            // Old version is doing this next call asynchronously
            if (nodeVMs.Length > 1)
            {
                CalculatePositions(graphComponents);
            }
        }
示例#9
0
        public void AddNode(ScriptableNodeMapData scriptableNode)
        {
            NodeMapData objNode = ScriptableMapper.GetNode(scriptableNode);

            GraphComponents graphComponents = GraphManager.Instance.DefaultGraphComponentsInstance;

            MappingExtensions.AddNode(graphComponents, CreationType.Live, objNode);
        }
示例#10
0
        public void RemoveNode(string nodeId)
        {
            GraphComponents graphComponents = GraphManager.Instance.DefaultGraphComponentsInstance;
            GraphData       graphData       = graphComponents.Data;

            INode      node      = graphData.GetNode(nodeId);
            INodeShape nodeShape = graphComponents.GetNodeViewModel(node);

            graphComponents.RemoveNodeViewModel(nodeShape);
        }
示例#11
0
        /// <summary>
        /// Performs the actual layout algorithm. This will execute on a background thread.
        /// </summary>
        /// <param name="isAnimated">Indicates whether or not the layout should be animated</param>
        /// <param name="graphComponents">The object containing the graph data</param>
        /// <param name="rootNode">Root node</param>
        public void ComputeLayout(bool isAnimated, GraphComponents graphComponents, INode rootNode)
        {
            //TODO:  NEED TO DECOUPLE THIS
            GraphViewModel    graphVM = ViewModelLocator.GraphDataStatic;
            List <INodeShape> nodeVMs = graphComponents.GetNodeViewModels().ToList(); // Get all the node view models

            // Reset the new node position collection
            nodeToNewPositions.Clear();

            // First we determine the amount of space that we are dealing with
            double totalArea = 0;

            foreach (INodeShape nodeVMBase in nodeVMs)
            {
                double nodeWidth  = nodeVMBase.Width + this.margin.Left + this.margin.Right;
                double nodeHeight = nodeVMBase.Height + this.margin.Top + this.margin.Bottom;

                totalArea += nodeWidth * nodeHeight;
            }

            nodeVMs.Sort(NodeSizeComparer);

            // Calculate the bounding height and width of our square
            double boundingHeight = CalculateWidthAndHeight(totalArea);
            double boundingWidth  = boundingHeight * (graphVM.Width / graphVM.Height);

            boundingHeight = boundingHeight / (graphVM.Width / graphVM.Height);

            //TODO: THE LINES ABOVE ARE THE ONLY REASON WE ARE COUPLED TO THE GRAPH VIEW MODEL

            double currentX       = 0;
            double currentY       = 0;
            double maxColumnWidth = 0;

            double maxHeight  = nodeVMs.Max(nodeVM => nodeVM.Height) + margin.Top + margin.Bottom;
            int    columnSize = (int)Math.Round(boundingHeight / maxHeight);

            //var column = nodeVMs.Take(columnSize);
            foreach (INodeShape nodeVM in nodeVMs)
            {
                if (currentY > boundingHeight)
                {
                    currentX      += maxColumnWidth + margin.Left + margin.Right;
                    maxColumnWidth = 0;
                    currentY       = 0;
                }

                maxColumnWidth = Math.Max(nodeVM.Width, maxColumnWidth);

                nodeToNewPositions.Add(nodeVM, new Point(currentX, currentY));

                currentY += maxHeight;
                //currentX += nodeVM.Width + margin.Left + margin.Right;
            }
        }
示例#12
0
        public void RemoveEdge(string sourceId, string targetId)
        {
            GraphComponents graphComponents = GraphManager.Instance.DefaultGraphComponentsInstance;
            GraphData       graphData       = graphComponents.Data;

            INode sourceNode = graphData.GetNode(sourceId);
            IEnumerable <IEdge> sourceNodeEdges = graphData.Edges(sourceNode);

            IEdge edge = sourceNodeEdges.First <IEdge>(e => e.Source.ID.Equals(sourceId) && e.Target.ID.Equals(targetId));

            graphComponents.RemoveEdgeViewModel(edge);
        }
示例#13
0
        /// <summary>
        /// Performs the actual layout algorithm. This will execute on a background thread.
        /// </summary>
        /// <param name="isAnimated">Indicates whether or not the layout should be animated</param>
        /// <param name="graphComponents">The object containing the graph data</param>
        /// <param name="rootNode">Root node</param>
        public void ComputeLayout(bool isAnimated, GraphComponents graphComponents, INode rootNode)
        {
            //TODO:  NEED TO DECOUPLE THIS
            GraphViewModel graphVM = ViewModelLocator.GraphDataStatic;
            List<INodeShape> nodeVMs = graphComponents.GetNodeViewModels().ToList(); // Get all the node view models

            // Reset the new node position collection
            nodeToNewPositions.Clear();

            // First we determine the amount of space that we are dealing with
            double totalArea = 0;
            foreach (INodeShape nodeVMBase in nodeVMs)
            {
                double nodeWidth = nodeVMBase.Width + this.margin.Left + this.margin.Right;
                double nodeHeight = nodeVMBase.Height + this.margin.Top + this.margin.Bottom;

                totalArea += nodeWidth * nodeHeight;
            }

            nodeVMs.Sort(NodeSizeComparer);

            // Calculate the bounding height and width of our square
            double boundingHeight  =  CalculateWidthAndHeight(totalArea);
            double boundingWidth = boundingHeight * (graphVM.Width / graphVM.Height);
            boundingHeight = boundingHeight / (graphVM.Width / graphVM.Height);

            //TODO: THE LINES ABOVE ARE THE ONLY REASON WE ARE COUPLED TO THE GRAPH VIEW MODEL

            double currentX = 0;
            double currentY = 0;
            double maxColumnWidth = 0;

            double maxHeight = nodeVMs.Max(nodeVM => nodeVM.Height) + margin.Top + margin.Bottom;
            int columnSize = (int)Math.Round(boundingHeight / maxHeight);

            //var column = nodeVMs.Take(columnSize);
            foreach (INodeShape nodeVM in nodeVMs)
            {
                if (currentY > boundingHeight)
                {
                    currentX += maxColumnWidth + margin.Left + margin.Right;
                    maxColumnWidth = 0;
                    currentY = 0;
                }

                maxColumnWidth = Math.Max(nodeVM.Width, maxColumnWidth);

                nodeToNewPositions.Add(nodeVM, new Point(currentX, currentY));

                currentY += maxHeight;
                //currentX += nodeVM.Width + margin.Left + margin.Right;
            }
        }
示例#14
0
        public string PerformExport()
        {
            // the following is not available because it attempts to open a save file dialog
            // which can only be initiated via a user clicking a button; security feature of silverlight
            //GraphManager.Instance.PerformExport(graphComponents.Scope);

            GraphMLGraphDataFormat graphMlFormat   = new GraphMLGraphDataFormat();
            GraphComponents        graphComponents = GraphManager.Instance.DefaultGraphComponentsInstance;
            string exportedData = graphMlFormat.Export(graphComponents.Scope);

            return(exportedData);
        }
示例#15
0
        /// <summary>
        /// Handles the DataLoaded event
        /// </summary>
        /// <param name="args">The arguments for the event</param>
        public void DataLoadedEventHandler(DataLoadedEventArgs args)
        {
            GraphComponents graph = GraphManager.Instance.GetGraphComponents(args.Scope);

            if (graph != null && graph.Data.Order > 0)
            {
                IsEnabled = true;
            }
            else
            {
                IsEnabled = false;
            }
        }
示例#16
0
        /// <summary>
        /// Performs the actual layout algorithm.
        /// </summary>
        /// <param name="graph">The object containing the graph data</param>
        /// <param name="rootNode">Root node</param>
        protected override void PerformLayout(GraphMapData graph, INode rootNode)
        {
            // this ensures that the end result will remain the same across multiple runs
            // because each node will have the same starting position
            new GridLayout().CalculateLayout(graph);

            System.Diagnostics.Debug.WriteLine("");
            foreach (Delegate d in ContextMenuManager.Instance.GetContextMenuOpeningInvocationList())
            {
                System.Diagnostics.Debug.WriteLine((d.Target as GraphComponents).Scope);
            }

            // Create a GraphComponents instance that is a partitioned
            // representation of the original graph. Each node in this
            // graph is a partition node.
            GraphComponents          connectedGraphComponents = GraphManager.Instance.GetConnectedComponents(GraphManager.Instance.DefaultGraphComponentsInstance.Scope);
            IEnumerable <INodeShape> connectedComponents      = connectedGraphComponents.GetNodeViewModels();

            System.Diagnostics.Debug.WriteLine("");
            foreach (Delegate d in ContextMenuManager.Instance.GetContextMenuOpeningInvocationList())
            {
                System.Diagnostics.Debug.WriteLine((d.Target as GraphComponents).Scope);
            }

            foreach (PartitionNode connectedComponent in connectedComponents)
            {
                using (GraphComponents connectedGraph = connectedComponent.GetGraph())
                {
                    LayoutByClusters(graph, connectedGraph);
                }
            }

            // Layout the overall graph
            GraphMapData connectedGraphMapData            = GetClusteredGraph(graph, connectedGraphComponents);
            IDictionary <string, Point> originalPositions = GetOriginalPositions(connectedGraphMapData);
            GridLayout gridLayout = new GridLayout();

            gridLayout.CalculateLayout(connectedGraphMapData);
            ApplyOffsetToSubGraphs(graph, connectedGraphComponents, originalPositions, connectedGraphMapData);

            connectedGraphComponents.Dispose();

            System.Diagnostics.Debug.WriteLine("");
            foreach (Delegate d in ContextMenuManager.Instance.GetContextMenuOpeningInvocationList())
            {
                System.Diagnostics.Debug.WriteLine((d.Target as GraphComponents).Scope);
            }
        }
示例#17
0
        public void Wikipedia_example()
        {
            var nodes = new List <GraphNode <char> >()
            {
                new GraphNode <char>('a'),
                new GraphNode <char>('b'),
                new GraphNode <char>('c'),
                new GraphNode <char>('d'),
                new GraphNode <char>('e'),
                new GraphNode <char>('f'),
                new GraphNode <char>('g'),
                new GraphNode <char>('h')
            };

            var edges = new List <DirectedEdge <char> >()
            {
                new DirectedEdge <char>(nodes[0], nodes[1]),
                new DirectedEdge <char>(nodes[1], nodes[2]),
                new DirectedEdge <char>(nodes[1], nodes[4]),
                new DirectedEdge <char>(nodes[1], nodes[5]),
                new DirectedEdge <char>(nodes[2], nodes[3]),
                new DirectedEdge <char>(nodes[2], nodes[6]),
                new DirectedEdge <char>(nodes[3], nodes[2]),
                new DirectedEdge <char>(nodes[3], nodes[7]),
                new DirectedEdge <char>(nodes[4], nodes[5]),
                new DirectedEdge <char>(nodes[4], nodes[0]),
                new DirectedEdge <char>(nodes[5], nodes[6]),
                new DirectedEdge <char>(nodes[6], nodes[5]),
                new DirectedEdge <char>(nodes[7], nodes[3]),
                new DirectedEdge <char>(nodes[7], nodes[6]),
            };

            var graph = new DirectedGraph <char>(nodes, edges);
            var componentAlgorithms = new GraphComponents <char>();

            var connectedComponents = componentAlgorithms.KosarajuScc(graph);

            Assert.Equal('a', connectedComponents[nodes[0]]);
            Assert.Equal('a', connectedComponents[nodes[1]]);
            Assert.Equal('a', connectedComponents[nodes[4]]);
            Assert.Equal('c', connectedComponents[nodes[2]]);
            Assert.Equal('c', connectedComponents[nodes[3]]);
            Assert.Equal('c', connectedComponents[nodes[7]]);
            Assert.Equal('g', connectedComponents[nodes[5]]);
            Assert.Equal('g', connectedComponents[nodes[6]]);
        }
示例#18
0
        /// <summary>
        /// Imports the provided data
        /// </summary>
        /// <param name="data">The data (in string format) to be imported</param>
        /// <param name="components">The GraphComponents instance</param>
        /// <param name="sourceMechanism">Specifies the mechanism for which objects on the graph were imported</param>
        /// <returns>true if the import was successfull (and contained
        /// data); otherwise false</returns>
        public bool Import(string data, GraphComponents components, CreationType sourceMechanism)
        {
            _logger.WriteLogEntry(LogLevel.DEBUG, "Import started", null, null);
            SnaglEventAggregator.DefaultInstance.GetEvent <DataImportingEvent>().Publish(new DataLoadedEventArgs(components.Scope, CreationType.Imported));

            // Cal the abstract ImportData method
            GraphMapData graph = ImportData(data);

            // Convert the mapping data to GraphComponents
            graph.ImportGraph(components, sourceMechanism);
            //MappingExtensions.ImportGraph(graph, components, sourceMechanism);

            _logger.WriteLogEntry(LogLevel.DEBUG, "Import completed", null, null);
            SnaglEventAggregator.DefaultInstance.GetEvent <DataImportedEvent>().Publish(new DataLoadedEventArgs(components.Scope, CreationType.Imported));

            return(true);
        }
示例#19
0
        public void NoEdge_undirected_graph_components()
        {
            var nodes = new List <GraphNode <int> >()
            {
                new GraphNode <int>(0),
                new GraphNode <int>(1),
                new GraphNode <int>(2)
            };

            var edges = new List <UndirectedEdge <int> >();
            var graph = new UndirectedGraph <int>(nodes, edges);
            var componentAlgorithms = new GraphComponents <int>();

            var connectedComponents = componentAlgorithms.DfsConnectedComponents(graph);

            Assert.Equal(0, connectedComponents[nodes[0]]);
            Assert.Equal(1, connectedComponents[nodes[1]]);
            Assert.Equal(2, connectedComponents[nodes[2]]);
        }
示例#20
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public GraphComponents GetGraph()
        {
            // Validate the internal nodes collection
            if (nodes.Count == 0)
            {
                return(null);
            }

            // Get the scope from the first node in the
            // nodes collection
            string scope = nodes[0].Scope;

            // Create a new instance of GraphComponents using the scope
            // previously obtained from one of the node view models that
            // is part of this partition node
            GraphComponents graphComponents = new GraphComponents(scope);
            List <IEdge>    edges           = new List <IEdge>();

            // Loop over all the node view models, contained in
            // this partition node, and add them to the new graph
            foreach (NodeViewModelBase nodeVM in nodes)
            {
                // Add this node view model to the graph
                graphComponents.AddNodeViewModel(nodeVM);

                // Get all the edges for this node
                edges.AddRange(GraphManager.Instance.GetGraphComponents(nodeVM.Scope).Data.Edges(nodeVM.ParentNode).ToList());
            }

            // Loop over the edges that were found for all the
            // nodes in the graph
            foreach (IEdge edge in edges)
            {
                // Ensure that both ends of the edge are in this graph
                if (graphComponents.Data.ContainsNode(edge.Source) && graphComponents.Data.ContainsNode(edge.Target))
                {
                    graphComponents.Data.AddEdge(edge);
                }
            }

            return(graphComponents);
        }
示例#21
0
        /// <summary>
        /// Determines whether there is any data for the given scope
        /// </summary>
        /// <param name="scope">The scope of the data being requested</param>
        /// <returns>true if there is any data present; otherwise false</returns>
        public bool HasData(string scope)
        {
            GraphComponents components = GetGraphComponents(scope);

            // Check if there are any components present
            if (components == null)
            {
                return(false);
            }

            // Check if we have any nodes in the data
            if (components.Data.Order > 0)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
示例#22
0
        private static void ApplyOffsetToSubGraphs(GraphMapData graph, GraphComponents clusteredGraphComponents, IDictionary <string, Point> originalPositions, GraphMapData partitionGraph)
        {
            IEnumerable <INodeShape> clusteredComponents = clusteredGraphComponents.GetNodeViewModels();

            foreach (PartitionNode clusteredComponent in clusteredComponents)
            {
                Point  originalPosition = originalPositions[clusteredComponent.ID];
                double xOffset          = partitionGraph.Nodes[clusteredComponent.ID].Position.X - originalPosition.X;
                double yOffset          = partitionGraph.Nodes[clusteredComponent.ID].Position.Y - originalPosition.Y;

                IList <NodeViewModelBase> viewModelNodes = clusteredComponent.Nodes;
                foreach (NodeViewModelBase viewModelNode in viewModelNodes)
                {
                    NodeMapData nodeMapData = graph.Nodes[viewModelNode.ParentNode.ID];

                    Point offsetPosition = new Point(nodeMapData.Position.X + xOffset, nodeMapData.Position.Y + yOffset);
                    nodeMapData.Position = offsetPosition;
                }
            }
        }
示例#23
0
        /// <summary>
        /// Returns bare-bone graph needed for layouts
        /// </summary>
        /// <param name="graphComponents">GraphComponents</param>
        /// <returns>GraphMapData</returns>
        public static GraphMapData GetGraph(GraphComponents graphComponents)
        {
            GraphMapData graph = new GraphMapData();

            // Nodes
            IEnumerable <INodeShape> uiNodeViewModels = graphComponents.GetNodeViewModels();

            foreach (NodeViewModelBase uiNodeVM in uiNodeViewModels)
            {
                NodeMapData objNode = new TextNodeMapData(uiNodeVM.ParentNode.ID);
                graph.Add(objNode);

                // Properties
                Size dimension = new Size(uiNodeVM.Width, uiNodeVM.Height);
                objNode.Dimension = dimension;
                objNode.Position  = uiNodeVM.Position;
                objNode.IsHidden  = uiNodeVM.IsHidden;
            }

            // Edges
            IEnumerable <IEdgeViewModel> uiEdgeViewModels = graphComponents.GetEdgeViewModels();

            foreach (EdgeViewModelBase uiEdgeVM in uiEdgeViewModels)
            {
                EdgeMapData objEdge = new EdgeMapData(uiEdgeVM.ParentEdge.Source.ID, uiEdgeVM.ParentEdge.Target.ID);
                graph.Add(objEdge);

                // Properties
                objEdge.Type = uiEdgeVM.ParentEdge.Type;
                SimilarityDataEdge uiSDE = uiEdgeVM.ParentEdge as SimilarityDataEdge;
                if (uiSDE != null)
                {
                    objEdge.Weight = uiSDE.Weight;
                }
            }

            return(graph);
        }
示例#24
0
        /// <summary>
        /// Adds a highlight to the graph to indicate which data is clustered together
        /// </summary>
        /// <returns>A collection of polygron of clustered highlights on the graph</returns>
        public ICollection <Polygon> HighlightClusters()
        {
            RemoveHighlights();

            _cluster = new Cluster(GraphManager.Instance.GetGraphComponents(_scope));
            _cluster.EdgePredicate = delegate(Model.IEdge e) { return(e is Model.SimilarityDataEdge); };

            GraphComponents clusteredGraph = _cluster.GetClusteredGraph();

            foreach (PartitionNode pn in clusteredGraph.GetNodeViewModels())
            {
                if (pn.Nodes.Count > 1)
                {
                    Polygon highlightPolygon = CreateHighlightPolygon(pn);
                    _clusterPolygons[highlightPolygon] = pn;
                }
            }
            clusteredGraph.Dispose();

            _highlightPolygons = _clusterPolygons.Keys;

            return(_highlightPolygons);
        }
示例#25
0
        /// <summary>
        /// Returns bare-bone graph needed for layouts
        /// </summary>
        /// <param name="graphComponents">GraphComponents</param>
        /// <returns>GraphMapData</returns>
        public static GraphMapData GetGraph(GraphComponents graphComponents)
        {
            GraphMapData graph = new GraphMapData();

            // Nodes
            IEnumerable<INodeShape> uiNodeViewModels = graphComponents.GetNodeViewModels();
            foreach (NodeViewModelBase uiNodeVM in uiNodeViewModels)
            {
                NodeMapData objNode = new TextNodeMapData(uiNodeVM.ParentNode.ID);
                graph.Add(objNode);

                // Properties
                Size dimension = new Size(uiNodeVM.Width, uiNodeVM.Height);
                objNode.Dimension = dimension;
                objNode.Position = uiNodeVM.Position;
                objNode.IsHidden = uiNodeVM.IsHidden;
            }

            // Edges
            IEnumerable<IEdgeViewModel> uiEdgeViewModels = graphComponents.GetEdgeViewModels();
            foreach (EdgeViewModelBase uiEdgeVM in uiEdgeViewModels)
            {
                EdgeMapData objEdge = new EdgeMapData(uiEdgeVM.ParentEdge.Source.ID, uiEdgeVM.ParentEdge.Target.ID);
                graph.Add(objEdge);

                // Properties
                objEdge.Type = uiEdgeVM.ParentEdge.Type;
                SimilarityDataEdge uiSDE = uiEdgeVM.ParentEdge as SimilarityDataEdge;
                if (uiSDE != null)
                {
                    objEdge.Weight = uiSDE.Weight;
                }
            }

            return graph;
        }
示例#26
0
        /// <summary>
        /// Converts the provided GraphComponents instance to a GraphMapData
        /// instance that can be exported to a target file format
        /// </summary>
        /// <param name="graphComponents">The graph to be exported</param>
        /// <returns>A GraphMapData instance ready to be exported to the target format</returns>
        public static GraphMapData ExportGraph(this GraphComponents graphComponents)
        {
            GraphMapData graph = new GraphMapData();

            // Nodes
            IEnumerable <INodeShape> uiNodeViewModels = graphComponents.GetNodeViewModels();

            foreach (NodeViewModelBase uiNodeVM in uiNodeViewModels)
            {
                NodeMapData objNode = GetNode(uiNodeVM);
                graph.Add(objNode);
            }

            // Edges
            IEnumerable <IEdgeViewModel> edgeViewModels = graphComponents.GetEdgeViewModels();

            foreach (EdgeViewModelBase uiEdge in edgeViewModels)
            {
                EdgeMapData objEdge = GetEdge(uiEdge);
                graph.Add(objEdge);
            }

            return(graph);
        }
示例#27
0
        private static GraphMapData GetGraph(GraphMapData graphMapData, GraphComponents clusteredGraph)
        {
            GraphMapData clusteredGraphMapData = new GraphMapData();

            // Nodes
            IEnumerable <INodeShape> uiNodeViewModels = clusteredGraph.GetNodeViewModels();

            foreach (NodeViewModelBase uiNodeVM in uiNodeViewModels)
            {
                NodeMapData nodeMapData = graphMapData.Nodes[uiNodeVM.ParentNode.ID];
                clusteredGraphMapData.Add(nodeMapData);

                // Edges
                IEnumerable <IEdge> uiEdgeViewModels = clusteredGraph.GetEdges(uiNodeVM.ParentNode);
                foreach (IEdge uiEdgeVM in uiEdgeViewModels)
                {
                    string      edgeKey     = uiEdgeVM.Source.ID + uiEdgeVM.Target.ID;
                    EdgeMapData edgeMapData = graphMapData.Edges[edgeKey];
                    clusteredGraphMapData.Add(edgeMapData);
                }
            }

            return(clusteredGraphMapData);
        }
示例#28
0
        /// <summary>
        /// Collapse all children (outgoing nodes) for the target node
        /// </summary>
        /// <param name="targetNode"></param>
        private void CollapseNode(NodeViewModelBase targetNode)
        {
            List<INode> childNodes = new List<INode>();
            List<IEdgeViewModel> edgesToBeRemoved = new List<IEdgeViewModel>();
            List<IEdgeViewModel> edgesToBeAdded = new List<IEdgeViewModel>();
            List<NodeViewModelBase> nodesToBeRemoved = new List<NodeViewModelBase>();

            graph = Data.GraphManager.Instance.GetGraphComponents(targetNode.Scope);

            // Get all the chidren for the target node
            childNodes = GetChildren(targetNode.ParentNode);

            // Ensure we have any child nodes before continuing
            if (childNodes.Count > 0)
            {
                foreach (INode childNode in childNodes)
                {
                    NodeViewModelBase nodeVM = graph.GetNodeViewModel(childNode) as NodeViewModelBase;

                    foreach (IEdge edge in graph.GetEdges(childNode))
                    {
                        IEdgeViewModel edgeVM = graph.GetEdgeViewModel(edge);

                        // Determine if this is an incoming edge
                        if (edge.Target == childNode)
                        {
                            // Existing incoming edges need to be removed
                            // and new ones need to be added
                            edgesToBeRemoved.Add(edgeVM);

                            // Determine if this edge's source node is inside
                            // of the child nodes being collapsed
                            if (!childNodes.Contains(edge.Source) && edge.Source != targetNode.ParentNode)
                            {
                                IEdgeViewModel newEdgeVM = (edgeVM as EdgeViewModelBase).Copy(edge.Source, targetNode.ParentNode);

                                edgesToBeAdded.Add(newEdgeVM);
                            }
                        }
                        else // Handle the outgoing edges
                        {
                            // Outgoing edges need to be saved and removed
                            edgesToBeRemoved.Add(edgeVM);
                        }
                    }

                    // Remove (hide) the node
                    //nodeVM.IsHidden = true;
                    nodesToBeRemoved.Add(nodeVM);
                }

                graph.RemoveNodeViewModels(nodesToBeRemoved);

                // Remove (hide) the edges
                RemoveEdges(edgesToBeRemoved, targetNode);

                // Add new edges
                AddEdges(edgesToBeAdded, targetNode);

            }
        }
示例#29
0
        /// <summary>
        /// Calculates the rank for the graph specified by the provided scope.
        /// For ranks normalized between 0 and 1, use the CalculateNormalizedRank
        /// method.
        /// </summary>
        /// <param name="scope">The scope for the graph to be ranked</param>
        /// <returns>the ranking for the nodes on the graph in the form
        /// of a dictionary of nodes and their scores.  The ranking is
        /// normalized between 0 and 1.</returns>
        public override Dictionary<INode, double> CalculateRank(string scope)
        {
            // Valid the scope parameter
            if (string.IsNullOrEmpty(scope))
                throw new ArgumentNullException("Scope", "No scope was provided");

            // Initialize the results dictionary
            Dictionary<INode, double> results = new Dictionary<INode, double>();

            // Get the graph data using the provided scope
            _graph = GraphManager.Instance.GetGraphComponents(scope);

            // Iterate over the algorithm multiple times in order
            // to hone the results to the 'true' value
            for (int i = 0; i < NumIterations; i++)
            {
                // Loop over all the nodes in the graph
                foreach (INode node in _graph.Nodes)
                {
                    // Get the degree for the current node
                    results[node] = DetermineNodeRank(node, results);
                }
            }

            return results;
        }
示例#30
0
        /// <summary>
        /// Imports the provided data
        /// </summary>
        /// <param name="data">The data (in string format) to be imported</param>
        /// <param name="components">The GraphComponents instance</param>
        /// <param name="sourceMechanism">Specifies the mechanism for which objects on the graph were imported</param>
        /// <returns>true if the import was successfull (and contained
        /// data); otherwise false</returns>
        public bool Import(string data, GraphComponents components, CreationType sourceMechanism)
        {
            _logger.WriteLogEntry(LogLevel.DEBUG, "Import started", null, null);
            SnaglEventAggregator.DefaultInstance.GetEvent<DataImportingEvent>().Publish(new DataLoadedEventArgs(components.Scope, CreationType.Imported));

            // Cal the abstract ImportData method
            GraphMapData graph = ImportData(data);

            // Convert the mapping data to GraphComponents
            graph.ImportGraph(components, sourceMechanism);
            //MappingExtensions.ImportGraph(graph, components, sourceMechanism);

            _logger.WriteLogEntry(LogLevel.DEBUG, "Import completed", null, null);
            SnaglEventAggregator.DefaultInstance.GetEvent<DataImportedEvent>().Publish(new DataLoadedEventArgs(components.Scope, CreationType.Imported));

            return true;
        }
示例#31
0
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public GraphComponents GetGraph()
        {
            // Validate the internal nodes collection
            if (nodes.Count == 0)
                return null;

            // Get the scope from the first node in the
            // nodes collection
            string scope = nodes[0].Scope;

            // Create a new instance of GraphComponents using the scope
            // previously obtained from one of the node view models that
            // is part of this partition node
            GraphComponents graphComponents = new GraphComponents(scope);
            List<IEdge> edges = new List<IEdge>();

            // Loop over all the node view models, contained in
            // this partition node, and add them to the new graph
            foreach (NodeViewModelBase nodeVM in nodes)
            {
                // Add this node view model to the graph
                graphComponents.AddNodeViewModel(nodeVM);

                // Get all the edges for this node
                edges.AddRange(GraphManager.Instance.GetGraphComponents(nodeVM.Scope).Data.Edges(nodeVM.ParentNode).ToList());
            }

            // Loop over the edges that were found for all the
            // nodes in the graph
            foreach (IEdge edge in edges)
            {
                // Ensure that both ends of the edge are in this graph
                if (graphComponents.Data.ContainsNode(edge.Source) && graphComponents.Data.ContainsNode(edge.Target))
                    graphComponents.Data.AddEdge(edge);
            }

            return graphComponents;
        }
示例#32
0
        /// <summary>
        /// Converts a GraphMapData instance, with data from an import operation,
        /// to a Graph (GraphComponents)
        /// </summary>
        /// <param name="graph">The mapping data to be imported into the Graph</param>
        /// <param name="graphComponents">The Graph that data is being imported into</param>
        /// <param name="creationType">The specified CreationType</param>
        public static void ImportGraph(this GraphMapData graph, GraphComponents graphComponents, CreationType creationType)
        {
            // Ensure that valid mapping data was provided
            if (graph == null)
            {
                throw new ArgumentNullException("graph", "No mapping data was provided");
            }

            graphComponents.NodeType = NodeTypes.Text;
            foreach (NodeMapData objNode in graph.GetNodes())
            {
                if (objNode is IconNodeMapData)
                {
                    graphComponents.NodeType = NodeTypes.Icon;
                    break;
                }
            }

            // TODO edgedefault?

            // Loop over the node mapping objects
            foreach (NodeMapData objNode in graph.GetNodes())
            {
                AddNode(graphComponents, creationType, objNode);
            }

            // Edges
            foreach (EdgeMapData objEdge in graph.GetEdges())
            {
                AddEdge(graphComponents, creationType, objEdge);
            }
        }
示例#33
0
        private static GraphMapData GetClusteredGraph(GraphMapData graphMapData, GraphComponents graphComponents)
        {
            GraphMapData graphComponentsMapData = new GraphMapData();

            IEnumerable<INodeShape> clusteredComponents = graphComponents.GetNodeViewModels();
            foreach (PartitionNode clusteredComponent in clusteredComponents)
            {
                NodeMapData nodeMapData = new TextNodeMapData(clusteredComponent.ID);
                graphComponentsMapData.Add(nodeMapData);

                // Properties
                object[] dimensionAndPosition = GetPartitionNodeDimensionAndPosition(graphMapData, clusteredComponent);
                nodeMapData.Dimension = (Size)dimensionAndPosition[0];
                nodeMapData.Position = (Point)dimensionAndPosition[1];

                nodeMapData.IsHidden = clusteredComponent.IsHidden;

                IEnumerable<IEdge> clusteredComponentEdges = graphComponents.GetEdges(clusteredComponent);
                foreach (IEdge clusteredComponentEdge in clusteredComponentEdges)
                {
                    EdgeMapData edgeMapData = new EdgeMapData(clusteredComponentEdge.Source.ID, clusteredComponentEdge.Target.ID);
                    graphComponentsMapData.Add(edgeMapData);
                }
            }

            return graphComponentsMapData;
        }
示例#34
0
        /// <summary>
        /// Creates a new random graph
        /// </summary>
        private void CreateRandomGraph(string _scope)
        {
            StopWatch stopWatch = StopWatch.StartNew();
                GraphComponents components = null;

                // Check if the provided scope is null or empty
                if (string.IsNullOrEmpty(_scope))
                {
                    // This is a new graph so we will generate new GraphComponents
                    // for it
                    components = new GraphComponents();
                }
                else
                {
                    // Attempt to get the graph components instance for
                    // the given scope
                    components = GetGraphComponents(_scope);

                    // If we were unable to get an instance, create a
                    // new one
                    if (components == null)
                        components = new GraphComponents(_scope);
                }

                // Generate the graph
                components.GenerateGraph(500, 200);

                stopWatch.Stop();
                System.Diagnostics.Debug.WriteLine("Graph Generated:  {0} seconds", stopWatch.Elapsed.Seconds);

                //TODO: THE NEXT PORTION OF CODE (THAT ADDS OR UPDATES THE COMPONENTS) SHOULD BE RELOCATED TO ITS OWN METHOD

                // Check if the default instance (which is the first instance
                // created) has been initialized yet
                if (this.defaultComponentInstanceScope == string.Empty)
                {
                    // TODO:  ENSURE THIS IS VALID IN THE FUTURE AS THE MAIN GRAPH MAY NOT ALWAYS POPULATE FIRST (BUT SHOULD BE)

                    // Save the newly created components as the default
                    this.defaultComponentInstanceScope = _scope;
                }

                // Now we need to update or add the components to the collection of components
                // Check if the collection has never been initialized
                if (this.graphComponentsInstances == null)
                {
                    // Initialize the collection
                    this.graphComponentsInstances = new Dictionary<string, GraphComponents>();
                }

                // Check if we have no items
                if (this.graphComponentsInstances.Count == 0)
                {
                    // Add the components instance to the collection
                    this.graphComponentsInstances.Add(components.Scope, components);
                }
                else
                {
                    // Ensure that the scope doesn't already exist
                    if (this.graphComponentsInstances.ContainsKey(components.Scope))
                    {
                        // Update the components instance for the specified scope
                        this.graphComponentsInstances[components.Scope] = components;
                    }
                    else
                    {
                        // Add the new instance for the specified scope
                        this.graphComponentsInstances.Add(components.Scope, components);
                    }
                }
        }
示例#35
0
 /// <summary>
 ///
 /// </summary>
 public Cluster(GraphComponents graphComponents)
 {
     _sourceGraph = graphComponents;
 }
示例#36
0
文件: Cluster.cs 项目: senfo/snaglV2
        public GraphComponents GetClusteredGraph()
        {
            IEnumerable<INodeShape> nodes = _sourceGraph.GetNodeViewModels();
            _partitionedGraph = new GraphComponents(_sourceGraph.Scope);

            // Loop over all the nodes in the list
            foreach (NodeViewModelBase nodeVM in nodes)
            {
                // Create a partition node for clusters
                PartitionNode pn = GetClusterAsPartitionNode(nodeVM);

                // Add the partition node to the graph
                _partitionedGraph.AddNodeViewModel(pn);
            }

            // Loop over all of the partition nodes in our partition graph
            foreach (PartitionNode pn in _partitionNodes)
            {
                // Loop over all the external connections
                foreach (Edge edge in pn.ExternalConnections)
                {
                    INodeShape targetNodeVM = GraphManager.Instance.GetGraphComponents(_sourceGraph.Scope).GetNodeViewModel(edge.Target);

                    // Check if the edge's target node is in our partition collection
                    if (_nodeToPartition.ContainsKey(targetNodeVM))
                    {
                        IEdge newEdge = edge.Copy(pn, _nodeToPartition[targetNodeVM]);
                        _partitionedGraph.Data.AddEdge(newEdge);
                    }
                }
            }

            return _partitionedGraph;
        }
示例#37
0
        /// <summary>
        /// Local attractive force between 2 connected nodesnode
        /// </summary>
        /// <param name="distance"></param>
        /// <param name="neighborCount"></param>
        /// <param name="edge"></param>
        /// <param name="graphComponents"></param>
        /// <returns></returns>
        protected double LocalForce(double distance, double neighborCount, Model.IEdge edge, GraphComponents graphComponents)
        {
            double bigDistanceApart = 60000;

            double length    = K;
            double stiffness = defaultStiffness;

            if (neighborCount == 0)
            {
                neighborCount = 1;
            }

            // Check if the edge we are dealing with is a similarity edge
            if (edge is Model.SimilarityDataEdge)
            {
                Model.SimilarityDataEdge forceDirectedEdge = edge as Model.SimilarityDataEdge;

                length    = forceDirectedEdge.SpringLength;
                stiffness = forceDirectedEdge.SpringStiffness;
            }

            double sourceNodeWidth = 0;
            double targetNodeWidth = 0;

            // Get the width for the source node.  How we get this depends on
            // the type of node that we are dealing with.
            if (edge.Source is PartitionNode)
            {
                sourceNodeWidth = (edge.Source as PartitionNode).Width;
            }
            else
            {
                DispatcherHelper.UIDispatcher.BeginInvoke(() => sourceNodeWidth = graphComponents.GetNodeViewModel(edge.Source).Width);
            }

            // Get the width for the target node.  How we get this depends on
            // the type of node that we are dealing with.
            if (edge.Target is PartitionNode)
            {
                targetNodeWidth = (edge.Target as PartitionNode).Width;
            }
            else
            {
                //targetNodeWidth = GraphComponents.GetNodeViewModel(edge.Target).Width;
                DispatcherHelper.UIDispatcher.BeginInvoke(() => targetNodeWidth = graphComponents.GetNodeViewModel(edge.Target).Width);
            }

            double edgeLength         = length + sourceNodeWidth + targetNodeWidth;
            double distanceMultiplier = Math.Max(Math.Abs(distance - edgeLength) / bigDistanceApart, 1);

            return((stiffness * distanceMultiplier) * ((distance - edgeLength) / neighborCount));
        }
示例#38
0
        protected void CalculatePositions(GraphComponents graphComponents)
        {
            double   deltaNorm;
            double   otherNorm;
            bool     converged           = false;
            double   T                   = K;
            double   tolerance           = 0.02;
            double   coolingConstant     = 0.99;
            Point    tempDelta           = new Point();
            Point    displacement        = new Point();
            TimeSpan globalForceTimespan = new TimeSpan();
            TimeSpan localForceTimespan  = new TimeSpan();
            TimeSpan indexOfTime         = new TimeSpan();
            DateTime start;

            Model.INode currentNode = null;

            List <int> listOfAllNodeIndices = new List <int>();

            // If we aren't partitioning into grids then use all the nodes every time
            if (!useGraphPartitioning)
            {
                for (int i = 0; i < nodeVMs.Length; i++)
                {
                    listOfAllNodeIndices.Add(i);
                }
            }

            for (int loop = 0; loop < maxIterations && !converged; loop++)
            {
                double max = 200;
                double min = 65;
                double R   = max - ((loop / maxIterations) * (max - min) + min);

                if (useGraphPartitioning)
                {
                    // Put all vertices into appropraite cells
                    CalculateNodeCells(R);
                }

                converged = true;

                // Loop over nodes
                for (int currentNodeIndex = 0; currentNodeIndex < nodeVMs.Length; currentNodeIndex++)
                {
                    if (nodeVMs[currentNodeIndex] is PartitionNode)
                    {
                        currentNode = nodeVMs[currentNodeIndex] as Model.INode;
                    }
                    else
                    {
                        currentNode = (nodeVMs[currentNodeIndex] as NodeViewModelBase).ParentNode;
                    }

                    displacement = new Point(0, 0);

                    // global repulsive force (huh??)
                    start = DateTime.Now;

                    IList <int> repulsionNodes = null;
                    if (useGraphPartitioning)
                    {
                        // Find all nodes, within a certain distance, to perform repulstion on.
                        // Get nodes within maxDistance from this node.
                        double maxDistance = 50; //TODO:  MAKE THIS CONFIGURABLE
                        repulsionNodes = FindNodesForRepulsion(currentNodeIndex, R, maxDistance);
                    }
                    else
                    {
                        // Just repulse all nodes
                        repulsionNodes = listOfAllNodeIndices;
                    }

                    // Loop over all nodes in repulsion list
                    foreach (int i in repulsionNodes)
                    {
                        // We skip this calculation for the current node
                        if (i != currentNodeIndex)
                        {
                            tempDelta.X = positions[i].X - positions[currentNodeIndex].X;
                            tempDelta.Y = positions[i].Y - positions[currentNodeIndex].Y;

                            if (tempDelta.X == 0)
                            {
                                tempDelta.X = random.NextDouble() * .001 * K;
                            }
                            if (tempDelta.Y == 0)
                            {
                                tempDelta.Y = random.NextDouble() * .001 * K;
                            }

                            deltaNorm = Math.Max(1, Math.Abs(tempDelta.X) + Math.Abs(tempDelta.Y));
                            otherNorm = Math.Abs(positions[i].X + Math.Abs(positions[i].Y));

                            double globalForce = GlobalForce(deltaNorm, otherNorm);

                            displacement.X += (tempDelta.X / deltaNorm) * globalForce;
                            displacement.Y += (tempDelta.Y / deltaNorm) * globalForce;
                        }
                    }

                    globalForceTimespan += (DateTime.Now - start);

                    // Local forces
                    start = DateTime.Now;

                    // Loop over all the edges for this node
                    foreach (Model.IEdge edge in graphComponents.GetEdges(currentNode))
                    {
                        DateTime startIndex = DateTime.Now;

                        int    index  = -1;
                        string nodeID = string.Empty;

                        INodeShape oppositeNode = graphComponents.GetOppositeNode(edge, currentNode);
                        //NodeViewModelBase oppositeNodeVM = GraphComponents.GetOppositeNode(edgeVM.ParentEdge, nodeVMs[currentNode].ParentNode);

                        // Get the ID for the opposite node.  How we do this depends
                        // on the type of node that we are dealing with.
                        if (oppositeNode is PartitionNode)
                        {
                            nodeID = (oppositeNode as PartitionNode).ID;
                        }
                        else
                        {
                            nodeID = (oppositeNode as NodeViewModelBase).ParentNode.ID;
                        }

                        if (!nodeIDToIndex.TryGetValue(nodeID, out index))
                        {
                            continue;
                        }
                        indexOfTime += DateTime.Now - startIndex;

                        if (index != -1)
                        {
                            tempDelta = new Point(positions[index].X - positions[currentNodeIndex].X, positions[index].Y - positions[currentNodeIndex].Y);

                            if (tempDelta.X == 0)
                            {
                                tempDelta.X = random.NextDouble() * .001 * K;
                            }
                            if (tempDelta.Y == 0)
                            {
                                tempDelta.Y = random.NextDouble() * .001 * K;
                            }

                            deltaNorm = Math.Max(Math.Sqrt((tempDelta.X * tempDelta.X) + (tempDelta.Y * tempDelta.Y)), 1);
                            otherNorm = Math.Max(Math.Sqrt((oppositeNode.Position.X * oppositeNode.Position.X) + (oppositeNode.Position.Y * oppositeNode.Position.Y)), 1);

                            double localForce = LocalForce(deltaNorm, edgeCounts[currentNodeIndex], edge, graphComponents);

                            displacement.X += (tempDelta.X / deltaNorm) * localForce;
                            displacement.Y += (tempDelta.Y / deltaNorm) * localForce;
                        }
                    }

                    localForceTimespan += (DateTime.Now - start);

                    // Reposition node (huh??)
                    if (displacement.X == 0)
                    {
                        displacement.X = 1;
                    }

                    double displacementNorm = Math.Sqrt((displacement.X * displacement.X) + (displacement.Y * displacement.Y));
                    double newX             = positions[currentNodeIndex].X + (displacement.X / displacementNorm) * Math.Min(T, displacementNorm);
                    double newY             = positions[currentNodeIndex].Y + (displacement.Y / displacementNorm) * Math.Min(T, displacementNorm);

                    tempDelta = new Point(newX - positions[currentNodeIndex].X, newY - positions[currentNodeIndex].Y);

                    positions[currentNodeIndex].X = newX;
                    positions[currentNodeIndex].Y = newY;

                    // no clue what this is doing
                    if (Math.Sqrt((tempDelta.X * tempDelta.X) + (tempDelta.Y * tempDelta.Y)) > K * tolerance)
                    {
                        converged = false;
                    }
                }

                // cool (huh??)
                T *= coolingConstant;
            }

            //System.Diagnostics.Debug.WriteLine(globalForceTimespan);
            //System.Diagnostics.Debug.WriteLine(localForceTimespan);
            //System.Diagnostics.Debug.WriteLine(indexOfTime);
        }
示例#39
0
        /// <summary>
        /// Adds the specificed node
        /// </summary>
        /// <param name="graphComponents">The Graph that data is being imported into</param>
        /// <param name="creationType">The specified CreationType</param>
        /// <param name="objNode">Node to be added</param>
        public static void AddNode(GraphComponents graphComponents, CreationType creationType, NodeMapData objNode)
        {
            // Create new node
            Node uiNode = new Node(objNode.Id);
            uiNode.SourceMechanism = creationType;

            // TODO as NodeMapData types expands, this needs to be adjusted
            NodeTypes uiNodeType = NodeTypes.Simple;
            if (objNode is IconNodeMapData)
            {
                uiNodeType = NodeTypes.Icon;
            }
            else if (objNode is TextNodeMapData)
            {
                uiNodeType = NodeTypes.Text;
            }

            NodeViewModelBase uiNodeVM = NodeViewModelBase.GetNodeViewModel(uiNodeType, uiNode, graphComponents.Scope);

            // Properties
            if (uiNodeType == NodeTypes.Icon)
            {
                IconNodeMapData objIconNode = (IconNodeMapData)objNode;
                if (objIconNode.ImageSource != null)
                {
                    ((IconNodeViewModel)uiNodeVM).ImageSource = objIconNode.ImageSource.ToString();
                }
            }

            uiNodeVM.Description = objNode.Description;
            uiNodeVM.DisplayValue = objNode.Label;
            uiNodeVM.Width = objNode.Dimension.Width;
            uiNodeVM.Height = objNode.Dimension.Height;
            uiNodeVM.Position = objNode.Position;
            uiNodeVM.IsHidden = objNode.IsHidden;

            SolidColorBrush uiBackgroundColorBrush = new SolidColorBrush(objNode.BackgroundColor);
            uiNodeVM.BackgroundColor = uiBackgroundColorBrush;

            SolidColorBrush uiSelectionColorBrush = new SolidColorBrush(objNode.SelectionColor);
            uiNodeVM.SelectionColor = uiSelectionColorBrush;

            if (uiNodeVM.Height == 0)
            {
                uiNodeVM.Height = 45;
            }

            if (uiNodeVM.Width == 0)
            {
                uiNodeVM.Width = 45;
            }

            // Add the node to the graph
            graphComponents.AddNodeViewModel(uiNodeVM);

            // Attributes
            foreach (KeyValuePair<string, AttributeMapData> objNodeAttrKVP in objNode.Attributes)
            {
                Attributes.Attribute uiNodeAttribute = new Attributes.Attribute(objNodeAttrKVP.Value.Name);
                AttributeValue uiNodeAttributeValue = new AttributeValue(objNodeAttrKVP.Value.Value);

                uiNode.Attributes.Add(uiNodeAttribute.Name, uiNodeAttributeValue);
                GlobalAttributeCollection.GetInstance(graphComponents.Scope).Add(uiNodeAttribute, uiNodeAttributeValue);

                uiNodeAttribute.SemanticType = objNodeAttrKVP.Value.SemanticType;
                uiNodeAttribute.PreferredSimilarityMeasure = objNodeAttrKVP.Value.SimilarityMeasure;
                uiNodeAttribute.Visible = !objNodeAttrKVP.Value.IsHidden;
            }
        }
示例#40
0
        private void RankingCompletedHandler(object sender, RankingEventArgs e)
        {
            // Remove event handler for currently selected ranker
            SelectedRanker.RankingCompleted -= RankingCompletedHandler;

            GraphComponents    graph = GraphManager.Instance.DefaultGraphComponentsInstance;
            List <RankingData> data  = new List <RankingData>();

            if (_colorVisualizer == null)
            {
                _colorVisualizer = new ColorVisualizer(e.Results.Values.Min(), e.Results.Values.Max());
            }
            else
            {
                _colorVisualizer.Reset(e.Results.Values.Min(), e.Results.Values.Max());
            }

            _scaleVisualizer = new ScaleVisualizer();

            foreach (INode node in e.Results.Keys)
            {
                RankingData rankingData = new RankingData {
                    Score = e.Results[node], NodeCount = 1
                };

                if (data.Contains(rankingData))
                {
                    data[data.IndexOf(rankingData)].NodeCount += 1;
                }
                else
                {
                    data.Add(rankingData);
                }

                NodeViewModelBase nodeVM = graph.GetNodeViewModel(node) as NodeViewModelBase;

                if (nodeVM != null)
                {
                    if ((VisualizationOption & VisualizationOptions.Color) == VisualizationOptions.Color)
                    {
                        _colorVisualizer.Visualize(nodeVM, e.Results[node]);
                    }
                    else
                    {
                        _colorVisualizer.ClearVisualization(nodeVM);
                    }

                    if ((VisualizationOption & VisualizationOptions.Scale) == VisualizationOptions.Scale)
                    {
                        _scaleVisualizer.Visualize(nodeVM, e.Results[node]);
                    }
                    else
                    {
                        _scaleVisualizer.ClearVisualization(nodeVM);
                    }
                }
            }

            Scores   = new ObservableCollection <RankingData>(data.OrderBy(rankData => rankData.Score));
            IsActive = true;
        }
示例#41
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;
        }
示例#42
0
        /// <summary>
        /// Imports GraphML into SnagL on a new graph
        /// </summary>
        /// <param name="data">The graph data to place on the graph</param>
        /// <param name="scope">Specifies the graphs scope</param>
        /// <param name="format">Specifies the graph data format</param>
        public void ImportData(string data, string scope, GraphDataFormatBase format)
        {
            SnaglEventAggregator.DefaultInstance.GetEvent<UI.TimeConsumingTaskExecutingEvent>().Publish(new UI.TimeConsumingTaskEventArgs());

            GraphComponents components = null;

            // Check if the provided scope is null or empty
            if (string.IsNullOrEmpty(scope))
            {
                // This is a new graph so we will generate new GraphComponents
                // for it
                components = new GraphComponents();
            }
            else
            {
                // Attempt to get the graph components instance for
                // the given scope
                components = GetGraphComponents(scope);

                // If we were unable to get an instance, create a
                // new one
                if (components == null)
                    components = new GraphComponents();
            }

            components.Clear();

            GlobalAttributeCollection.GetInstance(scope).Clear();

            // Import the data into the provided components
            format.Import(data, components, CreationType.Imported);

            // Check if the default instance (which is the first instance
            // created) has been initialized yet
            if (this.defaultComponentInstanceScope == string.Empty)
            {
                // TODO:  ENSURE THIS IS VALID IN THE FUTURE AS THE MAIN GRAPH MAY NOT ALWAYS POPULATE FIRST (BUT SHOULD BE)

                // Save the newly created components as the default
                this.defaultComponentInstanceScope = components.Scope;
            }

            // Now we need to update or add the components to the collection of components
            // Check if the collection has never been initialized
            if (this.graphComponentsInstances == null)
            {
                // Initialize the collection
                this.graphComponentsInstances = new Dictionary<string, GraphComponents>();
            }

            // Check if we have no items
            if (this.graphComponentsInstances.Count == 0)
            {
                // Add the components instance to the collection
                this.graphComponentsInstances.Add(components.Scope, components);
            }
            else
            {
                // Ensure that the scope doesn't already exist
                if (this.graphComponentsInstances.ContainsKey(components.Scope))
                {
                    // Update the components instance for the specified scope
                    this.graphComponentsInstances[components.Scope] = components;
                }
                else
                {
                    // Add the new instance for the specified scope
                    this.graphComponentsInstances.Add(components.Scope, components);
                }
            }

            //TODO  MAKE SURE THAT WE HAVE DATA

            // Fire the DataLoaded event
            DispatcherHelper.UIDispatcher.BeginInvoke(() =>
                SnaglEventAggregator.DefaultInstance.GetEvent<DataLoadedEvent>().Publish(new DataLoadedEventArgs(components.Scope, CreationType.Imported))
                );

            SnaglEventAggregator.DefaultInstance.GetEvent<TimeConsumingTaskCompletedEvent>().Publish(new TimeConsumingTaskEventArgs());
        }
示例#43
0
        /// <summary>
        /// Clusters and lays out the provided graph
        /// </summary>
        /// <param name="graphMapData">The graph to update</param>
        /// <param name="connectedGraph">The graph that needs to be clustered and layed out</param>
        private static void LayoutByClusters(GraphMapData graphMapData, GraphComponents connectedGraph)
        {
            System.Diagnostics.Debug.WriteLine("");
            foreach (Delegate d in ContextMenuManager.Instance.GetContextMenuOpeningInvocationList())
            {
                System.Diagnostics.Debug.WriteLine((d.Target as GraphComponents).Scope);
            }

            // Create a Cluster instance for the graph
            //Cluster clusterer = new Cluster(connectedGraph);

            // Specify the predicate to be used by the Cluster class.  In this case
            // we are determining clusters based on edges createdf during similarity
            // clustering.
            //clusterer.EdgePredicate = delegate(IEdge edge)
            //{
            //	bool isSimilarityDataEdge = edge is SimilarityDataEdge;
            //	return isSimilarityDataEdge;
            //};

            // Create the clusters and return a new graph.  Each node on the
            // graph will be represented as a PartitionNode
            //GraphComponents clusteredGraphComponents = clusterer.GetClusteredGraph();

            //bool isAttributeLayout = true;
            // If there is no different between the initial graph that was provided and
            // out clustered graph, we didn't really find clusters (most likely because
            // similarity clustering was not performed).
            //int clusteredNodesCount = clusteredGraphComponents.GetNodeViewModels().Count();
            //int connectedNodesCount = connectedGraph.GetNodeViewModels().Count();
            //if (clusteredNodesCount == connectedNodesCount)
            //{
                // TODO handle this better than just re-running

                // Rerun clustering without a predicate.  This means that clusters will
                // be based on regular edges.
            Cluster clusterer = new Cluster(connectedGraph);
            GraphComponents clusteredGraphComponents = clusterer.GetClusteredGraph();

            bool isAttributeLayout = false;
            //}

            System.Diagnostics.Debug.WriteLine("");
            foreach (Delegate d in ContextMenuManager.Instance.GetContextMenuOpeningInvocationList())
            {
                System.Diagnostics.Debug.WriteLine((d.Target as GraphComponents).Scope);
            }

            // Get all the nodes that are in the clustered graph. Remember that these are partition nodes.
            IEnumerable<INodeShape> clusteredComponents = clusteredGraphComponents.GetNodeViewModels();
            foreach (PartitionNode clusteredComponent in clusteredComponents)
            {
                // Create an appropriate layout to use for this cluster
                AsynchronousLayoutBase clusterLayout = GetClusterLayout(isAttributeLayout);
                using (GraphComponents clusteredGraph = clusteredComponent.GetGraph())
                {
                    GraphMapData clusteredGraphMapData = GetGraph(graphMapData, clusteredGraph);

                    // Run the layout.  This is laying out the individual cluster itself
                    clusterLayout.CalculateLayout(clusteredGraphMapData);
                }

                System.Diagnostics.Debug.WriteLine("");
                foreach (Delegate d in ContextMenuManager.Instance.GetContextMenuOpeningInvocationList())
                {
                    System.Diagnostics.Debug.WriteLine((d.Target as GraphComponents).Scope);
                }
            }

            System.Diagnostics.Debug.WriteLine("");
            foreach (Delegate d in ContextMenuManager.Instance.GetContextMenuOpeningInvocationList())
            {
                System.Diagnostics.Debug.WriteLine((d.Target as GraphComponents).Scope);
            }

            // Now we need to layout the entired clustered graph so it looks more organized
            GraphMapData clusteredGraphComponentsGraphMapData = GetClusteredGraph(graphMapData, clusteredGraphComponents);
            IDictionary<string, Point> originalPositions = GetOriginalPositions(clusteredGraphComponentsGraphMapData);
            FRLayout frLayout = new FRLayout();
            frLayout.CalculateLayout(clusteredGraphComponentsGraphMapData);
            ApplyOffsetToSubGraphs(graphMapData, clusteredGraphComponents, originalPositions, clusteredGraphComponentsGraphMapData);

            clusteredGraphComponents.Dispose();

            System.Diagnostics.Debug.WriteLine("");
            foreach (Delegate d in ContextMenuManager.Instance.GetContextMenuOpeningInvocationList())
            {
                System.Diagnostics.Debug.WriteLine((d.Target as GraphComponents).Scope);
            }
        }
示例#44
0
        private static void ApplyOffsetToSubGraphs(GraphMapData graph, GraphComponents clusteredGraphComponents, IDictionary<string, Point> originalPositions, GraphMapData partitionGraph)
        {
            IEnumerable<INodeShape> clusteredComponents = clusteredGraphComponents.GetNodeViewModels();
            foreach (PartitionNode clusteredComponent in clusteredComponents)
            {
                Point originalPosition = originalPositions[clusteredComponent.ID];
                double xOffset = partitionGraph.Nodes[clusteredComponent.ID].Position.X - originalPosition.X;
                double yOffset = partitionGraph.Nodes[clusteredComponent.ID].Position.Y - originalPosition.Y;

                IList<NodeViewModelBase> viewModelNodes = clusteredComponent.Nodes;
                foreach (NodeViewModelBase viewModelNode in viewModelNodes)
                {
                    NodeMapData nodeMapData = graph.Nodes[viewModelNode.ParentNode.ID];

                    Point offsetPosition = new Point(nodeMapData.Position.X + xOffset, nodeMapData.Position.Y + yOffset);
                    nodeMapData.Position = offsetPosition;
                }
            }
        }
示例#45
0
        /// <summary>
        /// Local attractive force between 2 connected nodesnode
        /// </summary>
        /// <param name="distance"></param>
        /// <param name="neighborCount"></param>
        /// <param name="edge"></param>
        /// <param name="graphComponents"></param>
        /// <returns></returns>
        protected double LocalForce(double distance, double neighborCount, Model.IEdge edge, GraphComponents graphComponents)
        {
            double bigDistanceApart = 60000;

            double length = K;
            double stiffness = defaultStiffness;

            if (neighborCount == 0) neighborCount = 1;

            // Check if the edge we are dealing with is a similarity edge
            if (edge is Model.SimilarityDataEdge)
            {
                Model.SimilarityDataEdge forceDirectedEdge = edge as Model.SimilarityDataEdge;

                length = forceDirectedEdge.SpringLength;
                stiffness = forceDirectedEdge.SpringStiffness;
            }

            double sourceNodeWidth = 0;
            double targetNodeWidth = 0;

            // Get the width for the source node.  How we get this depends on
            // the type of node that we are dealing with.
            if (edge.Source is PartitionNode)
                sourceNodeWidth = (edge.Source as PartitionNode).Width;
            else
                DispatcherHelper.UIDispatcher.BeginInvoke(() => sourceNodeWidth = graphComponents.GetNodeViewModel(edge.Source).Width);

            // Get the width for the target node.  How we get this depends on
            // the type of node that we are dealing with.
            if (edge.Target is PartitionNode)
                targetNodeWidth = (edge.Target as PartitionNode).Width;
            else
            {
                //targetNodeWidth = GraphComponents.GetNodeViewModel(edge.Target).Width;
                DispatcherHelper.UIDispatcher.BeginInvoke(() => targetNodeWidth = graphComponents.GetNodeViewModel(edge.Target).Width);
            }

            double edgeLength = length + sourceNodeWidth + targetNodeWidth;
            double distanceMultiplier = Math.Max(Math.Abs(distance - edgeLength) / bigDistanceApart, 1);

            return (stiffness * distanceMultiplier) * ((distance - edgeLength) / neighborCount);
        }
示例#46
0
        private static GraphMapData GetGraph(GraphMapData graphMapData, GraphComponents clusteredGraph)
        {
            GraphMapData clusteredGraphMapData = new GraphMapData();

            // Nodes
            IEnumerable<INodeShape> uiNodeViewModels = clusteredGraph.GetNodeViewModels();
            foreach (NodeViewModelBase uiNodeVM in uiNodeViewModels)
            {
                NodeMapData nodeMapData = graphMapData.Nodes[uiNodeVM.ParentNode.ID];
                clusteredGraphMapData.Add(nodeMapData);

                // Edges
                IEnumerable<IEdge> uiEdgeViewModels = clusteredGraph.GetEdges(uiNodeVM.ParentNode);
                foreach (IEdge uiEdgeVM in uiEdgeViewModels)
                {
                    string edgeKey = uiEdgeVM.Source.ID + uiEdgeVM.Target.ID;
                    EdgeMapData edgeMapData = graphMapData.Edges[edgeKey];
                    clusteredGraphMapData.Add(edgeMapData);
                }
            }

            return clusteredGraphMapData;
        }
示例#47
0
        /// <summary>
        /// Adds the specificed edge
        /// </summary>
        /// <param name="graphComponents">The Graph that data is being imported into</param>
        /// <param name="creationType">The specified CreationType</param>
        /// <param name="objEdge">Edge to be added</param>
        public static void AddEdge(GraphComponents graphComponents, CreationType creationType, EdgeMapData objEdge)
        {
            INode uiSourceNode = graphComponents.Data.GetNode(objEdge.Source);
            if (uiSourceNode == null && creationType == CreationType.Imported)
            {
                throw new Exception("Missing Source Node");
            }
            else if (uiSourceNode == null)// && creationType == CreationType.Live
            {
                uiSourceNode = new GhostNode(objEdge.Source);
            }

            INode uiTargetNode = graphComponents.Data.GetNode(objEdge.Target);
            if (uiTargetNode == null && creationType == CreationType.Imported)
            {
                throw new Exception("Missing Target Node");
            }
            else if (uiTargetNode == null)// && creationType == CreationType.Live
            {
                uiTargetNode = new GhostNode(objEdge.Target);
            }

            if (string.IsNullOrEmpty(objEdge.Label) && objEdge.Attributes.Count == 0)
            {
                Berico.SnagL.Model.Edge uiEdge = new Berico.SnagL.Model.Edge(uiSourceNode, uiTargetNode);
                uiEdge.SourceMechanism = creationType;

                // Properties
                uiEdge.Type = objEdge.Type;

                // the EdgeViewModel must be created after uiEdge has had a Type specified
                IEdgeViewModel uiEdgeVM = EdgeViewModelBase.GetEdgeViewModel(uiEdge, graphComponents.Scope);
                graphComponents.AddEdgeViewModel(uiEdgeVM);
            }
            else
            {
                DataEdge uiEdge = new DataEdge(uiSourceNode, uiTargetNode);
                uiEdge.SourceMechanism = creationType;

                // Properties
                uiEdge.Type = objEdge.Type;
                uiEdge.DisplayValue = objEdge.Label;

                // the EdgeViewModel must be created after uiEdge has had a Type specified
                IEdgeViewModel uiEdgeVM = EdgeViewModelBase.GetEdgeViewModel(uiEdge, graphComponents.Scope);
                graphComponents.AddEdgeViewModel(uiEdgeVM);

                uiEdgeVM.Thickness = objEdge.Thickness;
                uiEdgeVM.Color = new SolidColorBrush(objEdge.Color);
                uiEdgeVM.EdgeLine.Text = objEdge.Label;
                uiEdgeVM.EdgeLine.LabelTextUnderline = objEdge.IsLabelTextUnderlined;
                uiEdgeVM.EdgeLine.LabelBackgroundColor = new SolidColorBrush(objEdge.LabelBackgroundColor);
                uiEdgeVM.EdgeLine.LabelForegroundColor = new SolidColorBrush(objEdge.LabelForegroundColor);
                uiEdgeVM.EdgeLine.LabelFontStyle = objEdge.LabelFontStyle;
                uiEdgeVM.EdgeLine.LabelFontWeight = objEdge.LabelFontWeight;
                if (objEdge.LabelFont != null)
                {
                    uiEdgeVM.EdgeLine.LabelFont = objEdge.LabelFont;
                }

                // Attributes
                foreach (KeyValuePair<string, AttributeMapData> objEdgeAttrKVP in objEdge.Attributes)
                {
                    Attributes.Attribute uiEdgeAttribute = new Attributes.Attribute(objEdgeAttrKVP.Value.Name);
                    AttributeValue uiEdgeAttributeValue = new AttributeValue(objEdgeAttrKVP.Value.Value);

                    uiEdge.Attributes.Add(uiEdgeAttribute.Name, uiEdgeAttributeValue);
                    //GlobalAttributeCollection.GetInstance(graphComponents.Scope).Add(uiEdgeAttribute, uiEdgeAttributeValue);

                    uiEdgeAttribute.SemanticType = objEdgeAttrKVP.Value.SemanticType;
                    uiEdgeAttribute.PreferredSimilarityMeasure = objEdgeAttrKVP.Value.SimilarityMeasure;
                    uiEdgeAttribute.Visible = !objEdgeAttrKVP.Value.IsHidden;
                }
            }
        }
示例#48
0
        protected void CalculatePositions(GraphComponents graphComponents)
        {
            double deltaNorm;
            double otherNorm;
            bool converged = false;
            double T = K;
            double tolerance = 0.02;
            double coolingConstant = 0.99;
            Point tempDelta = new Point();
            Point displacement = new Point();
            TimeSpan globalForceTimespan = new TimeSpan();
            TimeSpan localForceTimespan = new TimeSpan();
            TimeSpan indexOfTime = new TimeSpan();
            DateTime start;
            Model.INode currentNode = null;

            List<int> listOfAllNodeIndices = new List<int>();

            // If we aren't partitioning into grids then use all the nodes every time
            if (!useGraphPartitioning)
            {
                for (int i = 0; i < nodeVMs.Length; i++)
                {
                    listOfAllNodeIndices.Add(i);
                }
            }

            for (int loop = 0; loop < maxIterations && !converged; loop++)
            {
                double max = 200;
                double min = 65;
                double R = max - ((loop / maxIterations) * (max - min) + min);

                if (useGraphPartitioning)
                {
                    // Put all vertices into appropraite cells
                    CalculateNodeCells(R);
                }

                converged = true;

                // Loop over nodes
                for (int currentNodeIndex = 0; currentNodeIndex < nodeVMs.Length; currentNodeIndex++)
                {
                    if (nodeVMs[currentNodeIndex] is PartitionNode)
                        currentNode = nodeVMs[currentNodeIndex] as Model.INode;
                    else
                        currentNode = (nodeVMs[currentNodeIndex] as NodeViewModelBase).ParentNode;

                    displacement = new Point(0, 0);

                    // global repulsive force (huh??)
                    start = DateTime.Now;

                    IList<int> repulsionNodes = null;
                    if (useGraphPartitioning)
                    {
                        // Find all nodes, within a certain distance, to perform repulstion on.
                        // Get nodes within maxDistance from this node.
                        double maxDistance = 50; //TODO:  MAKE THIS CONFIGURABLE
                        repulsionNodes = FindNodesForRepulsion(currentNodeIndex, R, maxDistance);
                    }
                    else
                    {
                        // Just repulse all nodes
                        repulsionNodes = listOfAllNodeIndices;
                    }

                    // Loop over all nodes in repulsion list
                    foreach (int i in repulsionNodes)
                    {
                        // We skip this calculation for the current node
                        if (i != currentNodeIndex)
                        {
                            tempDelta.X = positions[i].X - positions[currentNodeIndex].X;
                            tempDelta.Y = positions[i].Y - positions[currentNodeIndex].Y;

                            if (tempDelta.X == 0)
                                tempDelta.X = random.NextDouble() * .001 * K;
                            if (tempDelta.Y == 0)
                                tempDelta.Y = random.NextDouble() * .001 * K;

                            deltaNorm = Math.Max(1, Math.Abs(tempDelta.X) + Math.Abs(tempDelta.Y));
                            otherNorm = Math.Abs(positions[i].X + Math.Abs(positions[i].Y));

                            double globalForce = GlobalForce(deltaNorm, otherNorm);

                            displacement.X += (tempDelta.X / deltaNorm) * globalForce;
                            displacement.Y += (tempDelta.Y / deltaNorm) * globalForce;
                        }
                    }

                    globalForceTimespan += (DateTime.Now - start);

                    // Local forces
                    start = DateTime.Now;

                    // Loop over all the edges for this node
                    foreach (Model.IEdge edge in graphComponents.GetEdges(currentNode))
                    {
                        DateTime startIndex = DateTime.Now;

                        int index = -1;
                        string nodeID = string.Empty;

                        INodeShape oppositeNode = graphComponents.GetOppositeNode(edge, currentNode);
                        //NodeViewModelBase oppositeNodeVM = GraphComponents.GetOppositeNode(edgeVM.ParentEdge, nodeVMs[currentNode].ParentNode);

                        // Get the ID for the opposite node.  How we do this depends
                        // on the type of node that we are dealing with.
                        if (oppositeNode is PartitionNode)
                            nodeID = (oppositeNode as PartitionNode).ID;
                        else
                            nodeID = (oppositeNode as NodeViewModelBase).ParentNode.ID;

                        if (!nodeIDToIndex.TryGetValue(nodeID, out index))
                        {
                            continue;
                        }
                        indexOfTime += DateTime.Now - startIndex;

                        if (index != -1)
                        {
                            tempDelta = new Point(positions[index].X - positions[currentNodeIndex].X, positions[index].Y - positions[currentNodeIndex].Y);

                            if (tempDelta.X == 0)
                                tempDelta.X = random.NextDouble() * .001 * K;
                            if (tempDelta.Y == 0)
                                tempDelta.Y = random.NextDouble() * .001 * K;

                            deltaNorm = Math.Max(Math.Sqrt((tempDelta.X * tempDelta.X) + (tempDelta.Y * tempDelta.Y)), 1);
                            otherNorm = Math.Max(Math.Sqrt((oppositeNode.Position.X * oppositeNode.Position.X) + (oppositeNode.Position.Y * oppositeNode.Position.Y)), 1);

                            double localForce = LocalForce(deltaNorm, edgeCounts[currentNodeIndex], edge, graphComponents);

                            displacement.X += (tempDelta.X / deltaNorm) * localForce;
                            displacement.Y += (tempDelta.Y / deltaNorm) * localForce;
                        }
                    }

                    localForceTimespan+=(DateTime.Now - start);

                    // Reposition node (huh??)
                    if (displacement.X == 0) displacement.X = 1;

                    double displacementNorm = Math.Sqrt((displacement.X * displacement.X) + (displacement.Y * displacement.Y));
                    double newX = positions[currentNodeIndex].X + (displacement.X / displacementNorm) * Math.Min(T, displacementNorm);
                    double newY = positions[currentNodeIndex].Y + (displacement.Y / displacementNorm) * Math.Min(T, displacementNorm);

                    tempDelta = new Point(newX - positions[currentNodeIndex].X, newY - positions[currentNodeIndex].Y);

                    positions[currentNodeIndex].X = newX;
                    positions[currentNodeIndex].Y = newY;

                    // no clue what this is doing
                    if (Math.Sqrt((tempDelta.X * tempDelta.X) + (tempDelta.Y * tempDelta.Y)) > K * tolerance)
                        converged=false;

                }

                // cool (huh??)
                T *= coolingConstant;
            }

            //System.Diagnostics.Debug.WriteLine(globalForceTimespan);
            //System.Diagnostics.Debug.WriteLine(localForceTimespan);
            //System.Diagnostics.Debug.WriteLine(indexOfTime);
        }
示例#49
0
        /// <summary>
        /// Clusters and lays out the provided graph
        /// </summary>
        /// <param name="graphMapData">The graph to update</param>
        /// <param name="connectedGraph">The graph that needs to be clustered and layed out</param>
        private static void LayoutByClusters(GraphMapData graphMapData, GraphComponents connectedGraph)
        {
            System.Diagnostics.Debug.WriteLine("");
            foreach (Delegate d in ContextMenuManager.Instance.GetContextMenuOpeningInvocationList())
            {
                System.Diagnostics.Debug.WriteLine((d.Target as GraphComponents).Scope);
            }

            // Create a Cluster instance for the graph
            //Cluster clusterer = new Cluster(connectedGraph);


            // Specify the predicate to be used by the Cluster class.  In this case
            // we are determining clusters based on edges createdf during similarity
            // clustering.
            //clusterer.EdgePredicate = delegate(IEdge edge)
            //{
            //	bool isSimilarityDataEdge = edge is SimilarityDataEdge;
            //	return isSimilarityDataEdge;
            //};

            // Create the clusters and return a new graph.  Each node on the
            // graph will be represented as a PartitionNode
            //GraphComponents clusteredGraphComponents = clusterer.GetClusteredGraph();

            //bool isAttributeLayout = true;
            // If there is no different between the initial graph that was provided and
            // out clustered graph, we didn't really find clusters (most likely because
            // similarity clustering was not performed).
            //int clusteredNodesCount = clusteredGraphComponents.GetNodeViewModels().Count();
            //int connectedNodesCount = connectedGraph.GetNodeViewModels().Count();
            //if (clusteredNodesCount == connectedNodesCount)
            //{
            // TODO handle this better than just re-running

            // Rerun clustering without a predicate.  This means that clusters will
            // be based on regular edges.
            Cluster         clusterer = new Cluster(connectedGraph);
            GraphComponents clusteredGraphComponents = clusterer.GetClusteredGraph();

            bool isAttributeLayout = false;

            //}

            System.Diagnostics.Debug.WriteLine("");
            foreach (Delegate d in ContextMenuManager.Instance.GetContextMenuOpeningInvocationList())
            {
                System.Diagnostics.Debug.WriteLine((d.Target as GraphComponents).Scope);
            }

            // Get all the nodes that are in the clustered graph. Remember that these are partition nodes.
            IEnumerable <INodeShape> clusteredComponents = clusteredGraphComponents.GetNodeViewModels();

            foreach (PartitionNode clusteredComponent in clusteredComponents)
            {
                // Create an appropriate layout to use for this cluster
                AsynchronousLayoutBase clusterLayout = GetClusterLayout(isAttributeLayout);
                using (GraphComponents clusteredGraph = clusteredComponent.GetGraph())
                {
                    GraphMapData clusteredGraphMapData = GetGraph(graphMapData, clusteredGraph);

                    // Run the layout.  This is laying out the individual cluster itself
                    clusterLayout.CalculateLayout(clusteredGraphMapData);
                }

                System.Diagnostics.Debug.WriteLine("");
                foreach (Delegate d in ContextMenuManager.Instance.GetContextMenuOpeningInvocationList())
                {
                    System.Diagnostics.Debug.WriteLine((d.Target as GraphComponents).Scope);
                }
            }

            System.Diagnostics.Debug.WriteLine("");
            foreach (Delegate d in ContextMenuManager.Instance.GetContextMenuOpeningInvocationList())
            {
                System.Diagnostics.Debug.WriteLine((d.Target as GraphComponents).Scope);
            }

            // Now we need to layout the entired clustered graph so it looks more organized
            GraphMapData clusteredGraphComponentsGraphMapData = GetClusteredGraph(graphMapData, clusteredGraphComponents);
            IDictionary <string, Point> originalPositions     = GetOriginalPositions(clusteredGraphComponentsGraphMapData);
            FRLayout frLayout = new FRLayout();

            frLayout.CalculateLayout(clusteredGraphComponentsGraphMapData);
            ApplyOffsetToSubGraphs(graphMapData, clusteredGraphComponents, originalPositions, clusteredGraphComponentsGraphMapData);

            clusteredGraphComponents.Dispose();

            System.Diagnostics.Debug.WriteLine("");
            foreach (Delegate d in ContextMenuManager.Instance.GetContextMenuOpeningInvocationList())
            {
                System.Diagnostics.Debug.WriteLine((d.Target as GraphComponents).Scope);
            }
        }
示例#50
0
        /// <summary>
        /// Positions the nodes
        /// </summary>
        /// <param name="isAnimated">Indicates whether or not the layout should be animated</param>
        /// <param name="graphComponents">The object containing the graph data</param>
        /// <param name="rootNode">Root node</param>
        public void ComputeLayout(bool isAnimated, GraphComponents graphComponents, INode rootNode)
        {
            nodeVMs = graphComponents.GetNodeViewModels().Where(node => !node.IsHidden).ToArray();
            positions = new Point[nodeVMs.Length];
            edgeCounts = new int[nodeVMs.Length];
            nodeIDToIndex = new Dictionary<string, int>();

            for (int i = 0; i < nodeVMs.Length; i++)
            {
                // Save this nodes position
                positions[i] = nodeVMs[i].Position;

                if (nodeVMs[i] is PartitionNode)
                    nodeIDToIndex[(nodeVMs[i] as PartitionNode).ID] = i;
                else
                    nodeIDToIndex[(nodeVMs[i] as NodeViewModelBase).ParentNode.ID] = i;

                // Get a count of all the edges for this node

                //testcount += GraphComponents.GetNumberOfEdges(nodeVMs[i].ParentNode);

                List<INodeShape> visitedNeighbors = new List<INodeShape>();
                Model.INode currentNode = null;

                if (nodeVMs[i] is PartitionNode)
                    currentNode = nodeVMs[i] as Model.INode;
                else
                    currentNode = (nodeVMs[i] as NodeViewModelBase).ParentNode;

                // Loop over all the edges for this node
                foreach (Model.IEdge edge in graphComponents.GetEdges(currentNode))
                {
                    // Get the node at the opposite end of this edge
                    INodeShape oppositeNode = graphComponents.GetOppositeNode(edge, currentNode);

                    // Ensure that this edge is not a similarity edge and that
                    // the opposite node has not been visited already
                    if (!(edge is Model.SimilarityDataEdge) && !visitedNeighbors.Contains(oppositeNode))
                    {
                        edgeCounts[i]++;
                        visitedNeighbors.Add(oppositeNode);
                    }
                }
            }

            // Old version is doing this next call asynchronously
            if (nodeVMs.Length > 1)
                CalculatePositions(graphComponents);
        }
示例#51
0
文件: Cluster.cs 项目: senfo/snaglV2
 /// <summary>
 /// 
 /// </summary>
 public Cluster(GraphComponents graphComponents)
 {
     _sourceGraph = graphComponents;
 }