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: * CategoryTableXYDataset.java
029: * ---------------------------
030: * (C) Copyright 2004, 2005, 2007, by Andreas Schroeder and Contributors.
031: *
032: * Original Author: Andreas Schroeder;
033: * Contributor(s): David Gilbert (for Object Refinery Limited);
034: *
035: * $Id: CategoryTableXYDataset.java,v 1.7.2.3 2007/02/02 15:14:53 mungady Exp $
036: *
037: * Changes
038: * -------
039: * 31-Mar-2004 : Version 1 (AS);
040: * 05-May-2004 : Now extends AbstractIntervalXYDataset (DG);
041: * 15-Jul-2004 : Switched interval access method names (DG);
042: * 18-Aug-2004 : Moved from org.jfree.data --> org.jfree.data.xy (DG);
043: * 17-Nov-2004 : Updates required by changes to DomainInfo interface (DG);
044: * 11-Jan-2005 : Removed deprecated code in preparation for 1.0.0 release (DG);
045: * 05-Oct-2005 : Made the interval delegate a dataset change listener (DG);
046: * 02-Feb-2007 : Removed author tags all over JFreeChart sources (DG);
047: *
048: */
049:
050: package org.jfree.data.xy;
051:
052: import org.jfree.data.DefaultKeyedValues2D;
053: import org.jfree.data.DomainInfo;
054: import org.jfree.data.Range;
055: import org.jfree.data.general.DatasetChangeEvent;
056: import org.jfree.data.general.DatasetUtilities;
057:
058: /**
059: * An implementation variant of the {@link TableXYDataset} where every series
060: * shares the same x-values (required for generating stacked area charts).
061: * This implementation uses a {@link DefaultKeyedValues2D} Object as backend
062: * implementation and is hence more "category oriented" than the {@link
063: * DefaultTableXYDataset} implementation.
064: * <p>
065: * This implementation provides no means to remove data items yet.
066: * This is due to the lack of such facility in the DefaultKeyedValues2D class.
067: * <p>
068: * This class also implements the {@link IntervalXYDataset} interface, but this
069: * implementation is provisional.
070: */
071: public class CategoryTableXYDataset extends AbstractIntervalXYDataset
072: implements TableXYDataset, IntervalXYDataset, DomainInfo {
073:
074: /**
075: * The backing data structure.
076: */
077: private DefaultKeyedValues2D values;
078:
079: /** A delegate for controlling the interval width. */
080: private IntervalXYDelegate intervalDelegate;
081:
082: /**
083: * Creates a new empty CategoryTableXYDataset.
084: */
085: public CategoryTableXYDataset() {
086: this .values = new DefaultKeyedValues2D(true);
087: this .intervalDelegate = new IntervalXYDelegate(this );
088: addChangeListener(this .intervalDelegate);
089: }
090:
091: /**
092: * Adds a data item to this dataset and sends a {@link DatasetChangeEvent}
093: * to all registered listeners.
094: *
095: * @param x the x value.
096: * @param y the y value.
097: * @param seriesName the name of the series to add the data item.
098: */
099: public void add(double x, double y, String seriesName) {
100: add(new Double(x), new Double(y), seriesName, true);
101: }
102:
103: /**
104: * Adds a data item to this dataset and, if requested, sends a
105: * {@link DatasetChangeEvent} to all registered listeners.
106: *
107: * @param x the x value.
108: * @param y the y value.
109: * @param seriesName the name of the series to add the data item.
110: * @param notify notify listeners?
111: */
112: public void add(Number x, Number y, String seriesName,
113: boolean notify) {
114: this .values.addValue(y, (Comparable) x, seriesName);
115: if (notify) {
116: fireDatasetChanged();
117: }
118: }
119:
120: /**
121: * Removes a value from the dataset.
122: *
123: * @param x the x-value.
124: * @param seriesName the series name.
125: */
126: public void remove(double x, String seriesName) {
127: remove(new Double(x), seriesName, true);
128: }
129:
130: /**
131: * Removes an item from the dataset.
132: *
133: * @param x the x-value.
134: * @param seriesName the series name.
135: * @param notify notify listeners?
136: */
137: public void remove(Number x, String seriesName, boolean notify) {
138: this .values.removeValue((Comparable) x, seriesName);
139: if (notify) {
140: fireDatasetChanged();
141: }
142: }
143:
144: /**
145: * Returns the number of series in the collection.
146: *
147: * @return The series count.
148: */
149: public int getSeriesCount() {
150: return this .values.getColumnCount();
151: }
152:
153: /**
154: * Returns the key for a series.
155: *
156: * @param series the series index (zero-based).
157: *
158: * @return The key for a series.
159: */
160: public Comparable getSeriesKey(int series) {
161: return this .values.getColumnKey(series);
162: }
163:
164: /**
165: * Returns the number of x values in the dataset.
166: *
167: * @return The item count.
168: */
169: public int getItemCount() {
170: return this .values.getRowCount();
171: }
172:
173: /**
174: * Returns the number of items in the specified series.
175: * Returns the same as {@link CategoryTableXYDataset#getItemCount()}.
176: *
177: * @param series the series index (zero-based).
178: *
179: * @return The item count.
180: */
181: public int getItemCount(int series) {
182: return getItemCount(); // all series have the same number of items in
183: // this dataset
184: }
185:
186: /**
187: * Returns the x-value for the specified series and item.
188: *
189: * @param series the series index (zero-based).
190: * @param item the item index (zero-based).
191: *
192: * @return The value.
193: */
194: public Number getX(int series, int item) {
195: return (Number) this .values.getRowKey(item);
196: }
197:
198: /**
199: * Returns the starting X value for the specified series and item.
200: *
201: * @param series the series index (zero-based).
202: * @param item the item index (zero-based).
203: *
204: * @return The starting X value.
205: */
206: public Number getStartX(int series, int item) {
207: return this .intervalDelegate.getStartX(series, item);
208: }
209:
210: /**
211: * Returns the ending X value for the specified series and item.
212: *
213: * @param series the series index (zero-based).
214: * @param item the item index (zero-based).
215: *
216: * @return The ending X value.
217: */
218: public Number getEndX(int series, int item) {
219: return this .intervalDelegate.getEndX(series, item);
220: }
221:
222: /**
223: * Returns the y-value for the specified series and item.
224: *
225: * @param series the series index (zero-based).
226: * @param item the item index (zero-based).
227: *
228: * @return The y value (possibly <code>null</code>).
229: */
230: public Number getY(int series, int item) {
231: return this .values.getValue(item, series);
232: }
233:
234: /**
235: * Returns the starting Y value for the specified series and item.
236: *
237: * @param series the series index (zero-based).
238: * @param item the item index (zero-based).
239: *
240: * @return The starting Y value.
241: */
242: public Number getStartY(int series, int item) {
243: return getY(series, item);
244: }
245:
246: /**
247: * Returns the ending Y value for the specified series and item.
248: *
249: * @param series the series index (zero-based).
250: * @param item the item index (zero-based).
251: *
252: * @return The ending Y value.
253: */
254: public Number getEndY(int series, int item) {
255: return getY(series, item);
256: }
257:
258: /**
259: * Returns the minimum x-value in the dataset.
260: *
261: * @param includeInterval a flag that determines whether or not the
262: * x-interval is taken into account.
263: *
264: * @return The minimum value.
265: */
266: public double getDomainLowerBound(boolean includeInterval) {
267: return this .intervalDelegate
268: .getDomainLowerBound(includeInterval);
269: }
270:
271: /**
272: * Returns the maximum x-value in the dataset.
273: *
274: * @param includeInterval a flag that determines whether or not the
275: * x-interval is taken into account.
276: *
277: * @return The maximum value.
278: */
279: public double getDomainUpperBound(boolean includeInterval) {
280: return this .intervalDelegate
281: .getDomainUpperBound(includeInterval);
282: }
283:
284: /**
285: * Returns the range of the values in this dataset's domain.
286: *
287: * @param includeInterval a flag that determines whether or not the
288: * x-interval is taken into account.
289: *
290: * @return The range.
291: */
292: public Range getDomainBounds(boolean includeInterval) {
293: if (includeInterval) {
294: return this .intervalDelegate
295: .getDomainBounds(includeInterval);
296: } else {
297: return DatasetUtilities.iterateDomainBounds(this ,
298: includeInterval);
299: }
300: }
301:
302: /**
303: * Returns the interval position factor.
304: *
305: * @return The interval position factor.
306: */
307: public double getIntervalPositionFactor() {
308: return this .intervalDelegate.getIntervalPositionFactor();
309: }
310:
311: /**
312: * Sets the interval position factor. Must be between 0.0 and 1.0 inclusive.
313: * If the factor is 0.5, the gap is in the middle of the x values. If it
314: * is lesser than 0.5, the gap is farther to the left and if greater than
315: * 0.5 it gets farther to the right.
316: *
317: * @param d the new interval position factor.
318: */
319: public void setIntervalPositionFactor(double d) {
320: this .intervalDelegate.setIntervalPositionFactor(d);
321: fireDatasetChanged();
322: }
323:
324: /**
325: * Returns the full interval width.
326: *
327: * @return The interval width to use.
328: */
329: public double getIntervalWidth() {
330: return this .intervalDelegate.getIntervalWidth();
331: }
332:
333: /**
334: * Sets the interval width to a fixed value, and sends a
335: * {@link DatasetChangeEvent} to all registered listeners.
336: *
337: * @param d the new interval width (must be > 0).
338: */
339: public void setIntervalWidth(double d) {
340: this .intervalDelegate.setFixedIntervalWidth(d);
341: fireDatasetChanged();
342: }
343:
344: /**
345: * Returns whether the interval width is automatically calculated or not.
346: *
347: * @return whether the width is automatically calculated or not.
348: */
349: public boolean isAutoWidth() {
350: return this .intervalDelegate.isAutoWidth();
351: }
352:
353: /**
354: * Sets the flag that indicates whether the interval width is automatically
355: * calculated or not.
356: *
357: * @param b the flag.
358: */
359: public void setAutoWidth(boolean b) {
360: this .intervalDelegate.setAutoWidth(b);
361: fireDatasetChanged();
362: }
363:
364: /**
365: * Tests this dataset for equality with an arbitrary object.
366: *
367: * @param obj the object (<code>null</code> permitted).
368: *
369: * @return A boolean.
370: */
371: public boolean equals(Object obj) {
372: if (!(obj instanceof CategoryTableXYDataset)) {
373: return false;
374: }
375: CategoryTableXYDataset that = (CategoryTableXYDataset) obj;
376: if (!this .intervalDelegate.equals(that.intervalDelegate)) {
377: return false;
378: }
379: if (!this .values.equals(that.values)) {
380: return false;
381: }
382: return true;
383: }
384:
385: }
|