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