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