001/* ===========================================================
002 * JFreeChart : a free chart library for the Java(tm) platform
003 * ===========================================================
004 *
005 * (C) Copyright 2000-present, by David Gilbert 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-present, by David Gilbert and Contributors.
031 *
032 * Original Author:  David Gilbert;
033 * Contributor(s):   -;
034 *
035 */
036
037package org.jfree.data.statistics;
038
039import java.io.Serializable;
040import org.jfree.chart.util.PublicCloneable;
041
042/**
043 * A bin for the {@link SimpleHistogramDataset}.
044 */
045public class SimpleHistogramBin implements Comparable,
046        Cloneable, PublicCloneable, Serializable {
047
048    /** For serialization. */
049    private static final long serialVersionUID = 3480862537505941742L;
050
051    /** The lower bound for the bin. */
052    private double lowerBound;
053
054    /** The upper bound for the bin. */
055    private double upperBound;
056
057    /**
058     * A flag that controls whether the lower bound is included in the bin
059     * range.
060     */
061    private boolean includeLowerBound;
062
063    /**
064     * A flag that controls whether the upper bound is included in the bin
065     * range.
066     */
067    private boolean includeUpperBound;
068
069    /** The item count. */
070    private int itemCount;
071
072    /**
073     * Creates a new bin.
074     *
075     * @param lowerBound  the lower bound (inclusive).
076     * @param upperBound  the upper bound (inclusive);
077     */
078    public SimpleHistogramBin(double lowerBound, double upperBound) {
079        this(lowerBound, upperBound, true, true);
080    }
081
082    /**
083     * Creates a new bin.
084     *
085     * @param lowerBound  the lower bound.
086     * @param upperBound  the upper bound.
087     * @param includeLowerBound  include the lower bound?
088     * @param includeUpperBound  include the upper bound?
089     */
090    public SimpleHistogramBin(double lowerBound, double upperBound,
091                              boolean includeLowerBound,
092                              boolean includeUpperBound) {
093        if (lowerBound >= upperBound) {
094            throw new IllegalArgumentException("Invalid bounds");
095        }
096        this.lowerBound = lowerBound;
097        this.upperBound = upperBound;
098        this.includeLowerBound = includeLowerBound;
099        this.includeUpperBound = includeUpperBound;
100        this.itemCount = 0;
101    }
102
103    /**
104     * Returns the lower bound.
105     *
106     * @return The lower bound.
107     */
108    public double getLowerBound() {
109        return this.lowerBound;
110    }
111
112    /**
113     * Return the upper bound.
114     *
115     * @return The upper bound.
116     */
117    public double getUpperBound() {
118        return this.upperBound;
119    }
120
121    /**
122     * Returns the item count.
123     *
124     * @return The item count.
125     */
126    public int getItemCount() {
127        return this.itemCount;
128    }
129
130    /**
131     * Sets the item count.
132     *
133     * @param count  the item count.
134     */
135    public void setItemCount(int count) {
136        this.itemCount = count;
137    }
138
139    /**
140     * Returns {@code true} if the specified value belongs in the bin,
141     * and {@code false} otherwise.
142     *
143     * @param value  the value.
144     *
145     * @return A boolean.
146     */
147    public boolean accepts(double value) {
148        if (Double.isNaN(value)) {
149            return false;
150        }
151        if (value < this.lowerBound) {
152            return false;
153        }
154        if (value > this.upperBound) {
155            return false;
156        }
157        if (value == this.lowerBound) {
158            return this.includeLowerBound;
159        }
160        if (value == this.upperBound) {
161            return this.includeUpperBound;
162        }
163        return true;
164    }
165
166    /**
167     * Returns {@code true} if this bin overlaps with the specified bin,
168     * and {@code false} otherwise.
169     *
170     * @param bin  the other bin ({@code null} not permitted).
171     *
172     * @return A boolean.
173     */
174    public boolean overlapsWith(SimpleHistogramBin bin) {
175        if (this.upperBound < bin.lowerBound) {
176            return false;
177        }
178        if (this.lowerBound > bin.upperBound) {
179            return false;
180        }
181        if (this.upperBound == bin.lowerBound) {
182            return this.includeUpperBound && bin.includeLowerBound;
183        }
184        if (this.lowerBound == bin.upperBound) {
185            return this.includeLowerBound && bin.includeUpperBound;
186        }
187        return true;
188    }
189
190    /**
191     * Compares the bin to an arbitrary object and returns the relative
192     * ordering.
193     *
194     * @param obj  the object.
195     *
196     * @return An integer indicating the relative ordering of the this bin and
197     *         the given object.
198     */
199    @Override
200    public int compareTo(Object obj) {
201        if (!(obj instanceof SimpleHistogramBin)) {
202            return 0;
203        }
204        SimpleHistogramBin bin = (SimpleHistogramBin) obj;
205        if (this.lowerBound < bin.lowerBound) {
206            return -1;
207        }
208        if (this.lowerBound > bin.lowerBound) {
209            return 1;
210        }
211        // lower bounds are the same
212        if (this.upperBound < bin.upperBound) {
213            return -1;
214        }
215        if (this.upperBound > bin.upperBound) {
216            return 1;
217        }
218        return 0;
219    }
220
221    /**
222     * Tests this bin for equality with an arbitrary object.
223     *
224     * @param obj  the object ({@code null} permitted).
225     *
226     * @return A boolean.
227     */
228    @Override
229    public boolean equals(Object obj) {
230        if (!(obj instanceof SimpleHistogramBin)) {
231            return false;
232        }
233        SimpleHistogramBin that = (SimpleHistogramBin) obj;
234        if (this.lowerBound != that.lowerBound) {
235            return false;
236        }
237        if (this.upperBound != that.upperBound) {
238            return false;
239        }
240        if (this.includeLowerBound != that.includeLowerBound) {
241            return false;
242        }
243        if (this.includeUpperBound != that.includeUpperBound) {
244            return false;
245        }
246        if (this.itemCount != that.itemCount) {
247            return false;
248        }
249        return true;
250    }
251
252    /**
253     * Returns a clone of the bin.
254     *
255     * @return A clone.
256     *
257     * @throws CloneNotSupportedException not thrown by this class.
258     */
259    @Override
260    public Object clone() throws CloneNotSupportedException {
261        return super.clone();
262    }
263
264}