emsApplication/applications/WebConfigure/web/js/lib/timeglider/timeglider.timeline.widget.js

412 lines
10 KiB
JavaScript

/*
* 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 = "<div id='tg-container' class='timeglider-container'>"
+ "<div class='timeglider-loading'><div>loading</div></div>"
+ "<div class='timeglider-centerline'></div>"
+ "<div class='tg-oof-count tg-oof-left'></div>"
+ "<div class='tg-oof-count tg-oof-right'></div>"
+ "<div class='timeglider-truck' id='tg-truck'>"
+ "<div class='timeglider-ticks noselect'>"
+ "<div class='timeglider-handle'></div>"
+ "</div>"
+ "</div>"
+ "<div class='tg-scrim'></div>"
+ "<div class='tg-scroller'><div class='tg-scroller-handle'></div></div>"
+ "<div class='timeglider-footer' id='tg-footer'>"
+ " <div class='tg-footer-center'>"
+ " <div class='tg-date-display noselect'><div class='tg-date-display-arrow'></div><span id='currentdate'></span></div>"
+ " </div>"
+ " <div class='tg-footer-buttons'>"
+ " <div class='timeglider-footer-button timeglider-filter-bt'></div>"
+ " <div class='timeglider-footer-button timeglider-settings-bt'></div>"
+ " </div>"
+ "</div>"
+ "<div class='timeglider-event-hover-info'></div>"
+ "</div><span id='timeglider-measure-span'></span>";
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);