/* * Mazama_databrowser.js * * Jonathan Callahan * http://mazamascience.com * * Default behavior for Mazama Science databrowsers. * * 1) Any change to an element in the form should trigger a plot request so that the * current state of the UI always reflects the parameters used to generate the plot. * * 2) Each successful response contains a url for the plot and an array of values * for potential use in this javascript code. * */ /**** GLOBAL VARIABLES ********************************************************/ // All global variables begin with 'G_' var G_CONUSArrival_UTC = 9; var G_NorthAmericaFineArrival_UTC = 9; var G_EurAsiaFineArrival_UTC = 22; var G_initialDate = null; /**** UTILITY FUNCTIONS *******************************************************/ // Display text as an error message function displayError(errorText) { alert(errorText); } /**** EVENT HANDLERS **********************************************************/ // User chooses a new Region function selectRegion() { // Only show the hourly for English language North American and Eurasian trajectories var region = $('#region').val(); var language = $('#language').val(); if (language == "en") { if (region == "NorthAmericaFine_NorthAmerica" || region == "EurAsiaFine_Eurasia") { $('#hourRollover_container').show(); } else { $('#hourRollover_container').hide(); } } loadNewImages(); } // User chooses a new gfsGrid function loadNewImages() { var regionParts = $('#region').val().split('_'); var gfsGrid = regionParts[0]; if (gfsGrid == "CONUS" || gfsGrid == "NorthAmericaFine") { $('#plotType').val('CONUSArctic'); } else if (gfsGrid == 'EurAsiaFine') { $('#plotType').val('EurasiaArctic'); } else { err_msg = "gfsGrid '" + gfsGrid + "' is not recognized."; alert(err_msg); } loadDay1(); // Add the rolloverImages loadRolloverImage(1); loadRolloverImage(2); loadRolloverImage(3); } // One layer of abstraction before sending the request allows us to take UI // specific actions, e.g. setting hidden parameters or disabling some elements, // before sending the request. function updatePlot() { // Set any hidden parameter values based on UI state. // ('#hiddenParameter').val(1.0) prePlotActions(); sendRequest(); } // Set styles, disable elements, etc. function prePlotActions() { $('#spinner').fadeIn(1000); } // Reset styles, enable disabled elements, etc. function postPlotActions(JSONResponse) { $('#spinner').hide(); } // Get GFS datestring from UI elements function gfsDateString() { var regionParts = $('#region').val().split('_'); var gfsGrid = regionParts[0]; // User selected date // NOTE: datepicker is not fully initialized when the page loads so we need // NOTE: this check the very first time through var userDate = $('#datepicker').datepicker("getDate"); if (userDate == null) { userDate = G_initialDate; } // Today's date var d = new Date(); var UTCHours = d.getHours() + d.getTimezoneOffset()/60; var userDateString = $.datepicker.formatDate('yymmdd',userDate); var dDateString = $.datepicker.formatDate('yymmdd',d); if (userDateString == dDateString) { if (gfsGrid == "CONUS" || gfsGrid == "NorthAmericaFine") { if ( UTCHours >= G_CONUSArrival_UTC) { var gfsDate = d; // today } else { var msecs = d.getTime() - 86400000 var gfsDate = new Date(msecs) // yesterday } var dateString = $.datepicker.formatDate('yymmdd00',gfsDate); } else if (gfsGrid == "EurAsiaFine") { if ( UTCHours >= G_EurAsiaFineArrival_UTC) { var gfsDate = d; // today } else { var msecs = d.getTime() - 86400000 var gfsDate = new Date(msecs) // yesterday } var dateString = $.datepicker.formatDate('yymmdd12',gfsDate); } } else { // All earlier dates selected from the datepicker are OK if (gfsGrid == "CONUS" || gfsGrid == "NorthAmericaFine") { var dateString = $.datepicker.formatDate('yymmdd00',userDate); } else if (gfsGrid == "EurAsiaFine") { var dateString = $.datepicker.formatDate('yymmdd12',userDate); } } return(dateString); } // Change images function loadDay(e) { var id = e.currentTarget.id.substr(0,4); var buttonId = "#" + id; var dayClass = "." + id; // Set active rollovers $('.dayRollover').removeClass('dayRolloverActive'); $(buttonId).addClass('dayRolloverActive'); $('.hourRollover').removeClass('hourRolloverActive'); $(dayClass).addClass('hourRolloverActive'); // Load new image loadImage(id); } function loadHour(e) { var region = $('#region').val(); var id = e.currentTarget.id; // NOTE: hourRollover id's start with "Hour000" but EurAsiaFine hours start // NOTE: with "Hour012" so we may need to convert. if (region == "EurAsiaFine_Eurasia") { var a = {"Hour000":"Hour012", "Hour003":"Hour015", "Hour006":"Hour018", "Hour009":"Hour021", "Hour012":"Hour024", "Hour015":"Hour027", "Hour018":"Hour030", "Hour021":"Hour033", "Hour024":"Hour036", "Hour027":"Hour039", "Hour030":"Hour042", "Hour033":"Hour045", "Hour036":"Hour048", "Hour039":"Hour051", "Hour042":"Hour054", "Hour045":"Hour057", "Hour048":"Hour060", "Hour051":"Hour063", "Hour054":"Hour066", "Hour057":"Hour069", "Hour060":"Hour072", "Hour063":"Hour075", "Hour066":"Hour078", "Hour069":"Hour081"} id = a[id]; } // Set active rollovers $('.dayRollover').removeClass('dayRolloverActive'); if ( $(e.currentTarget).hasClass('Day1') ) { $('#Day1').addClass('dayRolloverActive'); } else if ( $(e.currentTarget).hasClass('Day2') ) { $('#Day2').addClass('dayRolloverActive'); } else if ( $(e.currentTarget).hasClass('Day3') ) { $('#Day3').addClass('dayRolloverActive'); } $('.hourRollover').removeClass('hourRolloverActive'); $(e.currentTarget).addClass('hourRolloverActive'); // Load new image loadImage(id); } function loadDay1() { // Set active rollovers $('.dayRollover').removeClass('dayRolloverActive'); $('#Day1').addClass('dayRolloverActive'); $('.hourRollover').removeClass('hourRolloverActive'); $('.Day1').addClass('hourRolloverActive'); // Load new image loadImage("Day1"); } function loadRolloverImage(dayNum) { var language = $('#language').val(); var regionParts = $('#region').val().split('_'); var gfsGrid = regionParts[0]; var region = regionParts[1]; var dateString = gfsDateString(); var imageName = gfsGrid + "Arctic_" + dateString + "_Day" + dayNum + "_" + region; var img_url = "output_" + language + "/" + imageName + ".png"; var id = "#Day" + dayNum + "Image"; $(id).attr('src',img_url); } /**** REQUEST HANDLERS ********************************************************/ function handleJSONResponse(JSONResponse) { if (JSONResponse.status == 'ERROR') { displayError(JSONResponse.error_text); } else { $('#plot').attr('src',JSONResponse.img_url); returnValues = JSONResponse.return_values; // return_values have many potential uses but are not used in the example databrowser } postPlotActions(); } function sendRequest() { var url = '/cgi-bin/arctic-transport.cgi'; data = $('#controls_form').serialize(); $.getJSON(url, data, handleJSONResponse); } // The loadImage() function loads images without checking to see if they exist // This makes for a single round-trip instead of the request-response used with // sendRequest(). function loadImage(id) { var language = $('#language').val(); var regionParts = $('#region').val().split('_'); var gfsGrid = regionParts[0]; var region = regionParts[1]; var dateString = gfsDateString(); var imageName = gfsGrid + "Arctic_" + dateString + "_" + id + "_" + region; var img_url = "output_" + language + "/" + imageName + ".png"; $('#plot').attr('src',img_url); } /**** INITIALIZATION **********************************************************/ $(function() { // Hide the spinner $('#spinner').hide(); // Hide the hourRollovers for non-English var language = $('#language').val(); if (language != "en") { $('#hourRollover_container').hide(); } // Attach behavior to UI elements $('#region').change(selectRegion); $('.dayRollover').click(loadDay); $('.hourRollover').mouseenter(loadHour); // Set up datepicker to end 'yesterday' unless the CONUS images are ready (>16:00 PST) // NOTE: To avoid dealing with the date rollover, we calculate our own UTCHours that // NOTE: can be 24 or larger. // var d = new Date(); // var UTCHours = d.getHours() + d.getTimezoneOffset()/60; // if ( UTCHours >= G_CONUSArrival_UTC) { // var daysFromNow = 0; // } else { // var daysFromNow = -1; // } // var msecs = d.getTime() + daysFromNow * 86400000 // var gfsDate = new Date(msecs) // today or yesterday // Use PHP determination of most recent available data var language = $('#language').val(); if (language == "en") { var gfsDate = new Date(2023, 10-1, 4); } else { var gfsDate = new Date(2023, 10-1, 3); } var dateString = $.datepicker.formatDate('yy-mm-dd',gfsDate); $("#datepicker").val(dateString); // NOTE: Date object months start with 0, hence the '7-1' notation for July (July=7, 7-1=6) options = { minDate: new Date(2012,9-1,1), maxDate: gfsDate, dateFormat: "yy-mm-dd", defaultDate: gfsDate, onSelect: loadNewImages } $("#datepicker").datepicker(options); // Activate tooltips $('span.tooltip').cluetip({width: '500px', attribute: 'id', hoverClass: 'highlight'}); // NOTE: The datepicker isn't initialized until it is opened by the user. // NOTE: The gfsDateString() uses the datepicker unless it returns null. // NOTE: We need to have G_iniitalDate for the first call to loadNewImages() // NOTE: when the datepicker returns null. G_initialDate = gfsDate; loadNewImages(); });