// Location Hash wrapper script // https://gist.github.com/2927857 var LocationHash=function(e){function r(){var e=location.hash.substr(1).split("&");t={};for(var r=0,i;i=e[r];r++){var s=i.split("=");if(s.length){var o=s[1].split(",");t[s[0]]=o.length>1?o:o[0]}}for(var r=0,u;u=n[r];r++)u()}function i(e){var n=[];for(var r in t){var i=t[r],s="=";if(e=="h")n.push(r+s+(i.join?i.join(","):i));else{i.join?s="[]=":i=[i];for(var o=0,u;u=i[o];o++)n.push(r+s+u)}}return n.join("&")}var t,n=[];return e(window).on("hashchange",r),r(),{params:function(e){return i(e)},changed:function(e){n.push(e)},get:function(e){return t[e]},set:function(e){for(var n in e){var r=e[n];r==undefined?delete t[n]:t[n]=r}location.hash=i("h")}}}(d3.select); // TODO find a d3 datetimepicker (or make one) // then drop jquery, jqueryui and datetimerpicker altogether (function(){ $('button').button(); var now = Date.now(); var defaults = [now - (1000 * 60 * 30), now]; $('.date-time').datetimepicker().each(function(i){ var input = $(this); var time = LocationHash.get(input.attr('name')); input.datetimepicker('setDate', new Date(time ? time * 1000 : defaults[i])); }); }()); // graphs using nv.d3 (function(){ var loading = d3.select('#loading'); var main_el = d3.select('#main-graph'); if (main_el.empty()) return; var validate = /counters|timers|gauges/; var inputs = d3.selectAll('.date-time')[0]; var graph = main_el.select('svg'); var view = d3.select('button'); loading.toggle = function(){ this.style('display', this.style('display') == 'block' ? 'none' : 'block'); }; function set_time_params(){ var map = {}; for (var i = 0, elem; elem = inputs[i]; i++) map[elem.name] = +new Date(elem.value) / 1000; LocationHash.set(map); } function time_axis_formatter(resp){ var format = { 600: '%x', 60: '%X', 10: '%X' }[resp.interval]; return function(d){ return d3.time.format(format)(new Date(d)); }; } function render_graph(){ var xhr, params = LocationHash.params(); if (!validate.test(params) && location.pathname != '/') return alert('Need to supply at least one counter, timer or gauge'); main_el.select('em').remove(); loading.toggle(); d3.json('/data?'+ params, function(resp){ loading.toggle(); if (!resp) return main_el.append('em').text('An Error Occurred!'); nv.addGraph(function(){ // initialize a new chart object var chart = nv.models.lineChart() .x(function(d){ return d[0]; }) .y(function(d){ return d[1]; }) // set xAxis tick format based up range and interval chart.xAxis.tickFormat(time_axis_formatter(resp)) // force 0 into yAxis domain chart.forceY([0]); // bind data and render graph graph.datum(resp.results) .transition().duration(500) .call(chart); return chart; }); }); } // view button handler view.on('click', function(){ set_time_params(); render_graph(); }); // listen for changes to URL LocationHash.changed(render_graph); // initial graph render render_graph(); }());