--- /dev/null
+/**\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