dashboard
Version:
Create dashboards with gadgets on node.js
421 lines (355 loc) • 13.9 kB
text/xml
xml version="1.0" encoding="UTF-8"
<Module>
<ModulePrefs title="HR Diagram 2">
<Require feature="locked-domain" />
<Require feature="dynamic-height"/>
<Require feature="opensocial-0.8"/>
<Require feature="minimessage"/>
</ModulePrefs>
<Content type="html"><![CDATA[
<div id="divSelections" style="width: 100%;">
<table>
<TBODY>
<TR>
<td>
<input id="btDoHR" onclick="hr.plotHR();" type="button" value="Plot HR"/>
</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="chartVisualization">
<img id="imgChartVis" src="images/1px.gif" style="display: none"/>
</div>
<div id="visualization">
</div>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<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 = "HR Diagram" + "_" + Math.floor(Math.random()*100000+1).toString();
// 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();
google.load('visualization', '1', {packages: ['ScatterChart']});
//google.setOnLoadCallback(hr.initPlot);
gadgets.window.adjustHeight();
}
function Plotter(){
var my = new Object();
// CONSTANTS
var DEFAULT_NAMESPACE = "NS2",
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...");
// clear visualization
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 = 180;
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 showVisualization(show) {
if (show) {
document.getElementById('imgChartVis').style.display = 'inline';
}
else {
document.getElementById('imgChartVis').style.display = 'none';
}
gadgets.window.adjustHeight();
}
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
var pointsList = [];
var rows = xmlDoc.getElementsByTagName('Row');
if (rows.length === 0){
// no rows
showSpinner(false, 'No Objects');
return;
}
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
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;
// add info to the placemark description
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;
}
}
cObj.setCelestialCoord(cc);
// add point to the list
pointsList.push(cObj);
}
// write the points to the scatter plot
if (pointsList.length > 0) {
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 dt = new google.visualization.DataTable();
//
// dt.addColumn('number', 'r');
// dt.addColumn('number', 'g-r');
// dt.addRows(pList.length);
// 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)) {
// dt.setValue(i,0, g_r); // x value
// dt.setValue(i,1, -1*r); // y value // make negative to flip the axis
// }
// }
// }
//
//
// var splot = new google.visualization.ImageChart(document.getElementById('visualization'));
// splot.draw(dt,{titleX: 'g-r', titleY: 'r', legend: 'none', height: PLOT_HEIGHT, width: PLOT_WIDTH, axisFontSize: '11', cht: 's'});
//
// document.getElementById('visualization').style.height = PLOT_HEIGHT + "px";
var min = 9999,
max = -9999,
xCoords = [],
yCoords = [];
for (var i=0, len=pList.length; i<len; i++) {
var cObj = pList[i];
var g = Math.round(cObj.getGMag() * 100) / 100; // round to 7 decimal places
var r = Math.round(cObj.getRMag() * 100) / 100; // round to 7 decimal places
var g_r = Math.round((g-r) * 100) / 100;
if ((g_r >= -1) && (g_r <= 3)) {
if (g < min) {
min = g;
} else if (g > max) {
max = g;
}
xCoords.push(g_r);
yCoords.push(r); // make neg to flip y values
}
}
var params = 'cht=s' + // type: scatter chart
'&chd=t:' + xCoords.join(',') + '|' + yCoords.join(',') + // data
'&chs=250x400' + // size
'&chds=-1,3,' + max + ',' + min + // actual (hidden) x/y axis limits
'&chxt=y,x' + // show y and x axis y = 0 , x = 1
'&chxr=0,' + max + ',' + min +
'|1,-1,3' +
'&chm=o,4080CF,0,-1,6';
document.getElementById('imgChartVis').src = 'http://chart.apis.google.com/chart?' + params;
document.getElementById('chartVisualization').style.height = PLOT_HEIGHT + "px";
showVisualization(true);
}
my.initPlot = function() {
// create datatable
var dt = new google.visualization.DataTable();
var splot = new google.visualization.ScatterChart(document.getElementById('visualization'));
dt.addColumn('number', 'g-r');
dt.addColumn('number', 'g');
splot.draw(dt,{titleX: 'G-R', titleY: 'G', legend: 'none', height: '400', width: '400', });
}
my.testPlot = function() {
// create datatable
var dt = new google.visualization.DataTable();
// add them to the VP_Point_List so they show up as placemarks
var pList = di.readVariable(DEFAULT_NAMESPACE, "VP_Point_List"); // grab the current (plotted) points list
if (pList === null){
pList = new UW.astro.UniqIdList();
}
dt.addColumn('number', 'g-r');
dt.addColumn('number', 'g');
numRows = 20;
dt.addRows(numRows);
for (var i=0; i<numRows-1; i++){
ra = Math.floor(Math.random() * 24);
dec = Math.floor(Math.random() * 180 - 90);
dt.setValue(i,0,ra); // set random ra
dt.setValue(i,1,dec); // set random dec
cc = new UW.astro.CelestialCoordinate(ra, dec);
pList.append(cc);
}
// plot all the points on the scatter plot
var splot = new google.visualization.ScatterChart(document.getElementById('visualization'));
splot.draw(dt,{titleX: 'G-R', titleY: 'G', legend: 'none'});
// add points to VP as placemarks
di.writeVariable(DEFAULT_NAMESPACE, "VP_Point_List", pList);
// add to the 'click' event on the scatter plot
// we will make the VP zoom to that point
google.visualization.events.addListener(splot, 'select',
function(){
var sel_row = splot.getSelection()[0].row;
var sel_ra = dt.getValue(sel_row, 0);
var sel_dec = dt.getValue(sel_row, 1);
cc = new UW.astro.CelestialCoordinate(sel_ra, sel_dec);
di.writeVariable(DEFAULT_NAMESPACE, "VP_Coord", cc); // make the viewport zoom to this point
});
}
// PRIVATE
function showSpinner(show, text){
// set text status
document.getElementById('divStatusText').innerHTML = text;
if (show){
document.getElementById('imgSpinner').style.display = 'inline';
}
else{
document.getElementById('imgSpinner').style.display = 'none';
}
}
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>