Merge commit '42b2e5ca519766e37ce6941ba4faecc9691cc403' into upstream
[debian/openrocket] / android-libraries / achartengine / src / org / achartengine / chart / TimeChart.java
diff --git a/android-libraries/achartengine/src/org/achartengine/chart/TimeChart.java b/android-libraries/achartengine/src/org/achartengine/chart/TimeChart.java
new file mode 100644 (file)
index 0000000..ba201de
--- /dev/null
@@ -0,0 +1,226 @@
+/**\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.chart;\r
+\r
+import java.text.DateFormat;\r
+import java.text.SimpleDateFormat;\r
+import java.util.ArrayList;\r
+import java.util.Date;\r
+import java.util.List;\r
+\r
+import org.achartengine.model.XYMultipleSeriesDataset;\r
+import org.achartengine.model.XYSeries;\r
+import org.achartengine.renderer.XYMultipleSeriesRenderer;\r
+\r
+import android.graphics.Canvas;\r
+import android.graphics.Paint;\r
+\r
+/**\r
+ * The time chart rendering class.\r
+ */\r
+public class TimeChart extends LineChart {\r
+  /** The constant to identify this chart type. */\r
+  public static final String TYPE = "Time";\r
+  /** The number of milliseconds in a day. */\r
+  public static final long DAY = 24 * 60 * 60 * 1000;\r
+  /** The date format pattern to be used in formatting the X axis labels. */\r
+  private String mDateFormat;\r
+  /** The starting point for labels. */\r
+  private Double mStartPoint;\r
+\r
+  TimeChart() {\r
+  }\r
+\r
+  /**\r
+   * Builds a new time chart instance.\r
+   * \r
+   * @param dataset the multiple series dataset\r
+   * @param renderer the multiple series renderer\r
+   */\r
+  public TimeChart(XYMultipleSeriesDataset dataset, XYMultipleSeriesRenderer renderer) {\r
+    super(dataset, renderer);\r
+  }\r
+\r
+  /**\r
+   * Returns the date format pattern to be used for formatting the X axis\r
+   * labels.\r
+   * \r
+   * @return the date format pattern for the X axis labels\r
+   */\r
+  public String getDateFormat() {\r
+    return mDateFormat;\r
+  }\r
+\r
+  /**\r
+   * Sets the date format pattern to be used for formatting the X axis labels.\r
+   * \r
+   * @param format the date format pattern for the X axis labels. If null, an\r
+   *          appropriate default format will be used.\r
+   */\r
+  public void setDateFormat(String format) {\r
+    mDateFormat = format;\r
+  }\r
+\r
+  /**\r
+   * The graphical representation of the labels on the X axis.\r
+   * \r
+   * @param xLabels the X labels values\r
+   * @param xTextLabelLocations the X text label locations\r
+   * @param canvas the canvas to paint to\r
+   * @param paint the paint to be used for drawing\r
+   * @param left the left value of the labels area\r
+   * @param top the top value of the labels area\r
+   * @param bottom the bottom value of the labels area\r
+   * @param xPixelsPerUnit the amount of pixels per one unit in the chart labels\r
+   * @param minX the minimum value on the X axis in the chart\r
+   * @param maxX the maximum value on the X axis in the chart\r
+   */\r
+  @Override\r
+  protected void drawXLabels(List<Double> xLabels, Double[] xTextLabelLocations, Canvas canvas,\r
+      Paint paint, int left, int top, int bottom, double xPixelsPerUnit, double minX, double maxX) {\r
+    int length = xLabels.size();\r
+    if (length > 0) {\r
+      boolean showLabels = mRenderer.isShowLabels();\r
+      boolean showGridY = mRenderer.isShowGridY();\r
+      DateFormat format = getDateFormat(xLabels.get(0), xLabels.get(length - 1));\r
+      for (int i = 0; i < length; i++) {\r
+        long label = Math.round(xLabels.get(i));\r
+        float xLabel = (float) (left + xPixelsPerUnit * (label - minX));\r
+        if (showLabels) {\r
+          paint.setColor(mRenderer.getXLabelsColor());\r
+          canvas\r
+              .drawLine(xLabel, bottom, xLabel, bottom + mRenderer.getLabelsTextSize() / 3, paint);\r
+          drawText(canvas, format.format(new Date(label)), xLabel,\r
+              bottom + mRenderer.getLabelsTextSize() * 4 / 3, paint, mRenderer.getXLabelsAngle());\r
+        }\r
+        if (showGridY) {\r
+          paint.setColor(mRenderer.getGridColor());\r
+          canvas.drawLine(xLabel, bottom, xLabel, top, paint);\r
+        }\r
+      }\r
+    }\r
+    drawXTextLabels(xTextLabelLocations, canvas, paint, true, left, top, bottom, xPixelsPerUnit,\r
+        minX, maxX);\r
+  }\r
+\r
+  /**\r
+   * Returns the date format pattern to be used, based on the date range.\r
+   * \r
+   * @param start the start date in milliseconds\r
+   * @param end the end date in milliseconds\r
+   * @return the date format\r
+   */\r
+  private DateFormat getDateFormat(double start, double end) {\r
+    if (mDateFormat != null) {\r
+      SimpleDateFormat format = null;\r
+      try {\r
+        format = new SimpleDateFormat(mDateFormat);\r
+        return format;\r
+      } catch (Exception e) {\r
+        // do nothing here\r
+      }\r
+    }\r
+    DateFormat format = SimpleDateFormat.getDateInstance(SimpleDateFormat.MEDIUM);\r
+    double diff = end - start;\r
+    if (diff > DAY && diff < 5 * DAY) {\r
+      format = SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.SHORT, SimpleDateFormat.SHORT);\r
+    } else if (diff < DAY) {\r
+      format = SimpleDateFormat.getTimeInstance(SimpleDateFormat.MEDIUM);\r
+    }\r
+    return format;\r
+  }\r
+\r
+  /**\r
+   * Returns the chart type identifier.\r
+   * \r
+   * @return the chart type\r
+   */\r
+  public String getChartType() {\r
+    return TYPE;\r
+  }\r
+\r
+  protected List<Double> getXLabels(double min, double max, int count) {\r
+    final List<Double> result = new ArrayList<Double>();\r
+    if (!mRenderer.isXRoundedLabels()) {\r
+      if (mDataset.getSeriesCount() > 0) {\r
+        XYSeries series = mDataset.getSeriesAt(0);\r
+        int length = series.getItemCount();\r
+        int intervalLength = 0;\r
+        int startIndex = -1;\r
+        for (int i = 0; i < length; i++) {\r
+          double value = series.getX(i);\r
+          if (min <= value && value <= max) {\r
+            intervalLength++;\r
+            if (startIndex < 0) {\r
+              startIndex = i;\r
+            }\r
+          }\r
+        }\r
+        if (intervalLength < count) {\r
+          for (int i = startIndex; i < startIndex + intervalLength; i++) {\r
+            result.add(series.getX(i));\r
+          }\r
+        } else {\r
+          float step = (float) intervalLength / count;\r
+          int intervalCount = 0;\r
+          for (int i = 0; i < length && intervalCount < count; i++) {\r
+            double value = series.getX(Math.round(i * step));\r
+            if (min <= value && value <= max) {\r
+              result.add(value);\r
+              intervalCount++;\r
+            }\r
+          }\r
+        }\r
+        return result;\r
+      } else {\r
+        return super.getXLabels(min, max, count);\r
+      }\r
+    }\r
+    if (mStartPoint == null) {\r
+      mStartPoint = min - (min % DAY) + DAY + new Date(Math.round(min)).getTimezoneOffset() * 60\r
+          * 1000;\r
+    }\r
+    if (count > 25) {\r
+      count = 25;\r
+    }\r
+\r
+    \r
+    final double cycleMath = (max - min) / count;\r
+    if (cycleMath <= 0) {\r
+      return result;\r
+    }\r
+    double cycle = DAY;\r
+\r
+    if (cycleMath <= DAY) {\r
+      while (cycleMath < cycle / 2) {\r
+        cycle = cycle / 2;\r
+      }\r
+    } else {\r
+      while (cycleMath > cycle) {\r
+        cycle = cycle * 2;\r
+      }\r
+    }\r
+\r
+    double val = mStartPoint - Math.floor((mStartPoint - min) / cycle) * cycle;\r
+    int i = 0;\r
+    while (val < max && i++ <= count) {\r
+      result.add(val);\r
+      val += cycle;\r
+    }\r
+\r
+    return result;\r
+  }\r
+}\r