source: trunk/src/org/expeditee/items/widgets/charts/TimeSeries.java@ 919

Last change on this file since 919 was 919, checked in by jts21, 10 years ago

Added license headers to all files, added full GPL3 license file, moved license header generator script to dev/bin/scripts

File size: 7.2 KB
Line 
1/**
2 * TimeSeries.java
3 * Copyright (C) 2010 New Zealand Digital Library, http://expeditee.org
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19package org.expeditee.items.widgets.charts;
20
21import java.awt.Color;
22import java.text.DateFormat;
23import java.text.ParseException;
24import java.text.SimpleDateFormat;
25import java.util.Calendar;
26import java.util.Collection;
27import java.util.Date;
28
29import org.expeditee.gui.AttributeValuePair;
30import org.expeditee.gui.Frame;
31import org.expeditee.gui.MessageBay;
32import org.expeditee.items.Text;
33import org.expeditee.stats.Formatter;
34import org.jfree.chart.ChartFactory;
35import org.jfree.chart.JFreeChart;
36import org.jfree.data.time.Day;
37import org.jfree.data.time.Hour;
38import org.jfree.data.time.Millisecond;
39import org.jfree.data.time.Minute;
40import org.jfree.data.time.Month;
41import org.jfree.data.time.Quarter;
42import org.jfree.data.time.RegularTimePeriod;
43import org.jfree.data.time.Second;
44import org.jfree.data.time.TimeSeriesCollection;
45import org.jfree.data.time.Week;
46import org.jfree.data.time.Year;
47import org.jfree.data.xy.XYDataset;
48
49public class TimeSeries extends AbstractValueAxis {
50
51 public TimeSeries(Text source, String[] args) {
52 super(source, args);
53 }
54
55 private TimeSeriesCollection _data;
56
57 private Class<? extends RegularTimePeriod> _periodType;
58
59 private Date _startDate;
60
61 protected XYDataset getChartData() {
62 if (_data == null)
63 _data = new TimeSeriesCollection();
64 return _data;
65 }
66
67 @Override
68 public void refreshData(Frame dataFrame) {
69 String period = dataFrame.getAnnotationValue("period");
70 if (period == null) {
71 period = "day";
72 } else {
73 period = period.toLowerCase();
74 }
75 if (period.startsWith("quarter")) {
76 _periodType = Quarter.class;
77 } else if (period.startsWith("year")) {
78 _periodType = Year.class;
79 } else if (period.startsWith("month")) {
80 _periodType = Month.class;
81 } else if (period.startsWith("week")) {
82 _periodType = Week.class;
83 } else if (period.startsWith("hour")) {
84 _periodType = Hour.class;
85 } else if (period.startsWith("min")) {
86 _periodType = Minute.class;
87 } else if (period.startsWith("sec")) {
88 _periodType = Second.class;
89 } else if (period.startsWith("milli")) {
90 _periodType = Millisecond.class;
91 } else if (period.startsWith("day")) {
92 _periodType = Day.class;
93 } else {
94 MessageBay.errorMessage("Invalid time series period type: "
95 + period);
96 _periodType = Day.class;
97 }
98
99 try {
100 String startDateString = dataFrame.getAnnotationValue("start");
101 if (startDateString != null) {
102 _startDate = parseDate(startDateString);
103 }
104 } catch (Exception e) {
105 // Use the current date
106 }
107 if (_startDate == null) {
108 _startDate = new Date();
109 }
110 super.refreshData(dataFrame);
111 }
112
113 /**
114 * @param dataFrame
115 */
116 @Override
117 protected void clearData() {
118 _data.removeAllSeries();
119 }
120
121 @Override
122 protected JFreeChart createNewChart() {
123 return ChartFactory.createTimeSeriesChart(DEFAULT_TITLE, DEFAULT_XAXIS,
124 DEFAULT_YAXIS, getChartData(), true, // legend?
125 true, // tooltips?
126 false // URLs?
127 );
128 }
129
130 @Override
131 protected boolean addCategoryData(String categoryName,
132 Collection<Text> items, boolean swap) {
133 org.jfree.data.time.TimeSeries newSeries = new org.jfree.data.time.TimeSeries(
134 categoryName, _periodType);
135
136 boolean foundData = false;
137 Color newColor = null;
138 for (Text i : items) {
139 if (!i.isLineEnd()) {
140 Text t = (Text) i;
141 AttributeValuePair avp = new AttributeValuePair(t.getText());
142 if (avp != null) {
143 Double attribute = null;
144 try {
145 attribute = avp.getDoubleAttribute();
146 } catch (NumberFormatException e) {
147 }
148 Double value = null;
149 try {
150 // If the data is not valid move to the next item
151 value = avp.getDoubleValue();
152 } catch (NumberFormatException e) {
153 continue;
154 }
155
156 try {
157 RegularTimePeriod rtp = null;
158 if (attribute == null) {
159 Date date = parseDate(avp.getAttribute());
160 rtp = _periodType.getConstructor(
161 new Class[] { Date.class }).newInstance(
162 new Object[] { date });
163 } else {
164 if (_periodType.equals(Year.class)) {
165 int year = (int) Math.floor(attribute);
166 Calendar c = Calendar.getInstance();
167 c.setTime(_startDate);
168 rtp = new Year(year + c.get(Calendar.YEAR));
169 } else if (_periodType.equals(Quarter.class)) {
170 int quarter = (int) Math.floor(attribute);
171 rtp = new Quarter(quarter, new Year(_startDate));
172 } else if (_periodType.equals(Month.class)) {
173 int month = (int) Math.floor(attribute);
174 rtp = new Month(month, new Year(_startDate));
175 } else if (_periodType.equals(Week.class)) {
176 int week = (int) Math.floor(attribute);
177 rtp = new Week(week, new Year(_startDate));
178 } else if (_periodType.equals(Day.class)) {
179 int day = (int) Math.floor(attribute);
180 Calendar c = Calendar.getInstance();
181 c.setTime(_startDate);
182 rtp = new Day(day
183 + c.get(Calendar.DAY_OF_MONTH), 1 + c
184 .get(Calendar.MONTH), c
185 .get(Calendar.YEAR));
186 } else if (_periodType.equals(Hour.class)) {
187 int hour = (int) Math.floor(attribute);
188 rtp = new Hour(hour, new Day(_startDate));
189 } else if (_periodType.equals(Minute.class)) {
190 int minute = (int) Math.floor(attribute);
191 rtp = new Minute(minute, new Hour(_startDate));
192 } else if (_periodType.equals(Second.class)) {
193 int second = (int) Math.floor(attribute);
194 rtp = new Second(second, new Minute(_startDate));
195 } else if (_periodType.equals(Millisecond.class)) {
196 int milli = (int) Math.floor(attribute);
197 rtp = new Millisecond(milli, new Second(
198 _startDate));
199 }
200 }
201 newSeries.add(rtp, value);
202 foundData = true;
203 if (newColor == null)
204 newColor = i.getColor();
205 } catch (Exception e) {
206 // Ignore the data point if it cant be parsed
207 e.printStackTrace();
208 }
209 }
210 }
211 }
212 if (foundData) {
213 _data.addSeries(newSeries);
214 _paints.put(categoryName, newColor);
215 }
216 return foundData;
217 }
218
219 /**
220 * @param avp
221 * @return
222 * @throws ParseException
223 */
224 public static Date parseDate(String dateString) throws ParseException {
225 // Select the best match for a date or time format
226 DateFormat df = null;
227 if (dateString.length() > Formatter.DATE_FORMAT
228 .length()) {
229 df = new SimpleDateFormat(Formatter.DATE_TIME_FORMAT);
230 } else if (dateString.length() <= Formatter.TIME_FORMAT.length()) {
231 df = new SimpleDateFormat(Formatter.TIME_FORMAT);
232 }else {
233 df = new SimpleDateFormat(Formatter.DATE_FORMAT);
234 }
235 Date date = df.parse(dateString);
236 return date;
237 }
238}
Note: See TracBrowser for help on using the repository browser.