dynamictimeseriescollection.java

来自「JfreeChart 常用图表例子」· Java 代码 · 共 974 行 · 第 1/3 页

JAVA
974
字号
/* =========================================================== * JFreeChart : a free chart library for the Java(tm) platform * =========================================================== * * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors. * * Project Info:  http://www.jfree.org/jfreechart/index.html * * This library is free software; you can redistribute it and/or modify it  * under the terms of the GNU Lesser General Public License as published by  * the Free Software Foundation; either version 2.1 of the License, or  * (at your option) any later version. * * This library is distributed in the hope that it will be useful, but  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public  * License for more details. * * You should have received a copy of the GNU Lesser General Public License  * along with this library; if not, write to the Free Software Foundation,  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * * [Java is a trademark or registered trademark of Sun Microsystems, Inc.  * in the United States and other countries.] * * -------------------------------- * DynamicTimeSeriesCollection.java * -------------------------------- * (C) Copyright 2002-2005, by I. H. Thomae and Contributors. * * Original Author:  I. H. Thomae (ithomae@ists.dartmouth.edu); * Contributor(s):   David Gilbert (for Object Refinery Limited); * * $Id: DynamicTimeSeriesCollection.java,v 1.11 2005/05/20 08:20:03 mungady Exp $ * * Changes * ------- * 22-Nov-2002 : Initial version completed *    Jan 2003 : Optimized advanceTime(), added implemnt'n of RangeInfo intfc *               (using cached values for min, max, and range); also added *               getOldestIndex() and getNewestIndex() ftns so client classes *               can use this class as the master "index authority". * 22-Jan-2003 : Made this class stand on its own, rather than extending *               class FastTimeSeriesCollection * 31-Jan-2003 : Changed TimePeriod --> RegularTimePeriod (DG); * 13-Mar-2003 : Moved to com.jrefinery.data.time package (DG); * 29-Apr-2003 : Added small change to appendData method, from Irv Thomae (DG); * 19-Sep-2003 : Added new appendData method, from Irv Thomae (DG); * 05-May-2004 : Now extends AbstractIntervalXYDataset.  This also required a *               change to the return type of the getY() method - I'm slightly *               unsure of the implications of this, so it might require some *               further amendment (DG); * 15-Jul-2004 : Switched getX() with getXValue() and getY() with  *               getYValue() (DG); * 11-Jan-2004 : Removed deprecated code in preparation for the 1.0.0  *               release (DG); *  */package org.jfree.data.time;import java.util.Calendar;import java.util.TimeZone;import org.jfree.data.DomainInfo;import org.jfree.data.Range;import org.jfree.data.RangeInfo;import org.jfree.data.general.SeriesChangeEvent;import org.jfree.data.xy.AbstractIntervalXYDataset;import org.jfree.data.xy.IntervalXYDataset;/** * A dynamic dataset. * <p> * Like FastTimeSeriesCollection, this class is a functional replacement * for JFreeChart's TimeSeriesCollection _and_ TimeSeries classes. * FastTimeSeriesCollection is appropriate for a fixed time range; for * real-time applications this subclass adds the ability to append new * data and discard the oldest. * In this class, the arrays used in FastTimeSeriesCollection become FIFO's. * NOTE:As presented here, all data is assumed >= 0, an assumption which is * embodied only in methods associated with interface RangeInfo. * * @author Irv Thomae. */public class DynamicTimeSeriesCollection extends AbstractIntervalXYDataset                                         implements IntervalXYDataset,                                                    DomainInfo,                                                    RangeInfo {    /**      * Useful constant for controlling the x-value returned for a time      * period.      */    public static final int START = 0;    /**      * Useful constant for controlling the x-value returned for a time period.      */    public static final int MIDDLE = 1;    /**      * Useful constant for controlling the x-value returned for a time period.      */    public static final int END = 2;    /** The maximum number of items for each series (can be overridden). */    private int maximumItemCount = 2000;  // an arbitrary safe default value    /** The history count. */    protected int historyCount;    /** Storage for the series keys. */    private Comparable[] seriesKeys;    /** The time period class - barely used, and could be removed (DG). */    private Class timePeriodClass = Minute.class;   // default value;    /** Storage for the x-values. */    protected RegularTimePeriod[] pointsInTime;    /** The number of series. */    private int seriesCount;    /**     * A wrapper for a fixed array of float values.     */    protected class ValueSequence {        /** Storage for the float values. */        float[] dataPoints;        /**         * Default constructor:         */        public ValueSequence() {            this(DynamicTimeSeriesCollection.this.maximumItemCount);        }        /**         * Creates a sequence with the specified length.         *         * @param length  the length.         */        public ValueSequence(int length) {            this.dataPoints = new float[length];            for (int i = 0; i < length; i++) {                this.dataPoints[i] = 0.0f;            }        }        /**         * Enters data into the storage array.         *         * @param index  the index.         * @param value  the value.         */        public void enterData(int index, float value) {            this.dataPoints[index] = value;        }        /**         * Returns a value from the storage array.         *         * @param index  the index.         *         * @return The value.         */        public float getData(int index) {            return this.dataPoints[index];        }    }    /** An array for storing the objects that represent each series. */    protected ValueSequence[] valueHistory;    /** A working calendar (to recycle) */    protected Calendar workingCalendar;    /**      * The position within a time period to return as the x-value (START,      * MIDDLE or END).      */    private int position;    /**     * A flag that indicates that the domain is 'points in time'.  If this flag      * is true, only the x-value is used to determine the range of values in      * the domain, the start and end x-values are ignored.     */    private boolean domainIsPointsInTime;    /** index for mapping: points to the oldest valid time & data. */    private int oldestAt;  // as a class variable, initializes == 0    /** Index of the newest data item. */    private int newestAt;    // cached values used for interface DomainInfo:    /** the # of msec by which time advances. */    private long deltaTime;    /** Cached domain start (for use by DomainInfo). */    private Long domainStart;    /** Cached domain end (for use by DomainInfo). */    private Long domainEnd;    /** Cached domain range (for use by DomainInfo). */    private Range domainRange;    // Cached values used for interface RangeInfo: (note minValue pinned at 0)    //   A single set of extrema covers the entire SeriesCollection    /** The minimum value. */    private Float minValue = new Float(0.0f);    /** The maximum value. */    private Float maxValue = null;    /** The value range. */    private Range valueRange;  // autoinit's to null.    /**     * Constructs a dataset with capacity for N series, tied to default      * timezone.     *     * @param nSeries the number of series to be accommodated.     * @param nMoments the number of TimePeriods to be spanned.     */    public DynamicTimeSeriesCollection(int nSeries, int nMoments) {        this(nSeries, nMoments, new Millisecond(), TimeZone.getDefault());        this.newestAt = nMoments - 1;    }    /**     * Constructs an empty dataset, tied to a specific timezone.     *     * @param nSeries the number of series to be accommodated     * @param nMoments the number of TimePeriods to be spanned     * @param zone the timezone.     */    public DynamicTimeSeriesCollection(int nSeries, int nMoments,                                        TimeZone zone) {        this(nSeries, nMoments, new Millisecond(), zone);        this.newestAt = nMoments - 1;    }    /**     * Creates a new dataset.     *     * @param nSeries  the number of series.     * @param nMoments  the number of items per series.     * @param timeSample  a time period sample.     */    public DynamicTimeSeriesCollection(int nSeries,                                       int nMoments,                                       RegularTimePeriod timeSample) {        this(nSeries, nMoments, timeSample, TimeZone.getDefault());    }    /**     * Creates a new dataset.     *     * @param nSeries  the number of series.     * @param nMoments  the number of items per series.     * @param timeSample  a time period sample.     * @param zone  the time zone.     */    public DynamicTimeSeriesCollection(int nSeries,                                       int nMoments,                                       RegularTimePeriod timeSample,                                       TimeZone zone) {        // the first initialization must precede creation of the ValueSet array:        this.maximumItemCount = nMoments;  // establishes length of each array        this.historyCount = nMoments;        this.seriesKeys = new Comparable[nSeries];        // initialize the members of "seriesNames" array so they won't be null:        for (int i = 0; i < nSeries; i++) {            this.seriesKeys[i] = "";        }        this.newestAt = nMoments - 1;        this.valueHistory = new ValueSequence[nSeries];        this.timePeriodClass = timeSample.getClass();        /// Expand the following for all defined TimePeriods:        if (this.timePeriodClass == Second.class) {            this.pointsInTime = new Second[nMoments];        }        else if (this.timePeriodClass == Minute.class) {            this.pointsInTime = new Minute[nMoments];        }        else if (this.timePeriodClass == Hour.class) {            this.pointsInTime = new Hour[nMoments];        }        ///  .. etc....        this.workingCalendar = Calendar.getInstance(zone);        this.position = START;        this.domainIsPointsInTime = true;    }    /**     * Fill the pointsInTime with times using TimePeriod.next():     * Will silently return if the time array was already populated.     *     * Also computes the data cached for later use by     * methods implementing the DomainInfo interface:     *     * @param start  the start.     *     * @return ??.     */    public synchronized long setTimeBase(RegularTimePeriod start) {        if (this.pointsInTime[0] == null) {            this.pointsInTime[0] = start;            for (int i = 1; i < this.historyCount; i++) {                this.pointsInTime[i] = this.pointsInTime[i - 1].next();            }        }        long oldestL = this.pointsInTime[0].getFirstMillisecond(

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?