Skip to content

Instantly share code, notes, and snippets.

@gtzilla
Created May 17, 2011 04:26
Show Gist options
  • Save gtzilla/975948 to your computer and use it in GitHub Desktop.
Save gtzilla/975948 to your computer and use it in GitHub Desktop.
//
// BitsMetricViews.js
// bitly2
//
// Created by gregory tomlinson on 2011-05-12.
// Copyright 2011 the public domain. All rights reserved.
//
/*
Usage:
// 1st argument is 'settings' which are 'global to all instances or BitsMetricViews'
var pages = new BitsMetricViews({
box : "#select_metrics_summary_view",
dropdown_id : "#catd_dropdown_box_fub",
interval : 15000,
page_type : 1
});
Extend Existing Views -- uses jQuery to extend to add new and replace existing for 'display_views'
pages.extend_views({
"HOURBYHOUR" : {
meta : null,
period : 60,
measure_unit : "DAY",
title : "Past 7 Days",
anchor : "#past7days",
auto_update : false
}
})
Remove a View (by key name):
pages.remove_view("total");
call pages.display(); to update display
Set All Views (Event) Methods -- lazy method. Assigns same type to all options.
Creates a new BitsMetaMetric(), sets events, and adds to the [realtime|summary etc].meta
pages.add_all_views_events({
"click" : {
"params" : { "hash" : page_hash },
"method" : bit_metrics.click_remote_callback,
"scope" : bit_metrics
},
"country" : {
"params" : { "hash" : page_hash },
"method" : bit_metrics.country_remote_callback,
"scope" : bit_metrics
},
"domain" : {
"params" : { "hash" : page_hash },
"method" : bit_metrics.domain_remote_callback,
"scope" : bit_metrics
}
});
Manually Add Instances to Views
This method allows user to manually add events to BitsMetaMetric instance
pages.add_view_meta("realtime", new BitsMetaMetric() );
*/
(function(window, undefined) {
var settings={
box : "#middle",
dropdown_id : "#catd_dropdown_box",
page_type : 0,
interval : 30000
},
timer_interval=null,
display_views={
"REALTIME" : {
meta : null, // reference to new BitsMetaMetric(). Must contain a .phone() method
period : 60,
measure_unit : "REALTIME",
title : "Realtime",
anchor : "#pasthour",
auto_update : true
},
"24HOUR" : {
meta : null,
period : 24,
measure_unit : "HOUR",
title : "Past 24 Hours",
anchor : "#past24hours",
auto_update : false
},
"7DAY": {
meta : null,
period : 7,
measure_unit : "DAY",
title : "Past 7 Days",
anchor : "#past7days",
auto_update : false
},
"14DAY": {
meta : null,
period : 14,
measure_unit : "DAY",
title : "Past 14 Days",
anchor : "#past14days",
auto_update : false
},
"30DAY": {
meta : null,
period : 30,
measure_unit : "DAY",
title : "Past 30 Days",
anchor : "#past30days",
auto_update : false
},
"TOTAL": {
meta : null, //
period : -1,
measure_unit : "DAY",
title : "Total",
anchor : "#total",
auto_update : false
}
};
window.BitsMetricViews=function( opts ) {
// settings is 'global'
settings=jQuery.extend(true, {}, settings, opts);
var self=this, lst=[], views={},
styles_added=false,
active_view_name="REALTIME"; // views are specific to this instance of BitsMetricViews (could have two?)
views=jQuery.extend(true, {}, views, display_views);
/*
View Meta:
an instance of BitsMetaMetric or some other object
which provides:
.phone() method
display_view (string) -- a display view to be associated with
REALTIME, "TOTAL" etc
*/
this.add_view_meta=function( display_view, bits_meta_instance ) {
views[display_view.toUpperCase()].meta=bits_meta_instance;
}
this.add_view=function( key, view ) {
views[key.toUpperCase()]=view;
}
this.remove_view=function( key ) {
delete views[ key.toUpperCase() ];
}
this.extend_views=function( new_views ) {
views=jQuery.extend(true, {}, views, new_views );
}
this.get_views=function() {
return views;
}
this.update =function( display_name ) {
active_view_name=(display_name || active_view_name).toUpperCase();
if(views[active_view_name].meta) {
views[active_view_name].meta.phone();
this.start_updates();
} // make remote call
}
this.stop_updates=function() {
clearInterval( timer_interval );
if( views[active_view_name].meta && views[active_view_name].meta.abort) {
views[active_view_name].meta.abort();
}
}
this.start_updates=function() {
if(views[active_view_name].auto_update) {
clearInterval( timer_interval );
timer_interval=setInterval( (function( curr_view ){
return function() {
views[curr_view].meta.phone.call( views[curr_view].meta );
}
})( active_view_name ), settings.interval );
}
}
this.display=function( display_name ) {
// DOM management
// Instance private var: active_view_name
var structure_frag=build_dropdown_frag( views ),
$box=$(settings.box), $elem, $parent;
if(!styles_added) { build_styles(); }
$(settings.dropdown_id).remove(); // remove exisitng menu
$box.append( fastFrag.create( structure_frag ) ).toggle( self.menu_open, self.menu_close );
this.update( display_name ); // makes a remote call, sets the active view
$elem=$box.find("a[view="+active_view_name+"]").parent("li");
$parent=$elem.parent("ul");
if($elem) {
$elem.detach().prependTo( $parent );
}
$(settings.dropdown_id).find("a").bind("click", self.click_event);
}
/*
And Events for Each Menu Option
Iterate Over List of known views
Stitch events for each type, click, referrer, domain
obj {
endpoint_type:{
params : {}
callback : func
scope : context || this
}
}
*/
this.add_all_views_events=function( obj ) {
// okay, build the meta here
var bmm, type;
for(var view in views) {
bmm = new BitsMetaMetric({
"page_type" : settings.page_type
});
for(var endpoint_type in obj ) {
type=endpoint_type;
obj[type].params.days=views[view].period;
bmm.add_event( type, obj[type].params, obj[type].method, obj[type].scope || this );
bmm.units_by_name( views[view].measure_unit );
bmm.set( "period", views[view].period );
}
this.add_view_meta(view, bmm);
bmm=null;
}
}
// public click event for options in dropdown, can be replaced
this.click_event=function(evt, view) {
// scope: 'this' is the DOM element, aka jquery event is continued
evt.preventDefault();
var curr_view_name = $(evt.target).attr("view"),
view = views[curr_view_name.toUpperCase()],
$elem=$(this).parent("li") || $(this), $parent=$elem.parent("ul");
// set the active view to the selected value, using 'view' as the view name
// ex: realtime|day|hour etc
// this is what actuall calls that...
// do my thing first.. then public :)
if($elem) {
$elem.detach().prependTo( $parent );
self.update( curr_view_name );
}
}
this.menu_open=function(evt, data) {
var $box=$(settings.dropdown_id);
$box.animate({
height:$box.find("ul").height()
});
}
this.menu_close=function(evt, data ) {
$(settings.dropdown_id).animate({
height:15 // see reference in build_styles()
});
}
}
function build_dropdown_frag( views ) {
var item, frags=[], structure_frag;
for(var k in views) {
item=views[k];
frags.push({
type : "li",
css : "catd_single_drop_item",
"content" : {
type : "a",
content : item.title,
attr : {
href : item.anchor,
view : k,
type : item.measure_unit
}
}
});
}
structure_frag={
"id" : settings.dropdown_id.substr(1),
content : {
css : "catd_dropdown_list_box",
"content" : {
type : "ul",
content : frags
}
}
}
return structure_frag;
}
/*
CSS Styles
.css
Could be loaded via an external sheet
*/
function build_styles() {
// some tests suggest this is 'faster' than str+="more string" concat method
var drop_styles=[
".catd_dropdown_list_box { text-align:left; }",
".catd_single_drop_item { diplay:block; padding:2px 6px; }",
".catd_single_drop_item a { color: #666; display:block; margin-right:10px; }",
".catd_single_drop_item a:hover { color: #69f; }",
settings.dropdown_id + " { border:1px solid #ccc; padding:2px 4px 6px; background:#f6f6f6; overflow:hidden; height:15px; width:150px; }"
], frag={
type : "style",
content : drop_styles.join(" ")
};
$("head").append( fastFrag.create( frag ));
}
})(window);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment