UNPKG

dashboard

Version:

Create dashboards with gadgets on node.js

474 lines (395 loc) 16.2 kB
<?xml version="1.0" encoding="UTF-8"?> <!-- get_data.xml --> <!-- Author: Ian Smith (imsmith@uw.edu) --> <Module> <ModulePrefs title="Plot"> <Require feature="locked-domain" /> <Require feature="dynamic-height"/> <Require feature="opensocial-0.9"/> <Require feature="minimessage"/> <Require feature="settitle"/> </ModulePrefs> <Content type="html"><![CDATA[ <link href="css/gadget.css" rel="stylesheet" type="text/css"> <script src="js/DataInterface.js" type="text/javascript"></script> <script src="js/astroObjectLib.js" type="text/javascript"></script> <script src="js/dataset.js" type="text/javascript"></script> <div id="divQuery" style="width: 100%;"> Dataset Name: <input id="txtDatasetName" type="text" /> <div id="divStatusText" class="statusBox"></div> </div> <div id="divVPBounds" style="float:right;" class="infoBox"> <h3>Viewport Bounds</h3> <span id="spViewportBounds" class="info"></span> </div> <div id="divQueryButtons"> </div> <div id="divCatalog"> Catalog: <select id="selCatalog"> </select> </div> <div id="divQueryBox" style="width:100%;"> Query String: <br/> <textarea id="txtQueryString" rows="5" style="width:100%;"></textarea> <br/> <input id="btGetData" onclick="ga.getData();" type="button" value="Submit"/> </div> <script type="text/javascript"> var ga = null, DEBUG = false; function debugLog(msg){ if(DEBUG){UW.astro.debugLog(GADGET_NAME + ": " + msg);}} // GLOBAL CONSTANTS var GADGET_NAME = "Get_Data" + "_" + Math.floor(Math.random()*100000).toString(); // Text in {{ }} such as " {{ra.lower}}" are substituted in setQueryText() method var QUERY_BUTTONS = [ { buttonNum: 0, name: "SDSS Stars", desc: "Get star magnitudes in U, G, R, I, Z from SDSS", catalog: "SDSS", query: "SELECT TOP 500 objid, ra, dec, modelMag_u, modelMag_g, modelMag_r, modelMag_i, modelMag_z, (modelMag_u - modelMag_g) as u_g, (modelMag_g - modelMag_r) as g_r, (modelMag_r - modelMag_i) as r_i, (modelMag_i - modelMag_z) as i_z from Star where ra between {{ra.lower}} and {{ra.upper}} and dec between {{dec.lower}} and {{dec.upper}} and modelMag_g > -9999 ORDER BY modelMag_g ASC" }, { buttonNum: 1, name: "SDSS Galaxies", desc: "Get galaxy magnitudes in U, G, R, I, Z from SDSS", catalog: "SDSS", query: "SELECT TOP 500 g.objid, g.ra, g.dec, s.z, g.modelMag_u, g.modelMag_g, g.modelMag_r, g.modelMag_i, g.modelMag_z, (g.modelMag_u - g.modelMag_g) as u_g, (g.modelMag_g - g.modelMag_r) as g_r, (g.modelMag_r - g.modelMag_i) as r_i, (g.modelMag_i - g.modelMag_z) as i_z from Galaxy as g left outer join SpecObjAll as s on g.specobjID = s.specobjID where g.ra between {{ra.lower}} and {{ra.upper}} and g.dec between {{dec.lower}} and {{dec.upper}} and g.modelMag_g > -9999 ORDER BY g.modelMag_g ASC" }]; // // { buttonNum: 2, // name: "2MASS 1", // desc: "2MASS 1", // catalog: "2MASS", // query: "Under Construction" // } // ]; // // create HR object function init(){ gadgets.window.setTitle("Data Query"); ga = new GetData(); ga.setFields(); gadgets.window.adjustHeight(); } function GetData(){ var my = new Object(); var _myFields = {}; // CONSTANTS var PLOT_HEIGHT = 400, PLOT_WIDTH = 300; // Status Icons var ICON_URL_SELECTED = '/ascot/gadgets/images/target_yellow.png', ICON_URL_DEFAULT = '/ascot/gadgets/images/target.png', ICON_URL_SPINNER = '/ascot/gadgets/images/spinnerGrey.gif', ICON_URL_ERROR = '/ascot/gadgets/images/errorIcon.gif', ICON_URL_SUCCESS = '/ascot/gadgets/images/successIcon.gif'; var ICON = { SUCCESS : ICON_URL_SUCCESS, ERROR : ICON_URL_ERROR, SPINNER : ICON_URL_SPINNER, NONE : ""} // PRIVATE var _namespaceList = [ UW.astro.DEFAULT_NAMESPACE ]; // list of our current Namespaces. Just init with the default var _catalogs = [ { name: "SDSS", url: "http://cas.sdss.org/public/en/tools/search/x_sql.asp" }, // contains info for catalogs and thier urls // { name: "2MASS", url: "" } ]; // Private Helper Variables var di = new UW.astro.DataInterface(GADGET_NAME); // make dataInterface object, init with default // INIT di.registerMe( { namespaceList : _namespaceList, variableList : [ "Dataset_List", "Viewport_Current_Bounds" ], triggerList : [ [ "Viewport_Current_Bounds", setVPBounds] ], } ); function getDatasetNameText () { return document.getElementById("txtDatasetName").value; } function clearForm() { document.getElementById("txtDatasetName").value = ''; // no reason to clear query string yet // document.getElementById("txtQueryString").value = ''; } // PUBLIC METHODS my.setFields = function() { // set the catalog options var options = []; for (var i=0, len=_catalogs.length; i<len; i++) { options.push(_catalogs[i].name); } setSelectOptions("selCatalog", options); // create the buttons for (var i=0, len=QUERY_BUTTONS.length; i<len; i++) { createQueryButton(QUERY_BUTTONS[i]); } } function createQueryButton(buttonObj) { var divButtons = document.getElementById('divQueryButtons'); var button = document.createElement('input'); button.setAttribute('type', 'button'); button.setAttribute('name', buttonObj.name); button.setAttribute('value', buttonObj.name); button.setAttribute('title', buttonObj.desc); button.onclick = function(){ ga.setQueryText(buttonObj.buttonNum); }; divButtons.appendChild(button); } my.getData = function() { var dsName = getDatasetNameText(); if (dsName.length < 1) { showError("Enter dataset name"); return; } // TODO: other ways to choose the bounds we want on the gadget showSpinner("Getting objects..."); // get query string from the text area var queryObj = {data: {cmd:null, format:null}, url: null}; queryObj.data.cmd = getQueryString(); if (queryObj.data.cmd === "") { showError('Enter query string'); return; } // find catalog in the _catalogs object to get the url var selectedCatalog = getSelectedOption("selCatalog"); for (var i=0, len=_catalogs.length; i<len; i++) { if (_catalogs[i].name === selectedCatalog) { queryObj.url = _catalogs[i].url; } } // set to XML (for SDSS anyway) queryObj.data.format = "xml"; if (queryObj.url === null) { showError('Select a catalog'); return; } // finishes with callback "queryResponseCB" makeGETRequest(queryObj.url, queryObj.data, queryResponseCB); } my.setQueryText = function(buttonNum) { if (QUERY_BUTTONS.length > buttonNum) { // set catalog var buttonObj = QUERY_BUTTONS[buttonNum]; setSelectedCatalog(buttonObj.catalog); var qString = buttonObj.query; // replace bounds var bounds = getVPBounds(); if (bounds !== null) { qString = replaceQueryVars(qString, "{{ra.lower}}", bounds[0].getRa().toFixed(6)); qString = replaceQueryVars(qString, "{{ra.upper}}", bounds[1].getRa().toFixed(6)); qString = replaceQueryVars(qString, "{{dec.lower}}", bounds[1].getDec().toFixed(6)); qString = replaceQueryVars(qString, "{{dec.upper}}", bounds[0].getDec().toFixed(6)); } setQueryString(qString); } } function replaceQueryVars(str, replacee, replacer) { return str.replace(replacee, replacer); } function getVPBounds() { // get current VP bounds // bounds is array of CelestialCoordinates: [topLeft, bottomRight] return di.readVariable(UW.astro.DEFAULT_NAMESPACE, "Viewport_Current_Bounds"); } function makeGETRequest(url, data, callback) { var params = {}; getdata = gadgets.io.encodeValues(data); params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.GET; url = url + '?' + getdata; gadgets.io.makeRequest(url, callback, params); } function queryResponseCB(obj) { // parse the XML if (obj.errors.length > 0){ // errors debugLog(obj.errors); if (obj.errors[0].indexOf("504") !== -1) { showError("Request Timed out.<br/>Try restricting search to<br/>smaller ra/dec bounds."); } else { showError('Service: ' + obj.errors); } return; } else if (obj.text === ""){ // returned empty string showError('Service returned empty string'); return; } xmlDoc = xmlStringToDoc(obj.text); // walk XML to create points and write to objectData var rows = xmlDoc.getElementsByTagName('Row'); if ((rows.length === 0) || ((rows.length === 1) && (rows[0].textContent.indexOf('No rows returned') !== -1))){ // the special case answer is that no rows were returned showError('No objects from ' + getSelectedOption("selCatalog") + ' catalog'); return; } // indicate status to user showSuccess("Returned " + rows.length + " records."); // We probably have valid data at this point, so parse it and display it // create and write Dataset from the row data var ds = createDataset(rows); ds.setName(getDatasetNameText()); writeDataset(ds); } function arrayContains(a, obj) { var i = a.length; while (i--) { if (a[i] === obj) { return true; } } return false; } function writeDataset(ds) { // TODO: this needs to be redone with di functions like: di.getDataset_List, di.addDataset // write dataset list var list = di.readVariable(UW.astro.DEFAULT_NAMESPACE, "Dataset_List"); if (list === null) { list = []; } var name = ds.getName(); if (!arrayContains(list, name)) { di.registerVariable(name, null); di.writeVariable(UW.astro.DEFAULT_NAMESPACE, name, ds); list.push(name); di.writeVariable(UW.astro.DEFAULT_NAMESPACE, "Dataset_List", list); } else { // write dataset di.writeVariable(UW.astro.DEFAULT_NAMESPACE, name, ds); } } // Accepts "rows" as an ObjectHTML collection // and creates a Dataset from it and returns it function createDataset(rows) { var json = []; for (var i=0,len=rows.length; i<len; i++){ var row = rows[i]; var elem = {}; // loop through attributes for (var k=0, kLen=row.attributes.length; k<kLen; k++){ // k is the attribute index var attName = row.attributes[k].nodeName; var attValue = row.attributes[k].nodeValue; elem[attName] = attValue; } json.push(elem); } // create dataset ds = new UW.astro.Dataset(json); return ds; } // HELPER function clearStatus() { showStatus(ICON.NONE, ""); } function showSpinner(text) { showStatus(ICON.SPINNER, text); } function showSuccess(text) { showStatus(ICON.SUCCESS, text); } function showError(text) { showStatus(ICON.ERROR, text); } function showStatus(iconUrl, text){ if (iconUrl !== ICON.NONE) { setStatus( '<img id="imgStatus" src="' + iconUrl + '" /> ' + text); } else { setStatus(text); } } function setStatus(text) { // set text status var statusDiv = document.getElementById('divStatusText'); statusDiv.innerHTML = text; // make visible statusDiv.style.visibility = 'block'; } function setVPBounds() { var bounds = getVPBounds(); if (bounds !== null) { getField('spViewportBounds').innerHTML = "ra between " + bounds[0].getRa().toFixed(4) + " and " + bounds[1].getRa().toFixed(4) + " and<br/>dec between " + bounds[1].getDec().toFixed(4) + " and " + bounds[0].getDec().toFixed(4); } } function xmlStringToDoc(text){ if (window.DOMParser){ parser=new DOMParser(); xmlDoc=parser.parseFromString(text,"text/xml"); } else // Internet Explorer { xmlDoc=new ActiveXObject("Microsoft.XMLDOM"); xmlDoc.async="false"; xmlDoc.loadXML(text); } // TODO: test to verify its created return xmlDoc; } // HTML Field Getters/Setters function getField(field) { if (!(_myFields.hasOwnProperty(field)) || (_myFields[field] === null)) { _myFields[field] = document.getElementById(field); } return _myFields[field]; } function getQueryString() { return getField("txtQueryString").value; } function setQueryString(str) { setTextBoxValue("txtQueryString", str); } function setSelectedCatalog(catalog) { selectValue("selCatalog", catalog); } function restrictVPBounds() { return getField('ckVPBounds').checked; } function setTextBoxValue(textBoxName, value) { textBox = document.getElementById(textBoxName); if (textBox !== null && textBox !== undefined) { textBox.value = value; } } // accepts name of select box // returns the value in the select box, or "" function getSelectedOption(select) { var selName = document.getElementById(select); if (selName.length > 0){ return selName.options[selName.selectedIndex].value; } else { return ""; } } function selectValue(selectName, value) { var sel = document.getElementById(selectName); if (sel === undefined || sel === null) { return; } for (var i=0, len=sel.options.length; i<len; i++) { if (sel.options[i].value === value) { sel.options[i].selected = true; return; } } } // Accepts the name of a select object, and an array of strings // replaces the options with the array of strings function setSelectOptions(selectName, options) { var select = document.getElementById(selectName); if (select === null) { return; } // save old selected option so maybe it can be reselected var oldOpt = getSelectedOption(selectName); // clear options for (var i=select.length-1; i>=0; i--) { select.remove(i); } // add options for (var i=0, len=options.length; i<len; i++) { // if oldOption is in the list, then select it select.add(new Option(options[i], options[i], false, (oldOpt === options[i])), null); } } return my; } gadgets.util.registerOnLoadHandler(init); </script> ]]> </Content> </Module>