/// <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); } }
/// <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; }