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.graph.graph; 005 006 import graphlab.graph.atributeset.EdgeAttrSet; 007 import graphlab.graph.event.EdgeModelListener; 008 import graphlab.graph.old.Arrow; 009 import graphlab.graph.old.ArrowHandler; 010 import graphlab.graph.old.GStroke; 011 import graphlab.library.BaseEdge; 012 import graphlab.library.BaseEdgeProperties; 013 import graphlab.platform.attribute.AttributeSet; 014 015 import java.awt.geom.Line2D; 016 import java.util.HashMap; 017 import java.util.Map; 018 019 /** 020 * User: azin azadi,roozbeh ebrahimi 021 */ 022 public class EdgeModel extends BaseEdge<VertexModel> { 023 024 public EdgeModelListener view; 025 private boolean isSelected = false; 026 private boolean showWeight = true; 027 private GStroke stroke; 028 029 private Arrow arrow = ArrowHandler.defaultArrow; 030 031 /** 032 * the location of the lable relative to the center of the edge 033 */ 034 private GraphPoint labelLocation = new GraphPoint(0, 0); 035 036 /** 037 * it's a straight line between source and target vertices 038 */ 039 public Line2D.Double line = new Line2D.Double(); 040 041 public GraphPoint curveControlPoint = new GraphPoint(0, 0); 042 043 /** 044 * the text that is showing as the label of the edge on screen 045 */ 046 String text = ""; 047 048 /** 049 * This is a place to put custom attributes in the vertex, It will be shown in property editor and editable 050 */ 051 private HashMap<String, Object> userDefinedAttributes = null; 052 053 /** 054 * these attributed will be added to each vertice's userDefinedAttributes on constructing time. 055 */ 056 private static HashMap<String, Object> globalUserDefinedAttributes = null; 057 058 059 /** 060 * sets and stores a user defined attribute for the vertex. here you can put any attribute you like that are not available 061 * in the standard attributes. your attributes will be editable in property editor part of GUI. 062 * Use this method carefully. user defined attributes are stored in HashMap and bad use of them will cause memory leak in large graphs 063 * 064 * @param name 065 * @param value 066 */ 067 public void setUserDefinedAttribute(String name, Object value) { 068 if (userDefinedAttributes == null) { 069 userDefinedAttributes = new HashMap<String, Object>(); 070 } 071 userDefinedAttributes.put(name, value); 072 } 073 074 /** 075 * returns the specified user defined attribute, or null if it does not exists. 076 * 077 * @param name 078 * @return 079 */ 080 public <t> t getUserDefinedAttribute(String name) { 081 if (userDefinedAttributes == null) 082 return null; 083 return (t) userDefinedAttributes.get(name); 084 } 085 086 /** 087 * removes the given attribute from the list of user defined attributes 088 * 089 * @param name 090 */ 091 public void removeUserDefinedAttribute(String name) { 092 userDefinedAttributes.remove(name); 093 if (userDefinedAttributes.size() == 0) 094 userDefinedAttributes = null; 095 } 096 097 /** 098 * @return a HashMap containing all user defined attributes. 099 */ 100 public HashMap<String, Object> getUserDefinedAttributes() { 101 return userDefinedAttributes; 102 } 103 104 105 /** 106 * sets and stores a global user defined attribute for the vertex. this attributes will be added to each vertex on 107 * constructing time using setUserDefinedAttribute method. 108 * <p/> 109 * note that this method only affects the afterward created vertices, and current vertices will not affected by this method. 110 */ 111 public static void addGlobalUserDefinedAttribute(String name, Object defaultvalue) { 112 if (globalUserDefinedAttributes == null) { 113 globalUserDefinedAttributes = new HashMap<String, Object>(); 114 } 115 globalUserDefinedAttributes.put(name, defaultvalue); 116 } 117 118 /** 119 * @see VertexModel#addGlobalUserDefinedAttribute 120 */ 121 public static void removeGlobalUserDefinedAttribute(String name) { 122 globalUserDefinedAttributes.remove(name); 123 if (globalUserDefinedAttributes.size() == 0) 124 globalUserDefinedAttributes = null; 125 } 126 127 { 128 //default constructor 129 if (globalUserDefinedAttributes != null) { 130 userDefinedAttributes = new HashMap<String, Object>(); 131 userDefinedAttributes.putAll(globalUserDefinedAttributes); 132 } 133 } 134 135 /** 136 * This is the copy constructor method for the Edge Model 137 * 138 * @param vm1 139 * @param vm2 140 * @return 141 */ 142 public EdgeModel getCopy(VertexModel vm1, VertexModel vm2) { 143 return new EdgeModel(this, vm1, vm2); 144 } 145 146 /** 147 * copy constructor 148 * creates a copy (clone) of edge, 149 * the source and target of edge will be source and target parameters 150 * other properties of edge will be copied from edge parameter 151 * 152 * @param edge 153 */ 154 public EdgeModel(EdgeModel edge, VertexModel source, VertexModel target) { 155 super(source, target); 156 //copies all attributes from second edge to first edge 157 AttributeSet a = new EdgeAttrSet(edge); 158 AttributeSet b = new EdgeAttrSet(this); 159 Map<String, Object> map = a.getAttrs(); 160 for (String name : map.keySet()) { 161 b.put(name, map.get(name)); 162 } 163 updateText(); 164 showWeight = GraphModel.showEdgeWeights; 165 stroke = FastRenderer.defaultStroke; 166 } 167 168 public EdgeModel(VertexModel v1, VertexModel v2) { 169 super(v1, v2); 170 showWeight = GraphModel.showEdgeWeights; 171 stroke = FastRenderer.defaultStroke; 172 } 173 174 GStroke last; 175 176 public void setMark(boolean m) { 177 super.setMark(m); 178 repaintView(); 179 } 180 181 private void repaintView() { 182 if (view != null) { 183 view.repaint(this); 184 } 185 } 186 187 public void setStroke(GStroke stroke) { 188 this.stroke = stroke; 189 repaintView(); 190 } 191 192 public GStroke getStroke() { 193 return stroke; 194 } 195 196 public void setWeight(int weight) { 197 super.setWeight(weight); 198 updateText(); 199 repaintView(); 200 } 201 202 public void setProp(BaseEdgeProperties prop) { 203 super.setProp(prop); 204 repaintView(); 205 } 206 207 public void setColor(int color) { 208 super.setColor(color); 209 repaintView(); 210 } 211 212 public Arrow getArrow() { 213 return arrow; 214 } 215 216 public void setArrow(Arrow a) { 217 this.arrow = a; 218 repaintView(); 219 } 220 221 public void setEdgeModelListener(EdgeModelListener listener) { 222 this.view = listener; 223 } 224 225 /** 226 * Returns the getAngle, in radians, of the edge from the positive 227 * x-axis, where the source vertex marks the origin of the edge. The 228 * getAngle will be in the range of 0 to 2<em>pi</em> and will increase 229 * counter-clockwise around the origin. 230 * (this method taked from GraphMaker Project) 231 * 232 * @return getAngle in radians from positive x-axis. 233 */ 234 public double getAngle() { 235 // Subtract y coordinates in reverse order from normal 236 // as the screen coordinate system is flipped along the 237 // x-axis from the Cartesian coordinate system. 238 GraphPoint sourceLoc = source.getLocation(); 239 GraphPoint targetLoc = target.getLocation(); 240 double angle = Math.atan2(sourceLoc.y + source.getCenter().y - targetLoc.y - target.getCenter().y, 241 sourceLoc.x + source.getCenter().x - targetLoc.x - target.getCenter().x); 242 if (angle < 0) { 243 // atan2 returns getAngle in phase -pi to pi, which means 244 // we have to convert the answer into 0 to 2pi range. 245 angle += 2 * Math.PI; 246 } 247 return angle; 248 } // getAngle 249 250 public String toString() { 251 return source + "->" + target; 252 } 253 254 public boolean isSelected() { 255 return isSelected; 256 } 257 258 public void setSelected(boolean selected) { 259 isSelected = selected; 260 repaintView(); 261 } 262 263 public String getId() { 264 //todo: omid: BaseEdge doesn't have id! 265 return source.getId() + "" + target.getId(); 266 } 267 268 269 //--------------- + Curved Edge -------------------- 270 /** 271 * @return return the curve control point of this edge, relative to the center of the edge 272 * the abstract position can be give by: (src.x + trg.x) / 2 + ctrlPnt.x , also for y 273 */ 274 public GraphPoint getCurveControlPoint() { 275 if (curveControlPoint == null) { 276 curveControlPoint = new GraphPoint(0, 0); 277 } 278 return curveControlPoint; 279 } 280 281 public void setCurveControlPoint(GraphPoint controlPoint) { 282 this.curveControlPoint = controlPoint; 283 repaintView(); 284 } 285 //--------------- - Curved Edge -------------------- 286 287 //-------------- +text operation --------------- 288 String label; 289 290 public void setLabel(String label) { 291 this.label = label; 292 updateText(); 293 } 294 295 public String getLabel() { 296 return label; 297 } 298 299 private void updateText() { 300 String _label; 301 if (!isShowWeight()) 302 _label = label; 303 else if (isShowWeight()) 304 _label = String.valueOf(super.getWeight()); 305 else 306 _label = label + "," + String.valueOf(super.getWeight()); 307 this.text = _label; 308 repaintView(); 309 } 310 //-------------- -text operation --------------- 311 312 313 public boolean isShowWeight() { 314 return showWeight; 315 } 316 317 public void setShowWeight(boolean showWeight) { 318 this.showWeight = showWeight; 319 updateText(); 320 repaintView(); 321 } 322 323 public void updateBounds() { 324 repaintView(); 325 } 326 327 public void setLabelLocation(GraphPoint graphPoint) { 328 this.labelLocation = graphPoint; 329 repaintView(); 330 } 331 332 public GraphPoint getLabelLocation() { 333 return labelLocation; 334 } 335 336 }