Source for org.jfree.data.xy.XYBarDataset

   1: /* ===========================================================
   2:  * JFreeChart : a free chart library for the Java(tm) platform
   3:  * ===========================================================
   4:  *
   5:  * (C) Copyright 2000-2007, by Object Refinery Limited and Contributors.
   6:  *
   7:  * Project Info:  http://www.jfree.org/jfreechart/index.html
   8:  *
   9:  * This library is free software; you can redistribute it and/or modify it 
  10:  * under the terms of the GNU Lesser General Public License as published by 
  11:  * the Free Software Foundation; either version 2.1 of the License, or 
  12:  * (at your option) any later version.
  13:  *
  14:  * This library is distributed in the hope that it will be useful, but 
  15:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
  16:  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
  17:  * License for more details.
  18:  *
  19:  * You should have received a copy of the GNU Lesser General Public
  20:  * License along with this library; if not, write to the Free Software
  21:  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
  22:  * USA.  
  23:  *
  24:  * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
  25:  * in the United States and other countries.]
  26:  *
  27:  * -----------------
  28:  * XYBarDataset.java
  29:  * -----------------
  30:  * (C) Copyright 2004-2007, by Object Refinery Limited and Contributors.
  31:  *
  32:  * Original Author:  David Gilbert (for Object Refinery Limited);
  33:  * Contributor(s):   -;
  34:  *
  35:  * Changes
  36:  * -------
  37:  * 02-Mar-2004 : Version 1 (DG);
  38:  * 05-May-2004 : Now extends AbstractIntervalXYDataset (DG);
  39:  * 15-Jul-2004 : Switched getX() with getXValue() and getY() with 
  40:  *               getYValue() (DG);
  41:  * ------------- JFREECHART 1.0.x ---------------------------------------------
  42:  * 25-Jan-2007 : Added some accessor methods, plus new equals() and clone()
  43:  *               overrides (DG);
  44:  * 30-Jan-2007 : Added method overrides to prevent unnecessary object 
  45:  *               creation (DG);
  46:  *
  47:  */
  48: 
  49: package org.jfree.data.xy;
  50: 
  51: import org.jfree.data.general.DatasetChangeEvent;
  52: import org.jfree.data.general.DatasetChangeListener;
  53: import org.jfree.util.PublicCloneable;
  54: 
  55: /**
  56:  * A dataset wrapper class that converts a standard {@link XYDataset} into an
  57:  * {@link IntervalXYDataset} suitable for use in creating XY bar charts.
  58:  */
  59: public class XYBarDataset extends AbstractIntervalXYDataset
  60:                           implements IntervalXYDataset, DatasetChangeListener {
  61:     
  62:     /** The underlying dataset. */
  63:     private XYDataset underlying;
  64:     
  65:     /** The bar width. */
  66:     private double barWidth;
  67:     
  68:     /**
  69:      * Creates a new dataset.
  70:      * 
  71:      * @param underlying  the underlying dataset (<code>null</code> not 
  72:      *     permitted).
  73:      * @param barWidth  the width of the bars.
  74:      */
  75:     public XYBarDataset(XYDataset underlying, double barWidth) {
  76:         this.underlying = underlying;   
  77:         this.underlying.addChangeListener(this);
  78:         this.barWidth = barWidth;
  79:     }
  80:     
  81:     /**
  82:      * Returns the underlying dataset that was specified via the constructor.
  83:      * 
  84:      * @return The underlying dataset (never <code>null</code>).
  85:      * 
  86:      * @since 1.0.4
  87:      */
  88:     public XYDataset getUnderlyingDataset() {
  89:         return this.underlying;
  90:     }
  91: 
  92:     /**
  93:      * Returns the bar width.
  94:      * 
  95:      * @return The bar width.
  96:      * 
  97:      * @see #setBarWidth(double)
  98:      * @since 1.0.4
  99:      */
 100:     public double getBarWidth() {
 101:         return this.barWidth;
 102:     }
 103:     
 104:     /**
 105:      * Sets the bar width and sends a {@link DatasetChangeEvent} to all 
 106:      * registered listeners.
 107:      * 
 108:      * @param barWidth  the bar width.
 109:      * 
 110:      * @see #getBarWidth()
 111:      * @since 1.0.4
 112:      */
 113:     public void setBarWidth(double barWidth) {
 114:         this.barWidth = barWidth;
 115:         notifyListeners(new DatasetChangeEvent(this, this));
 116:     }
 117:     
 118:     /**
 119:      * Returns the number of series in the dataset.
 120:      *
 121:      * @return The series count.
 122:      */
 123:     public int getSeriesCount() {
 124:         return this.underlying.getSeriesCount();   
 125:     }
 126: 
 127:     /**
 128:      * Returns the key for a series.
 129:      *
 130:      * @param series  the series index (in the range <code>0</code> to 
 131:      *     <code>getSeriesCount() - 1</code>).
 132:      *
 133:      * @return The series key.
 134:      */
 135:     public Comparable getSeriesKey(int series) {
 136:         return this.underlying.getSeriesKey(series);   
 137:     }
 138:     
 139:     /**
 140:      * Returns the number of items in a series.
 141:      *
 142:      * @param series  the series index (zero-based).
 143:      *
 144:      * @return The item count.
 145:      */
 146:     public int getItemCount(int series) {
 147:         return this.underlying.getItemCount(series);   
 148:     }
 149: 
 150:     /**
 151:      * Returns the x-value for an item within a series. 
 152:      *
 153:      * @param series  the series index (zero-based).
 154:      * @param item  the item index (zero-based).
 155:      *
 156:      * @return The x-value.
 157:      * 
 158:      * @see #getXValue(int, int)
 159:      */
 160:     public Number getX(int series, int item) {
 161:         return this.underlying.getX(series, item);   
 162:     }
 163: 
 164:     /**
 165:      * Returns the x-value (as a double primitive) for an item within a series.
 166:      * 
 167:      * @param series  the series index (zero-based).
 168:      * @param item  the item index (zero-based).
 169:      * 
 170:      * @return The value.
 171:      * 
 172:      * @see #getX(int, int)
 173:      */
 174:     public double getXValue(int series, int item) {
 175:         return this.underlying.getXValue(series, item);   
 176:     }
 177: 
 178:     /**
 179:      * Returns the y-value for an item within a series.
 180:      *
 181:      * @param series  the series index (zero-based).
 182:      * @param item  the item index (zero-based).
 183:      *
 184:      * @return The y-value (possibly <code>null</code>).
 185:      * 
 186:      * @see #getYValue(int, int)
 187:      */
 188:     public Number getY(int series, int item) {
 189:         return this.underlying.getY(series, item);   
 190:     }
 191: 
 192:     /**
 193:      * Returns the y-value (as a double primitive) for an item within a series.
 194:      * 
 195:      * @param series  the series index (zero-based).
 196:      * @param item  the item index (zero-based).
 197:      * 
 198:      * @return The value.
 199:      * 
 200:      * @see #getY(int, int)
 201:      */
 202:     public double getYValue(int series, int item) {
 203:         return this.underlying.getYValue(series, item);  
 204:     }
 205:     
 206:     /**
 207:      * Returns the starting X value for the specified series and item.
 208:      *
 209:      * @param series  the series index (zero-based).
 210:      * @param item  the item index (zero-based).
 211:      *
 212:      * @return The value.
 213:      */
 214:     public Number getStartX(int series, int item) {
 215:         Number result = null;
 216:         Number xnum = this.underlying.getX(series, item);
 217:         if (xnum != null) {
 218:              result = new Double(xnum.doubleValue() - this.barWidth / 2.0);   
 219:         }
 220:         return result;   
 221:     }
 222: 
 223:     /**
 224:      * Returns the starting x-value (as a double primitive) for an item within 
 225:      * a series.
 226:      * 
 227:      * @param series  the series index (zero-based).
 228:      * @param item  the item index (zero-based).
 229:      * 
 230:      * @return The value.
 231:      * 
 232:      * @see #getXValue(int, int)
 233:      */
 234:     public double getStartXValue(int series, int item) {
 235:         return getXValue(series, item) - this.barWidth / 2.0;   
 236:     }
 237: 
 238:     /**
 239:      * Returns the ending X value for the specified series and item.
 240:      *
 241:      * @param series  the series index (zero-based).
 242:      * @param item  the item index (zero-based).
 243:      *
 244:      * @return The value.
 245:      */
 246:     public Number getEndX(int series, int item) {
 247:         Number result = null;
 248:         Number xnum = this.underlying.getX(series, item);
 249:         if (xnum != null) {
 250:              result = new Double(xnum.doubleValue() + this.barWidth / 2.0);   
 251:         }
 252:         return result;   
 253:     }
 254: 
 255:     /**
 256:      * Returns the ending x-value (as a double primitive) for an item within 
 257:      * a series.
 258:      * 
 259:      * @param series  the series index (zero-based).
 260:      * @param item  the item index (zero-based).
 261:      * 
 262:      * @return The value.
 263:      * 
 264:      * @see #getXValue(int, int)
 265:      */
 266:     public double getEndXValue(int series, int item) {
 267:         return getXValue(series, item) + this.barWidth / 2.0;   
 268:     }
 269: 
 270:     /**
 271:      * Returns the starting Y value for the specified series and item.
 272:      *
 273:      * @param series  the series index (zero-based).
 274:      * @param item  the item index (zero-based).
 275:      *
 276:      * @return The value.
 277:      */
 278:     public Number getStartY(int series, int item) {
 279:         return this.underlying.getY(series, item);   
 280:     }
 281:     
 282:     /**
 283:      * Returns the starting y-value (as a double primitive) for an item within 
 284:      * a series.  
 285:      * 
 286:      * @param series  the series index (zero-based).
 287:      * @param item  the item index (zero-based).
 288:      * 
 289:      * @return The value.
 290:      * 
 291:      * @see #getYValue(int, int)
 292:      */
 293:     public double getStartYValue(int series, int item) {
 294:         return getYValue(series, item);   
 295:     }
 296: 
 297:     /**
 298:      * Returns the ending Y value for the specified series and item.
 299:      *
 300:      * @param series  the series index (zero-based).
 301:      * @param item  the item index (zero-based).
 302:      *
 303:      * @return The value.
 304:      */
 305:     public Number getEndY(int series, int item) {
 306:         return this.underlying.getY(series, item);   
 307:     }
 308: 
 309:     /**
 310:      * Returns the ending y-value (as a double primitive) for an item within 
 311:      * a series.  
 312:      * 
 313:      * @param series  the series index (zero-based).
 314:      * @param item  the item index (zero-based).
 315:      * 
 316:      * @return The value.
 317:      * 
 318:      * @see #getYValue(int, int)
 319:      */
 320:     public double getEndYValue(int series, int item) {
 321:         return getYValue(series, item);   
 322:     }
 323: 
 324:     /**
 325:      * Receives notification of an dataset change event.
 326:      *
 327:      * @param event  information about the event.
 328:      */
 329:     public void datasetChanged(DatasetChangeEvent event) {
 330:         this.notifyListeners(event);
 331:     }
 332:     
 333:     /**
 334:      * Tests this dataset for equality with an arbitrary object.
 335:      * 
 336:      * @param obj  the object (<code>null</code> permitted).
 337:      * 
 338:      * @return A boolean.
 339:      */
 340:     public boolean equals(Object obj) {
 341:         if (obj == this) {
 342:             return true;
 343:         }
 344:         if (!(obj instanceof XYBarDataset)) {
 345:             return false;
 346:         }
 347:         XYBarDataset that = (XYBarDataset) obj;
 348:         if (!this.underlying.equals(that.underlying)) {
 349:             return false;
 350:         }
 351:         if (this.barWidth != that.barWidth) {
 352:             return false;
 353:         }
 354:         return true;
 355:     }
 356:     
 357:     /**
 358:      * Returns an independent copy of the dataset.  Note that:
 359:      * <ul>
 360:      * <li>the underlying dataset is only cloned if it implements the 
 361:      * {@link PublicCloneable} interface;</li>
 362:      * <li>the listeners registered with this dataset are not carried over to
 363:      * the cloned dataset.</li>
 364:      * </ul>
 365:      * 
 366:      * @return An independent copy of the dataset.
 367:      * 
 368:      * @throws CloneNotSupportedException if the dataset cannot be cloned for 
 369:      *         any reason.
 370:      */
 371:     public Object clone() throws CloneNotSupportedException {
 372:         XYBarDataset clone = (XYBarDataset) super.clone();
 373:         if (this.underlying instanceof PublicCloneable) {
 374:             clone.underlying 
 375:                     = (XYDataset) ((PublicCloneable) this.underlying).clone();
 376:         }
 377:         return clone;
 378:     }
 379: 
 380: }