/* * Timeglider for Javascript / jQuery * http://timeglider.com/jquery * * Copyright 2011, Mnemograph LLC * Licensed under Timeglider Dual License * http://timeglider.com/jquery/?p=license * /* * DEPENDENCIES: rafael.js ba-tinyPubSub jquery jquery ui (and css) jquery.mousewheel jquery.ui.ipad TG_Date.js TG_Timeline.js TG_TimelineView.js TG_Mediator.js TG_Org.js Timeglider.css * */ (function($){ /** * The main jQuery widget factory for Timeglider */ var timelinePlayer, tg = timeglider, MED, TG_Date = timeglider.TG_Date; $.widget( "timeglider.timeline", { // defaults! options : { base_namespace:"tg", timezone:"00:00", initial_focus:tg.TG_Date.getToday(), editor:"none", min_zoom : 1, max_zoom : 100, show_centerline:true, data_source:"", culture:"en", base_font_size:12, mousewheel: "zoom", // !TODO | pan | none initial_timeline_id:'', icon_folder:"js/timeglider/icons/", image_lane_height: 32, show_footer:true, use_scroller: false, minimum_timeline_bottom: 24, display_zoom_level:false, display_single_timeline_info:true, initial_timeline_modal:true, constrain_to_data:true, boost:0, tick_top:"", event_modal:{type:"default"}, event_overflow:"plus", // plus | scroll legend:{type:"default"}, loaded:{display:true} }, _create : function () { this._id = $(this.element).attr("id"); /* Anatomy: * * -container: main frame of entire timeline * -centerline * -truck: entire movable (left-right) container * -ticks: includes "ruler" as well as events * -handle: the grabbable part of the truck which * self-adjusts to center * -slider-container: wrapper for zoom slider * -slider: jQuery UI vertical slider * -timeline-menu * * -measure-span: utility div for measuring text lengths * * -footer: (not shown) gets added dynamically unless * options indicate otherwise */ // no need for template here as no data being passed var MAIN_TEMPLATE = "
" + "
loading
" + "
" + "
" + "
" + "
" + "
" + "
" + "
" + "
" + "
" + "
" + "" + "
" + "
"; this.element.html(MAIN_TEMPLATE); }, // eof _create() /** * takes the created template and inserts functionality * from Mediator and View constructors * * */ _init : function () { // validateOptions should come out as empty string var optionsCheck = timeglider.validateOptions(this.options); if (optionsCheck == "") { tg.TG_Date.setCulture(this.options.culture); MED = new tg.TG_Mediator(this.options, this.element); timelinePlayer = new tg.TG_TimelinePlayer(this, MED); this.player = timelinePlayer; // after timelinePlayer is created this stuff can be done MED.setFocusDate(new TG_Date(this.options.initial_focus)); MED.loadTimelineData(this.options.data_source, this.options.loaded); } else { alert("Rats. There's a problem with your widget settings:" + optionsCheck); } this.element.data("timeline", this.element.data("timegliderTimeline")); }, /** ********* PUBLIC METHODS *************** * */ /* * goTo * sends timeline to a specific date and, optionally, zoom * @param d {String} ISO8601 date: 'YYYY-MM-DD HH:MM:SS' * @param z {Number} zoom level to change to; optional */ goTo : function (d, z) { if (d == "next") { MED.gotoNextEvent(); } else if (d == "previous") { MED.gotoPreviousEvent(); } else { MED.gotoDateZoom(d,z); } return this; }, refresh : function () { MED.refresh(); return this; }, resize : function () { timelinePlayer.resize(); return this; }, filterBy : function (type, content) { MED.filterBy(type, content); return this; }, addFilterAction: function (name, filterFunction, actionFunction) { MED.addFilterAction(name, filterFunction, actionFunction); return this; }, removeFilterAction: function (name) { MED.removeFilterAction(name); return this; }, getMediator : function () { return MED; }, /* * getEventByID * By passing just an id, this returns the whole event object * (or the attributes of the Backbone model) * By adding a property such as "title", you can just get one property * @param id {String} The event id, as it was passed in JSON data * @param prop {String} optional property name string in case you * only want that one property */ getEventByID : function (id, prop) { return MED.getEventByID(id, prop); }, updateEvent: function (model_object) { return MED.updateEvent(model_object); }, /* * focusToEvent * By passing just an id, this returns the whole event object * (or the attributes of the Backbone model) * By adding a property such as "title", you can just get one property * @param id {String} The event id, as it was passed in JSON data * @param prop {String} optional property name string in case you * only want that one property */ focusToEvent : function (event_id) { var ev = MED.getEventByID(event_id); MED.focusToEvent(ev); return this; }, getScope : function () { return MED.getScope(); }, fitToContainer : function () { MED.fitToContainer(); return this; }, /* * adjustNowEvents * keeps ongoing events current to the latest time * For this to work, events need a property in them * that looks like this: * "keepCurrent": "start" * OR * "keepCurrent": "end" * The "start" value would update the startdate to be the * current time and if start & end are the same, it would * update both; the "end" value would update the enddate * only, creating a "leading edge" event with a continuous * "still happening" state */ adjustNowEvents : function () { return MED.adjustNowEvents(); }, /* * addEvent * adds and event to any of the existing, loaded timelines * @param new_event {Object} simple TG event including: .id, .title, .startdate (simple ISO8601 string) AND .timelines (array with timeline ids) * @param refresh {Bool} Do we want to refresh the display * after the event is loaded? use false is loading a * group of events * */ addEvent : function (new_event, refresh) { return MED.addEvent(new_event, refresh); }, /** * zoom * zooms the timeline in or out, adding an amount, often 1 or -1 * * @param n {number|string} * numerical: -1 (or less) for zooming in, 1 (or more) for zooming out * string: "in" is the same as -1, "out" the same as 1 */ zoom : function (n) { switch(n) { case "in": n = -1; break; case "out": n = 1; break; } // non-valid zoom levels if (n > 99 || n < -99) { return false; } MED.zoom(n); return this; }, /** * loadTimeline * basic wrapper for Mediator loadTimeline * * @param src {String} JSON source for timeline * * @param callback_object {Function} simple function to run * after data is loaded, toggles timeline to view by default ***** * OR ***** * callback_object includes * .fn = function that will be called * .args = arguments Object to be passed in fn (above) * .display = boolean, set to true to swap in just the first timeline loaded; otherwise it will load but won't immediately display * (fn will also have timeline(s) available as "data" in 2nd arg) * * @param reload {Boolean} replace an existing timeline with the same id as the one to be loaded in src * * */ loadTimeline : function (src, callback_object, reload) { MED.loadTimelineData(src, callback_object, reload); return this; }, /** * reloadTimelime * reloads already loaded timeline from json * * @param id {String} timeline id * @param source {string url} url at which JSON will be fetched */ reloadTimeline : function (id, source) { MED.reloadTimeline(id, source); return this; }, /** * panButton * sets a pan action on an element for mousedown and mouseup|mouseover * * */ panButton : function (jquery_sel, vel) { var _vel = 0; switch(vel) { case "left": _vel = 30; break; case "right": _vel = -30; break; default: _vel = vel; break; } timelinePlayer.setPanButton(jquery_sel, _vel); }, /** * destroy * wipes out everything */ destroy : function () { MED.emptyData(); $.Widget.prototype.destroy.apply(this, arguments); $(this.element).html(""); } }); // end widget process })(jQuery);