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