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