001 package org.LiveGraph.dataCache;
002
003 import java.util.Iterator;
004
005 import com.softnetConsult.utils.collections.NullIterator;
006 import com.softnetConsult.utils.collections.ReadOnlyIterator;
007
008
009 /**
010 * Repsesents a data series inside the cache; stores all series specific information
011 * and provides convenience methods for accessing that information. A data series
012 * usually cossesponds to a data column inside a data file.
013 *
014 * <p>
015 * <strong>LiveGraph</strong>
016 * (<a href="http://www.live-graph.org" target="_blank">http://www.live-graph.org</a>).
017 * </p>
018 * <p>Copyright (c) 2007 by G. Paperin.</p>
019 * <p>File: DataSeries.java</p>
020 * <p style="font-size:smaller;">Redistribution and use in source and binary forms, with or
021 * without modification, are permitted provided that the following terms and conditions are met:
022 * </p>
023 * <p style="font-size:smaller;">1. Redistributions of source code must retain the above
024 * acknowledgement of the LiveGraph project and its web-site, the above copyright notice,
025 * this list of conditions and the following disclaimer.<br />
026 * 2. Redistributions in binary form must reproduce the above acknowledgement of the
027 * LiveGraph project and its web-site, the above copyright notice, this list of conditions
028 * and the following disclaimer in the documentation and/or other materials provided with
029 * the distribution.<br />
030 * 3. All advertising materials mentioning features or use of this software or any derived
031 * software must display the following acknowledgement:<br />
032 * <em>This product includes software developed by the LiveGraph project and its
033 * contributors.<br />(http://www.live-graph.org)</em><br />
034 * 4. All advertising materials distributed in form of HTML pages or any other technology
035 * permitting active hyper-links that mention features or use of this software or any
036 * derived software must display the acknowledgment specified in condition 3 of this
037 * agreement, and in addition, include a visible and working hyper-link to the LiveGraph
038 * homepage (http://www.live-graph.org).
039 * </p>
040 * <p style="font-size:smaller;">THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY
041 * OF ANY KIND, EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
042 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
043 * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
044 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
045 * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
046 * </p>
047 *
048 * @author Greg Paperin (<a href="http://www.paperin.org" target="_blank">http://www.paperin.org</a>)
049 * @version {@value org.LiveGraph.LiveGraph#version}
050 */
051 public class DataSeries {
052
053 /**
054 * Serien name/label.
055 */
056 private String label = null;
057
058 /**
059 * The cache in which the data of this series is stored.
060 */
061 private DataCache adminCache = null;
062
063 /**
064 * The (0 based) index of this series' data in the cache.
065 */
066 private int seriesIndexInCache = -1;
067
068 /**
069 * Min data value in this series.
070 */
071 private double minValue = Double.NaN;
072
073 /**
074 * Max data value in this series.
075 */
076 private double maxValue = Double.NaN;
077
078 /**
079 * The constructor.
080 *
081 * @param label Series label.
082 * @param adminCache The cache adminestering the data.
083 * @param seriesIndexInCache The index of this series in the cache.
084 */
085 /*package*/ DataSeries(String label, DataCache adminCache, int seriesIndexInCache) {
086 this.label = label;
087 this.adminCache = adminCache;
088 this.seriesIndexInCache = seriesIndexInCache;
089 resetExtremeValues();
090 }
091
092 /**
093 * @return This series' name / label.
094 */
095 public String getLabel() {
096 return label;
097 }
098
099 /**
100 * @return The cache holding the data of this series.
101 */
102 public DataCache getAdministratingCache() {
103 return adminCache;
104 }
105
106 /**
107 * @return The series' data index in the cache.
108 */
109 public int getSeriesIndexInCache() {
110 return seriesIndexInCache;
111 }
112
113 /**
114 * @return Number of datasets the cache currently holds for this series.
115 */
116 public int countDataSets() {
117 return adminCache.countDataSets();
118 }
119
120 /**
121 * @return A read-only iterator over the data values of this series currently held in cache.
122 */
123 public ReadOnlyIterator<Double> iterateDataValues() {
124
125 return new DataValuesIterator(adminCache.iterateDataSets(), seriesIndexInCache);
126 }
127
128 /**
129 * @param cacheIndex A cache index of a dataset.
130 * @return This series' dataset the held at the specified index in the cache.
131 */
132 public double getDataValue(int cacheIndex) {
133 return adminCache.getDataSet(cacheIndex).getValue(seriesIndexInCache);
134 }
135
136 /**
137 * @param cacheIndex A cache index of a dataset.
138 * @return The index in the original file of the dataset at the specified cache index.
139 */
140 public int getDatasetFileIndex(int cacheIndex) {
141 return adminCache.getDataSet(cacheIndex).getDataFileIndex();
142 }
143
144 /**
145 * @param dataFileIndex An data row index of the original data file.
146 * @return The data value of this series' dataset which was located at the specified
147 * index in the original data file; if that dataset is not in the cache, this method
148 * returns {@link DataSet#returnValueForIllegalIndex}.doubleValue().
149 */
150 public double findDataValue(int dataFileIndex) {
151
152 DataSet ds = adminCache.findDataSet(dataFileIndex);
153
154 if (null == ds)
155 return DataSet.returnValueForIllegalIndex.doubleValue();
156
157 return ds.getValue(seriesIndexInCache);
158 }
159
160 /**
161 * @param val Makes sure that min and max value caches of this series include the
162 * specified value.
163 */
164 /*package*/ void includeExtremeValue(double val) {
165
166 if (Double.isNaN(val) || Double.isInfinite(val))
167 return;
168
169 if (val < minValue || Double.isNaN(minValue) )
170 minValue = val;
171
172 if (val > maxValue || Double.isNaN(maxValue))
173 maxValue = val;
174 }
175
176 /**
177 * @return The smallest data value of this series or {@code Double.NaN} if this series
178 * is empty.
179 */
180 public double getMinValue() {
181 return minValue;
182 }
183
184 /**
185 * @return The largest data value of this series or {@code Double.NaN} if this series
186 * is empty.
187 */
188 public double getMaxValue() {
189 return maxValue;
190 }
191
192 /**
193 * Resets the min and max value caches for this series.
194 */
195 /*package*/ void resetExtremeValues() {
196 minValue = Double.NaN;
197 maxValue = Double.NaN;
198 }
199
200 /**
201 * A read-only iterator over the data values of a series.
202 */
203 private class DataValuesIterator extends ReadOnlyIterator<Double> {
204
205 private Iterator<DataSet> iterator = null;
206 private int seriesIndexInCache = -1;
207
208 public DataValuesIterator(Iterator<DataSet> iter, int seriesIndexInCache) {
209 super(NullIterator.getSingeltonInstance(Double.class));
210 this.iterator = iter;
211 this.seriesIndexInCache = seriesIndexInCache;
212 }
213
214 @Override
215 public boolean hasNext() {
216 return iterator.hasNext();
217 }
218
219 @Override
220 public Double next() {
221 return iterator.next().getValue(seriesIndexInCache);
222 }
223
224 @Override
225 public void remove() {
226 throw new UnsupportedOperationException("Cannot use this iterator to remove items.");
227 }
228
229 } // class DataSeriesLabelIterator
230
231 } // class DataSeries