001/* =========================================================== 002 * JFreeChart : a free chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C) Copyright 2000-present, by David Gilbert 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 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates. 025 * Other names may be trademarks of their respective owners.] 026 * 027 * ------------------------------- 028 * XYIntervalSeriesCollection.java 029 * ------------------------------- 030 * (C) Copyright 2006-present, by David Gilbert. 031 * 032 * Original Author: David Gilbert; 033 * Contributor(s): -; 034 * 035 */ 036 037package org.jfree.data.xy; 038 039import java.io.Serializable; 040import java.util.List; 041import java.util.Objects; 042import org.jfree.chart.util.Args; 043import org.jfree.chart.util.PublicCloneable; 044 045import org.jfree.data.general.DatasetChangeEvent; 046 047/** 048 * A collection of {@link XYIntervalSeries} objects. 049 * 050 * @see XYIntervalSeries 051 */ 052public class XYIntervalSeriesCollection extends AbstractIntervalXYDataset 053 implements IntervalXYDataset, PublicCloneable, Serializable { 054 055 /** Storage for the data series. */ 056 private List data; 057 058 /** 059 * Creates a new instance of {@code XIntervalSeriesCollection}. 060 */ 061 public XYIntervalSeriesCollection() { 062 this.data = new java.util.ArrayList(); 063 } 064 065 /** 066 * Adds a series to the collection and sends a {@link DatasetChangeEvent} 067 * to all registered listeners. 068 * 069 * @param series the series ({@code null} not permitted). 070 */ 071 public void addSeries(XYIntervalSeries series) { 072 Args.nullNotPermitted(series, "series"); 073 this.data.add(series); 074 series.addChangeListener(this); 075 fireDatasetChanged(); 076 } 077 078 /** 079 * Returns the number of series in the collection. 080 * 081 * @return The series count. 082 */ 083 @Override 084 public int getSeriesCount() { 085 return this.data.size(); 086 } 087 088 /** 089 * Returns a series from the collection. 090 * 091 * @param series the series index (zero-based). 092 * 093 * @return The series. 094 * 095 * @throws IllegalArgumentException if {@code series} is not in the 096 * range {@code 0} to {@code getSeriesCount() - 1}. 097 */ 098 public XYIntervalSeries getSeries(int series) { 099 if ((series < 0) || (series >= getSeriesCount())) { 100 throw new IllegalArgumentException("Series index out of bounds"); 101 } 102 return (XYIntervalSeries) this.data.get(series); 103 } 104 105 /** 106 * Returns the key for a series. 107 * 108 * @param series the series index (in the range {@code 0} to 109 * {@code getSeriesCount() - 1}). 110 * 111 * @return The key for a series. 112 * 113 * @throws IllegalArgumentException if {@code series} is not in the 114 * specified range. 115 */ 116 @Override 117 public Comparable getSeriesKey(int series) { 118 // defer argument checking 119 return getSeries(series).getKey(); 120 } 121 122 /** 123 * Returns the number of items in the specified series. 124 * 125 * @param series the series (zero-based index). 126 * 127 * @return The item count. 128 * 129 * @throws IllegalArgumentException if {@code series} is not in the 130 * range {@code 0} to {@code getSeriesCount() - 1}. 131 */ 132 @Override 133 public int getItemCount(int series) { 134 // defer argument checking 135 return getSeries(series).getItemCount(); 136 } 137 138 /** 139 * Returns the x-value for an item within a series. 140 * 141 * @param series the series index. 142 * @param item the item index. 143 * 144 * @return The x-value. 145 */ 146 @Override 147 public Number getX(int series, int item) { 148 XYIntervalSeries s = (XYIntervalSeries) this.data.get(series); 149 return s.getX(item); 150 } 151 152 /** 153 * Returns the start x-value (as a double primitive) for an item within a 154 * series. 155 * 156 * @param series the series index (zero-based). 157 * @param item the item index (zero-based). 158 * 159 * @return The value. 160 */ 161 @Override 162 public double getStartXValue(int series, int item) { 163 XYIntervalSeries s = (XYIntervalSeries) this.data.get(series); 164 return s.getXLowValue(item); 165 } 166 167 /** 168 * Returns the end x-value (as a double primitive) for an item within a 169 * series. 170 * 171 * @param series the series index (zero-based). 172 * @param item the item index (zero-based). 173 * 174 * @return The value. 175 */ 176 @Override 177 public double getEndXValue(int series, int item) { 178 XYIntervalSeries s = (XYIntervalSeries) this.data.get(series); 179 return s.getXHighValue(item); 180 } 181 182 /** 183 * Returns the y-value (as a double primitive) for an item within a 184 * series. 185 * 186 * @param series the series index (zero-based). 187 * @param item the item index (zero-based). 188 * 189 * @return The value. 190 */ 191 @Override 192 public double getYValue(int series, int item) { 193 XYIntervalSeries s = (XYIntervalSeries) this.data.get(series); 194 return s.getYValue(item); 195 } 196 197 /** 198 * Returns the start y-value (as a double primitive) for an item within a 199 * series. 200 * 201 * @param series the series index (zero-based). 202 * @param item the item index (zero-based). 203 * 204 * @return The value. 205 */ 206 @Override 207 public double getStartYValue(int series, int item) { 208 XYIntervalSeries s = (XYIntervalSeries) this.data.get(series); 209 return s.getYLowValue(item); 210 } 211 212 /** 213 * Returns the end y-value (as a double primitive) for an item within a 214 * series. 215 * 216 * @param series the series (zero-based index). 217 * @param item the item (zero-based index). 218 * 219 * @return The value. 220 */ 221 @Override 222 public double getEndYValue(int series, int item) { 223 XYIntervalSeries s = (XYIntervalSeries) this.data.get(series); 224 return s.getYHighValue(item); 225 } 226 227 /** 228 * Returns the y-value for an item within a series. 229 * 230 * @param series the series index. 231 * @param item the item index. 232 * 233 * @return The y-value. 234 */ 235 @Override 236 public Number getY(int series, int item) { 237 return getYValue(series, item); 238 } 239 240 /** 241 * Returns the start x-value for an item within a series. 242 * 243 * @param series the series index. 244 * @param item the item index. 245 * 246 * @return The x-value. 247 */ 248 @Override 249 public Number getStartX(int series, int item) { 250 return getStartXValue(series, item); 251 } 252 253 /** 254 * Returns the end x-value for an item within a series. 255 * 256 * @param series the series index. 257 * @param item the item index. 258 * 259 * @return The x-value. 260 */ 261 @Override 262 public Number getEndX(int series, int item) { 263 return getEndXValue(series, item); 264 } 265 266 /** 267 * Returns the start y-value for an item within a series. This method 268 * maps directly to {@link #getY(int, int)}. 269 * 270 * @param series the series index. 271 * @param item the item index. 272 * 273 * @return The start y-value. 274 */ 275 @Override 276 public Number getStartY(int series, int item) { 277 return getStartYValue(series, item); 278 } 279 280 /** 281 * Returns the end y-value for an item within a series. This method 282 * maps directly to {@link #getY(int, int)}. 283 * 284 * @param series the series index. 285 * @param item the item index. 286 * 287 * @return The end y-value. 288 */ 289 @Override 290 public Number getEndY(int series, int item) { 291 return getEndYValue(series, item); 292 } 293 294 /** 295 * Removes a series from the collection and sends a 296 * {@link DatasetChangeEvent} to all registered listeners. 297 * 298 * @param series the series index (zero-based). 299 */ 300 public void removeSeries(int series) { 301 if ((series < 0) || (series >= getSeriesCount())) { 302 throw new IllegalArgumentException("Series index out of bounds."); 303 } 304 XYIntervalSeries ts = (XYIntervalSeries) this.data.get(series); 305 ts.removeChangeListener(this); 306 this.data.remove(series); 307 fireDatasetChanged(); 308 } 309 310 /** 311 * Removes a series from the collection and sends a 312 * {@link DatasetChangeEvent} to all registered listeners. 313 * 314 * @param series the series ({@code null} not permitted). 315 */ 316 public void removeSeries(XYIntervalSeries series) { 317 Args.nullNotPermitted(series, "series"); 318 if (this.data.contains(series)) { 319 series.removeChangeListener(this); 320 this.data.remove(series); 321 fireDatasetChanged(); 322 } 323 } 324 325 /** 326 * Removes all the series from the collection and sends a 327 * {@link DatasetChangeEvent} to all registered listeners. 328 */ 329 public void removeAllSeries() { 330 // Unregister the collection as a change listener to each series in 331 // the collection. 332 for (int i = 0; i < this.data.size(); i++) { 333 XYIntervalSeries series = (XYIntervalSeries) this.data.get(i); 334 series.removeChangeListener(this); 335 } 336 this.data.clear(); 337 fireDatasetChanged(); 338 } 339 340 /** 341 * Tests this instance for equality with an arbitrary object. 342 * 343 * @param obj the object ({@code null} permitted). 344 * 345 * @return A boolean. 346 */ 347 @Override 348 public boolean equals(Object obj) { 349 if (obj == this) { 350 return true; 351 } 352 if (!(obj instanceof XYIntervalSeriesCollection)) { 353 return false; 354 } 355 XYIntervalSeriesCollection that = (XYIntervalSeriesCollection) obj; 356 return Objects.equals(this.data, that.data); 357 } 358 359 /** 360 * Returns a clone of this dataset. 361 * 362 * @return A clone of this dataset. 363 * 364 * @throws CloneNotSupportedException if there is a problem cloning. 365 */ 366 @Override 367 public Object clone() throws CloneNotSupportedException { 368 XYIntervalSeriesCollection clone 369 = (XYIntervalSeriesCollection) super.clone(); 370 int seriesCount = getSeriesCount(); 371 clone.data = new java.util.ArrayList(seriesCount); 372 for (int i = 0; i < this.data.size(); i++) { 373 clone.data.set(i, getSeries(i).clone()); 374 } 375 return clone; 376 } 377 378}