001: /* ===========================================================
002: * JFreeChart : a free chart library for the Java(tm) platform
003: * ===========================================================
004: *
005: * (C) Copyright 2000-2007, by Object Refinery Limited and Contributors.
006: *
007: * Project Info: http://www.jfree.org/jfreechart/index.html
008: *
009: * This library is free software; you can redistribute it and/or modify it
010: * under the terms of the GNU Lesser General Public License as published by
011: * the Free Software Foundation; either version 2.1 of the License, or
012: * (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful, but
015: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
016: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
017: * License for more details.
018: *
019: * You should have received a copy of the GNU Lesser General Public
020: * License along with this library; if not, write to the Free Software
021: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
022: * USA.
023: *
024: * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
025: * in the United States and other countries.]
026: *
027: * -----------------
028: * XYBarDataset.java
029: * -----------------
030: * (C) Copyright 2004-2007, by Object Refinery Limited and Contributors.
031: *
032: * Original Author: David Gilbert (for Object Refinery Limited);
033: * Contributor(s): -;
034: *
035: * $Id: XYBarDataset.java,v 1.4.2.4 2007/01/30 15:02:33 mungady Exp $
036: *
037: * Changes
038: * -------
039: * 02-Mar-2004 : Version 1 (DG);
040: * 05-May-2004 : Now extends AbstractIntervalXYDataset (DG);
041: * 15-Jul-2004 : Switched getX() with getXValue() and getY() with
042: * getYValue() (DG);
043: * ------------- JFREECHART 1.0.x ---------------------------------------------
044: * 25-Jan-2007 : Added some accessor methods, plus new equals() and clone()
045: * overrides (DG);
046: * 30-Jan-2007 : Added method overrides to prevent unnecessary object
047: * creation (DG);
048: *
049: */
050:
051: package org.jfree.data.xy;
052:
053: import org.jfree.data.general.DatasetChangeEvent;
054: import org.jfree.data.general.DatasetChangeListener;
055: import org.jfree.util.PublicCloneable;
056:
057: /**
058: * A dataset wrapper class that converts a standard {@link XYDataset} into an
059: * {@link IntervalXYDataset} suitable for use in creating XY bar charts.
060: */
061: public class XYBarDataset extends AbstractIntervalXYDataset implements
062: IntervalXYDataset, DatasetChangeListener {
063:
064: /** The underlying dataset. */
065: private XYDataset underlying;
066:
067: /** The bar width. */
068: private double barWidth;
069:
070: /**
071: * Creates a new dataset.
072: *
073: * @param underlying the underlying dataset (<code>null</code> not
074: * permitted).
075: * @param barWidth the width of the bars.
076: */
077: public XYBarDataset(XYDataset underlying, double barWidth) {
078: this .underlying = underlying;
079: this .underlying.addChangeListener(this );
080: this .barWidth = barWidth;
081: }
082:
083: /**
084: * Returns the underlying dataset that was specified via the constructor.
085: *
086: * @return The underlying dataset (never <code>null</code>).
087: *
088: * @since 1.0.4
089: */
090: public XYDataset getUnderlyingDataset() {
091: return this .underlying;
092: }
093:
094: /**
095: * Returns the bar width.
096: *
097: * @return The bar width.
098: *
099: * @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
221: / 2.0);
222: }
223: return result;
224: }
225:
226: /**
227: * Returns the starting x-value (as a double primitive) for an item within
228: * a series.
229: *
230: * @param series the series index (zero-based).
231: * @param item the item index (zero-based).
232: *
233: * @return The value.
234: *
235: * @see #getXValue(int, int)
236: */
237: public double getStartXValue(int series, int item) {
238: return getXValue(series, item) - this .barWidth / 2.0;
239: }
240:
241: /**
242: * Returns the ending X value for the specified series and item.
243: *
244: * @param series the series index (zero-based).
245: * @param item the item index (zero-based).
246: *
247: * @return The value.
248: */
249: public Number getEndX(int series, int item) {
250: Number result = null;
251: Number xnum = this .underlying.getX(series, item);
252: if (xnum != null) {
253: result = new Double(xnum.doubleValue() + this .barWidth
254: / 2.0);
255: }
256: return result;
257: }
258:
259: /**
260: * Returns the ending x-value (as a double primitive) for an item within
261: * a series.
262: *
263: * @param series the series index (zero-based).
264: * @param item the item index (zero-based).
265: *
266: * @return The value.
267: *
268: * @see #getXValue(int, int)
269: */
270: public double getEndXValue(int series, int item) {
271: return getXValue(series, item) + this .barWidth / 2.0;
272: }
273:
274: /**
275: * Returns the starting Y value for the specified series and item.
276: *
277: * @param series the series index (zero-based).
278: * @param item the item index (zero-based).
279: *
280: * @return The value.
281: */
282: public Number getStartY(int series, int item) {
283: return this .underlying.getY(series, item);
284: }
285:
286: /**
287: * Returns the starting y-value (as a double primitive) for an item within
288: * a series.
289: *
290: * @param series the series index (zero-based).
291: * @param item the item index (zero-based).
292: *
293: * @return The value.
294: *
295: * @see #getYValue(int, int)
296: */
297: public double getStartYValue(int series, int item) {
298: return getYValue(series, item);
299: }
300:
301: /**
302: * Returns the ending Y value for the specified series and item.
303: *
304: * @param series the series index (zero-based).
305: * @param item the item index (zero-based).
306: *
307: * @return The value.
308: */
309: public Number getEndY(int series, int item) {
310: return this .underlying.getY(series, item);
311: }
312:
313: /**
314: * Returns the ending y-value (as a double primitive) for an item within
315: * a series.
316: *
317: * @param series the series index (zero-based).
318: * @param item the item index (zero-based).
319: *
320: * @return The value.
321: *
322: * @see #getYValue(int, int)
323: */
324: public double getEndYValue(int series, int item) {
325: return getYValue(series, item);
326: }
327:
328: /**
329: * Receives notification of an dataset change event.
330: *
331: * @param event information about the event.
332: */
333: public void datasetChanged(DatasetChangeEvent event) {
334: this .notifyListeners(event);
335: }
336:
337: /**
338: * Tests this dataset for equality with an arbitrary object.
339: *
340: * @param obj the object (<code>null</code> permitted).
341: *
342: * @return A boolean.
343: */
344: public boolean equals(Object obj) {
345: if (obj == this ) {
346: return true;
347: }
348: if (!(obj instanceof XYBarDataset)) {
349: return false;
350: }
351: XYBarDataset that = (XYBarDataset) obj;
352: if (!this .underlying.equals(that.underlying)) {
353: return false;
354: }
355: if (this .barWidth != that.barWidth) {
356: return false;
357: }
358: return true;
359: }
360:
361: /**
362: * Returns an independent copy of the dataset. Note that:
363: * <ul>
364: * <li>the underlying dataset is only cloned if it implements the
365: * {@link PublicCloneable} interface;</li>
366: * <li>the listeners registered with this dataset are not carried over to
367: * the cloned dataset.</li>
368: * </ul>
369: *
370: * @return An independent copy of the dataset.
371: *
372: * @throws CloneNotSupportedException if the dataset cannot be cloned for
373: * any reason.
374: */
375: public Object clone() throws CloneNotSupportedException {
376: XYBarDataset clone = (XYBarDataset) super .clone();
377: if (this .underlying instanceof PublicCloneable) {
378: clone.underlying = (XYDataset) ((PublicCloneable) this.underlying)
379: .clone();
380: }
381: return clone;
382: }
383:
384: }
|