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.hierarchical; 005 006 import graphlab.graph.atributeset.GraphAttrSet; 007 import graphlab.graph.graph.EdgeModel; 008 import graphlab.graph.graph.GraphModel; 009 import graphlab.graph.graph.VertexModel; 010 import graphlab.platform.core.AbstractAction; 011 import graphlab.platform.core.BlackBoard; 012 import graphlab.plugins.visualization.corebasics.animator.GeneralAnimator; 013 import graphlab.ui.UIUtils; 014 015 import java.awt.geom.Point2D; 016 import java.util.HashMap; 017 import java.util.Iterator; 018 import java.util.Vector; 019 020 /** 021 * @author Rouzbeh Ebrahimi 022 */ 023 public class BendedTrees extends AbstractAction { 024 String event = UIUtils.getUIEventKey("BendedTrees"); 025 public Vector<VertexModel> visitedVertices = new Vector<VertexModel>(); 026 public HashMap<VertexModel, Point2D> vertexPlaces = new HashMap<VertexModel, Point2D>(); 027 public HashMap<EdgeModel, Vector<Point2D>> edgeBendPoints = new HashMap<EdgeModel, Vector<Point2D>>(); 028 public Vector<VertexModel> children = new Vector<VertexModel>(); 029 public GraphModel graph; 030 031 /** 032 * constructor 033 * 034 * @param bb the blackboard of the action 035 */ 036 public BendedTrees(BlackBoard bb) { 037 super(bb); 038 listen4Event(event); 039 } 040 041 private VertexModel findAppropriateRoot(GraphModel g) { 042 VertexModel root = g.getAVertex(); 043 Iterator<VertexModel> ei = g.iterator(); 044 for (; ei.hasNext();) { 045 VertexModel e = ei.next(); 046 root = findHigherVertex(e, root); 047 } 048 return root; 049 } 050 051 private VertexModel findHigherVertex(VertexModel v1, VertexModel v2) { 052 Vector<VertexModel> t1 = new Vector<VertexModel>(); 053 Vector<VertexModel> t2 = new Vector<VertexModel>(); 054 t1.add(v1); 055 t2.add(v2); 056 if (BFS(new Vector<VertexModel>(), t1, 0) > BFS(new Vector<VertexModel>(), t2, 0)) { 057 return v1; 058 } else { 059 return v2; 060 } 061 } 062 063 private int BFS(Vector<VertexModel> marked, Vector<VertexModel> currentLevel, int maxLevel) { 064 marked.addAll(currentLevel); 065 Vector<VertexModel> nextLevel = new Vector<VertexModel>(); 066 for (VertexModel v : currentLevel) { 067 v.setMark(true); 068 Iterator<EdgeModel> em = g.edgeIterator(v); 069 for (; em.hasNext();) { 070 EdgeModel e = em.next(); 071 VertexModel v2 = e.source; 072 if (!marked.contains(v2)) { 073 nextLevel.add(v2); 074 } 075 } 076 } 077 maxLevel++; 078 if (nextLevel.size() != 0) { 079 return BFS(marked, nextLevel, maxLevel); 080 } else { 081 return maxLevel; 082 } 083 } 084 085 static GraphModel g; 086 087 public void performAction(String eventName, Object value) { 088 visitedVertices = new Vector<VertexModel>(); 089 vertexPlaces = new HashMap<VertexModel, Point2D>(); 090 children = new Vector<VertexModel>(); 091 edgeBendPoints = new HashMap<EdgeModel, Vector<Point2D>>(); 092 g = ((GraphModel) (blackboard.getData(GraphAttrSet.name))); 093 try { 094 this.graph = g; 095 VertexModel root = findAppropriateRoot(g); 096 visitedVertices.add(root); 097 locateAllVertices(visitedVertices, 800, 50); 098 reshapeAllEdges(); 099 GeneralAnimator t = new GeneralAnimator(vertexPlaces, edgeBendPoints, g, blackboard); 100 t.start(); 101 } catch (NullPointerException e) { 102 System.out.println("Graph is Empty"); 103 // e.printStackTrace(); 104 } 105 106 } 107 108 public Vector<VertexModel> findNextLevelChildren(Vector<VertexModel> currentLevelVertices) { 109 Vector<VertexModel> newChildren = new Vector<VertexModel>(); 110 for (VertexModel v : currentLevelVertices) { 111 Iterator<EdgeModel> e = g.edgeIterator(v); 112 for (; e.hasNext();) { 113 EdgeModel ed = e.next(); 114 VertexModel dest = ed.source; 115 if (!visitedVertices.contains(dest)) { 116 newChildren.add(dest); 117 } 118 } 119 } 120 return newChildren; 121 } 122 123 public void reshapeAllEdges() { 124 Iterator<EdgeModel> ei = graph.edgeIterator(); 125 for (; ei.hasNext();) { 126 EdgeModel e = ei.next(); 127 Point2D d1 = vertexPlaces.get(e.target); 128 Point2D d2 = vertexPlaces.get(e.source); 129 Vector<Point2D> bendPoints = new Vector<Point2D>(); 130 bendPoints.add(new Point2D.Double(d1.getX(), d1.getY() - 15)); 131 bendPoints.add(new Point2D.Double(d2.getX(), d2.getY() + 15)); 132 edgeBendPoints.put(e, bendPoints); 133 } 134 } 135 136 public void locateAllVertices(Vector<VertexModel> currentLevelVertices, int width, int currentLevelHeight) { 137 int currentLevelCount = currentLevelVertices.size(); 138 int i = 0; 139 140 Vector<VertexModel> nextLevel = findNextLevelChildren(currentLevelVertices); 141 int nextLevelCount = nextLevel.size(); 142 int horizontalDist = width / (currentLevelCount + nextLevelCount); 143 144 145 for (VertexModel v : currentLevelVertices) { 146 if (nextLevelCount != 0) { 147 Point2D.Double newPoint = new Point2D.Double(horizontalDist * (i + 1) + width / (nextLevelCount + currentLevelCount), currentLevelHeight); 148 vertexPlaces.put(v, newPoint); 149 i += g.getInDegree(v); 150 } else { 151 Point2D.Double newPoint = new Point2D.Double(horizontalDist * (i) + width / (currentLevelCount), currentLevelHeight); 152 vertexPlaces.put(v, newPoint); 153 i++; 154 } 155 } 156 157 if (!nextLevel.isEmpty()) { 158 visitedVertices.addAll(nextLevel); 159 locateAllVertices(nextLevel, width, currentLevelHeight + 30); 160 } else { 161 return; 162 } 163 } 164 }