Merge commit '42b2e5ca519766e37ce6941ba4faecc9691cc403' into upstream
[debian/openrocket] / android-libraries / achartengine / src / org / achartengine / model / XYSeries.java
diff --git a/android-libraries/achartengine/src/org/achartengine/model/XYSeries.java b/android-libraries/achartengine/src/org/achartengine/model/XYSeries.java
new file mode 100644 (file)
index 0000000..56063b7
--- /dev/null
@@ -0,0 +1,255 @@
+/**\r
+ * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ * \r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.achartengine.model;\r
+\r
+import java.io.Serializable;\r
+import java.util.Iterator;\r
+import java.util.SortedMap;\r
+\r
+import org.achartengine.util.IndexXYMap;\r
+import org.achartengine.util.MathHelper;\r
+import org.achartengine.util.XYEntry;\r
+\r
+/**\r
+ * An XY series encapsulates values for XY charts like line, time, area,\r
+ * scatter... charts.\r
+ */\r
+public class XYSeries implements Serializable {\r
+  /** The series title. */\r
+  private String mTitle;\r
+  /** A map to contain values for X and Y axes and index for each bundle */\r
+  private final IndexXYMap<Double, Double> mXY = new IndexXYMap<Double, Double>();\r
+  /** The minimum value for the X axis. */\r
+  private double mMinX = MathHelper.NULL_VALUE;\r
+  /** The maximum value for the X axis. */\r
+  private double mMaxX = -MathHelper.NULL_VALUE;\r
+  /** The minimum value for the Y axis. */\r
+  private double mMinY = MathHelper.NULL_VALUE;\r
+  /** The maximum value for the Y axis. */\r
+  private double mMaxY = -MathHelper.NULL_VALUE;\r
+  /** The scale number for this series. */\r
+  private final int mScaleNumber;\r
+\r
+  /**\r
+   * Builds a new XY series.\r
+   * \r
+   * @param title the series title.\r
+   */\r
+  public XYSeries(String title) {\r
+    this(title, 0);\r
+  }\r
+\r
+  /**\r
+   * Builds a new XY series.\r
+   * \r
+   * @param title the series title.\r
+   * @param scaleNumber the series scale number\r
+   */\r
+  public XYSeries(String title, int scaleNumber) {\r
+    mTitle = title;\r
+    mScaleNumber = scaleNumber;\r
+    initRange();\r
+  }\r
+\r
+  public int getScaleNumber() {\r
+    return mScaleNumber;\r
+  }\r
+\r
+  /**\r
+   * Initializes the range for both axes.\r
+   */\r
+  private void initRange() {\r
+    mMinX = MathHelper.NULL_VALUE;\r
+    mMaxX = -MathHelper.NULL_VALUE;\r
+    mMinY = MathHelper.NULL_VALUE;\r
+    mMaxY = -MathHelper.NULL_VALUE;\r
+    int length = getItemCount();\r
+    for (int k = 0; k < length; k++) {\r
+      double x = getX(k);\r
+      double y = getY(k);\r
+      updateRange(x, y);\r
+    }\r
+  }\r
+\r
+  /**\r
+   * Updates the range on both axes.\r
+   * \r
+   * @param x the new x value\r
+   * @param y the new y value\r
+   */\r
+  private void updateRange(double x, double y) {\r
+    mMinX = Math.min(mMinX, x);\r
+    mMaxX = Math.max(mMaxX, x);\r
+    mMinY = Math.min(mMinY, y);\r
+    mMaxY = Math.max(mMaxY, y);\r
+  }\r
+\r
+  /**\r
+   * Returns the series title.\r
+   * \r
+   * @return the series title\r
+   */\r
+  public String getTitle() {\r
+    return mTitle;\r
+  }\r
+\r
+  /**\r
+   * Sets the series title.\r
+   * \r
+   * @param title the series title\r
+   */\r
+  public void setTitle(String title) {\r
+    mTitle = title;\r
+  }\r
+\r
+  /**\r
+   * Adds a new value to the series.\r
+   * \r
+   * @param x the value for the X axis\r
+   * @param y the value for the Y axis\r
+   */\r
+  public synchronized void add(double x, double y) {\r
+    mXY.put(x, y);\r
+    updateRange(x, y);\r
+  }\r
+\r
+  /**\r
+   * Removes an existing value from the series.\r
+   * \r
+   * @param index the index in the series of the value to remove\r
+   */\r
+  public synchronized void remove(int index) {\r
+    XYEntry<Double, Double> removedEntry = mXY.removeByIndex(index);\r
+    double removedX = removedEntry.getKey();\r
+    double removedY = removedEntry.getValue();\r
+    if (removedX == mMinX || removedX == mMaxX || removedY == mMinY || removedY == mMaxY) {\r
+      initRange();\r
+    }\r
+  }\r
+\r
+  /**\r
+   * Removes all the existing values from the series.\r
+   */\r
+  public synchronized void clear() {\r
+    mXY.clear();\r
+    initRange();\r
+  }\r
+\r
+  /**\r
+   * Returns the X axis value at the specified index.\r
+   * \r
+   * @param index the index\r
+   * @return the X value\r
+   */\r
+  public synchronized double getX(int index) {\r
+    return mXY.getXByIndex(index);\r
+  }\r
+\r
+  /**\r
+   * Returns the Y axis value at the specified index.\r
+   * \r
+   * @param index the index\r
+   * @return the Y value\r
+   */\r
+  public synchronized double getY(int index) {\r
+    return mXY.getYByIndex(index);\r
+  }\r
+\r
+  /**\r
+   * Returns submap of x and y values according to the given start and end\r
+   * \r
+   * @param start start x value\r
+   * @param stop stop x value\r
+   * @return a submap of x and y values\r
+   */\r
+  public synchronized SortedMap<Double, Double> getRange(double start, double stop,\r
+      int beforeAfterPoints) {\r
+    // we need to add one point before the start and one point after the end (if\r
+    // there are any)\r
+    // to ensure that line doesn't end before the end of the screen\r
+\r
+    // this would be simply: start = mXY.lowerKey(start) but NavigableMap is\r
+    // available since API 9\r
+    SortedMap<Double, Double> headMap = mXY.headMap(start);\r
+    if (!headMap.isEmpty()) {\r
+      start = headMap.lastKey();\r
+    }\r
+\r
+    // this would be simply: end = mXY.higherKey(end) but NavigableMap is\r
+    // available since API 9\r
+    // so we have to do this hack in order to support older versions\r
+    SortedMap<Double, Double> tailMap = mXY.tailMap(stop);\r
+    if (!tailMap.isEmpty()) {\r
+      Iterator<Double> tailIterator = tailMap.keySet().iterator();\r
+      Double next = tailIterator.next();\r
+      if (tailIterator.hasNext()) {\r
+        stop = tailIterator.next();\r
+      } else {\r
+        stop += next;\r
+      }\r
+    }\r
+    return mXY.subMap(start, stop);\r
+  }\r
+\r
+  public int getIndexForKey(double key) {\r
+    return mXY.getIndexForKey(key);\r
+  }\r
+\r
+  /**\r
+   * Returns the series item count.\r
+   * \r
+   * @return the series item count\r
+   */\r
+  public synchronized int getItemCount() {\r
+    return mXY.size();\r
+  }\r
+\r
+  /**\r
+   * Returns the minimum value on the X axis.\r
+   * \r
+   * @return the X axis minimum value\r
+   */\r
+  public double getMinX() {\r
+    return mMinX;\r
+  }\r
+\r
+  /**\r
+   * Returns the minimum value on the Y axis.\r
+   * \r
+   * @return the Y axis minimum value\r
+   */\r
+  public double getMinY() {\r
+    return mMinY;\r
+  }\r
+\r
+  /**\r
+   * Returns the maximum value on the X axis.\r
+   * \r
+   * @return the X axis maximum value\r
+   */\r
+  public double getMaxX() {\r
+    return mMaxX;\r
+  }\r
+\r
+  /**\r
+   * Returns the maximum value on the Y axis.\r
+   * \r
+   * @return the Y axis maximum value\r
+   */\r
+  public double getMaxY() {\r
+    return mMaxY;\r
+  }\r
+}\r