    001    /* ===========================================================
    002     * JFreeChart : a free chart library for the Java(tm) platform
    003     * ===========================================================
    004     *
    005     * (C) Copyright 2000-2011, by Object Refinery Limited and Contributors.
    006     *
    007     * Project Info:  http://www.jfree.org/jfreechart/index.html
    008     *
    009     * This library is free software; you can redistribute it and/or modify it
    010     * under the terms of the GNU Lesser General Public License as published by
    011     * the Free Software Foundation; either version 2.1 of the License, or
    012     * (at your option) any later version.
    013     *
    014     * This library is distributed in the hope that it will be useful, but
    015     * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    016     * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
    017     * License for more details.
    018     *
    019     * You should have received a copy of the GNU Lesser General Public
    020     * License along with this library; if not, write to the Free Software
    021     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
    022     * USA.
    023     *
    024     * [Oracle and Java are registered trademarks of Oracle and/or its affiliates.
    025     * Other names may be trademarks of their respective owners.]
    026     *
    027     * -----------------------
    028     * SimpleHistogramBin.java
    029     * -----------------------
    030     * (C) Copyright 2005-2008, by Object Refinery Limited and Contributors.
    031     *
    032     * Original Author:  David Gilbert (for Object Refinery Limited);
    033     * Contributor(s):   -;
    034     *
    035     * Changes
    036     * -------
    037     * 10-Jan-2005 : Version 1 (DG);
    038     *
    039     */
    040
    041    package org.jfree.data.statistics;
    042
    043    import java.io.Serializable;
    044
    045    import org.jfree.util.PublicCloneable;
    046
    047    /**
    048     * A bin for the {@link SimpleHistogramDataset}.
    049     */
    050    public class SimpleHistogramBin implements Comparable,
    051            Cloneable, PublicCloneable, Serializable {
    052
    053        /** For serialization. */
    054        private static final long serialVersionUID = 3480862537505941742L;
    055
    056        /** The lower bound for the bin. */
    057        private double lowerBound;
    058
    059        /** The upper bound for the bin. */
    060        private double upperBound;
    061
    062        /**
    063         * A flag that controls whether the lower bound is included in the bin
    064         * range.
    065         */
    066        private boolean includeLowerBound;
    067
    068        /**
    069         * A flag that controls whether the upper bound is included in the bin
    070         * range.
    071         */
    072        private boolean includeUpperBound;
    073
    074        /** The item count. */
    075        private int itemCount;
    076
    077        /**
    078         * Creates a new bin.
    079         *
    080         * @param lowerBound  the lower bound (inclusive).
    081         * @param upperBound  the upper bound (inclusive);
    082         */
    083        public SimpleHistogramBin(double lowerBound, double upperBound) {
    084            this(lowerBound, upperBound, true, true);
    085        }
    086
    087        /**
    088         * Creates a new bin.
    089         *
    090         * @param lowerBound  the lower bound.
    091         * @param upperBound  the upper bound.
    092         * @param includeLowerBound  include the lower bound?
    093         * @param includeUpperBound  include the upper bound?
    094         */
    095        public SimpleHistogramBin(double lowerBound, double upperBound,
    096                                  boolean includeLowerBound,
    097                                  boolean includeUpperBound) {
    098            if (lowerBound >= upperBound) {
    099                throw new IllegalArgumentException("Invalid bounds");
    100            }
    101            this.lowerBound = lowerBound;
    102            this.upperBound = upperBound;
    103            this.includeLowerBound = includeLowerBound;
    104            this.includeUpperBound = includeUpperBound;
    105            this.itemCount = 0;
    106        }
    107
    108        /**
    109         * Returns the lower bound.
    110         *
    111         * @return The lower bound.
    112         */
    113        public double getLowerBound() {
    114            return this.lowerBound;
    115        }
    116
    117        /**
    118         * Return the upper bound.
    119         *
    120         * @return The upper bound.
    121         */
    122        public double getUpperBound() {
    123            return this.upperBound;
    124        }
    125
    126        /**
    127         * Returns the item count.
    128         *
    129         * @return The item count.
    130         */
    131        public int getItemCount() {
    132            return this.itemCount;
    133        }
    134
    135        /**
    136         * Sets the item count.
    137         *
    138         * @param count  the item count.
    139         */
    140        public void setItemCount(int count) {
    141            this.itemCount = count;
    142        }
    143
    144        /**
    145         * Returns <code>true</code> if the specified value belongs in the bin,
    146         * and <code>false</code> otherwise.
    147         *
    148         * @param value  the value.
    149         *
    150         * @return A boolean.
    151         */
    152        public boolean accepts(double value) {
    153            if (Double.isNaN(value)) {
    154                return false;
    155            }
    156            if (value < this.lowerBound) {
    157                return false;
    158            }
    159            if (value > this.upperBound) {
    160                return false;
    161            }
    162            if (value == this.lowerBound) {
    163                return this.includeLowerBound;
    164            }
    165            if (value == this.upperBound) {
    166                return this.includeUpperBound;
    167            }
    168            return true;
    169        }
    170
    171        /**
    172         * Returns <code>true</code> if this bin overlaps with the specified bin,
    173         * and <code>false</code> otherwise.
    174         *
    175         * @param bin  the other bin (<code>null</code> not permitted).
    176         *
    177         * @return A boolean.
    178         */
    179        public boolean overlapsWith(SimpleHistogramBin bin) {
    180            if (this.upperBound < bin.lowerBound) {
    181                return false;
    182            }
    183            if (this.lowerBound > bin.upperBound) {
    184                return false;
    185            }
    186            if (this.upperBound == bin.lowerBound) {
    187                return this.includeUpperBound && bin.includeLowerBound;
    188            }
    189            if (this.lowerBound == bin.upperBound) {
    190                return this.includeLowerBound && bin.includeUpperBound;
    191            }
    192            return true;
    193        }
    194
    195        /**
    196         * Compares the bin to an arbitrary object and returns the relative
    197         * ordering.
    198         *
    199         * @param obj  the object.
    200         *
    201         * @return An integer indicating the relative ordering of the this bin and
    202         *         the given object.
    203         */
    204        public int compareTo(Object obj) {
    205            if (!(obj instanceof SimpleHistogramBin)) {
    206                return 0;
    207            }
    208            SimpleHistogramBin bin = (SimpleHistogramBin) obj;
    209            if (this.lowerBound < bin.lowerBound) {
    210                return -1;
    211            }
    212            if (this.lowerBound > bin.lowerBound) {
    213                return 1;
    214            }
    215            // lower bounds are the same
    216            if (this.upperBound < bin.upperBound) {
    217                return -1;
    218            }
    219            if (this.upperBound > bin.upperBound) {
    220                return 1;
    221            }
    222            return 0;
    223        }
    224
    225        /**
    226         * Tests this bin for equality with an arbitrary object.
    227         *
    228         * @param obj  the object (<code>null</code> permitted).
    229         *
    230         * @return A boolean.
    231         */
    232        public boolean equals(Object obj) {
    233            if (!(obj instanceof SimpleHistogramBin)) {
    234                return false;
    235            }
    236            SimpleHistogramBin that = (SimpleHistogramBin) obj;
    237            if (this.lowerBound != that.lowerBound) {
    238                return false;
    239            }
    240            if (this.upperBound != that.upperBound) {
    241                return false;
    242            }
    243            if (this.includeLowerBound != that.includeLowerBound) {
    244                return false;
    245            }
    246            if (this.includeUpperBound != that.includeUpperBound) {
    247                return false;
    248            }
    249            if (this.itemCount != that.itemCount) {
    250                return false;
    251            }
    252            return true;
    253        }
    254
    255        /**
    256         * Returns a clone of the bin.
    257         *
    258         * @return A clone.
    259         *
    260         * @throws CloneNotSupportedException not thrown by this class.
    261         */
    262        public Object clone() throws CloneNotSupportedException {
    263            return super.clone();
    264        }
    265
    266    }