1 package prefuse.action.layout; 2 3 import java.awt.geom.Rectangle2D ; 4 import java.util.Iterator ; 5 6 import prefuse.Constants; 7 import prefuse.data.Table; 8 import prefuse.data.Tuple; 9 import prefuse.data.expression.Predicate; 10 import prefuse.data.query.NumberRangeModel; 11 import prefuse.data.query.ObjectRangeModel; 12 import prefuse.data.tuple.TupleSet; 13 import prefuse.util.DataLib; 14 import prefuse.util.MathLib; 15 import prefuse.util.ui.ValuedRangeModel; 16 import prefuse.visual.VisualItem; 17 18 29 public class AxisLayout extends Layout { 30 31 private String m_field; 32 private int m_scale = Constants.LINEAR_SCALE; 33 private int m_axis = Constants.X_AXIS; 34 private int m_type = Constants.UNKNOWN; 35 36 private boolean m_modelSet = false; 39 private ValuedRangeModel m_model = null; 40 private Predicate m_filter = null; 41 42 private double m_min; 44 private double m_range; 45 46 private double[] m_dist = new double[2]; 48 49 54 public AxisLayout(String group, String field) { 55 super(group); 56 m_field = field; 57 } 58 59 66 public AxisLayout(String group, String field, int axis) { 67 this(group, field); 68 setAxis(axis); 69 } 70 71 80 public AxisLayout(String group, String field, int axis, Predicate filter) { 81 this(group, field, axis); 82 setFilter(filter); 83 } 84 85 87 96 public void setDataField(String field) { 97 m_field = field; 98 if ( !m_modelSet ) 99 m_model = null; 100 } 101 102 107 public String getDataField() { 108 return m_field; 109 } 110 111 118 public void setRangeModel(ValuedRangeModel model) { 119 m_model = model; 120 m_modelSet = (model != null); 121 } 122 123 130 public ValuedRangeModel getRangeModel() { 131 return m_model; 132 } 133 134 141 public void setFilter(Predicate filter) { 142 m_filter = filter; 143 } 144 145 152 public Predicate getFilter() { 153 return m_filter; 154 } 155 156 158 167 public int getScale() { 168 return m_scale; 169 } 170 171 180 public void setScale(int scale) { 181 if ( scale < 0 || scale >= Constants.SCALE_COUNT ) 182 throw new IllegalArgumentException ( 183 "Unrecognized scale value: "+scale); 184 m_scale = scale; 185 } 186 187 192 public int getAxis() { 193 return m_axis; 194 } 195 196 201 public void setAxis(int axis) { 202 if ( axis < 0 || axis >= Constants.AXIS_COUNT ) 203 throw new IllegalArgumentException ( 204 "Unrecognized axis value: "+axis); 205 m_axis = axis; 206 } 207 208 215 public int getDataType() { 216 return m_type; 217 } 218 219 226 public void setDataType(int type) { 227 if ( type < 0 || type >= Constants.DATATYPE_COUNT ) 228 throw new IllegalArgumentException ( 229 "Unrecognized data type value: "+type); 230 m_type = type; 231 } 232 233 235 238 public void run(double frac) { 239 TupleSet ts = m_vis.getGroup(m_group); 240 setMinMax(); 241 242 switch ( getDataType(ts) ) { 243 case Constants.NUMERICAL: 244 numericalLayout(ts); 245 break; 246 default: 247 ordinalLayout(ts); 248 } 249 } 250 251 254 protected int getDataType(TupleSet ts) { 255 if ( m_type == Constants.UNKNOWN ) { 256 boolean numbers = true; 257 if ( ts instanceof Table ) { 258 numbers = ((Table)ts).canGetDouble(m_field); 259 } else { 260 for ( Iterator it = ts.tuples(); it.hasNext(); ) { 261 if ( !((Tuple)it.next()).canGetDouble(m_field) ) { 262 numbers = false; 263 break; 264 } 265 } 266 } 267 if ( numbers ) { 268 return Constants.NUMERICAL; 269 } else { 270 return Constants.ORDINAL; 271 } 272 } else { 273 return m_type; 274 } 275 } 276 277 280 private void setMinMax() { 281 Rectangle2D b = getLayoutBounds(); 282 if ( m_axis == Constants.X_AXIS ) { 283 m_min = b.getMinX(); 284 m_range = b.getMaxX() - m_min; 285 } else { 286 m_min = b.getMaxY(); 287 m_range = b.getMinY() - m_min; 288 } 289 } 290 291 294 protected void set(VisualItem item, double frac) { 295 double xOrY = m_min + frac*m_range; 296 if ( m_axis == Constants.X_AXIS ) { 297 setX(item, null, xOrY); 298 } else { 299 setY(item, null, xOrY); 300 } 301 } 302 303 306 protected void numericalLayout(TupleSet ts) { 307 if ( !m_modelSet ) { 308 m_dist[0] = DataLib.min(ts, m_field).getDouble(m_field); 309 m_dist[1] = DataLib.max(ts, m_field).getDouble(m_field); 310 311 double lo = m_dist[0], hi = m_dist[1]; 312 if ( m_model == null ) { 313 m_model = new NumberRangeModel(lo, hi, lo, hi); 314 } else { 315 ((NumberRangeModel)m_model).setValueRange(lo, hi, lo, hi); 316 } 317 } else { 318 m_dist[0] = ((Number )m_model.getLowValue()).doubleValue(); 319 m_dist[1] = ((Number )m_model.getHighValue()).doubleValue(); 320 } 321 322 Iterator iter = m_vis.items(m_group, m_filter); 323 while ( iter.hasNext() ) { 324 VisualItem item = (VisualItem)iter.next(); 325 double v = item.getDouble(m_field); 326 double f = MathLib.interp(m_scale, v, m_dist); 327 set(item, f); 328 } 329 } 330 331 334 protected void ordinalLayout(TupleSet ts) { 335 if ( !m_modelSet) { 336 Object [] array = DataLib.ordinalArray(ts, m_field); 337 338 if ( m_model == null ) { 339 m_model = new ObjectRangeModel(array); 340 } else { 341 ((ObjectRangeModel)m_model).setValueRange(array); 342 } 343 } 344 345 ObjectRangeModel model = (ObjectRangeModel)m_model; 346 int start = model.getValue(); 347 int end = start + model.getExtent(); 348 double total = (double)(end-start); 349 350 Iterator iter = m_vis.items(m_group, m_filter); 351 while ( iter.hasNext() ) { 352 VisualItem item = (VisualItem)iter.next(); 353 int order = model.getIndex(item.get(m_field)) - start; 354 set(item, order/total); 355 } 356 } 357 358 } | Popular Tags |