dynamictimeseriescollection.java

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

JAVA
974
字号
            this.workingCalendar        );        long nextL = this.pointsInTime[1].getFirstMillisecond(            this.workingCalendar        );        this.deltaTime = nextL - oldestL;        this.oldestAt = 0;        this.newestAt = this.historyCount - 1;        findDomainLimits();        return this.deltaTime;    }    /**     * Finds the domain limits.  Note: this doesn't need to be synchronized      * because it's called from within another method that already is.     */    protected void findDomainLimits() {        long startL = getOldestTime().getFirstMillisecond(this.workingCalendar);        long endL;        if (this.domainIsPointsInTime) {            endL = getNewestTime().getFirstMillisecond(this.workingCalendar);        }        else {            endL = getNewestTime().getLastMillisecond(this.workingCalendar);        }        this.domainStart = new Long(startL);        this.domainEnd = new Long(endL);        this.domainRange = new Range(startL, endL);    }    /**     * Returns the x position type (START, MIDDLE or END).     *     * @return The x position type.     */    public int getPosition() {        return this.position;    }    /**     * Sets the x position type (START, MIDDLE or END).     *     * @param position The x position type.     */    public void setPosition(int position) {        this.position = position;    }    /**     * Adds a series to the dataset.  Only the y-values are supplied, the      * x-values are specified elsewhere.     *     * @param values  the y-values.     * @param seriesNumber  the series index (zero-based).     * @param seriesKey  the series key.     *     * Use this as-is during setup only, or add the synchronized keyword around      * the copy loop.     */    public void addSeries(float[] values,                          int seriesNumber, Comparable seriesKey) {        invalidateRangeInfo();        int i;        if (values == null) {            throw new IllegalArgumentException("TimeSeriesDataset.addSeries(): "                + "cannot add null array of values.");        }        if (seriesNumber >= this.valueHistory.length) {            throw new IllegalArgumentException("TimeSeriesDataset.addSeries(): "                + "cannot add more series than specified in c'tor");        }        if (this.valueHistory[seriesNumber] == null) {            this.valueHistory[seriesNumber]                 = new ValueSequence(this.historyCount);            this.seriesCount++;        }           // But if that series array already exists, just overwrite its contents        // Avoid IndexOutOfBoundsException:        int srcLength = values.length;        int copyLength = this.historyCount;        boolean fillNeeded = false;        if (srcLength < this.historyCount) {            fillNeeded = true;            copyLength = srcLength;        }        //{        for (i = 0; i < copyLength; i++) { // deep copy from values[], caller                                            // can safely discard that array            this.valueHistory[seriesNumber].enterData(i, values[i]);        }        if (fillNeeded) {            for (i = copyLength; i < this.historyCount; i++) {                this.valueHistory[seriesNumber].enterData(i, 0.0f);            }        }      //}        if (seriesKey != null) {            this.seriesKeys[seriesNumber] = seriesKey;        }        fireSeriesChanged();    }    /**     * Sets the name of a series.  If planning to add values individually.     *     * @param seriesNumber  the series.     * @param key  the new key.     */    public void setSeriesKey(int seriesNumber, Comparable key) {        this.seriesKeys[seriesNumber] = key;    }    /**     * Adds a value to a series.     *     * @param seriesNumber  the series index.     * @param index  ??.     * @param value  the value.     */    public void addValue(int seriesNumber, int index, float value) {        invalidateRangeInfo();        if (seriesNumber >= this.valueHistory.length) {            throw new IllegalArgumentException(                "TimeSeriesDataset.addValue(): series #"                + seriesNumber + "unspecified in c'tor"            );        }        if (this.valueHistory[seriesNumber] == null) {            this.valueHistory[seriesNumber]                 = new ValueSequence(this.historyCount);            this.seriesCount++;        }          // But if that series array already exists, just overwrite its contents        //synchronized(this)        //{            this.valueHistory[seriesNumber].enterData(index, value);        //}        fireSeriesChanged();    }    /**     * Returns the number of series in the collection.     *     * @return The series count.     */    public int getSeriesCount() {        return this.seriesCount;    }    /**     * Returns the number of items in a series.     * <p>     * For this implementation, all series have the same number of items.     *     * @param series  the series index (zero-based).     *     * @return The item count.     */    public int getItemCount(int series) {  // all arrays equal length,                                            // so ignore argument:        return this.historyCount;    }    // Methods for managing the FIFO's:    /**     * Re-map an index, for use in retrieving data.     *     * @param toFetch  the index.     *     * @return The translated index.     */    protected int translateGet(int toFetch) {        if (this.oldestAt == 0) {            return toFetch;  // no translation needed        }        // else  [implicit here]        int newIndex = toFetch + this.oldestAt;        if (newIndex >= this.historyCount) {            newIndex -= this.historyCount;        }        return newIndex;    }    /**     * Returns the actual index to a time offset by "delta" from newestAt.     *     * @param delta  the delta.     *     * @return The offset.     */    public int offsetFromNewest(int delta) {        return wrapOffset(this.newestAt + delta);    }    /**     * ??     *     * @param delta ??     *     * @return The offset.     */    public int offsetFromOldest(int delta) {        return wrapOffset(this.oldestAt + delta);    }    /**     * ??     *     * @param protoIndex  the index.     *     * @return The offset.     */    protected int wrapOffset(int protoIndex) {        int tmp = protoIndex;        if (tmp >= this.historyCount) {            tmp -= this.historyCount;        }        else if (tmp < 0) {            tmp += this.historyCount;        }        return tmp;    }    /**     * Adjust the array offset as needed when a new time-period is added:     * Increments the indices "oldestAt" and "newestAt", mod(array length),     * zeroes the series values at newestAt, returns the new TimePeriod.     *     * @return The new time period.     */    public synchronized RegularTimePeriod advanceTime() {        RegularTimePeriod nextInstant = this.pointsInTime[this.newestAt].next();        this.newestAt = this.oldestAt;  // newestAt takes value previously held                                         // by oldestAT        /***          * The next 10 lines or so should be expanded if data can be negative          ***/        // if the oldest data contained a maximum Y-value, invalidate the stored        //   Y-max and Y-range data:        boolean extremaChanged = false;        float oldMax = 0.0f;        if (this.maxValue != null) {            oldMax = this.maxValue.floatValue();        }        for (int s = 0; s < getSeriesCount(); s++) {            if (this.valueHistory[s].getData(this.oldestAt) == oldMax) {                extremaChanged = true;            }            if (extremaChanged) {                break;            }        }  /*** If data can be < 0, add code here to check the minimum    **/        if (extremaChanged) {            invalidateRangeInfo();        }        //  wipe the next (about to be used) set of data slots        float wiper = (float) 0.0;        for (int s = 0; s < getSeriesCount(); s++) {            this.valueHistory[s].enterData(this.newestAt, wiper);        }        // Update the array of TimePeriods:        this.pointsInTime[this.newestAt] = nextInstant;        // Now advance "oldestAt", wrapping at end of the array        this.oldestAt++;        if (this.oldestAt >= this.historyCount) {            this.oldestAt = 0;        }        // Update the domain limits:        long startL = this.domainStart.longValue();  //(time is kept in msec)        this.domainStart = new Long(startL + this.deltaTime);        long endL = this.domainEnd.longValue();        this.domainEnd = new Long(endL + this.deltaTime);        this.domainRange = new Range(startL, endL);        fireSeriesChanged();        return nextInstant;    }    //  If data can be < 0, the next 2 methods should be modified    /**     * Invalidates the range info.     */    public void invalidateRangeInfo() {        this.maxValue = null;        this.valueRange = null;    }    /**     * Returns the maximum value.     *     * @return The maximum value.     */    protected double findMaxValue() {        double max = 0.0f;        for (int s = 0; s < getSeriesCount(); s++) {            for (int i = 0; i < this.historyCount; i++) {                double tmp = getYValue(s, i);                if (tmp > max) {                    max = tmp;                }            }        }        return max;    }    /** End, positive-data-only code  **/    /**     * Returns the index of the oldest data item.     *     * @return The index.     */    public int getOldestIndex() {        return this.oldestAt;    }    /**

⌨️ 快捷键说明

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