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