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.platform.preferences.lastsettings.UserModifiableProperty; 010 import graphlab.plugins.visualization.corebasics.extension.VisualizationExtension; 011 import graphlab.ui.UIUtils; 012 013 import java.awt.geom.Point2D; 014 import java.util.HashMap; 015 import java.util.Iterator; 016 import java.util.Vector; 017 018 /** 019 * @author Rouzbeh Ebrahimi 020 */ 021 public class SparseTreeVisualization implements VisualizationExtension { 022 String event = UIUtils.getUIEventKey("SparseTreeVisualization"); 023 public Vector<VertexModel> visitedVertices = new Vector<VertexModel>(); 024 public HashMap<VertexModel, Point2D> vertexPlaces; 025 public Vector<VertexModel> children; 026 027 private void unMarkVertices() { 028 for (VertexModel v : graph) { 029 v.setMark(false); 030 } 031 } 032 033 034 private VertexModel findAppropriateRoot(GraphModel g) { 035 VertexModel root = g.getAVertex(); 036 Iterator<VertexModel> ei = g.iterator(); 037 for (; ei.hasNext();) { 038 VertexModel e = ei.next(); 039 root = findHigherVertex(e, root); 040 } 041 return root; 042 } 043 044 private VertexModel findHigherVertex(VertexModel v1, VertexModel v2) { 045 Vector<VertexModel> t1 = new Vector<VertexModel>(); 046 Vector<VertexModel> t2 = new Vector<VertexModel>(); 047 t1.add(v1); 048 t2.add(v2); 049 if (BFS(t1, 0) > BFS(t2, 0)) { 050 return v1; 051 } else { 052 return v2; 053 } 054 } 055 056 private int BFS(Vector<VertexModel> currentLevel, int maxLevel) { 057 Vector<VertexModel> nextLevel = new Vector<VertexModel>(); 058 for (VertexModel v : currentLevel) { 059 v.setMark(true); 060 Iterator<EdgeModel> em = graph.edgeIterator(v); 061 for (; em.hasNext();) { 062 EdgeModel e = em.next(); 063 VertexModel v2 = e.source; 064 if (!v2.getMark()) { 065 nextLevel.add(v2); 066 v2.setMark(true); 067 } 068 } 069 } 070 maxLevel++; 071 if (nextLevel.size() != 0) { 072 return BFS(nextLevel, maxLevel); 073 } else { 074 return maxLevel; 075 } 076 } 077 078 static GraphModel graph; 079 080 public void performJob(String eventName, Object value) { 081 visitedVertices = new Vector<VertexModel>(); 082 vertexPlaces = new HashMap<VertexModel, Point2D>(); 083 children = new Vector<VertexModel>(); 084 try { 085 VertexModel root = findAppropriateRoot(graph); 086 visitedVertices.add(root); 087 unMarkVertices(); 088 locateAll(visitedVertices, width, eachLevelHeigh); 089 } catch (NullPointerException e) { 090 System.out.println("Graph is Empty"); 091 // e.printStackTrace(); 092 } 093 094 } 095 096 097 public Vector<VertexModel> findNextLevelChildren(Vector<VertexModel> currentLevelVertices) { 098 Vector<VertexModel> newChildren = new Vector<VertexModel>(); 099 for (VertexModel v : currentLevelVertices) { 100 Iterator<EdgeModel> e = graph.edgeIterator(v); 101 for (; e.hasNext();) { 102 EdgeModel ed = e.next(); 103 VertexModel dest = ed.source; 104 if (!visitedVertices.contains(dest)) { 105 newChildren.add(dest); 106 } 107 } 108 } 109 return newChildren; 110 } 111 112 public void locateAll(Vector<VertexModel> currentLevelVertices, int width, int LevelHeight) { 113 int currentLevelCount = currentLevelVertices.size(); 114 int i = 0; 115 116 Vector<VertexModel> nextLevel = findNextLevelChildren(currentLevelVertices); 117 int nextLevelCount = nextLevel.size(); 118 int horizontalDist = width / (currentLevelCount + nextLevelCount); 119 120 for (VertexModel x : currentLevelVertices) { 121 122 } 123 for (VertexModel v : currentLevelVertices) { 124 if (nextLevelCount != 0) { 125 Point2D.Double newPoint = new Point2D.Double(horizontalDist * (i + 1) + width / (nextLevelCount + currentLevelCount), LevelHeight); 126 vertexPlaces.put(v, newPoint); 127 i += graph.getOutDegree(v); 128 } else { 129 Point2D.Double newPoint = new Point2D.Double(horizontalDist * (i) + width / (currentLevelCount), LevelHeight); 130 vertexPlaces.put(v, newPoint); 131 i++; 132 } 133 } 134 135 if (!nextLevel.isEmpty()) { 136 visitedVertices.addAll(nextLevel); 137 locateAll(nextLevel, width, LevelHeight + eachLevelHeigh); 138 } else { 139 return; 140 } 141 } 142 143 public String getName() { 144 return "Sparse Tree Visualization"; 145 } 146 147 public String getDescription() { 148 return "Sparse Tree Visualization"; 149 }/* 150 @param g 151 */ 152 153 public void setWorkingGraph(GraphModel g) { 154 this.graph = g; 155 } 156 157 @UserModifiableProperty(displayName = "Sparse Tree Visualization Width", obeysAncestorCategory = false 158 , category = "Visualization Options") 159 public static Integer width = 800; 160 @UserModifiableProperty(displayName = "Sparse Tree Visualization : Each Level's height", obeysAncestorCategory = false 161 , category = "Visualization Options") 162 public static Integer eachLevelHeigh = 50; 163 164 public HashMap<VertexModel, Point2D> getNewVertexPlaces() { 165 visitedVertices = new Vector<VertexModel>(); 166 vertexPlaces = new HashMap<VertexModel, Point2D>(); 167 children = new Vector<VertexModel>(); 168 try { 169 VertexModel root = findAppropriateRoot(graph); 170 visitedVertices.add(root); 171 unMarkVertices(); 172 locateAll(visitedVertices, width, eachLevelHeigh); 173 } catch (NullPointerException e) { 174 System.out.println("Graph is Empty"); 175 // e.printStackTrace(); 176 } 177 return vertexPlaces; 178 } 179 180 public HashMap<EdgeModel, Point2D> getNewEdgeCurveControlPoints() { 181 return null; //To change body of implemented methods use File | Settings | File Templates. 182 } 183 }