2 * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL
\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
8 * http://www.apache.org/licenses/LICENSE-2.0
\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
16 package org.achartengine.chart;
\r
18 import java.text.DateFormat;
\r
19 import java.text.SimpleDateFormat;
\r
20 import java.util.ArrayList;
\r
21 import java.util.Date;
\r
22 import java.util.List;
\r
24 import org.achartengine.model.XYMultipleSeriesDataset;
\r
25 import org.achartengine.model.XYSeries;
\r
26 import org.achartengine.renderer.XYMultipleSeriesRenderer;
\r
28 import android.graphics.Canvas;
\r
29 import android.graphics.Paint;
\r
32 * The time chart rendering class.
\r
34 public class TimeChart extends LineChart {
\r
35 /** The constant to identify this chart type. */
\r
36 public static final String TYPE = "Time";
\r
37 /** The number of milliseconds in a day. */
\r
38 public static final long DAY = 24 * 60 * 60 * 1000;
\r
39 /** The date format pattern to be used in formatting the X axis labels. */
\r
40 private String mDateFormat;
\r
41 /** The starting point for labels. */
\r
42 private Double mStartPoint;
\r
48 * Builds a new time chart instance.
\r
50 * @param dataset the multiple series dataset
\r
51 * @param renderer the multiple series renderer
\r
53 public TimeChart(XYMultipleSeriesDataset dataset, XYMultipleSeriesRenderer renderer) {
\r
54 super(dataset, renderer);
\r
58 * Returns the date format pattern to be used for formatting the X axis
\r
61 * @return the date format pattern for the X axis labels
\r
63 public String getDateFormat() {
\r
68 * Sets the date format pattern to be used for formatting the X axis labels.
\r
70 * @param format the date format pattern for the X axis labels. If null, an
\r
71 * appropriate default format will be used.
\r
73 public void setDateFormat(String format) {
\r
74 mDateFormat = format;
\r
78 * The graphical representation of the labels on the X axis.
\r
80 * @param xLabels the X labels values
\r
81 * @param xTextLabelLocations the X text label locations
\r
82 * @param canvas the canvas to paint to
\r
83 * @param paint the paint to be used for drawing
\r
84 * @param left the left value of the labels area
\r
85 * @param top the top value of the labels area
\r
86 * @param bottom the bottom value of the labels area
\r
87 * @param xPixelsPerUnit the amount of pixels per one unit in the chart labels
\r
88 * @param minX the minimum value on the X axis in the chart
\r
89 * @param maxX the maximum value on the X axis in the chart
\r
92 protected void drawXLabels(List<Double> xLabels, Double[] xTextLabelLocations, Canvas canvas,
\r
93 Paint paint, int left, int top, int bottom, double xPixelsPerUnit, double minX, double maxX) {
\r
94 int length = xLabels.size();
\r
96 boolean showLabels = mRenderer.isShowLabels();
\r
97 boolean showGridY = mRenderer.isShowGridY();
\r
98 DateFormat format = getDateFormat(xLabels.get(0), xLabels.get(length - 1));
\r
99 for (int i = 0; i < length; i++) {
\r
100 long label = Math.round(xLabels.get(i));
\r
101 float xLabel = (float) (left + xPixelsPerUnit * (label - minX));
\r
103 paint.setColor(mRenderer.getXLabelsColor());
\r
105 .drawLine(xLabel, bottom, xLabel, bottom + mRenderer.getLabelsTextSize() / 3, paint);
\r
106 drawText(canvas, format.format(new Date(label)), xLabel,
\r
107 bottom + mRenderer.getLabelsTextSize() * 4 / 3, paint, mRenderer.getXLabelsAngle());
\r
110 paint.setColor(mRenderer.getGridColor());
\r
111 canvas.drawLine(xLabel, bottom, xLabel, top, paint);
\r
115 drawXTextLabels(xTextLabelLocations, canvas, paint, true, left, top, bottom, xPixelsPerUnit,
\r
120 * Returns the date format pattern to be used, based on the date range.
\r
122 * @param start the start date in milliseconds
\r
123 * @param end the end date in milliseconds
\r
124 * @return the date format
\r
126 private DateFormat getDateFormat(double start, double end) {
\r
127 if (mDateFormat != null) {
\r
128 SimpleDateFormat format = null;
\r
130 format = new SimpleDateFormat(mDateFormat);
\r
132 } catch (Exception e) {
\r
136 DateFormat format = SimpleDateFormat.getDateInstance(SimpleDateFormat.MEDIUM);
\r
137 double diff = end - start;
\r
138 if (diff > DAY && diff < 5 * DAY) {
\r
139 format = SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.SHORT, SimpleDateFormat.SHORT);
\r
140 } else if (diff < DAY) {
\r
141 format = SimpleDateFormat.getTimeInstance(SimpleDateFormat.MEDIUM);
\r
147 * Returns the chart type identifier.
\r
149 * @return the chart type
\r
151 public String getChartType() {
\r
155 protected List<Double> getXLabels(double min, double max, int count) {
\r
156 final List<Double> result = new ArrayList<Double>();
\r
157 if (!mRenderer.isXRoundedLabels()) {
\r
158 if (mDataset.getSeriesCount() > 0) {
\r
159 XYSeries series = mDataset.getSeriesAt(0);
\r
160 int length = series.getItemCount();
\r
161 int intervalLength = 0;
\r
162 int startIndex = -1;
\r
163 for (int i = 0; i < length; i++) {
\r
164 double value = series.getX(i);
\r
165 if (min <= value && value <= max) {
\r
167 if (startIndex < 0) {
\r
172 if (intervalLength < count) {
\r
173 for (int i = startIndex; i < startIndex + intervalLength; i++) {
\r
174 result.add(series.getX(i));
\r
177 float step = (float) intervalLength / count;
\r
178 int intervalCount = 0;
\r
179 for (int i = 0; i < length && intervalCount < count; i++) {
\r
180 double value = series.getX(Math.round(i * step));
\r
181 if (min <= value && value <= max) {
\r
189 return super.getXLabels(min, max, count);
\r
192 if (mStartPoint == null) {
\r
193 mStartPoint = min - (min % DAY) + DAY + new Date(Math.round(min)).getTimezoneOffset() * 60
\r
201 final double cycleMath = (max - min) / count;
\r
202 if (cycleMath <= 0) {
\r
205 double cycle = DAY;
\r
207 if (cycleMath <= DAY) {
\r
208 while (cycleMath < cycle / 2) {
\r
212 while (cycleMath > cycle) {
\r
217 double val = mStartPoint - Math.floor((mStartPoint - min) / cycle) * cycle;
\r
219 while (val < max && i++ <= count) {
\r