1 package prefuse.action.assignment; 2 3 import java.util.HashMap ; 4 import java.util.Map ; 5 import java.util.logging.Logger ; 6 7 import prefuse.Constants; 8 import prefuse.data.tuple.TupleSet; 9 import prefuse.util.ColorLib; 10 import prefuse.util.ColorMap; 11 import prefuse.util.DataLib; 12 import prefuse.util.MathLib; 13 import prefuse.visual.VisualItem; 14 15 46 public class DataColorAction extends ColorAction { 47 48 private String m_dataField; 49 private int m_type; 50 private int m_scale = Constants.LINEAR_SCALE; 51 private int m_tempScale; 52 53 private double[] m_dist; 54 private int m_bins = Constants.CONTINUOUS; 55 private Map m_omap; 56 private Object [] m_olist; 57 private ColorMap m_cmap = new ColorMap(null,0,1); 58 private int[] m_palette; 59 60 61 71 public DataColorAction(String group, String dataField, 72 int dataType, String colorField) 73 { 74 super(group, colorField); 75 setDataType(dataType); 76 setDataField(dataField); 77 } 78 79 91 public DataColorAction(String group, String dataField, 92 int dataType, String colorField, int[] palette) 93 { 94 super(group, colorField); 95 setDataType(dataType); 96 setDataField(dataField); 97 m_palette = palette; 98 } 99 100 102 106 public String getDataField() { 107 return m_dataField; 108 } 109 110 114 public void setDataField(String field) { 115 m_dataField = field; 116 } 117 118 124 public int getDataType() { 125 return m_type; 126 } 127 128 134 public void setDataType(int type) { 135 if ( type < 0 || type >= Constants.DATATYPE_COUNT ) 136 throw new IllegalArgumentException ( 137 "Unrecognized data type: "+type); 138 m_type = type; 139 } 140 141 151 public int getScale() { 152 return m_scale; 153 } 154 155 168 public void setScale(int scale) { 169 if ( scale < 0 || scale >= Constants.SCALE_COUNT ) 170 throw new IllegalArgumentException ( 171 "Unrecognized scale value: "+scale); 172 m_scale = scale; 173 } 174 175 180 public int getBinCount() { 181 return m_bins; 182 } 183 184 193 public void setBinCount(int count) { 194 if ( m_scale == Constants.QUANTILE_SCALE && count <= 0 ) { 195 throw new IllegalArgumentException ( 196 "The quantile scale can not be used without binning. " + 197 "Use a bin value greater than zero."); 198 } 199 m_bins = count; 200 } 201 202 208 public void setDefaultColor(int color) { 209 throw new UnsupportedOperationException (); 210 } 211 212 224 public void setOrdinalMap(Object [] values) { 225 m_olist = values; 226 m_omap = new HashMap (); 227 for ( int i=0; i<values.length; ++i ) { 228 m_omap.put(values[i], new Integer (i)); 229 } 230 } 231 232 234 238 protected void setup() { 239 int size = 64; 240 241 int[] palette = m_palette; 242 243 m_tempScale = m_scale; 245 if ( m_scale == Constants.QUANTILE_SCALE && m_bins <= 0 ) { 246 Logger.getLogger(getClass().getName()).warning( 247 "Can't use quantile scale with no binning. " + 248 "Defaulting to linear scale. Set the bin value " + 249 "greater than zero to use a quantile scale."); 250 m_scale = Constants.LINEAR_SCALE; 251 } 252 253 switch ( m_type ) { 255 case Constants.NOMINAL: 256 case Constants.ORDINAL: 257 m_dist = getDistribution(); 258 size = m_omap.size(); 259 palette = (m_palette!=null ? m_palette : createPalette(size)); 260 m_cmap.setColorPalette(palette); 261 m_cmap.setMinValue(m_dist[0]); 262 m_cmap.setMaxValue(m_dist[1]); 263 return; 264 case Constants.NUMERICAL: 265 m_dist = getDistribution(); 266 size = m_bins > 0 ? m_bins : size; 267 palette = (m_palette!=null ? m_palette : createPalette(size)); 268 m_cmap.setColorPalette(palette); 269 m_cmap.setMinValue(0.0); 270 m_cmap.setMaxValue(1.0); 271 return; 272 } 273 } 274 275 protected void finish() { 276 m_scale = m_tempScale; 278 } 279 280 284 protected double[] getDistribution() { 285 TupleSet ts = m_vis.getGroup(m_group); 286 287 if ( m_type == Constants.NUMERICAL ) { 288 m_omap = null; 289 if ( m_scale == Constants.QUANTILE_SCALE && m_bins > 0 ) { 290 double[] values = 291 DataLib.toDoubleArray(ts.tuples(), m_dataField); 292 return MathLib.quantiles(m_bins, values); 293 } else { 294 double[] dist = new double[2]; 295 dist[0] = DataLib.min(ts, m_dataField).getDouble(m_dataField); 296 dist[1] = DataLib.max(ts, m_dataField).getDouble(m_dataField); 297 return dist; 298 } 299 } else { 300 if ( m_olist == null ) 301 m_omap = DataLib.ordinalMap(ts, m_dataField); 302 return new double[] { 0, m_omap.size()-1 }; 303 } 304 } 305 306 309 protected int[] createPalette(int size) { 310 switch ( m_type ) { 311 case Constants.NOMINAL: 312 return ColorLib.getCategoryPalette(size); 313 case Constants.NUMERICAL: 314 case Constants.ORDINAL: 315 default: 316 return ColorLib.getGrayscalePalette(size); 317 } 318 } 319 320 323 public int getColor(VisualItem item) { 324 Object o = lookup(item); 326 if ( o != null ) { 327 if ( o instanceof ColorAction ) { 328 return ((ColorAction)o).getColor(item); 329 } else if ( o instanceof Integer ) { 330 return ((Integer )o).intValue(); 331 } else { 332 Logger.getLogger(this.getClass().getName()) 333 .warning("Unrecognized Object from predicate chain."); 334 } 335 } 336 337 switch ( m_type ) { 339 case Constants.NUMERICAL: 340 double v = item.getDouble(m_dataField); 341 double f = MathLib.interp(m_scale, v, m_dist); 342 return m_cmap.getColor(f); 343 default: 344 Integer idx = (Integer )m_omap.get(item.get(m_dataField)); 345 return m_cmap.getColor(idx.doubleValue()); 346 } 347 } 348 349 } | Popular Tags |