/timeplot/branches/1.0/src/webapp/api/scripts/sources.js

http://simile-widgets.googlecode.com/ · JavaScript · 288 lines · 225 code · 42 blank · 21 comment · 36 complexity · 278cfc963937c1137c19ddcf2adfebf8 MD5 · raw file

  1. /*==================================================
  2. * Default Data Source
  3. *==================================================*/
  4. Timeplot.DefaultEventSource = function(eventIndex) {
  5. Timeline.DefaultEventSource.apply(this, arguments);
  6. };
  7. Object.extend(Timeplot.DefaultEventSource.prototype, Timeline.DefaultEventSource.prototype);
  8. Timeplot.DefaultEventSource.prototype.loadText = function(text, separator, url, filter) {
  9. if (text == null) {
  10. return;
  11. }
  12. this._events.maxValues = new Array();
  13. var base = this._getBaseURL(url);
  14. var dateTimeFormat = 'iso8601';
  15. var parseDateTimeFunction = this._events.getUnit().getParser(dateTimeFormat);
  16. var data = this._parseText(text, separator);
  17. var added = false;
  18. if (filter) {
  19. data = filter(data);
  20. }
  21. if (data) {
  22. for (var i = 0; i < data.length; i++){
  23. var row = data[i];
  24. if (row.length > 1) {
  25. var evt = new Timeplot.DefaultEventSource.NumericEvent(
  26. parseDateTimeFunction(row[0]),
  27. row.slice(1)
  28. );
  29. this._events.add(evt);
  30. added = true;
  31. }
  32. }
  33. }
  34. if (added) {
  35. this._fire("onAddMany", []);
  36. }
  37. }
  38. /*
  39. * Adapted from http://www.kawa.net/works/js/jkl/js/jkl-parsexml.js by Yusuke Kawasaki
  40. */
  41. Timeplot.DefaultEventSource.prototype._parseText = function (text, separator) {
  42. text = text.replace( /\r\n?/g, "\n" ); // normalize newlines
  43. var pos = 0;
  44. var len = text.length;
  45. var table = [];
  46. while (pos < len) {
  47. var line = [];
  48. if (text.charAt(pos) != '#') { // if it's not a comment, process
  49. while (pos < len) {
  50. if (text.charAt(pos) == '"') { // "..." quoted column
  51. var nextquote = text.indexOf('"', pos+1 );
  52. while (nextquote<len && nextquote > -1) {
  53. if (text.charAt(nextquote+1) != '"') {
  54. break; // end of column
  55. }
  56. nextquote = text.indexOf('"', nextquote + 2);
  57. }
  58. if ( nextquote < 0 ) {
  59. // unclosed quote
  60. } else if (text.charAt(nextquote + 1) == separator) { // end of column
  61. var quoted = text.substr(pos + 1, nextquote-pos - 1);
  62. quoted = quoted.replace(/""/g,'"');
  63. line[line.length] = quoted;
  64. pos = nextquote + 2;
  65. continue;
  66. } else if (text.charAt(nextquote + 1) == "\n" || // end of line
  67. len == nextquote + 1 ) { // end of file
  68. var quoted = text.substr(pos + 1, nextquote-pos - 1);
  69. quoted = quoted.replace(/""/g,'"');
  70. line[line.length] = quoted;
  71. pos = nextquote + 2;
  72. break;
  73. } else {
  74. // invalid column
  75. }
  76. }
  77. var nextseparator = text.indexOf(separator, pos);
  78. var nextnline = text.indexOf("\n", pos);
  79. if (nextnline < 0) nextnline = len;
  80. if (nextseparator > -1 && nextseparator < nextnline) {
  81. line[line.length] = text.substr(pos, nextseparator-pos);
  82. pos = nextseparator + 1;
  83. } else { // end of line
  84. line[line.length] = text.substr(pos, nextnline-pos);
  85. pos = nextnline + 1;
  86. break;
  87. }
  88. }
  89. } else { // if it's a comment, ignore
  90. var nextnline = text.indexOf("\n", pos);
  91. pos = (nextnline > -1) ? nextnline + 1 : cur;
  92. }
  93. if (line.length > 0) {
  94. table[table.length] = line; // push line
  95. }
  96. }
  97. if (table.length < 0) return; // null data
  98. return table;
  99. }
  100. Timeplot.DefaultEventSource.prototype.getRange = function() {
  101. var earliestDate = this.getEarliestDate();
  102. var latestDate = this.getLatestDate();
  103. return {
  104. earliestDate: (earliestDate) ? earliestDate : null,
  105. latestDate: (latestDate) ? latestDate : null,
  106. min: 0,
  107. max: 0
  108. };
  109. }
  110. // -----------------------------------------------------------------------
  111. Timeplot.DefaultEventSource.NumericEvent = function(time, values) {
  112. this._id = "e" + Math.round(Math.random() * 1000000);
  113. this._time = time;
  114. this._values = values;
  115. };
  116. Timeplot.DefaultEventSource.NumericEvent.prototype = {
  117. getID: function() { return this._id; },
  118. getTime: function() { return this._time; },
  119. getValues: function() { return this._values; },
  120. // these are required by the EventSource
  121. getStart: function() { return this._time; },
  122. getEnd: function() { return this._time; }
  123. };
  124. // -----------------------------------------------------------------------
  125. Timeplot.DataSource = function(eventSource) {
  126. this._eventSource = eventSource;
  127. var source = this;
  128. this._processingListener = {
  129. onAddMany: function() { source._process(); },
  130. onClear: function() { source._clear(); }
  131. }
  132. this.addListener(this._processingListener);
  133. this._listeners = [];
  134. };
  135. Timeplot.DataSource.prototype = {
  136. _clear: function() {
  137. this._data = null;
  138. this._range = null;
  139. },
  140. _process: function() {
  141. this._data = {
  142. times: new Array(),
  143. values: new Array()
  144. };
  145. this._range = {
  146. earliestDate: null,
  147. latestDate: null,
  148. min: 0,
  149. max: 0
  150. };
  151. },
  152. getRange: function() {
  153. return this._range;
  154. },
  155. getData: function() {
  156. return this._data;
  157. },
  158. getValue: function(t) {
  159. if (this._data) {
  160. for (var i = 0; i < this._data.times.length; i++) {
  161. var l = this._data.times[i];
  162. if (l > t) {
  163. return this._data.values[i];
  164. }
  165. }
  166. }
  167. return 0;
  168. },
  169. addListener: function(listener) {
  170. this._eventSource.addListener(listener);
  171. },
  172. removeListener: function(listener) {
  173. this._eventSource.removeListener(listener);
  174. },
  175. replaceListener: function(oldListener, newListener) {
  176. this.removeListener(oldListener);
  177. this.addListener(newListener);
  178. }
  179. }
  180. // -----------------------------------------------------------------------
  181. /**
  182. * Data Source that extracts the time series out of a single column
  183. * from the events
  184. */
  185. Timeplot.ColumnSource = function(eventSource, column) {
  186. Timeplot.DataSource.apply(this, arguments);
  187. this._column = column - 1;
  188. };
  189. Object.extend(Timeplot.ColumnSource.prototype,Timeplot.DataSource.prototype);
  190. Timeplot.ColumnSource.prototype.dispose = function() {
  191. this.removeListener(this._processingListener);
  192. this._clear();
  193. }
  194. Timeplot.ColumnSource.prototype._process = function() {
  195. var count = this._eventSource.getCount();
  196. var times = new Array(count);
  197. var values = new Array(count);
  198. var min = Number.MAX_VALUE;
  199. var max = Number.MIN_VALUE;
  200. var i = 0;
  201. var iterator = this._eventSource.getAllEventIterator();
  202. while (iterator.hasNext()) {
  203. var event = iterator.next();
  204. var time = event.getTime();
  205. times[i] = time;
  206. var value = this._getValue(event);
  207. if (!isNaN(value)) {
  208. if (value < min) {
  209. min = value;
  210. }
  211. if (value > max) {
  212. max = value;
  213. }
  214. values[i] = value;
  215. }
  216. i++;
  217. }
  218. this._data = {
  219. times: times,
  220. values: values
  221. };
  222. this._range = {
  223. earliestDate: this._eventSource.getEarliestDate(),
  224. latestDate: this._eventSource.getLatestDate(),
  225. min: min,
  226. max: max
  227. };
  228. }
  229. Timeplot.ColumnSource.prototype._getValue = function(event) {
  230. return parseFloat(event.getValues()[this._column]);
  231. }
  232. // ---------------------------------------------------------------
  233. /**
  234. * Data Source that generates the time series out of the difference
  235. * between the first and the second column
  236. */
  237. Timeplot.ColumnDiffSource = function(eventSource, column1, column2) {
  238. Timeplot.ColumnSource.apply(this, arguments);
  239. this._column2 = column2 - 1;
  240. };
  241. Object.extend(Timeplot.ColumnDiffSource.prototype,Timeplot.ColumnSource.prototype);
  242. Timeplot.ColumnDiffSource.prototype._getValue = function(event) {
  243. var a = parseFloat(event.getValues()[this._column]);
  244. var b = parseFloat(event.getValues()[this._column2])
  245. return a - b;
  246. }