View Javadoc
1   /*
2    * Copyright (c) 2005, The JUNG Authors
3    * All rights reserved.
4    *
5    * This software is open-source under the BSD license; see either "license.txt"
6    * or https://github.com/jrtom/jung/blob/master/LICENSE for a description.
7    *
8    * Created on Aug 23, 2005
9    */
10  package edu.uci.ics.jung.visualization.subLayout;
11  
12  import com.google.common.base.Preconditions;
13  
14  import java.util.Collection;
15  import java.util.logging.Logger;
16  
17  import edu.uci.ics.jung.graph.Graph;
18  import edu.uci.ics.jung.graph.util.Pair;
19  
20  @SuppressWarnings({"rawtypes", "unchecked"})
21  public class GraphCollapser  {
22      
23      private static final Logger logger = Logger.getLogger(GraphCollapser.class.getClass().getName());
24  	private Graph originalGraph;
25      
26      public GraphCollapser(Graph originalGraph) {
27          this.originalGraph = originalGraph;
28      }
29      
30      Graph createGraph() throws InstantiationException, IllegalAccessException {
31          return (Graph)originalGraph.getClass().newInstance();
32      }
33      
34      public Graph collapse(Graph inGraph, Graph clusterGraph) {
35          
36          if(clusterGraph.getVertexCount() < 2) return inGraph;
37  
38          Graph graph = inGraph;
39          try {
40              graph = createGraph();
41          } catch(Exception ex) {
42              ex.printStackTrace();
43          }
44          Collection cluster = clusterGraph.getVertices();
45          
46          // add all vertices in the delegate, unless the vertex is in the
47          // cluster.
48          for(Object v : inGraph.getVertices()) {
49              if(cluster.contains(v) == false) {
50                  graph.addVertex(v);
51              }
52          }
53          // add the clusterGraph as a vertex
54          graph.addVertex(clusterGraph);
55          
56          //add all edges from the inGraph, unless both endpoints of
57          // the edge are in the cluster
58          for(Object e : (Collection<?>)inGraph.getEdges()) {
59              Pair endpoints = inGraph.getEndpoints(e);
60              // don't add edges whose endpoints are both in the cluster
61              if(cluster.containsAll(endpoints) == false) {
62  
63                  if(cluster.contains(endpoints.getFirst())) {
64                  	graph.addEdge(e, clusterGraph, endpoints.getSecond(), inGraph.getEdgeType(e));
65  
66                  } else if(cluster.contains(endpoints.getSecond())) {
67                  	graph.addEdge(e, endpoints.getFirst(), clusterGraph, inGraph.getEdgeType(e));
68  
69                  } else {
70                  	graph.addEdge(e,endpoints.getFirst(), endpoints.getSecond(), inGraph.getEdgeType(e));
71                  }
72              }
73          }
74          return graph;
75      }
76      
77      public Graph expand(Graph inGraph, Graph clusterGraph) {
78          Graph graph = inGraph;
79          try {
80              graph = createGraph();
81          } catch(Exception ex) {
82              ex.printStackTrace();
83          }
84          Collection cluster = clusterGraph.getVertices();
85          logger.fine("cluster to expand is "+cluster);
86  
87          // put all clusterGraph vertices and edges into the new Graph
88          for(Object v : cluster) {
89              graph.addVertex(v);
90              for(Object edge : clusterGraph.getIncidentEdges(v)) {
91                  Pair endpoints = clusterGraph.getEndpoints(edge);
92                  graph.addEdge(edge, endpoints.getFirst(), endpoints.getSecond(), clusterGraph.getEdgeType(edge));
93              }
94          }
95          // add all the vertices from the current graph except for
96          // the cluster we are expanding
97          for(Object v : inGraph.getVertices()) {
98              if(v.equals(clusterGraph) == false) {
99                  graph.addVertex(v);
100             }
101         }
102 
103         // now that all vertices have been added, add the edges,
104         // ensuring that no edge contains a vertex that has not
105         // already been added
106         for(Object v : inGraph.getVertices()) {
107             if(v.equals(clusterGraph) == false) {
108                 for(Object edge : inGraph.getIncidentEdges(v)) {
109                     Pair endpoints = inGraph.getEndpoints(edge);
110                     Object v1 = endpoints.getFirst();
111                     Object v2 = endpoints.getSecond();
112                      if(cluster.containsAll(endpoints) == false) {
113                         if(clusterGraph.equals(v1)) {
114                             // i need a new v1
115                             Object originalV1 = originalGraph.getEndpoints(edge).getFirst();
116                             Object newV1 = findVertex(graph, originalV1);
117                             Preconditions.checkState(newV1 != null, "newV1 for "+originalV1+" was not found!");
118                             graph.addEdge(edge, newV1, v2, inGraph.getEdgeType(edge));
119                         } else if(clusterGraph.equals(v2)) {
120                             // i need a new v2
121                             Object originalV2 = originalGraph.getEndpoints(edge).getSecond();
122                             Object newV2 = findVertex(graph, originalV2);
123                             Preconditions.checkState(newV2 != null, "newV2 for "+originalV2+" was not found!");
124                             graph.addEdge(edge, v1, newV2, inGraph.getEdgeType(edge));
125                         } else {
126                         	graph.addEdge(edge, v1, v2, inGraph.getEdgeType(edge));
127                         }
128                     }
129                 }
130             }
131         }
132         return graph;
133     }
134     Object findVertex(Graph inGraph, Object vertex) {
135         Collection vertices = inGraph.getVertices();
136         if(vertices.contains(vertex)) {
137             return vertex;
138         }
139         for(Object v : vertices) {
140             if(v instanceof Graph) {
141                 Graph g = (Graph)v;
142                 if(contains(g, vertex)) {
143                     return v;
144                 }
145             }
146         }
147         return null;
148     }
149     
150     private boolean contains(Graph inGraph, Object vertex) {
151     	boolean contained = false;
152     	if(inGraph.getVertices().contains(vertex)) return true;
153     	for(Object v : inGraph.getVertices()) {
154     		if(v instanceof Graph) {
155     			contained |= contains((Graph)v, vertex);
156     		}
157     	}
158     	return contained;
159     }
160     
161     public Graph getClusterGraph(Graph inGraph, Collection picked) {
162         Graph clusterGraph;
163         try {
164             clusterGraph = createGraph();
165         } catch (InstantiationException e) {
166             // TODO Auto-generated catch block
167             e.printStackTrace();
168             return null;
169         } catch (IllegalAccessException e) {
170             // TODO Auto-generated catch block
171             e.printStackTrace();
172             return null;
173         }
174         for(Object v : picked) {
175         	clusterGraph.addVertex(v);
176             Collection edges = inGraph.getIncidentEdges(v);
177             for(Object edge : edges) {
178                 Pair endpoints = inGraph.getEndpoints(edge);
179                 Object v1 = endpoints.getFirst();
180                 Object v2 = endpoints.getSecond();
181                 if(picked.containsAll(endpoints)) {
182                     clusterGraph.addEdge(edge, v1, v2, inGraph.getEdgeType(edge));
183                 }
184             }
185         }
186         return clusterGraph;
187     }
188 
189 }