intervalxydelegate.java

来自「JfreeChart 常用图表例子」· Java 代码 · 共 460 行

JAVA
460
字号
/* =========================================================== * 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.] * * ----------------------- * IntervalXYDelegate.java * ----------------------- * (C) Copyright 2004, 2005, by Andreas Schroeder and Contributors. * * Original Author:  Andreas Schroeder; * Contributor(s):   David Gilbert (for Object Refinery Limited); * * $Id: IntervalXYDelegate.java,v 1.10 2005/05/03 10:13:17 mungady Exp $ * * Changes (from 31-Mar-2004) * -------------------------- * 31-Mar-2004 : Version 1 (AS); * 15-Jul-2004 : Switched getX() with getXValue() and getY() with  *               getYValue() (DG); * 18-Aug-2004 : Moved from org.jfree.data --> org.jfree.data.xy (DG); * 04-Nov-2004 : Added argument check for setIntervalWidth() method (DG); * 17-Nov-2004 : New methods to reflect changes in DomainInfo (DG); * 11-Jan-2005 : Removed deprecated methods in preparation for the 1.0.0  *               release (DG); * 21-Feb-2005 : Made public and added equals() method (DG); *  */package org.jfree.data.xy;import java.io.Serializable;import org.jfree.data.DomainInfo;import org.jfree.data.Range;import org.jfree.data.general.DatasetUtilities;import org.jfree.util.PublicCloneable;/** * A class for delegating xy-interval issues to.  * Enhances a XYDataset to an XYIntervalDataset. The decorator pattern * was not used because of the several possibly implemented interfaces of  * the decorated instance (e.g. TableXYDataset, RangeInfo, DomainInfo etc.). * <p> * This class calculates the minimal interval width between two items. This  * width influences the width of bars displayed with this dataset.  * <p> * The width can be set manually or calculated automatically. The switch * autoWidth allows to determine which behavior is used. The behavior is  * transparent: The width is always calculated automatically in the background  * without affecting the manually set width. The switch simply determines which  * value is used. <br> As default manually set width, 1.0 is used. <br> If there * is only one item in the series, the auto width calculation fails and falls  * back on the manually set interval width (which is itself defaulted to 1.0).  *  * @author andreas.schroeder */public class IntervalXYDelegate implements DomainInfo, Serializable,                                            Cloneable, PublicCloneable {        /** For serialization. */    private static final long serialVersionUID = -685166711639592857L;        /**     * The dataset to enhance.      */    private XYDataset dataset;    /**     * A flag to indicate whether the width should be calculated automatically.     */    private boolean autoWidth;        /**     * A factor that determines the position of the gap between two bars - only     * relevant if the data is dispalyed with a bar renderer.     */    private double intervalPositionFactor;         /**     * The manually set interval width.     */    private double intervalWidth;        /**     * The automatically calculated interval width.     */    private double autoIntervalWidth;        /**     * The lower value of the interval. Only used for autoWidth.     */    private double lowerBound;        /**     * The upper value of the interval. Only used for autoWidth.     */    private double upperBound;        /**     * Creates an XYIntervalDelegate.     *      * @param dataset the dataset for which this interval delegate works.     */    public IntervalXYDelegate(XYDataset dataset) {        this(dataset, true);    }        /**     * Creates a new delegate for the specified dataset.     *      * @param dataset  the dataset for which this interval delegate works.     * @param autoWidth  a flag that controls whether the interval width is      *                   calculated automatically.     */    public IntervalXYDelegate(XYDataset dataset, boolean autoWidth) {        this.autoWidth = autoWidth;        this.dataset = dataset;        this.intervalPositionFactor = 0.5;        this.autoWidth = autoWidth;        this.autoIntervalWidth = Double.POSITIVE_INFINITY;         this.intervalWidth = 1.0;    }        /**     * Returns whether the interval width is automatically calculated or not.     *      * @return Whether the width is automatically calculated or not.     */    public boolean isAutoWidth() {        return this.autoWidth;    }        /**     * Sets the flag that indicates whether the interval width is automatically     * calculated or not.      *      * @param b  a boolean.     */    public void setAutoWidth(boolean b) {        this.autoWidth = b;    }        /**     * Returns the interval position factor.      *      * @return The interval position factor.     */    public double getIntervalPositionFactor() {        return this.intervalPositionFactor;    }    /**     * Sets the interval position factor. Must be between 0.0 and 1.0 inclusive.     * If the factor is 0.5, the gap is in the middle of the x values. If it     * is lesser than 0.5, the gap is farther to the left and if greater than     * 0.5 it gets farther to the right.     *       * @param d  the new interval position factor (in the range      *           <code>0.0</code> to <code>1.0</code> inclusive).     */    public void setIntervalPositionFactor(double d) {        if (d < 0.0 || 1.0 < d) {            throw new IllegalArgumentException(                "Argument 'd' outside valid range."            );        }        this.intervalPositionFactor = d;    }    /**     * Sets the manual interval width.      *      * @param w  the width (negative values not permitted).     */    public void setIntervalWidth(double w) {        if (w < 0.0) {            throw new IllegalArgumentException("Negative 'w' argument.");        }        this.intervalWidth = w;    }        /**     * Returns the full interval width. For behavior of this method, see     * the class comments.      *      * @return The interval width to use.     */    public double getIntervalWidth() {        if (isAutoWidth() && !Double.isInfinite(this.autoIntervalWidth)) {            // everything is fine: autoWidth is on, and an autoIntervalWidth             // was set.            return this.autoIntervalWidth;        }        else {            // either autoWidth is off or autoIntervalWidth was not set.            return this.intervalWidth;        }    }    /**     * Returns the start x value based on the intervalWidth and the      * intervalPositionFactor.     *      * @param series  the series index.     * @param item  the item index.     *      * @return The start value based on the intervalWidth and the      *         intervalPositionFactor.     */    public Number getStartX(int series, int item) {        Number startX = null;        Number x = this.dataset.getX(series, item);        if (x != null) {            startX = new Double(x.doubleValue()                      - (getIntervalPositionFactor() * getIntervalWidth()));         }        return startX;    }            /**     * Returns the end x value based on the intervalWidth and the      * intervalPositionFactor.     *      * @param series  the series index.     * @param item  the item index.     *      * @return The end value based on the intervalWidth and the      *         intervalPositionFactor.     */    public Number getEndX(int series, int item) {        Number endX = null;        Number x = this.dataset.getX(series, item);        if (x != null) {            endX = new Double(                x.doubleValue()                 + ((1.0 - getIntervalPositionFactor()) * getIntervalWidth())            );         }        return endX;    }    /**     * Returns the minimum x-value in the dataset.     *     * @param includeInterval  a flag that determines whether or not the     *                         x-interval is taken into account.     *      * @return The minimum value.     */    public double getDomainLowerBound(boolean includeInterval) {        double result = Double.NaN;        Range r = getDomainBounds(includeInterval);        if (r != null) {            result = r.getLowerBound();        }        return result;    }    /**     * Returns the maximum x-value in the dataset.     *     * @param includeInterval  a flag that determines whether or not the     *                         x-interval is taken into account.     *      * @return The maximum value.     */    public double getDomainUpperBound(boolean includeInterval) {        double result = Double.NaN;        Range r = getDomainBounds(includeInterval);        if (r != null) {            result = r.getUpperBound();        }        return result;    }    /**     * Returns the range of the values in this dataset's domain.     *     * @param includeInterval  a flag that determines whether or not the      *                         x-interval should be taken into account.     *      * @return The range.     */    public Range getDomainBounds(boolean includeInterval) {        Range range = DatasetUtilities.iterateDomainBounds(            this.dataset, includeInterval        );        if (this.dataset.getSeriesCount() == 1             && this.dataset.getItemCount(0) == 1) {            /* if there is only one interval value, so add some space to the              * left and the right - otherwise one bar looks like a background              * coloration.             */            range = new Range(                range.getLowerBound() - getIntervalWidth(),                 range.getUpperBound() + getIntervalWidth()            );        }        return range;    }        /**     * Updates the interval width if an item is added.  That is, relaxes the      * interval width to the minimum of the actual interval width, the      * distance between the actual x value and the previous x value and the      * distance between the next x value and the actual x value.      *      * @param item the number of the item.     * @param series the number of the series     *      */    public void itemAdded(int series, int item) {        double x = this.dataset.getXValue(series, item);                if (item > 0) {            double before = this.dataset.getXValue(series, item - 1);            double delta = x - before;            if (delta < this.autoIntervalWidth) {                this.autoIntervalWidth = delta;                this.lowerBound = before;                this.upperBound = x;            }        }                if (item + 1 < this.dataset.getItemCount(series)) {            double after = this.dataset.getXValue(series, item + 1);            double delta = after - x;            if (delta < this.autoIntervalWidth) {                this.autoIntervalWidth = delta;                this.lowerBound = x;                this.upperBound = after;            }        }    }        /**     * Updates the interval width if an item is removed. That is, enlarges the     * interval width to the new interval minimum if the removed value was     * part of the minimum. For performance reason this method should be called      * only if the x value was definitely removed from the series.     *       * @param x the x value of the removed item (that doesn't occur twice)     */    public void itemRemoved(double x) {        if (x == this.lowerBound || x == this.upperBound) {            recalculateIntervalWidth();        }    }        /**     * Recalculate the minimum width "from scratch".     */    private void recalculateIntervalWidth() {        this.autoIntervalWidth = Double.POSITIVE_INFINITY;                for (int series = 0, seriesCount = this.dataset.getSeriesCount();             series < seriesCount; series++) {                      calculateSeries(series);        }    }        /**     * Calculates the interval width for a given series.     *       * @param series  the series index.     */    private void calculateSeries(int series) {        int totalCount = this.dataset.getItemCount(series);        for (int item = 1, itemCount = totalCount; item < itemCount; item++) {                            double lower = this.dataset.getXValue(series, item - 1);            double upper = this.dataset.getXValue(series, item);            double delta = upper - lower;                            if (delta < this.autoIntervalWidth) {                this.autoIntervalWidth = delta;                this.lowerBound = lower;                this.upperBound = upper;            }        }    }        /**     * Convenience method for XYSeriesCollection.     *      * @param series  the series index.     */    public void seriesAdded(int series) {        calculateSeries(series);    }        /**     * A convenience method for {@link XYSeriesCollection} which is called      * whenever a series is removed - the interval width is recalculated.     */    public void seriesRemoved() {        recalculateIntervalWidth();    }        /**     * Tests the delegate for equality with an arbitrary object.     *      * @param obj  the object (<code>null</code> permitted).     *      * @return A boolean.     */    public boolean equals(Object obj) {        if (obj == this) {            return true;           }        if (!(obj instanceof IntervalXYDelegate)) {            return false;           }        IntervalXYDelegate that = (IntervalXYDelegate) obj;        if (this.autoWidth != that.autoWidth) {            return false;           }        if (this.intervalPositionFactor != that.intervalPositionFactor) {            return false;           }        if (this.intervalWidth != that.intervalWidth) {            return false;           }        return true;    }        /**     * @return A clone of this delegate.     *      * @throws CloneNotSupportedException if the object cannot be cloned.     */    public Object clone() throws CloneNotSupportedException {        return super.clone();    }    }

⌨️ 快捷键说明

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