create changelog entry
[debian/openrocket] / android-libraries / achartengine / src / org / achartengine / model / XYSeries.java
1 /**\r
2  * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL\r
3  * \r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  * \r
8  *      http://www.apache.org/licenses/LICENSE-2.0\r
9  * \r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 package org.achartengine.model;\r
17 \r
18 import java.io.Serializable;\r
19 import java.util.Iterator;\r
20 import java.util.SortedMap;\r
21 \r
22 import org.achartengine.util.IndexXYMap;\r
23 import org.achartengine.util.MathHelper;\r
24 import org.achartengine.util.XYEntry;\r
25 \r
26 /**\r
27  * An XY series encapsulates values for XY charts like line, time, area,\r
28  * scatter... charts.\r
29  */\r
30 public class XYSeries implements Serializable {\r
31   /** The series title. */\r
32   private String mTitle;\r
33   /** A map to contain values for X and Y axes and index for each bundle */\r
34   private final IndexXYMap<Double, Double> mXY = new IndexXYMap<Double, Double>();\r
35   /** The minimum value for the X axis. */\r
36   private double mMinX = MathHelper.NULL_VALUE;\r
37   /** The maximum value for the X axis. */\r
38   private double mMaxX = -MathHelper.NULL_VALUE;\r
39   /** The minimum value for the Y axis. */\r
40   private double mMinY = MathHelper.NULL_VALUE;\r
41   /** The maximum value for the Y axis. */\r
42   private double mMaxY = -MathHelper.NULL_VALUE;\r
43   /** The scale number for this series. */\r
44   private final int mScaleNumber;\r
45 \r
46   /**\r
47    * Builds a new XY series.\r
48    * \r
49    * @param title the series title.\r
50    */\r
51   public XYSeries(String title) {\r
52     this(title, 0);\r
53   }\r
54 \r
55   /**\r
56    * Builds a new XY series.\r
57    * \r
58    * @param title the series title.\r
59    * @param scaleNumber the series scale number\r
60    */\r
61   public XYSeries(String title, int scaleNumber) {\r
62     mTitle = title;\r
63     mScaleNumber = scaleNumber;\r
64     initRange();\r
65   }\r
66 \r
67   public int getScaleNumber() {\r
68     return mScaleNumber;\r
69   }\r
70 \r
71   /**\r
72    * Initializes the range for both axes.\r
73    */\r
74   private void initRange() {\r
75     mMinX = MathHelper.NULL_VALUE;\r
76     mMaxX = -MathHelper.NULL_VALUE;\r
77     mMinY = MathHelper.NULL_VALUE;\r
78     mMaxY = -MathHelper.NULL_VALUE;\r
79     int length = getItemCount();\r
80     for (int k = 0; k < length; k++) {\r
81       double x = getX(k);\r
82       double y = getY(k);\r
83       updateRange(x, y);\r
84     }\r
85   }\r
86 \r
87   /**\r
88    * Updates the range on both axes.\r
89    * \r
90    * @param x the new x value\r
91    * @param y the new y value\r
92    */\r
93   private void updateRange(double x, double y) {\r
94     mMinX = Math.min(mMinX, x);\r
95     mMaxX = Math.max(mMaxX, x);\r
96     mMinY = Math.min(mMinY, y);\r
97     mMaxY = Math.max(mMaxY, y);\r
98   }\r
99 \r
100   /**\r
101    * Returns the series title.\r
102    * \r
103    * @return the series title\r
104    */\r
105   public String getTitle() {\r
106     return mTitle;\r
107   }\r
108 \r
109   /**\r
110    * Sets the series title.\r
111    * \r
112    * @param title the series title\r
113    */\r
114   public void setTitle(String title) {\r
115     mTitle = title;\r
116   }\r
117 \r
118   /**\r
119    * Adds a new value to the series.\r
120    * \r
121    * @param x the value for the X axis\r
122    * @param y the value for the Y axis\r
123    */\r
124   public synchronized void add(double x, double y) {\r
125     mXY.put(x, y);\r
126     updateRange(x, y);\r
127   }\r
128 \r
129   /**\r
130    * Removes an existing value from the series.\r
131    * \r
132    * @param index the index in the series of the value to remove\r
133    */\r
134   public synchronized void remove(int index) {\r
135     XYEntry<Double, Double> removedEntry = mXY.removeByIndex(index);\r
136     double removedX = removedEntry.getKey();\r
137     double removedY = removedEntry.getValue();\r
138     if (removedX == mMinX || removedX == mMaxX || removedY == mMinY || removedY == mMaxY) {\r
139       initRange();\r
140     }\r
141   }\r
142 \r
143   /**\r
144    * Removes all the existing values from the series.\r
145    */\r
146   public synchronized void clear() {\r
147     mXY.clear();\r
148     initRange();\r
149   }\r
150 \r
151   /**\r
152    * Returns the X axis value at the specified index.\r
153    * \r
154    * @param index the index\r
155    * @return the X value\r
156    */\r
157   public synchronized double getX(int index) {\r
158     return mXY.getXByIndex(index);\r
159   }\r
160 \r
161   /**\r
162    * Returns the Y axis value at the specified index.\r
163    * \r
164    * @param index the index\r
165    * @return the Y value\r
166    */\r
167   public synchronized double getY(int index) {\r
168     return mXY.getYByIndex(index);\r
169   }\r
170 \r
171   /**\r
172    * Returns submap of x and y values according to the given start and end\r
173    * \r
174    * @param start start x value\r
175    * @param stop stop x value\r
176    * @return a submap of x and y values\r
177    */\r
178   public synchronized SortedMap<Double, Double> getRange(double start, double stop,\r
179       int beforeAfterPoints) {\r
180     // we need to add one point before the start and one point after the end (if\r
181     // there are any)\r
182     // to ensure that line doesn't end before the end of the screen\r
183 \r
184     // this would be simply: start = mXY.lowerKey(start) but NavigableMap is\r
185     // available since API 9\r
186     SortedMap<Double, Double> headMap = mXY.headMap(start);\r
187     if (!headMap.isEmpty()) {\r
188       start = headMap.lastKey();\r
189     }\r
190 \r
191     // this would be simply: end = mXY.higherKey(end) but NavigableMap is\r
192     // available since API 9\r
193     // so we have to do this hack in order to support older versions\r
194     SortedMap<Double, Double> tailMap = mXY.tailMap(stop);\r
195     if (!tailMap.isEmpty()) {\r
196       Iterator<Double> tailIterator = tailMap.keySet().iterator();\r
197       Double next = tailIterator.next();\r
198       if (tailIterator.hasNext()) {\r
199         stop = tailIterator.next();\r
200       } else {\r
201         stop += next;\r
202       }\r
203     }\r
204     return mXY.subMap(start, stop);\r
205   }\r
206 \r
207   public int getIndexForKey(double key) {\r
208     return mXY.getIndexForKey(key);\r
209   }\r
210 \r
211   /**\r
212    * Returns the series item count.\r
213    * \r
214    * @return the series item count\r
215    */\r
216   public synchronized int getItemCount() {\r
217     return mXY.size();\r
218   }\r
219 \r
220   /**\r
221    * Returns the minimum value on the X axis.\r
222    * \r
223    * @return the X axis minimum value\r
224    */\r
225   public double getMinX() {\r
226     return mMinX;\r
227   }\r
228 \r
229   /**\r
230    * Returns the minimum value on the Y axis.\r
231    * \r
232    * @return the Y axis minimum value\r
233    */\r
234   public double getMinY() {\r
235     return mMinY;\r
236   }\r
237 \r
238   /**\r
239    * Returns the maximum value on the X axis.\r
240    * \r
241    * @return the X axis maximum value\r
242    */\r
243   public double getMaxX() {\r
244     return mMaxX;\r
245   }\r
246 \r
247   /**\r
248    * Returns the maximum value on the Y axis.\r
249    * \r
250    * @return the Y axis maximum value\r
251    */\r
252   public double getMaxY() {\r
253     return mMaxY;\r
254   }\r
255 }\r