001 // GraphLab Project: http://graphlab.sharif.edu 002 // Copyright (C) 2008 Mathematical Science Department of Sharif University of Technology 003 // Distributed under the terms of the GNU General Public License (GPL): http://www.gnu.org/licenses/ 004 package graphlab.plugins.visualization.treevisualizations; 005 006 import graphlab.graph.graph.EdgeModel; 007 import graphlab.graph.graph.GraphModel; 008 import graphlab.graph.graph.VertexModel; 009 import graphlab.library.BaseVertexProperties; 010 import graphlab.platform.preferences.lastsettings.UserModifiableProperty; 011 import graphlab.plugins.graphgenerator.core.PositionGenerators; 012 import graphlab.plugins.visualization.corebasics.extension.VisualizationExtension; 013 import graphlab.ui.UIUtils; 014 015 import java.awt.geom.Point2D; 016 import java.util.HashMap; 017 import java.util.HashSet; 018 import java.util.Iterator; 019 import java.util.Vector; 020 021 /** 022 * @author Rouzbeh Ebrahimi 023 */ 024 public class BackwardTrees implements VisualizationExtension { 025 String event = UIUtils.getUIEventKey("BackwardTrees"); 026 public Vector<VertexModel> visitedVertices = new Vector<VertexModel>(); 027 public Vector<VertexModel> upperLevelVertices = new Vector<VertexModel>(); 028 029 public HashMap<VertexModel, Point2D> vertexPlaces = new HashMap<VertexModel, Point2D>(); 030 public Vector<VertexModel> children = new Vector<VertexModel>(); 031 public HashMap<VertexModel, Double> comingFrom = new HashMap<VertexModel, Double>(); 032 VertexModel root; 033 034 035 static GraphModel g; 036 /** 037 * @param eventName 038 * @param value 039 */ 040 public HashSet<VertexModel> placedVertices = new HashSet<VertexModel>(); 041 @UserModifiableProperty(displayName = "BackWard Tree Visualization Radius", obeysAncestorCategory = false 042 , category = "Visualization Options") 043 public static Integer radius = 60; 044 045 private VertexModel findHigherVertex(VertexModel v1, VertexModel v2) { 046 Vector<VertexModel> t1 = new Vector<VertexModel>(); 047 Vector<VertexModel> t2 = new Vector<VertexModel>(); 048 t1.add(v1); 049 t2.add(v2); 050 if (BFS(t1, 0) > BFS(t2, 0)) { 051 return v1; 052 } else { 053 return v2; 054 } 055 } 056 057 private VertexModel findAppropriateRoot(GraphModel g) { 058 VertexModel root = g.getAVertex(); 059 Iterator<VertexModel> ei = g.iterator(); 060 for (; ei.hasNext();) { 061 VertexModel e = ei.next(); 062 root = findHigherVertex(e, root); 063 } 064 return root; 065 } 066 067 private int BFS(Vector<VertexModel> currentLevel, int maxLevel) { 068 Vector<VertexModel> nextLevel = new Vector<VertexModel>(); 069 for (VertexModel v : currentLevel) { 070 v.setMark(true); 071 Iterator<EdgeModel> em = g.edgeIterator(v); 072 for (; em.hasNext();) { 073 EdgeModel e = em.next(); 074 VertexModel v2 = e.source; 075 if (!v2.getMark()) { 076 nextLevel.add(v2); 077 v2.setMark(true); 078 } 079 } 080 } 081 maxLevel++; 082 if (nextLevel.size() != 0) { 083 return BFS(nextLevel, maxLevel); 084 } else { 085 return maxLevel; 086 } 087 } 088 089 public Vector<VertexModel> findNextLevelChildren(Vector<VertexModel> currentLevelVertices) { 090 Vector<VertexModel> newChildren = new Vector<VertexModel>(); 091 if (currentLevelVertices.size() != 0) { 092 for (VertexModel v : currentLevelVertices) { 093 Iterator<EdgeModel> e = g.edgeIterator(v); 094 for (; e.hasNext();) { 095 EdgeModel ed = e.next(); 096 VertexModel dest = ed.source; 097 if (!visitedVertices.contains(dest)) { 098 newChildren.add(dest); 099 } 100 } 101 } 102 } else { 103 } 104 return newChildren; 105 } 106 107 public void locateAll(Vector<VertexModel> currentLevelVertices, int width, int currentLevelHeight, int level, int radius) { 108 109 int currentLevelCount = currentLevelVertices.size(); 110 int horizontalDist = width / currentLevelCount; 111 int i = 0; 112 Vector<VertexModel> nextLevel = findNextLevelChildren(currentLevelVertices); 113 if (currentLevelCount == 1 && currentLevelVertices.elementAt(0).equals(root)) { 114 Point2D.Double newPoint = new Point2D.Double(200, 200); 115 vertexPlaces.put(root, newPoint); 116 comingFrom.put(root, 0.0); 117 } else { 118 for (VertexModel v : upperLevelVertices) { 119 Iterator<EdgeModel> ei = g.edgeIterator(v); 120 int degree = g.getInDegree(v); 121 double p = comingFrom.get(v); 122 int j = 0; 123 124 double phase; 125 phase = 360 / (degree); 126 Point2D[] circle = PositionGenerators.circle((int) v.getLocation().getX(), (int) v.getLocation().getY(), radius, radius, degree); 127 int t = 0; 128 for (; ei.hasNext();) { 129 VertexModel ver = ei.next().source; 130 // double x; 131 // double y; 132 // double xPhase = Math.cos(((j * phase)+p) * Math.PI / 180); 133 // x = vertexPlaces.get(v).getX() + radius * xPhase; 134 // double yPhase = Math.sin(((j * phase)+p ) * Math.PI / 180); 135 // y = vertexPlaces.get(v).getY() + radius * yPhase; 136 comingFrom.put(ver, (j * phase) + p); 137 // Point2D.Double newPoint = new Point2D.Double(x, y); 138 vertexPlaces.put(ver, circle[t]); 139 j++; 140 t++; 141 142 } 143 } 144 145 // for (Vertex v : currentLevelVertices) { 146 // Point2D.Double newPoint = new Point2D.Double(horizontalDist * i + width / (currentLevelCount + 1), currentLevelHeight); 147 // vertexPlaces.put(v,newPoint); 148 // i++; 149 // } 150 } 151 upperLevelVertices = currentLevelVertices; 152 if (!nextLevel.isEmpty()) { 153 visitedVertices.addAll(nextLevel); 154 locateAll(nextLevel, width, currentLevelHeight + 30, level + 1, radius * 9 / 16); 155 } else { 156 return; 157 } 158 } 159 160 private void unMarkVertices() { 161 for (VertexModel v : g) { 162 v.setMark(false); 163 } 164 } 165 166 167 public void locateAllSubTrees(VertexModel v, double radius, double offSet) { 168 if (placedVertices.contains(root)) { 169 double angularSpan = (Double) v.getProp().obj; 170 int numberOfDivides = 1; 171 numberOfDivides = g.getInDegree(v); 172 if (numberOfDivides == 0) { 173 return; 174 } 175 Iterator<EdgeModel> iter = g.edgeIterator(v); 176 int sum = 0; 177 for (; iter.hasNext();) { 178 EdgeModel e = iter.next(); 179 VertexModel v1 = e.source.equals(v) ? e.target : e.source; 180 if (!placedVertices.contains(v1)) { 181 sum += g.getInDegree(v1); 182 } else { 183 } 184 } 185 iter = g.edgeIterator(v); 186 int j = 1; 187 for (; iter.hasNext();) { 188 EdgeModel e = iter.next(); 189 VertexModel v1 = e.source.equals(v) ? e.target : e.source; 190 if (!placedVertices.contains(v1)) { 191 double x = 350 + radius * Math.cos((angularSpan * j / (numberOfDivides) + offSet)); 192 double y = 350 + radius * Math.sin((angularSpan * j / (numberOfDivides) + offSet)); 193 double newOffset = (angularSpan * j / numberOfDivides + offSet); 194 Point2D.Double newPoint = new Point2D.Double(x, y); 195 vertexPlaces.put(v1, newPoint); 196 placedVertices.add(v1); 197 BaseVertexProperties properties = new BaseVertexProperties(v1.getColor(), v1.getMark()); 198 properties.obj = new Double((angularSpan / (Math.abs(sum))) * (g.getInDegree(v1))); 199 v1.setProp(properties); 200 locateAllSubTrees(v1, this.radius + radius, newOffset); 201 j++; 202 203 } else { 204 } 205 206 } 207 return; 208 } else { 209 double x = 350; 210 double y = 350; 211 Point2D.Double newPoint = new Point2D.Double(x, y); 212 placedVertices.add(v); 213 vertexPlaces.put(v, newPoint); 214 locateAllSubTrees(v, radius, offSet); 215 } 216 } 217 218 public String getName() { 219 return "BackWard Tree Visualization"; 220 } 221 222 public String getDescription() { 223 return null; //To change body of implemented methods use File | Settings | File Templates. 224 }/* 225 @param g 226 */ 227 228 public void setWorkingGraph(GraphModel g) { 229 this.g = g; 230 } 231 232 public HashMap<VertexModel, Point2D> getNewVertexPlaces() { 233 visitedVertices = new Vector<VertexModel>(); 234 vertexPlaces = new HashMap<VertexModel, Point2D>(); 235 children = new Vector<VertexModel>(); 236 placedVertices = new HashSet<VertexModel>(); 237 try { 238 root = findAppropriateRoot(g); 239 visitedVertices.add(root); 240 unMarkVertices(); 241 // locateAll(visitedVertices, 600, 50, 1,200); 242 BaseVertexProperties properties = new BaseVertexProperties(root.getColor(), root.getMark()); 243 properties.obj = new Double(2 * Math.PI); 244 root.setProp(properties); 245 246 locateAllSubTrees(root, radius, 0); 247 // GeneralAnimator t = new GeneralAnimator(vertexPlaces, g, blackboard); 248 // t.start(); 249 } catch (NullPointerException e) { 250 // System.out.println("Graph is Empty"); 251 e.printStackTrace(); 252 } 253 return vertexPlaces; 254 } 255 256 public HashMap<EdgeModel, Point2D> getNewEdgeCurveControlPoints() { 257 return null; //To change body of implemented methods use File | Settings | File Templates. 258 } 259 } 260