1 52 53 package org.jfree.data.xy; 54 55 import java.io.Serializable ; 56 57 import org.jfree.data.DomainInfo; 58 import org.jfree.data.Range; 59 import org.jfree.data.RangeInfo; 60 import org.jfree.data.general.DatasetChangeEvent; 61 import org.jfree.data.general.DatasetChangeListener; 62 import org.jfree.data.general.DatasetUtilities; 63 import org.jfree.util.PublicCloneable; 64 65 84 public class IntervalXYDelegate implements DatasetChangeListener, 85 DomainInfo, Serializable , 86 Cloneable , PublicCloneable { 87 88 89 private static final long serialVersionUID = -685166711639592857L; 90 91 94 private XYDataset dataset; 95 96 99 private boolean autoWidth; 100 101 105 private double intervalPositionFactor; 106 107 110 private double fixedIntervalWidth; 111 112 115 private double autoIntervalWidth; 116 117 122 public IntervalXYDelegate(XYDataset dataset) { 123 this(dataset, true); 124 } 125 126 133 public IntervalXYDelegate(XYDataset dataset, boolean autoWidth) { 134 if (dataset == null) { 135 throw new IllegalArgumentException ("Null 'dataset' argument."); 136 } 137 this.dataset = dataset; 138 this.autoWidth = autoWidth; 139 this.intervalPositionFactor = 0.5; 140 this.autoIntervalWidth = Double.POSITIVE_INFINITY; 141 this.fixedIntervalWidth = 1.0; 142 } 143 144 150 public boolean isAutoWidth() { 151 return this.autoWidth; 152 } 153 154 165 public void setAutoWidth(boolean b) { 166 this.autoWidth = b; 167 if (b) { 168 this.autoIntervalWidth = recalculateInterval(); 169 } 170 } 171 172 177 public double getIntervalPositionFactor() { 178 return this.intervalPositionFactor; 179 } 180 181 197 public void setIntervalPositionFactor(double d) { 198 if (d < 0.0 || 1.0 < d) { 199 throw new IllegalArgumentException ( 200 "Argument 'd' outside valid range."); 201 } 202 this.intervalPositionFactor = d; 203 } 204 205 210 public double getFixedIntervalWidth() { 211 return this.fixedIntervalWidth; 212 } 213 214 225 public void setFixedIntervalWidth(double w) { 226 if (w < 0.0) { 227 throw new IllegalArgumentException ("Negative 'w' argument."); 228 } 229 this.fixedIntervalWidth = w; 230 this.autoWidth = false; 231 } 232 233 240 public double getIntervalWidth() { 241 if (isAutoWidth() && !Double.isInfinite(this.autoIntervalWidth)) { 242 return this.autoIntervalWidth; 245 } 246 else { 247 return this.fixedIntervalWidth; 249 } 250 } 251 252 262 public Number getStartX(int series, int item) { 263 Number startX = null; 264 Number x = this.dataset.getX(series, item); 265 if (x != null) { 266 startX = new Double (x.doubleValue() 267 - (getIntervalPositionFactor() * getIntervalWidth())); 268 } 269 return startX; 270 } 271 272 282 public double getStartXValue(int series, int item) { 283 return dataset.getXValue(series, item) - getIntervalPositionFactor() 284 * getIntervalWidth(); 285 } 286 287 297 public Number getEndX(int series, int item) { 298 Number endX = null; 299 Number x = this.dataset.getX(series, item); 300 if (x != null) { 301 endX = new Double (x.doubleValue() 302 + ((1.0 - getIntervalPositionFactor()) * getIntervalWidth())); 303 } 304 return endX; 305 } 306 307 317 public double getEndXValue(int series, int item) { 318 return dataset.getXValue(series, item) 319 + (1.0 - getIntervalPositionFactor()) * getIntervalWidth(); 320 } 321 322 330 public double getDomainLowerBound(boolean includeInterval) { 331 double result = Double.NaN; 332 Range r = getDomainBounds(includeInterval); 333 if (r != null) { 334 result = r.getLowerBound(); 335 } 336 return result; 337 } 338 339 347 public double getDomainUpperBound(boolean includeInterval) { 348 double result = Double.NaN; 349 Range r = getDomainBounds(includeInterval); 350 if (r != null) { 351 result = r.getUpperBound(); 352 } 353 return result; 354 } 355 356 365 public Range getDomainBounds(boolean includeInterval) { 366 Range range = DatasetUtilities.findDomainBounds(this.dataset, false); 369 if (includeInterval && range != null) { 370 double lowerAdj = getIntervalWidth() * getIntervalPositionFactor(); 371 double upperAdj = getIntervalWidth() - lowerAdj; 372 range = new Range(range.getLowerBound() - lowerAdj, 373 range.getUpperBound() + upperAdj); 374 } 375 return range; 376 } 377 378 384 public void datasetChanged(DatasetChangeEvent e) { 385 if (this.autoWidth) { 389 this.autoIntervalWidth = recalculateInterval(); 390 } 391 } 392 393 396 private double recalculateInterval() { 397 double result = Double.POSITIVE_INFINITY; 398 int seriesCount = this.dataset.getSeriesCount(); 399 for (int series = 0; series < seriesCount; series++) { 400 result = Math.min(result, calculateIntervalForSeries(series)); 401 } 402 return result; 403 } 404 405 410 private double calculateIntervalForSeries(int series) { 411 double result = Double.POSITIVE_INFINITY; 412 int itemCount = this.dataset.getItemCount(series); 413 if (itemCount > 1) { 414 double prev = this.dataset.getXValue(series, 0); 415 for (int item = 1; item < itemCount; item++) { 416 double x = this.dataset.getXValue(series, item); 417 result = Math.min(result, x - prev); 418 prev = x; 419 } 420 } 421 return result; 422 } 423 424 431 public boolean equals(Object obj) { 432 if (obj == this) { 433 return true; 434 } 435 if (!(obj instanceof IntervalXYDelegate)) { 436 return false; 437 } 438 IntervalXYDelegate that = (IntervalXYDelegate) obj; 439 if (this.autoWidth != that.autoWidth) { 440 return false; 441 } 442 if (this.intervalPositionFactor != that.intervalPositionFactor) { 443 return false; 444 } 445 if (this.fixedIntervalWidth != that.fixedIntervalWidth) { 446 return false; 447 } 448 return true; 449 } 450 451 456 public Object clone() throws CloneNotSupportedException { 457 return super.clone(); 458 } 459 460 } 461 | Popular Tags |