001/* =========================================================== 002 * JFreeChart : a free chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C) Copyright 2000-2022, 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 * VectorSeriesCollection.java 029 * --------------------------- 030 * (C) Copyright 2007-2022, 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.ArrayList; 041import java.util.List; 042import java.util.Objects; 043 044import org.jfree.chart.internal.Args; 045import org.jfree.chart.internal.CloneUtils; 046import org.jfree.chart.api.PublicCloneable; 047 048import org.jfree.data.general.DatasetChangeEvent; 049 050/** 051 * A collection of {@link VectorSeries} objects. 052 * 053 * @param <S> The type for the series keys. 054 * 055 * @since 1.0.6 056 */ 057public class VectorSeriesCollection<S extends Comparable<S>> 058 extends AbstractXYDataset<S> 059 implements VectorXYDataset<S>, PublicCloneable, Serializable { 060 061 /** Storage for the data series. */ 062 private List<VectorSeries<S>> data; 063 064 /** 065 * Creates a new {@code VectorSeriesCollection} instance. 066 */ 067 public VectorSeriesCollection() { 068 this.data = new ArrayList<>(); 069 } 070 071 /** 072 * Adds a series to the collection and sends a {@link DatasetChangeEvent} 073 * to all registered listeners. 074 * 075 * @param series the series ({@code null} not permitted). 076 */ 077 public void addSeries(VectorSeries<S> series) { 078 Args.nullNotPermitted(series, "series"); 079 this.data.add(series); 080 series.addChangeListener(this); 081 fireDatasetChanged(); 082 } 083 084 /** 085 * Removes the specified series from the collection and sends a 086 * {@link DatasetChangeEvent} to all registered listeners. 087 * 088 * @param series the series ({@code null} not permitted). 089 * 090 * @return A boolean indicating whether the series has actually been 091 * removed. 092 */ 093 public boolean removeSeries(VectorSeries<S> series) { 094 Args.nullNotPermitted(series, "series"); 095 boolean removed = this.data.remove(series); 096 if (removed) { 097 series.removeChangeListener(this); 098 fireDatasetChanged(); 099 } 100 return removed; 101 } 102 103 /** 104 * Removes all the series from the collection and sends a 105 * {@link DatasetChangeEvent} to all registered listeners. 106 */ 107 public void removeAllSeries() { 108 109 // deregister the collection as a change listener to each series in the 110 // collection 111 for (VectorSeries<S> series : this.data) { 112 series.removeChangeListener(this); 113 } 114 115 // remove all the series from the collection and notify listeners. 116 this.data.clear(); 117 fireDatasetChanged(); 118 119 } 120 121 /** 122 * Returns the number of series in the collection. 123 * 124 * @return The series count. 125 */ 126 @Override 127 public int getSeriesCount() { 128 return this.data.size(); 129 } 130 131 /** 132 * Returns a series from the collection. 133 * 134 * @param series the series index (zero-based). 135 * 136 * @return The series. 137 * 138 * @throws IllegalArgumentException if {@code series} is not in the 139 * range {@code 0} to {@code getSeriesCount() - 1}. 140 */ 141 public VectorSeries<S> getSeries(int series) { 142 Args.requireInRange(series, "series", 0, this.data.size() - 1); 143 return this.data.get(series); 144 } 145 146 /** 147 * Returns the key for a series. 148 * 149 * @param series the series index (in the range {@code 0} to 150 * {@code getSeriesCount() - 1}). 151 * 152 * @return The key for a series. 153 * 154 * @throws IllegalArgumentException if {@code series} is not in the 155 * specified range. 156 */ 157 @Override 158 public S getSeriesKey(int series) { 159 // defer argument checking 160 return getSeries(series).getKey(); 161 } 162 163 /** 164 * Returns the index of the specified series, or -1 if that series is not 165 * present in the dataset. 166 * 167 * @param series the series ({@code null} not permitted). 168 * 169 * @return The series index. 170 */ 171 public int indexOf(VectorSeries<S> series) { 172 Args.nullNotPermitted(series, "series"); 173 return this.data.indexOf(series); 174 } 175 176 /** 177 * Returns the number of items in the specified series. 178 * 179 * @param series the series (zero-based index). 180 * 181 * @return The item count. 182 * 183 * @throws IllegalArgumentException if {@code series} is not in the 184 * range {@code 0} to {@code getSeriesCount() - 1}. 185 */ 186 @Override 187 public int getItemCount(int series) { 188 // defer argument checking 189 return getSeries(series).getItemCount(); 190 } 191 192 /** 193 * Returns the x-value for an item within a series. 194 * 195 * @param series the series index. 196 * @param item the item index. 197 * 198 * @return The x-value. 199 */ 200 @Override 201 public double getXValue(int series, int item) { 202 VectorSeries<S> s = this.data.get(series); 203 VectorDataItem di = (VectorDataItem) s.getDataItem(item); 204 return di.getXValue(); 205 } 206 207 /** 208 * Returns the x-value for an item within a series. Note that this method 209 * creates a new {@link Double} instance every time it is called---use 210 * {@link #getXValue(int, int)} instead, if possible. 211 * 212 * @param series the series index. 213 * @param item the item index. 214 * 215 * @return The x-value. 216 */ 217 @Override 218 public Number getX(int series, int item) { 219 return getXValue(series, item); 220 } 221 222 /** 223 * Returns the y-value for an item within a series. 224 * 225 * @param series the series index. 226 * @param item the item index. 227 * 228 * @return The y-value. 229 */ 230 @Override 231 public double getYValue(int series, int item) { 232 VectorSeries<S> s = this.data.get(series); 233 VectorDataItem di = (VectorDataItem) s.getDataItem(item); 234 return di.getYValue(); 235 } 236 237 /** 238 * Returns the y-value for an item within a series. Note that this method 239 * creates a new {@link Double} instance every time it is called---use 240 * {@link #getYValue(int, int)} instead, if possible. 241 * 242 * @param series the series index. 243 * @param item the item index. 244 * 245 * @return The y-value. 246 */ 247 @Override 248 public Number getY(int series, int item) { 249 return getYValue(series, item); 250 } 251 252 /** 253 * Returns the vector for an item in a series. 254 * 255 * @param series the series index. 256 * @param item the item index. 257 * 258 * @return The vector (possibly {@code null}). 259 */ 260 @Override 261 public Vector getVector(int series, int item) { 262 VectorSeries<S> s = this.data.get(series); 263 VectorDataItem di = (VectorDataItem) s.getDataItem(item); 264 return di.getVector(); 265 } 266 267 /** 268 * Returns the x-component of the vector for an item in a series. 269 * 270 * @param series the series index. 271 * @param item the item index. 272 * 273 * @return The x-component of the vector. 274 */ 275 @Override 276 public double getVectorXValue(int series, int item) { 277 VectorSeries<S> s = this.data.get(series); 278 VectorDataItem di = (VectorDataItem) s.getDataItem(item); 279 return di.getVectorX(); 280 } 281 282 /** 283 * Returns the y-component of the vector for an item in a series. 284 * 285 * @param series the series index. 286 * @param item the item index. 287 * 288 * @return The y-component of the vector. 289 */ 290 @Override 291 public double getVectorYValue(int series, int item) { 292 VectorSeries<S> s = this.data.get(series); 293 VectorDataItem di = (VectorDataItem) s.getDataItem(item); 294 return di.getVectorY(); 295 } 296 297 /** 298 * Tests this instance for equality with an arbitrary object. 299 * 300 * @param obj the object ({@code null} permitted). 301 * 302 * @return A boolean. 303 */ 304 @Override 305 public boolean equals(Object obj) { 306 if (obj == this) { 307 return true; 308 } 309 if (!(obj instanceof VectorSeriesCollection)) { 310 return false; 311 } 312 VectorSeriesCollection<S> that = (VectorSeriesCollection<S>) obj; 313 return Objects.equals(this.data, that.data); 314 } 315 316 /** 317 * Returns a clone of this instance. 318 * 319 * @return A clone. 320 * 321 * @throws CloneNotSupportedException if there is a problem. 322 */ 323 @Override 324 public Object clone() throws CloneNotSupportedException { 325 VectorSeriesCollection<S> clone 326 = (VectorSeriesCollection<S>) super.clone(); 327 clone.data = CloneUtils.cloneList(this.data); 328 return clone; 329 } 330 331}