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