source: trunk/src/org/expeditee/stats/SessionStats.java@ 418

Last change on this file since 418 was 418, checked in by ra33, 16 years ago

Added start time to session stats

File size: 13.1 KB
Line 
1package org.expeditee.stats;
2
3import java.awt.event.KeyEvent;
4import java.awt.event.MouseEvent;
5import java.sql.Time;
6import java.util.ArrayList;
7import java.util.Collection;
8import java.util.Date;
9import java.util.List;
10
11import org.expeditee.gui.DisplayIO;
12import org.expeditee.gui.Frame;
13import org.expeditee.gui.FrameMouseActions;
14import org.expeditee.gui.FrameUtils;
15import org.expeditee.gui.TimeKeeper;
16import org.expeditee.io.Logger;
17import org.expeditee.items.Dot;
18import org.expeditee.items.Item;
19import org.expeditee.items.Line;
20import org.expeditee.items.Picture;
21import org.expeditee.items.Text;
22
23public class SessionStats extends Stats{
24
25 public enum ItemType {
26 Text, Dot, Line, Picture, Total;
27 }
28
29 public enum StatType {
30 Created, Copied, Moved, Deleted;
31 }
32
33 private static final int STAT_TYPES = StatType.values().length;
34
35 private static final int ITEM_TYPES = ItemType.values().length;
36
37 private static int[][] _ItemStats = new int[ITEM_TYPES][STAT_TYPES];
38
39 private static List<String> _FrameEvents = new ArrayList<String>();
40
41 // statistics counters
42 private static final int MOUSE_BUTTONS = 4;
43
44 private static StringBuffer _FramesEdited = new StringBuffer();
45
46 private static int[] _MouseCounters = new int[MOUSE_BUTTONS];
47
48 private static int _AccessedFrames = 0;
49
50 private static int _SavedFrames = 0;
51
52 // the number of frames created via TDFC
53 private static int _CreatedFrames = 0;
54
55 // character counts
56 private static int[] _CharCounts = new int[255];
57
58 private static long _LastEvent = new Date().getTime();
59
60 private static final long DARK_TIME_THRESHOLD = 60000;
61
62 private static int _EscapeCount = 0;
63
64 private static boolean _StatsEnabled = true;
65
66 private static final int[] EVENT_INTERVALS = new int[] { 1, 2, 3, 4, 5, 10,
67 20, 60, 300, 600, Integer.MAX_VALUE };
68
69 private static int[] _EventTimes = new int[EVENT_INTERVALS.length];
70
71 private static int _BackspaceCount;
72
73 public static String getCurrentStats() {
74
75 StringBuffer stats = getLength();
76
77 long elapsedTime = (new Date()).getTime() - _StartTime.getTime();
78 stats.append("DarkTime: ").append(
79 _DarkTime.getTime() / MILLISECONDS_PER_MINUTE).append(
80 "-->" + _DarkTime.getTime() * 100 / elapsedTime + "%\n");
81
82 stats.append(getResponseStats()).append("\n");
83 stats.append(getFrameStats());
84
85 stats.append(getCharacterStats());
86
87 stats.append("Version: ").append(DisplayIO.TITLE);
88
89 return stats.toString();
90 }
91
92 private static String getTimeElapsed() {
93 Date currentTime = new Date();
94 long elapsedTime = currentTime.getTime() - _StartTime.getTime();
95 String time = ""
96 + Math.round((float) elapsedTime / MILLISECONDS_PER_MINUTE);
97 return time;
98 }
99
100 private static String getResponseStats() {
101 String stats = "ResponseTime: "
102 + TimeKeeper.Formatter.format(FrameUtils.getLastResponseTime())
103 + "sec, ";
104
105 if (_AccessedFrames > 0)
106 stats += TimeKeeper.Formatter.format(FrameUtils
107 .getResponseTimeTotal()
108 / _AccessedFrames)
109 + "avg";
110 else
111 stats += "--avg";
112
113 return stats;
114 }
115
116 private static String getFrameStats() {
117 return getFrameStats(true);
118 }
119
120 private static String getFrameStats(boolean newline) {
121 StringBuffer stats = new StringBuffer();
122 appendStat(stats, "FramesAccessed", _AccessedFrames, newline, false,
123 DEFAULT_VALUE_WIDTH, DEFAULT_RATE_WIDTH);
124 appendStat(stats, "FramesEdited", _SavedFrames, newline, false,
125 DEFAULT_VALUE_WIDTH, DEFAULT_RATE_WIDTH);
126 return stats.toString();
127 }
128
129 private static String getCharacterStats() {
130 int[] counts = _CharCounts;
131
132 int chars = 0;
133
134 for (int i = 'A'; i <= 'Z'; i++)
135 chars += counts[i];
136
137 for (int i = 'a'; i <= 'z'; i++)
138 chars += counts[i];
139
140 for (int i = '0'; i <= '9'; i++)
141 chars += counts[i];
142
143 chars -= counts[KeyEvent.VK_BACK_SPACE];
144 chars -= counts[KeyEvent.VK_DELETE];
145
146 int EOS = counts['.'] + counts[','] + counts['!'] + counts['?'];
147
148 int punct = counts[' '] + counts[';'] + counts[':'];
149 chars += counts['('] + counts[')'] + counts['\''] + counts['"']
150 + counts['+'] + counts['='] + counts['-'];
151
152 StringBuffer stats = new StringBuffer();
153 appendStat(stats, "Chars", chars + punct + EOS);
154 appendStat(stats, "Words", punct + EOS);
155 appendStat(stats, "Sentences", EOS);
156 appendStat(stats, "TextItems",
157 _ItemStats[ItemType.Text.ordinal()][StatType.Created.ordinal()]);
158 appendStat(stats, "Frames", _CreatedFrames);
159 appendStat(stats, "Escape", _EscapeCount);
160 appendStat(stats, "Backspace", _BackspaceCount);
161 appendStat(stats, "Left", _MouseCounters[MouseEvent.BUTTON1]);
162 appendStat(stats, "Middle", _MouseCounters[MouseEvent.BUTTON2]);
163 appendStat(stats, "Right", _MouseCounters[MouseEvent.BUTTON3]);
164
165 return stats.toString();
166 }
167
168 public static void resetStats() {
169 _StartTime = new Date();
170 _AccessedFrames = 0;
171 _SavedFrames = 0;
172 _CreatedFrames = 0;
173 _CharCounts = new int[255];
174 _EscapeCount = 0;
175 _BackspaceCount = 0;
176 _DarkTime.setTime(0);
177 _MouseCounters = new int[MOUSE_BUTTONS];
178
179 for (int i = 0; i < ITEM_TYPES; i++) {
180 for (int j = 0; j < STAT_TYPES; j++) {
181 _ItemStats[i][j] = 0;
182 }
183 }
184 }
185
186 /**
187 * Called signal that a frame has been accessed.
188 *
189 */
190 public static void AccessedFrame() {
191 if (_StatsEnabled) {
192 _AccessedFrames++;
193 }
194 }
195
196 public static void SavedFrame(String frameName) {
197 FrameEdited(frameName);
198 _SavedFrames++;
199
200 NewFrameSession();
201 }
202
203 public static void Escape() {
204 _EscapeCount++;
205 }
206
207 public static void CreatedFrame() {
208 _CreatedFrames++;
209 }
210
211 /**
212 * Increments the count for a character that is typed.
213 *
214 * @param ch
215 * ascii value for the typed character
216 */
217 public static void TypedChar(int ch) {
218 if (ch == KeyEvent.VK_BACK_SPACE || ch == KeyEvent.VK_DELETE)
219 _BackspaceCount++;
220 UserEvent();
221 _CharCounts[ch]++;
222 }
223
224 private static void UserEvent() {
225 long thisEvent = new Date().getTime();
226 long elapsedTime = thisEvent - _LastEvent;
227 addEventTime(elapsedTime);
228 if (elapsedTime > DARK_TIME_THRESHOLD)
229 _DarkTime.setTime(_DarkTime.getTime() + elapsedTime);
230 _LastEvent = thisEvent;
231 }
232
233 public static void AddFrameEvent(String description) {
234 Date elapsedTime = getFrameTotalTime();
235
236 _FrameEvents.add(Logger.EasyDateFormat("mm:ss:SSS", elapsedTime) + " "
237 + DisplayIO.getMouseX() + " " + FrameMouseActions.getY() + " "
238 + description);
239 }
240
241 public static String getFrameEventList(Frame currentFrame) {
242 StringBuilder eventList = new StringBuilder();
243 // First put on the session and darkTime
244 Time darkTime = currentFrame == null ? getFrameDarkTime()
245 : currentFrame.getDarkTime();
246 Time activeTime = currentFrame == null ? getFrameActiveTime()
247 : currentFrame.getActiveTime();
248 eventList.append(ACTIVE_TIME_ATTRIBUTE).append(
249 Logger.EasyTimeFormat(activeTime)).append('\n');
250 eventList.append(DARK_TIME_ATTRIBUTE).append(
251 Logger.EasyTimeFormat(darkTime)).append('\n');
252 for (String s : _FrameEvents)
253 eventList.append(s).append('\n');
254 if (eventList.length() > 0)
255 eventList.deleteCharAt(eventList.length() - 1);
256 return eventList.toString();
257 }
258
259 public static String getFrameEventList() {
260 return getFrameEventList(null);
261 }
262
263 public static void MouseClicked(int button) {
264 UserEvent();
265 _MouseCounters[button]++;
266 }
267
268 public static void setEnabled(boolean value) {
269 _StatsEnabled = true;
270 }
271
272 private static void FrameEdited(String name) {
273 _FramesEdited.append(Logger.EasyDateFormat("ddMMMyyyy:HHmm:ss"))
274 .append("[").append(name).append("]\n");
275 }
276
277 public static String getFramesEdited() {
278 return _FramesEdited.toString();
279 }
280
281 public static StringBuffer getShortStats() {
282 StringBuffer sb = new StringBuffer();
283 sb.append("FramesA:").append(_AccessedFrames);
284 sb.append(", FramesE:").append(_SavedFrames);
285 sb.append(", ").append(getResponseStats());
286 return sb;
287 }
288
289 private static void ItemStats(Collection<Item> items, StatType stat) {
290 if (items == null)
291 return;
292 for (Item i : items) {
293 if (i instanceof Text)
294 _ItemStats[ItemType.Text.ordinal()][stat.ordinal()]++;
295 else if (i instanceof Dot)
296 _ItemStats[ItemType.Dot.ordinal()][stat.ordinal()]++;
297 else if (i instanceof Picture)
298 _ItemStats[ItemType.Picture.ordinal()][stat.ordinal()]++;
299 else if (i instanceof Line)
300 _ItemStats[ItemType.Line.ordinal()][stat.ordinal()]++;
301 }
302 }
303
304 public static void CreatedItems(Collection<Item> items) {
305 ItemStats(items, StatType.Created);
306 }
307
308 public static void MovedItems(Collection<Item> items) {
309 ItemStats(items, StatType.Moved);
310 }
311
312 public static void CopiedItems(Collection<Item> items) {
313 ItemStats(items, StatType.Copied);
314 }
315
316 public static void DeletedItems(Collection<Item> items) {
317 ItemStats(items, StatType.Deleted);
318 }
319
320 public static void CreatedText() {
321 _ItemStats[ItemType.Text.ordinal()][StatType.Created.ordinal()]++;
322 }
323
324 public static String getItemStats() {
325
326 StringBuffer sb = getLength();
327
328 int max = 0;
329 final int TOTAL_INDEX = ITEM_TYPES - 1;
330 for (int i = 0; i < STAT_TYPES; i++) {
331 _ItemStats[TOTAL_INDEX][i] = 0;
332 for (int j = 0; j < TOTAL_INDEX; j++) {
333 _ItemStats[TOTAL_INDEX][i] += _ItemStats[j][i];
334 }
335 }
336 for (int i = 0; i < STAT_TYPES; i++) {
337 max = Math.max(_ItemStats[TOTAL_INDEX][i], max);
338 }
339 int maxWidthValue = ("" + max).length();
340 int maxWidthRate = (getRate(max)).length();
341
342 int maxNameWidth = 0;
343 int maxColumnWidth = 0;
344 ItemType[] itemTypes = ItemType.values();
345 StatType[] statTypes = StatType.values();
346 // Get the width of the longest itemType
347 for (int i = 0; i < ITEM_TYPES; i++) {
348 maxNameWidth = Math.max(maxNameWidth, itemTypes[i].toString()
349 .length());
350 }
351
352 for (int i = 0; i < STAT_TYPES; i++) {
353 maxNameWidth = Math.max(maxColumnWidth, statTypes[i].toString()
354 .length());
355 }
356 maxColumnWidth = Math.max(maxWidthRate + maxWidthValue + 3,
357 maxNameWidth);
358
359 sb.append(getBufferedString("", maxNameWidth)).append(COLUMN_SEPARATOR);
360
361 StringBuffer lineSeparator = getBufferedString("", maxNameWidth, ROW_SEPARATOR_CHAR);
362 lineSeparator.append(ROW_COLUMN_SEPARATOR);
363
364 for (int i = 0; i < STAT_TYPES; i++) {
365 sb.append(
366 getBufferedString(statTypes[i].toString(), maxColumnWidth))
367 .append(COLUMN_SEPARATOR);
368 lineSeparator.append(getBufferedString("", maxColumnWidth, ROW_SEPARATOR_CHAR)
369 .append(ROW_COLUMN_SEPARATOR));
370 }
371 // Remove the last column separator
372 lineSeparator.delete(lineSeparator.length()
373 - ROW_COLUMN_SEPARATOR.length(), lineSeparator.length() - 1);
374 sb.delete(sb.length() - COLUMN_SEPARATOR.length(), sb.length() - 1);
375 sb.append('\n');
376 sb.append(lineSeparator).append('\n');
377
378 for (int j = 0; j < ITEM_TYPES; j++) {
379 sb.append(getBufferedString(itemTypes[j].toString(), maxNameWidth))
380 .append(COLUMN_SEPARATOR);
381 for (int i = 0; i < STAT_TYPES; i++) {
382 int total = 0;
383 int nonZeroItems = 0;
384 String statName = StatType.values()[i].toString();
385
386 int value = _ItemStats[j][i];
387 if (value > 0)
388 nonZeroItems++;
389 total += value;
390 sb.append(getCompactStat(ItemType.values()[j].toString()
391 + statName, value, maxWidthValue, maxColumnWidth));
392 }
393 sb.delete(sb.length() - COLUMN_SEPARATOR.length(), sb.length() - 1);
394 sb.append('\n');
395 }
396 sb.append(lineSeparator.toString().replace(ROW_COLUMN_SEPARATOR_CHAR, BOTTOM_COLUMN_SEPARATOR_CHAR));
397 return sb.toString();
398 }
399
400 public static String getEventStats() {
401 StringBuffer stats = getLength();
402 int max = getMax(_EventTimes);
403 int maxWidthEvents = ("" + max).length();
404 int maxWidthRate = (getRate(max)).length();
405 for (int i = 0; i < _EventTimes.length - 1; i++) {
406 String upperBound = getFormattedTime(EVENT_INTERVALS[i]);
407 appendStat(stats, "<" + upperBound, _EventTimes[i], true, false,
408 maxWidthEvents, maxWidthRate);
409 }
410 int lastIndex = EVENT_INTERVALS.length - 1;
411 appendStat(stats, "+"
412 + getFormattedTime(EVENT_INTERVALS[lastIndex - 1]),
413 _EventTimes[lastIndex], false, false, maxWidthEvents,
414 maxWidthRate);
415 return stats.toString();
416 }
417
418 /**
419 * Gets the highest number in the list of numbers.
420 *
421 * @param nums
422 * list of numbers
423 * @return highest number in the list
424 */
425 private static int getMax(int[] nums) {
426 int max = 0;
427 for (int i = 0; i < nums.length; i++)
428 if (nums[i] > max)
429 max = nums[i];
430 return max;
431 }
432
433 private static String getFormattedTime(int secs) {
434 String time;
435 if (secs < 60) {
436 time = secs + "s";
437 } else if (secs < 60 * 60) {
438 time = (secs / 60) + "m";
439 } else {
440 time = (secs / 60 / 60) + "h";
441 }
442 if (time.length() == 2)
443 time = " " + time;
444 return time;
445 }
446
447 /**
448 * @return
449 */
450 public static StringBuffer getLength() {
451 StringBuffer stats = getDate();
452 stats.append("Start:").append(Logger.EasyDateFormat("ddMMMyyyy:HHmm", _StartTime)).append("\n");
453 stats.append("SessionTime: ").append(getTimeElapsed()).append("\n");
454 return stats;
455 }
456
457 private static void addEventTime(long millis) {
458
459 for (int i = 0; i < _EventTimes.length - 1; i++) {
460 if (millis < EVENT_INTERVALS[i] * 1000) {
461 _EventTimes[i]++;
462 return;
463 }
464 }
465 _EventTimes[_EventTimes.length - 1]++;
466 }
467
468 public static void DeletedItem(Item toDelete) {
469 List<Item> items = new ArrayList<Item>();
470 items.add(toDelete);
471 DeletedItems(items);
472 }
473
474 public static void NewFrameSession() {
475 _FrameEvents.clear();
476 _FrameAccessTime = new Date();
477 _FrameAccessDarkTime = (Time) _DarkTime.clone();
478 }
479}
Note: See TracBrowser for help on using the repository browser.