PageRenderTime 25ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/TEST/timeglider/js/timeglider/TG_Timeline.js

http://github.com/khaneh/Orders
JavaScript | 377 lines | 176 code | 123 blank | 78 comment | 32 complexity | 643e7c98f0f01f16542489960120e356 MD5 | raw file
  1. /*
  2. * Timeglider for Javascript / jQuery
  3. * http://timeglider.com/jquery
  4. *
  5. * Copyright 2011, Mnemograph LLC
  6. * Licensed under Timeglider Dual License
  7. * http://timeglider.com/jquery/?p=license
  8. *
  9. */
  10. /*
  11. *
  12. * Timeline
  13. * Backbone Model
  14. *
  15. */
  16. (function(tg){
  17. var TG_Date = tg.TG_Date,
  18. $ = jQuery,
  19. widget_options = {},
  20. tg_units = TG_Date.units,
  21. MED;
  22. tg.TG_EventCollection = Backbone.Collection.extend({
  23. eventHash:{},
  24. setTimelineHash: function(timeline_id, hash) {
  25. this.eventHash[timeline_id] = hash;
  26. },
  27. getTimelineHash: function(timeline_id, hash) {
  28. return this.eventHash[timeline_id];
  29. },
  30. model: tg.TG_Event
  31. });
  32. // map model onto larger timeglider namespace
  33. /////////////////////////////////////////////
  34. tg.TG_Event = Backbone.Model.extend({
  35. urlRoot : '/event',
  36. defaults: {
  37. "title": "Untitled"
  38. },
  39. initialize: function(ev) {
  40. if (ev.image) {
  41. // register image with image collection for gathering sizes.
  42. var display_class = ev.image_class || "above";
  43. ev.image = {id: ev.id, src:ev.image, display_class:display_class, width:0, height:0};
  44. // this will follow up with reporting size in separate "thread"
  45. this.getEventImageSize(ev.image);
  46. // MED.imagesToSize++;
  47. } else {
  48. ev.image = '';
  49. }
  50. ev.titleWidth = tg.getStringWidth(ev.title);
  51. this.set(ev);
  52. },
  53. // TODO: validate event attributes
  54. validate: function (attrs) {
  55. // TODO
  56. },
  57. getEventImageSize:function(img) {
  58. var that = this,
  59. imgTesting = new Image(),
  60. img_src = imgTesting.src = img.src;
  61. imgTesting.onerror= delegatr(imgTesting, function () {
  62. debug.log("error loading image:" + img_src);
  63. });
  64. imgTesting.onload = delegatr(imgTesting, function () {
  65. that.get("image").height = this.height;
  66. that.get("image").width = this.width;
  67. });
  68. function delegatr(contextObject, delegateMethod) {
  69. return function() {
  70. return delegateMethod.apply(contextObject, arguments);
  71. }
  72. };
  73. } // end getEventImageSize
  74. });
  75. tg.TG_TimelineCollection = Backbone.Collection.extend({
  76. model: tg.TG_Timeline
  77. });
  78. // map model onto larger timeglider namespace
  79. /////////////////////////////////////////////
  80. tg.TG_Timeline = Backbone.Model.extend({
  81. urlRoot : '/timeline',
  82. defaults: {
  83. // no other defaults?
  84. "initial_zoom":25,
  85. "focus_date":"today",
  86. "timezone":"00:00",
  87. "title": "Untitled",
  88. "events": [],
  89. "legend": []
  90. },
  91. // processes init model data, adds certain calculated values
  92. _chewTimeline : function (tdata) {
  93. // TODO ==> add additional units
  94. MED = tdata.mediator;
  95. tdata.timeline_id = tdata.id;
  96. // initiates the timeline hash
  97. var evHash = {};
  98. widget_options = MED.options;
  99. var dhash = {
  100. "da":[],
  101. "mo":[],
  102. "ye":[],
  103. "de":[],
  104. "ce":[],
  105. "thou":[],
  106. "tenthou":[],
  107. "hundredthou":[],
  108. "mill":[],
  109. "tenmill":[],
  110. "hundredmill":[],
  111. "bill":[]
  112. };
  113. tdata.startSeconds = [];
  114. tdata.endSeconds = [];
  115. tdata.spans = [];
  116. tdata.hasImagesAbove = false;
  117. var tzoff = tdata.timezone || "00:00";
  118. tdata.timeOffset = TG_Date.getTimeOffset(tzoff);
  119. // TODO: VALIDATE COLOR, centralize default color(options?)
  120. if (!tdata.color) { tdata.color = "#333333"; }
  121. if (tdata.events.length>0) {
  122. var date, ddisp, ev, id, unit, ser, tWidth;
  123. var l = tdata.events.length;
  124. for(var ei=0; ei< l; ei++) {
  125. ev=tdata.events[ei];
  126. // make sure it has an id!
  127. if (ev.id) {
  128. id = ev.id
  129. } else {
  130. // if lacking an id, we'll make one...
  131. ev.id = id = "anon" + this.anonEventId++;
  132. }
  133. /*
  134. We do some pre-processing ** INCLUDING HASHING THE EVENT *
  135. BEFORE putting the event into it's Model&Collection because some
  136. (processed) event attributes are needed at the timeline level
  137. */
  138. if (ev.map) {
  139. if (MED.main_map) {
  140. if (timeglider.mapping.ready){
  141. ev.map.marker_instance = timeglider.mapping.addAddMarkerToMap(ev, MED.main_map);
  142. // debug.log("marker_instance", ev.map.marker_instance);
  143. }
  144. // requires TG_Mapping.js component
  145. } else {
  146. // debug.log("NO MAIN MAP... BUT LOAD MAPS FOR MODAL");
  147. // load instance of maps for modal viewing
  148. // requires: TG_Mapping.js
  149. tg.googleMapsLoad();
  150. }
  151. }
  152. // date_limit is old JSON prop name, replaced by date_display
  153. ddisp = ev.date_display || ev.date_limit || "da";
  154. ev.date_display = ddisp.toLowerCase().substr(0,2);
  155. // if a timezone offset is set on the timeline, adjust
  156. // any events that do not have the timezone set on them
  157. if (tdata.timeOffset.seconds) {
  158. ev.startdate = TG_Date.tzOffsetStr(ev.startdate, tdata.timeOffset.string);
  159. if (ev.enddate) {
  160. ev.enddate = TG_Date.tzOffsetStr(ev.enddate, tdata.timeOffset.string);
  161. }
  162. }
  163. ev.startdateObj = new TG_Date(ev.startdate, ev.date_display);
  164. // !TODO: only if they're valid!
  165. if ((ev.enddate) && (ev.enddate !== ev.startdate)){
  166. ev.enddateObj = new TG_Date(ev.enddate, ev.date_display);
  167. ev.span=true;
  168. tdata.spans.push({id:ev.id, start:ev.startdateObj.sec, end:ev.enddateObj.sec});
  169. } else {
  170. ev.enddateObj = ev.startdateObj;
  171. ev.span = false;
  172. }
  173. // cache the initial date for updating hash later
  174. // important for edit/delete operations
  175. ev.cache = {enddateObj:ev.startdateObj, enddateObj:ev.enddateObj}
  176. if (ev.image_class == "above") {
  177. tdata.hasImagesAbove = true;
  178. }
  179. if (!ev.icon || ev.icon === "none") {
  180. ev.icon = "";
  181. } else {
  182. ev.icon = ev.icon;
  183. }
  184. // for collapsed view and other metrics
  185. tdata.startSeconds.push(ev.startdateObj.sec);
  186. tdata.endSeconds.push(ev.enddateObj.sec);
  187. //// !! TODO VALIDATE DATE respecting startdate, too
  188. var uxl = tg_units.length;
  189. for (var ux = 0; ux < uxl; ux++) {
  190. unit = tg_units[ux];
  191. ///// DATE HASHING in action
  192. ser = TG_Date.getTimeUnitSerial(ev.startdateObj, unit);
  193. if (dhash[unit][ser] !== undefined) {
  194. dhash[unit][ser].push(id);
  195. } else {
  196. // create the array
  197. dhash[unit][ser] = [id];
  198. }
  199. /////////////////////////////
  200. }
  201. /////////////////////////////////
  202. // Since model is defined in the eventCollection
  203. // we j ust need to add the raw object here and it
  204. // is "vivified", properties set, etc
  205. ev.timelines = [tdata.timeline_id];
  206. if (!MED.eventCollection.get(id)) {
  207. var newEvent = new tg.TG_Event(ev);
  208. MED.eventCollection.add(newEvent);
  209. } else {
  210. // it's in the collection, but not associated with this timeline
  211. // ... or maybe it is...
  212. ///////////////////////////////////
  213. // ADD TIMELINE TO EVENT timelines ARRAY
  214. // if
  215. // event does NOT have timeline_id in its timelines array
  216. // at least add timeline_id
  217. // debug.log("DUPLICATE EVENT:", id);
  218. }
  219. }// end for: cycling through timeline's events
  220. // adding event secs to catalog of entire timeline
  221. var fl = timeglider.getLowHigh($.merge(tdata.startSeconds,tdata.endSeconds));
  222. /// bounds of timeline
  223. tdata.bounds = {"first": fl.low, "last":fl.high };
  224. } /// end if there are events!
  225. /* !TODO: necessary to parse this now, or just leave as is? */
  226. if (tdata.legend.length > 0) {
  227. //var legend = tdata.legend;
  228. //for (var i=0; i<legend.length; i++) {
  229. // var legend_item = legend[i];
  230. // debug.log("leg. title:" + legend_item['title'])
  231. //}
  232. tdata.hasLegend = true;
  233. } else {
  234. tdata.hasLegend = false;
  235. }
  236. /// i.e. expanded or compressed...
  237. /// ought to be attribute at the timeline level
  238. /// TODO: create a $.merge for defaults for a timeline
  239. tdata.display = "expanded";
  240. MED.eventCollection.setTimelineHash(tdata.timeline_id, dhash);
  241. // keeping events in eventCollection
  242. // hashing references to evnet IDs inside the date hash
  243. delete tdata.events;
  244. return tdata;
  245. },
  246. initialize: function(attrs) {
  247. var processed = this._chewTimeline(attrs);
  248. this.set(processed);
  249. this.bind("change", function() {
  250. // debug.log("changola");
  251. });
  252. }
  253. });
  254. })(timeglider);