Frames | No Frames |
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: * CategoryTableXYDataset.java 29: * --------------------------- 30: * (C) Copyright 2004, 2005, 2007, by Andreas Schroeder and Contributors. 31: * 32: * Original Author: Andreas Schroeder; 33: * Contributor(s): David Gilbert (for Object Refinery Limited); 34: * 35: * $Id: CategoryTableXYDataset.java,v 1.7.2.3 2007/02/02 15:14:53 mungady Exp $ 36: * 37: * Changes 38: * ------- 39: * 31-Mar-2004 : Version 1 (AS); 40: * 05-May-2004 : Now extends AbstractIntervalXYDataset (DG); 41: * 15-Jul-2004 : Switched interval access method names (DG); 42: * 18-Aug-2004 : Moved from org.jfree.data --> org.jfree.data.xy (DG); 43: * 17-Nov-2004 : Updates required by changes to DomainInfo interface (DG); 44: * 11-Jan-2005 : Removed deprecated code in preparation for 1.0.0 release (DG); 45: * 05-Oct-2005 : Made the interval delegate a dataset change listener (DG); 46: * 02-Feb-2007 : Removed author tags all over JFreeChart sources (DG); 47: * 48: */ 49: 50: package org.jfree.data.xy; 51: 52: import org.jfree.data.DefaultKeyedValues2D; 53: import org.jfree.data.DomainInfo; 54: import org.jfree.data.Range; 55: import org.jfree.data.general.DatasetChangeEvent; 56: import org.jfree.data.general.DatasetUtilities; 57: 58: /** 59: * An implementation variant of the {@link TableXYDataset} where every series 60: * shares the same x-values (required for generating stacked area charts). 61: * This implementation uses a {@link DefaultKeyedValues2D} Object as backend 62: * implementation and is hence more "category oriented" than the {@link 63: * DefaultTableXYDataset} implementation. 64: * <p> 65: * This implementation provides no means to remove data items yet. 66: * This is due to the lack of such facility in the DefaultKeyedValues2D class. 67: * <p> 68: * This class also implements the {@link IntervalXYDataset} interface, but this 69: * implementation is provisional. 70: */ 71: public class CategoryTableXYDataset extends AbstractIntervalXYDataset 72: implements TableXYDataset, 73: IntervalXYDataset, 74: DomainInfo { 75: 76: /** 77: * The backing data structure. 78: */ 79: private DefaultKeyedValues2D values; 80: 81: /** A delegate for controlling the interval width. */ 82: private IntervalXYDelegate intervalDelegate; 83: 84: /** 85: * Creates a new empty CategoryTableXYDataset. 86: */ 87: public CategoryTableXYDataset() { 88: this.values = new DefaultKeyedValues2D(true); 89: this.intervalDelegate = new IntervalXYDelegate(this); 90: addChangeListener(this.intervalDelegate); 91: } 92: 93: /** 94: * Adds a data item to this dataset and sends a {@link DatasetChangeEvent} 95: * to all registered listeners. 96: * 97: * @param x the x value. 98: * @param y the y value. 99: * @param seriesName the name of the series to add the data item. 100: */ 101: public void add(double x, double y, String seriesName) { 102: add(new Double(x), new Double(y), seriesName, true); 103: } 104: 105: /** 106: * Adds a data item to this dataset and, if requested, sends a 107: * {@link DatasetChangeEvent} to all registered listeners. 108: * 109: * @param x the x value. 110: * @param y the y value. 111: * @param seriesName the name of the series to add the data item. 112: * @param notify notify listeners? 113: */ 114: public void add(Number x, Number y, String seriesName, boolean notify) { 115: this.values.addValue(y, (Comparable) x, seriesName); 116: if (notify) { 117: fireDatasetChanged(); 118: } 119: } 120: 121: /** 122: * Removes a value from the dataset. 123: * 124: * @param x the x-value. 125: * @param seriesName the series name. 126: */ 127: public void remove(double x, String seriesName) { 128: remove(new Double(x), seriesName, true); 129: } 130: 131: /** 132: * Removes an item from the dataset. 133: * 134: * @param x the x-value. 135: * @param seriesName the series name. 136: * @param notify notify listeners? 137: */ 138: public void remove(Number x, String seriesName, boolean notify) { 139: this.values.removeValue((Comparable) x, seriesName); 140: if (notify) { 141: fireDatasetChanged(); 142: } 143: } 144: 145: 146: /** 147: * Returns the number of series in the collection. 148: * 149: * @return The series count. 150: */ 151: public int getSeriesCount() { 152: return this.values.getColumnCount(); 153: } 154: 155: /** 156: * Returns the key for a series. 157: * 158: * @param series the series index (zero-based). 159: * 160: * @return The key for a series. 161: */ 162: public Comparable getSeriesKey(int series) { 163: return this.values.getColumnKey(series); 164: } 165: 166: /** 167: * Returns the number of x values in the dataset. 168: * 169: * @return The item count. 170: */ 171: public int getItemCount() { 172: return this.values.getRowCount(); 173: } 174: 175: /** 176: * Returns the number of items in the specified series. 177: * Returns the same as {@link CategoryTableXYDataset#getItemCount()}. 178: * 179: * @param series the series index (zero-based). 180: * 181: * @return The item count. 182: */ 183: public int getItemCount(int series) { 184: return getItemCount(); // all series have the same number of items in 185: // this dataset 186: } 187: 188: /** 189: * Returns the x-value for the specified series and item. 190: * 191: * @param series the series index (zero-based). 192: * @param item the item index (zero-based). 193: * 194: * @return The value. 195: */ 196: public Number getX(int series, int item) { 197: return (Number) this.values.getRowKey(item); 198: } 199: 200: /** 201: * Returns the starting X value for the specified series and item. 202: * 203: * @param series the series index (zero-based). 204: * @param item the item index (zero-based). 205: * 206: * @return The starting X value. 207: */ 208: public Number getStartX(int series, int item) { 209: return this.intervalDelegate.getStartX(series, item); 210: } 211: 212: /** 213: * Returns the ending X value for the specified series and item. 214: * 215: * @param series the series index (zero-based). 216: * @param item the item index (zero-based). 217: * 218: * @return The ending X value. 219: */ 220: public Number getEndX(int series, int item) { 221: return this.intervalDelegate.getEndX(series, item); 222: } 223: 224: /** 225: * Returns the y-value for the specified series and item. 226: * 227: * @param series the series index (zero-based). 228: * @param item the item index (zero-based). 229: * 230: * @return The y value (possibly <code>null</code>). 231: */ 232: public Number getY(int series, int item) { 233: return this.values.getValue(item, series); 234: } 235: 236: /** 237: * Returns the starting Y value for the specified series and item. 238: * 239: * @param series the series index (zero-based). 240: * @param item the item index (zero-based). 241: * 242: * @return The starting Y value. 243: */ 244: public Number getStartY(int series, int item) { 245: return getY(series, item); 246: } 247: 248: /** 249: * Returns the ending Y value for the specified series and item. 250: * 251: * @param series the series index (zero-based). 252: * @param item the item index (zero-based). 253: * 254: * @return The ending Y value. 255: */ 256: public Number getEndY(int series, int item) { 257: return getY(series, item); 258: } 259: 260: /** 261: * Returns the minimum x-value in the dataset. 262: * 263: * @param includeInterval a flag that determines whether or not the 264: * x-interval is taken into account. 265: * 266: * @return The minimum value. 267: */ 268: public double getDomainLowerBound(boolean includeInterval) { 269: return this.intervalDelegate.getDomainLowerBound(includeInterval); 270: } 271: 272: /** 273: * Returns the maximum x-value in the dataset. 274: * 275: * @param includeInterval a flag that determines whether or not the 276: * x-interval is taken into account. 277: * 278: * @return The maximum value. 279: */ 280: public double getDomainUpperBound(boolean includeInterval) { 281: return this.intervalDelegate.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.getDomainBounds(includeInterval); 295: } 296: else { 297: return DatasetUtilities.iterateDomainBounds(this, includeInterval); 298: } 299: } 300: 301: /** 302: * Returns the interval position factor. 303: * 304: * @return The interval position factor. 305: */ 306: public double getIntervalPositionFactor() { 307: return this.intervalDelegate.getIntervalPositionFactor(); 308: } 309: 310: /** 311: * Sets the interval position factor. Must be between 0.0 and 1.0 inclusive. 312: * If the factor is 0.5, the gap is in the middle of the x values. If it 313: * is lesser than 0.5, the gap is farther to the left and if greater than 314: * 0.5 it gets farther to the right. 315: * 316: * @param d the new interval position factor. 317: */ 318: public void setIntervalPositionFactor(double d) { 319: this.intervalDelegate.setIntervalPositionFactor(d); 320: fireDatasetChanged(); 321: } 322: 323: /** 324: * Returns the full interval width. 325: * 326: * @return The interval width to use. 327: */ 328: public double getIntervalWidth() { 329: return this.intervalDelegate.getIntervalWidth(); 330: } 331: 332: /** 333: * Sets the interval width to a fixed value, and sends a 334: * {@link DatasetChangeEvent} to all registered listeners. 335: * 336: * @param d the new interval width (must be > 0). 337: */ 338: public void setIntervalWidth(double d) { 339: this.intervalDelegate.setFixedIntervalWidth(d); 340: fireDatasetChanged(); 341: } 342: 343: /** 344: * Returns whether the interval width is automatically calculated or not. 345: * 346: * @return whether the width is automatically calculated or not. 347: */ 348: public boolean isAutoWidth() { 349: return this.intervalDelegate.isAutoWidth(); 350: } 351: 352: /** 353: * Sets the flag that indicates whether the interval width is automatically 354: * calculated or not. 355: * 356: * @param b the flag. 357: */ 358: public void setAutoWidth(boolean b) { 359: this.intervalDelegate.setAutoWidth(b); 360: fireDatasetChanged(); 361: } 362: 363: /** 364: * Tests this dataset for equality with an arbitrary object. 365: * 366: * @param obj the object (<code>null</code> permitted). 367: * 368: * @return A boolean. 369: */ 370: public boolean equals(Object obj) { 371: if (!(obj instanceof CategoryTableXYDataset)) { 372: return false; 373: } 374: CategoryTableXYDataset that = (CategoryTableXYDataset) obj; 375: if (!this.intervalDelegate.equals(that.intervalDelegate)) { 376: return false; 377: } 378: if (!this.values.equals(that.values)) { 379: return false; 380: } 381: return true; 382: } 383: 384: }