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