001/* =========================================================== 002 * Orson Charts : a 3D chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C)opyright 2013-2016, by Object Refinery Limited. All rights reserved. 006 * 007 * http://www.object-refinery.com/orsoncharts/index.html 008 * 009 * This program is free software: you can redistribute it and/or modify 010 * it under the terms of the GNU General Public License as published by 011 * the Free Software Foundation, either version 3 of the License, or 012 * (at your option) any later version. 013 * 014 * This program is distributed in the hope that it will be useful, 015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 017 * GNU General Public License for more details. 018 * 019 * You should have received a copy of the GNU General Public License 020 * along with this program. If not, see <http://www.gnu.org/licenses/>. 021 * 022 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates. 023 * Other names may be trademarks of their respective owners.] 024 * 025 * If you do not wish to be bound by the terms of the GPL, an alternative 026 * commercial license can be purchased. For details, please see visit the 027 * Orson Charts home page: 028 * 029 * http://www.object-refinery.com/orsoncharts/index.html 030 * 031 */ 032 033package com.orsoncharts.data.xyz; 034 035import java.io.Serializable; 036import java.util.ArrayList; 037import java.util.List; 038 039import com.orsoncharts.util.ArgChecks; 040import com.orsoncharts.data.AbstractDataset3D; 041import com.orsoncharts.data.JSONUtils; 042import com.orsoncharts.plot.XYZPlot; 043import com.orsoncharts.renderer.xyz.XYZRenderer; 044import com.orsoncharts.util.ObjectUtils; 045 046/** 047 * A collection of {@link XYZSeries} objects (implements the {@link XYZDataset} 048 * interface so that it can be used as a source of data for an 049 * {@link XYZRenderer} on an {@link XYZPlot}). 050 * <br><br> 051 * NOTE: This class is serializable, but the serialization format is subject 052 * to change in future releases and should not be relied upon for persisting 053 * instances of this class. 054 */ 055@SuppressWarnings("serial") 056public class XYZSeriesCollection extends AbstractDataset3D 057 implements XYZDataset, Serializable { 058 059 /** Storage for the data series. */ 060 private final List<XYZSeries> series; 061 062 /** 063 * Creates a new (empty) {@code XYZSeriesCollection} instance. 064 */ 065 public XYZSeriesCollection() { 066 this.series = new ArrayList<XYZSeries>(); 067 } 068 069 /** 070 * Returns the number of series in the collection. 071 * 072 * @return The number of series in the collection. 073 */ 074 @Override 075 public int getSeriesCount() { 076 return this.series.size(); 077 } 078 079 /** 080 * Returns the index of the series with the specified key, or 081 * {@code -1} if there is no series with the specified key. 082 * 083 * @param key the key ({@code null} not permitted). 084 * 085 * @return The series index or {@code -1}. 086 */ 087 @Override 088 public int getSeriesIndex(Comparable<?> key) { 089 ArgChecks.nullNotPermitted(key, "key"); 090 return getSeriesKeys().indexOf(key); 091 } 092 093 /** 094 * Returns a new list containing all the series keys. Modifying this list 095 * will have no impact on the {@code XYZSeriesCollection} instance. 096 * 097 * @return A list containing the series keys (possibly empty, but never 098 * {@code null}). 099 */ 100 @Override 101 public List<Comparable<?>> getSeriesKeys() { 102 List<Comparable<?>> result = new ArrayList<Comparable<?>>(); 103 for (XYZSeries s : this.series) { 104 result.add(s.getKey()); 105 } 106 return result; 107 } 108 109 /** 110 * Returns the key for the specified series. 111 * 112 * @param seriesIndex the series index. 113 * 114 * @return The series key. 115 * 116 * @since 1.3 117 */ 118 @Override 119 public Comparable<?> getSeriesKey(int seriesIndex) { 120 return getSeries(seriesIndex).getKey(); 121 } 122 123 /** 124 * Adds a series to the collection (note that the series key must be 125 * unique within the collection). 126 * 127 * @param series the series ({@code null} not permitted). 128 */ 129 public void add(XYZSeries series) { 130 ArgChecks.nullNotPermitted(series, "series"); 131 if (getSeriesIndex(series.getKey()) >= 0) { 132 throw new IllegalArgumentException("Another series with the same key already exists within the collection."); 133 } 134 this.series.add(series); 135 } 136 137 /** 138 * Returns the series with the specified index. 139 * 140 * @param index the series index. 141 * 142 * @return The series. 143 * 144 * @since 1.2 145 */ 146 public XYZSeries getSeries(int index) { 147 ArgChecks.checkArrayBounds(index, "index", this.series.size()); 148 return this.series.get(index); 149 } 150 151 /** 152 * Returns the series with the specified key, or {@code null} if 153 * there is no such series. 154 * 155 * @param key the key ({@code null} not permitted). 156 * 157 * @return The series. 158 * 159 * @since 1.2 160 */ 161 public XYZSeries getSeries(Comparable<?> key) { 162 ArgChecks.nullNotPermitted(key, "key"); 163 for (XYZSeries s : this.series) { 164 if (s.getKey().equals(key)) { 165 return s; 166 } 167 } 168 return null; 169 } 170 171 /** 172 * Returns the number of items in the specified series. 173 * 174 * @param seriesIndex the series index. 175 * 176 * @return The number of items in the specified series. 177 */ 178 @Override 179 public int getItemCount(int seriesIndex) { 180 XYZSeries s = this.series.get(seriesIndex); 181 return s.getItemCount(); 182 } 183 184 /** 185 * Returns the x-value for one item in a series. 186 * 187 * @param seriesIndex the series index. 188 * @param itemIndex the item index. 189 * 190 * @return The x-value. 191 */ 192 @Override 193 public double getX(int seriesIndex, int itemIndex) { 194 XYZSeries s = this.series.get(seriesIndex); 195 return s.getXValue(itemIndex); 196 } 197 198 /** 199 * Returns the y-value for one item in a series. 200 * 201 * @param seriesIndex the series index. 202 * @param itemIndex the item index. 203 * 204 * @return The y-value. 205 */ 206 @Override 207 public double getY(int seriesIndex, int itemIndex) { 208 XYZSeries s = this.series.get(seriesIndex); 209 return s.getYValue(itemIndex); 210 } 211 212 /** 213 * Returns the z-value for one item in a series. 214 * 215 * @param seriesIndex the series index. 216 * @param itemIndex the item index. 217 * 218 * @return The z-value. 219 */ 220 @Override 221 public double getZ(int seriesIndex, int itemIndex) { 222 XYZSeries s = this.series.get(seriesIndex); 223 return s.getZValue(itemIndex); 224 } 225 226 /** 227 * Tests this dataset for equality with an arbitrary object. 228 * 229 * @param obj the object ({@code null} not permitted). 230 * 231 * @return A boolean. 232 */ 233 @Override 234 public boolean equals(Object obj) { 235 if (obj == this) { 236 return true; 237 } 238 if (!(obj instanceof XYZSeriesCollection)) { 239 return false; 240 } 241 XYZSeriesCollection that = (XYZSeriesCollection) obj; 242 if (!this.series.equals(that.series)) { 243 return false; 244 } 245 return true; 246 } 247 248 @Override 249 public int hashCode() { 250 int hash = 5; 251 hash = 59 * hash + ObjectUtils.hashCode(this.series); 252 return hash; 253 } 254 255 /** 256 * Returns a string representation of this instance, primarily for 257 * debugging purposes. 258 * <br><br> 259 * Implementation note: the current implementation (which is subject to 260 * change) writes the dataset in JSON format using 261 * {@link JSONUtils#writeXYZDataset(com.orsoncharts.data.xyz.XYZDataset)}. 262 * 263 * @return A string. 264 */ 265 @Override 266 public String toString() { 267 return JSONUtils.writeXYZDataset(this); 268 } 269 270}