UNPKG

dashboard

Version:

Create dashboards with gadgets on node.js

363 lines (303 loc) 10.8 kB
<?xml version="1.0" encoding="UTF-8"?> <Module> <ModulePrefs title="Color Magnitude Diagram"> <Require feature="locked-domain" /> <Require feature="dynamic-height"/> <Require feature="opensocial-0.8"/> <Require feature="minimessage"/> </ModulePrefs> <Content type="html"><![CDATA[ <!-- chart dependencies --> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/javascript"></script> <script src="http://sky.astro.washington.edu/gadgets/highcharts/highcharts.js" type="text/javascript"></script> <div id="divSelections" style="width: 100%;"> <table> <TBODY> <TR> <td> <input id="btDoHR" onclick="hr.plotHR();" type="button" value="Plot Color Magnitude"/> </td> <td> <img id="imgSpinner" src="images/spinnerGrey.gif" style="display:none" /> </td> <td> <div id="divStatusText"></div> </td> </TR> </TBODY> </table> </div> <div id="divChart1"> </div> <script src="http://sky.astro.washington.edu/gadgets/js/gDataInterface.js" type="text/javascript"></script> <script src="http://sky.astro.washington.edu/gadgets/js/astroObjectLib.js" type="text/javascript"></script> <script type="text/javascript"> // Plot (hr) object is global var hr = null, debug = true; // Writes to the console if debug (global) is true function debugLog(msg){ if ((debug === true) && (window.console && console.log)) { console.log(GADGET_NAME + ": " + msg); } return; } // GLOBAL CONSTANTS var GADGET_NAME = "Color_Magnitude" + "_" + Math.floor(Math.random()*100000+1).toString(); var chart1; // globally available // Writes to the console if debug (global) is true function debugLog(msg){ if ((debug === true) && (window.console && console.log)) { console.log(GADGET_NAME + ": " + msg); } return; } // create HR object function init(){ hr = new Plotter(); gadgets.window.adjustHeight(); } function Plotter(){ var my = new Object(); // CONSTANTS var DEFAULT_NAMESPACE = "NS1", MM_TIMER_DURATION = 4, PLOT_HEIGHT = 400, PLOT_WIDTH = 300; // PRIVATE var _namespaceList = [ DEFAULT_NAMESPACE ]; // list of our current Namespaces. Just init with the default // Private Helper Variables var di = new gDataInterface(GADGET_NAME, DEFAULT_NAMESPACE); // make dataInterface object, init with default var miniMsg = new gadgets.MiniMessage();// make MiniMessage object // INIT var msg = miniMsg.createStaticMessage("Attempting to register gadget..."); di.registerMe( { gadgetName : GADGET_NAME, namespaceList : _namespaceList, variableList : [ "VP_Coord", "Active_Point_List", "VP_Point_List" ], triggerList : [], successCallback : registrationSuccess, failureCallback : registrationFailure } ); // Callback after successful registration function registrationSuccess(){ debugLog('Registration successful'); if (msg) { miniMsg.dismissMessage(msg); // free up msg msg = null; miniMsg.createTimerMessage("Registration Succesful.", MM_TIMER_DURATION); } } // Callback after a failure of registration // displays message showing failure function registrationFailure(){ debugLog('Registration FAILED!'); miniMsg.dismissMessage(msg); miniMsg.createDismissibleMessage("Unable to register gadget.\nWe cannot communicate with other gadgets."); } // PUBLIC METHODS my.plotHR = function() { // TODO: other ways to choose the bounds we want on the gadget showSpinner(true, "Getting objects..."); // disappear the chart showVisualization(false); // get current VP bounds // bounds is array of CelestialCoordinates: [topLeft, bottomRight] var bounds = di.readVariable(DEFAULT_NAMESPACE, "VP_Current_Bounds"); if (bounds === null){ alert('Set bounds'); showSpinner(false, ""); return; } // get objects within bounds from catalogue // multiply ra by 15 to convert to degrees // TODO: option for other catalogues var maxObjs = 500; var sdssQueryData = {cmd: "SELECT TOP " + maxObjs + " objid,modelMag_g,modelMag_r,modelMag_i,ra,dec FROM PhotoPrimary WHERE ra BETWEEN " + bounds[0].getRa() * 15 + " AND " + bounds[1].getRa() * 15 + " AND dec BETWEEN " + bounds[1].getDec() + " AND " + bounds[0].getDec() + " AND modelMag_g > -9999" + " ORDER BY modelMag_g ASC", format: "xml" }; url = 'http://cas.sdss.org/public/en/tools/search/x_sql.asp'; makeGETRequest(url, sdssQueryData, sdssResponseCB); } 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 sdssResponseCB(obj) { // parse the XML if (obj.errors.length > 0){ // errors debugLog(obj.errors); showSpinner(false, 'Service: ' + obj.errors); return; } else if (obj.text === ""){ // returned empty string showSpinner(false, 'Service returned empty string'); return; } xmlDoc = xmlStringToDoc(obj.text); // walk XML to create points and write to objectData // TODO: make objectData with tree widget var objDataText = []; var pointsList = []; var rows = xmlDoc.getElementsByTagName('Row'); if (rows.length === 0){ // no rows showSpinner(false, 'No Objects'); } else if ((rows.length === 1) && (rows[0].textContent.indexOf('No rows returned') !== -1)){ // the special case answer is that no rows were returned showSpinner(false, 'No Objects'); return; } // We probably have valid data at this point, so parse it and display it // Write total # rows to the gadget display objDataText.push("<b>Total Objects: " + rows.length + "</b></br>"); for (var i=0,len=rows.length; i<len; i++){ var row = rows[i]; var cc = new UW.astro.CelestialCoordinate(0,0); var cObj = new UW.astro.CelestialObject(); // 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; cc.appendDescription('<b>' + attName + "</b>: " + attValue + "</br>"); // TODO: make an SDSS Data table inside the description // set all the cc properties switch(attName){ case "ra": // divide ra by 15 to convert to hours cc.setRa(attValue /15); break; case "dec": cc.setDec(attValue); break; case "modelMag_g": cObj.setGMag(attValue); break; case "modelMag_r": cObj.setRMag(attValue); break; } // add text for gadget display objDataText.push(attName + ": " + attValue + "</br>"); } cObj.setCelestialCoord(cc); // add point to the list pointsList.push(cObj); } // write the points to the scatter plot plotPointsList(pointsList); // write the points to the public point list var pubList = di.readVariable(DEFAULT_NAMESPACE, "VP_Point_List"); // TODO: test for the UniqIDList type if (pubList === null){ pubList = new UW.astro.UniqIdList(); } for (var i=0, len=pointsList.length; i<len; i++){ pubList.append(pointsList[i].getCelestialCoord()); } di.writeVariable(DEFAULT_NAMESPACE, "VP_Point_List", pubList); showSpinner(false, ""); } // plots the g-r vs. g on the color-magnitude diagram // @param pList: is an array of celestial coordinates // with g and r as properties function plotPointsList(pList) { var graphData = []; for (var i=0, len=pList.length; i<len; i++) { var cObj = pList[i]; var g = Math.round(cObj.getGMag() * 10000000) / 10000000; // round to 7 decimal places var r = Math.round(cObj.getRMag() * 10000000) / 10000000; // round to 7 decimal places if ((g !== null) && (r !== null)) { var g_r = Math.round((g-r) * 10000000) / 10000000; // only display -1 < g-r < 3 if ((g_r >= -1) && (g_r <= 3)) { graphData.push( [g_r, r] ) } } } $(document).ready(function() { chart1 = new Highcharts.Chart({ chart: { renderTo: 'divChart1', defaultSeriesType: 'scatter' }, title: { text: 'Color Magnitude' }, xAxis: { title: { enabled: true, text: 'g - r' }, startOnTick: true, endOnTick: true, showLastLabel: true }, yAxis: { title: { text: 'r' }, reversed: true }, series: [{ name: 'Set 1', data: graphData }] }); }); debugger; document.getElementById('divChart1').style.height = PLOT_HEIGHT + "px"; showVisualization(true); } // HELPER function showVisualization(show) { if (show) { document.getElementById('divChart1').style.display = "block"; } else { document.getElementById('divChart1').style.display = "hidden"; } gadgets.window.adjustHeight(); } function showSpinner(show, text){ // set text status document.getElementById('divStatusText').innerHTML = text; if (show){ document.getElementById('imgSpinner').style.visibility = 'block'; } else{ document.getElementById('imgSpinner').style.visibility = 'hidden'; } } 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; } return my; } gadgets.util.registerOnLoadHandler(init); </script> ]]> </Content> </Module>