/* * Helper JS functions for charting with jQuery.flot (www.flotcharts.org) * * */ jQuery(function() { addTooltipToDomIfNeeded(); }); function addTooltipToDomIfNeeded() { if ( document.getElementById("#charttooltip") === null ) { jQuery("
").css({ position: "absolute", border: "1px solid #ffdddd", display: "none", padding: "2px", "background-color": "white", color: "black", "font-size": "10px", opacity: "1.0", }).appendTo("body"); } } jsonpFetch = function (url, func, callback) { function create() { jsonpFetch[func] = function (data) { callback(data); delete jsonpFetch[func]; script.remove(); }; return 'jsonpFetch.' + func; } var cb = create(); var script = d3.select("head") .append("script") .attr("type", "text/javascript") .attr("src", url); }; function EnlargeFlotChart( id, plot, w, h ) { jQuery('#' + id).css( 'height', h); jQuery('#' + id).css( 'width', w); jQuery('#' + id + '_embiggen')[0].style.display='none'; jQuery('#' + id + '_restore')[0].style.display='inline'; if ( w > 400 ) jQuery('#' + id + '_ranges' )[0].style.display='inline'; plot.resize(); } function RestoreFlotChart( id, plot, w, h ) { jQuery('#' + id).css( 'height', h); jQuery('#' + id).css( 'width', w); jQuery( '#' + id + '_embiggen')[0].style.display='inline'; jQuery( '#' + id + '_restore')[0].style.display='none'; if ( w < 400 ) jQuery('#' + id + '_ranges' )[0].style.display='none'; plot.resize(); } function AddFunctionsToPlot( plot, baseURL, divName, reloadFn, bIsBarChart, bIsPieChart ) { // helper to move the selected date range into view on the table, and load more data if needed plot.getOptions().showSelectedRange = function() { var dateStart = new Date(this.dateStart); var dateEnd = new Date(this.dateEnd); var newDateStart = dateStart.getFullYear() + "-" + (dateStart.getMonth() + 1) + "-" + dateStart.getDate(); var newDateEnd = dateEnd.getFullYear() + "-" + (dateEnd.getMonth() + 1) + "-" + dateEnd.getDate(); // force 0 padding on the date components so that the PHP side doesn't break our date format newDateStart = newDateStart.replace(/(\b\d{1}\b)/g, "0$1") newDateEnd = newDateEnd.replace(/(\b\d{1}\b)/g, "0$1") plot.getOptions().updatePlotAxis( plot ); if ( newDateStart != this.query_params["dateStart"] || newDateEnd != this.query_params["dateEnd"] ) { this.query_params["dateStart"] = newDateStart; this.query_params["dateEnd"] = newDateEnd; jsonpFetch(baseURL + jQuery.param(this.query_params), reloadFn.name , reloadFn ); //console.log( baseURL + jQuery.param( this.query_params ) ); jQuery('#' + divName).parent().addClass("loading"); } }; // helper function to move the current window of data forward or back plot.getOptions().shiftRange = function (percentMove, bShiftBack) { var dateStart = new Date(this.dateStart); var dateEnd = new Date(this.dateEnd); var minDate = new Date(this.minDate); var now = new Date(); now.setTime( now.getTime() - 60*60 ); // an hour in the past var currentRange = dateEnd.getTime() - dateStart.getTime(); var s_nMinZoomRange = this.getRangeInMS(8, "hour" ); if ( currentRange < s_nMinZoomRange ) currentRange = s_nMinZoomRange; var dateDiff = currentRange; if (bShiftBack) { dateDiff *= -1; } dateStart.setTime(dateStart.getTime() + dateDiff * (percentMove / 100)); dateEnd.setTime(dateStart.getTime() + currentRange ); if (dateStart < minDate) { dateStart = minDate; } if ( dateEnd > now ) { dateEnd = now; dateStart.setTime(dateEnd.getTime() - dateDiff ); } this.dateStart = dateStart.getTime(); this.dateEnd = dateEnd.getTime(); this.showSelectedRange(); }; // helper to get the number of msec given a range and type of range plot.getOptions().getRangeInMS = function( range, type ) { var unit = 1000 * 60; // base time is minutes if (type == "year") { unit *= 60 * 24 * 365; } else if (type == "month") { unit *= 60 * 24 * 30; } else if (type == "week") { unit *= 60 * 24 * 7; } else if (type == "day") { unit *= 60 * 24; } else if (type == "hour") { unit *= 60; } return unit * range; }; // given a type (year, day, week) and an amount, move to that selection plot.getOptions().updateRange = function (amount, range) { if (range == "now") { var dateStart = new Date(this.dateStart); var dateEnd = new Date(this.dateEnd); var dateDiff = dateEnd.getTime() - dateStart.getTime(); var today = new Date(); today.setTime( today.getTime() - 60*60 ); // an hour in the past dateStart.setTime(today.getTime() - dateDiff); // keep the current range, but start from today this.dateStart = dateStart.getTime(); this.dateEnd = today.getTime(); } else if (range == "max") { var dateStart = new Date(this.minDate); var dateEnd = new Date(); // today dateEnd.setTime( dateEnd.getTime() - 60*60 ); // an hour in the past this.dateStart = dateStart.getTime(); this.dateEnd = dateEnd.getTime(); } else { var dateStart = new Date(this.dateStart); var dateEnd = new Date(this.dateEnd); var timeRange = this.getRangeInMS(amount, range); dateStart.setTime(dateEnd.getTime() - timeRange); this.dateStart = dateStart.getTime(); } this.showSelectedRange(); }; // zoom in or out the range of the current graph plot.getOptions().zoom = function( nPercentage ) { var s_nMaxZoomRange = this.getRangeInMS(8, "year"); var s_nMinZoomRange = this.getRangeInMS(8, "hour" ); var nChange = nPercentage / 100; var dateStart = new Date(this.dateStart); var dateEnd = new Date(this.dateEnd); var currentRange = dateEnd.getTime() - dateStart.getTime(); //console.log( 'before zoom Start:' + dateStart.toString() + ' End:' + dateEnd.toString() ); //console.log( 'zoom :' + (currentRange/(1000*60*60)) ); var desiredRange = currentRange * nChange; if ( desiredRange < s_nMinZoomRange ) desiredRange = s_nMinZoomRange; else if ( desiredRange > s_nMaxZoomRange ) desiredRange = s_nMaxZoomRange; if ( desiredRange == currentRange ) { //console.log( 'min zoom :' + (desiredRange/(1000*60*60)) ); return; } dateStart.setTime( dateEnd.getTime() - desiredRange ); this.dateStart = dateStart.getTime(); this.dateEnd = dateEnd.getTime(); this.showSelectedRange(); }; plot.getOptions().updatePlotAxis = function( plot ) { var dateStart = new Date(this.dateStart); var dateEnd = new Date(this.dateEnd); //console.log( 'Start:' + dateStart.toString() + ' End:' + dateEnd.toString() ); var newEndOfDay = new Date( dateEnd.getFullYear(), dateEnd.getMonth(), dateEnd.getDate(), "23", "59", "59" ); plot.getOptions().xaxes[0].min = Math.max( dateStart.getTime(), plot.getAxes().xaxis.datamin ); plot.getOptions().xaxes[0].max = Math.min( newEndOfDay.getTime(), plot.getAxes().xaxis.datamax ); plot.setupGrid(); plot.draw(); }; // now add the tooltip hover function jQuery('#' + divName).bind("plothover", function (event, pos, item) { if (item) { if (bIsPieChart) { var div = jQuery('#' + divName); div.find(".legendLabel").removeClass("highlighted"); div.find( "td" ).filter(function () { return jQuery(this).text() == item.series.label; }).addClass( "highlighted" ); } else { var msg; if (bIsBarChart) { msg = item.datapoint[1].toLocaleString(); } else { var x = item.datapoint[1].toLocaleString(); var d = new Date(item.datapoint[0]); var timeFormat = { hour: '2-digit' }; if (d.getMinutes() != 0 ) { timeFormat = { hour: '2-digit', minute: '2-digit' }; } msg = d.toLocaleDateString("en-US" ) + ' ' + d.toLocaleTimeString("en-US" , timeFormat ) + ' ' + x; } jQuery("#charttooltip").html(msg) .css({top: item.pageY - 30, left: item.pageX - 25}) .fadeIn(200); } } else { if (bIsPieChart) { jQuery('#' + divName).find(".legendLabel").removeClass("highlighted"); } else { jQuery("#charttooltip").hide(); } } }); addTooltipToDomIfNeeded(); }