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