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 &quot;AS IS&quot;, 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