1 /* ===========================================================
2  * JFreeChart : a free chart library for the Java(tm) platform
3  * ===========================================================
4  *
5  * (C) Copyright 2000-2013, by Object Refinery Limited and Contributors.
6  *
7  * Project Info:  http://www.jfree.org/jfreechart/index.html
8  *
9  * This library is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2.1 of the License, or
12  * (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17  * License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
22  * USA.
23  *
24  * [Oracle and Java are registered trademarks of Oracle and/or its affiliates.
25  * Other names may be trademarks of their respective owners.]
26  *
27  * ---------------
28  * XYDataItem.java
29  * ---------------
30  * (C) Copyright 2003-2013, by Object Refinery Limited.
31  *
32  * Original Author:  David Gilbert (for Object Refinery Limited);
33  * Contributor(s):   -;
34  *
35  * Changes
36  * -------
37  * 05-Aug-2003 : Renamed XYDataPair --> XYDataItem (DG);
38  * 03-Feb-2004 : Fixed bug in equals() method (DG);
39  * 21-Feb-2005 : Added setY(double) method (DG);
40  * ------------- JFREECHART 1.0.x ---------------------------------------------
41  * 30-Nov-2007 : Implemented getXValue() and getYValue(), plus toString() for
42  *               debugging use (DG);
43  * 10-Jun-2009 : Reimplemented cloning (DG);
44  * 02-Jul-2013 : Use ParamChecks (DG);
45  *
46  */
47 
48 package org.jfree.data.xy;
49 
50 import java.io.Serializable;
51 import org.jfree.chart.util.ParamChecks;
52 
53 import org.jfree.util.ObjectUtilities;
54 
55 /**
56  * Represents one (x, y) data item for an {@link XYSeries}.  Note that
57  * subclasses are REQUIRED to support cloning.
58  */
59 public class XYDataItem implements Cloneable, Comparable, Serializable {
60 
61     /** For serialization. */
62     private static final long serialVersionUID = 2751513470325494890L;
63 
64     /** The x-value (<code>null</code> not permitted). */
65     private Number x;
66 
67     /** The y-value. */
68     private Number y;
69 
70     /**
71      * Constructs a new data item.
72      *
73      * @param x  the x-value (<code>null</code> NOT permitted).
74      * @param y  the y-value (<code>null</code> permitted).
75      */
XYDataItem(Number x, Number y)76     public XYDataItem(Number x, Number y) {
77         ParamChecks.nullNotPermitted(x, "x");
78         this.x = x;
79         this.y = y;
80     }
81 
82     /**
83      * Constructs a new data item.
84      *
85      * @param x  the x-value.
86      * @param y  the y-value.
87      */
XYDataItem(double x, double y)88     public XYDataItem(double x, double y) {
89         this(new Double(x), new Double(y));
90     }
91 
92     /**
93      * Returns the x-value.
94      *
95      * @return The x-value (never <code>null</code>).
96      */
getX()97     public Number getX() {
98         return this.x;
99     }
100 
101     /**
102      * Returns the x-value as a double primitive.
103      *
104      * @return The x-value.
105      *
106      * @see #getX()
107      * @see #getYValue()
108      *
109      * @since 1.0.9
110      */
getXValue()111     public double getXValue() {
112         // this.x is not allowed to be null...
113         return this.x.doubleValue();
114     }
115 
116     /**
117      * Returns the y-value.
118      *
119      * @return The y-value (possibly <code>null</code>).
120      */
getY()121     public Number getY() {
122         return this.y;
123     }
124 
125     /**
126      * Returns the y-value as a double primitive.
127      *
128      * @return The y-value.
129      *
130      * @see #getY()
131      * @see #getXValue()
132      *
133      * @since 1.0.9
134      */
getYValue()135     public double getYValue() {
136         double result = Double.NaN;
137         if (this.y != null) {
138             result = this.y.doubleValue();
139         }
140         return result;
141     }
142 
143     /**
144      * Sets the y-value for this data item.  Note that there is no
145      * corresponding method to change the x-value.
146      *
147      * @param y  the new y-value.
148      */
setY(double y)149     public void setY(double y) {
150         setY(new Double(y));
151     }
152 
153     /**
154      * Sets the y-value for this data item.  Note that there is no
155      * corresponding method to change the x-value.
156      *
157      * @param y  the new y-value (<code>null</code> permitted).
158      */
setY(Number y)159     public void setY(Number y) {
160         this.y = y;
161     }
162 
163     /**
164      * Returns an integer indicating the order of this object relative to
165      * another object.
166      * <P>
167      * For the order we consider only the x-value:
168      * negative == "less-than", zero == "equal", positive == "greater-than".
169      *
170      * @param o1  the object being compared to.
171      *
172      * @return An integer indicating the order of this data pair object
173      *      relative to another object.
174      */
175     @Override
compareTo(Object o1)176     public int compareTo(Object o1) {
177 
178         int result;
179 
180         // CASE 1 : Comparing to another TimeSeriesDataPair object
181         // -------------------------------------------------------
182         if (o1 instanceof XYDataItem) {
183             XYDataItem dataItem = (XYDataItem) o1;
184             double compare = this.x.doubleValue()
185                              - dataItem.getX().doubleValue();
186             if (compare > 0.0) {
187                 result = 1;
188             }
189             else {
190                 if (compare < 0.0) {
191                     result = -1;
192                 }
193                 else {
194                     result = 0;
195                 }
196             }
197         }
198 
199         // CASE 2 : Comparing to a general object
200         // ---------------------------------------------
201         else {
202             // consider time periods to be ordered after general objects
203             result = 1;
204         }
205 
206         return result;
207 
208     }
209 
210     /**
211      * Returns a clone of this object.
212      *
213      * @return A clone.
214      */
215     @Override
clone()216     public Object clone() {
217         Object clone = null;
218         try {
219             clone = super.clone();
220         }
221         catch (CloneNotSupportedException e) { // won't get here...
222             e.printStackTrace();
223         }
224         return clone;
225     }
226 
227     /**
228      * Tests if this object is equal to another.
229      *
230      * @param obj  the object to test against for equality (<code>null</code>
231      *             permitted).
232      *
233      * @return A boolean.
234      */
235     @Override
equals(Object obj)236     public boolean equals(Object obj) {
237         if (obj == this) {
238             return true;
239         }
240         if (!(obj instanceof XYDataItem)) {
241             return false;
242         }
243         XYDataItem that = (XYDataItem) obj;
244         if (!this.x.equals(that.x)) {
245             return false;
246         }
247         if (!ObjectUtilities.equal(this.y, that.y)) {
248             return false;
249         }
250         return true;
251     }
252 
253     /**
254      * Returns a hash code.
255      *
256      * @return A hash code.
257      */
258     @Override
hashCode()259     public int hashCode() {
260         int result;
261         result = this.x.hashCode();
262         result = 29 * result + (this.y != null ? this.y.hashCode() : 0);
263         return result;
264     }
265 
266     /**
267      * Returns a string representing this instance, primarily for debugging
268      * use.
269      *
270      * @return A string.
271      */
272     @Override
toString()273     public String toString() {
274         return "[" + getXValue() + ", " + getYValue() + "]";
275     }
276 
277 }
278