dashboard
Version:
Create dashboards with gadgets on node.js
408 lines (344 loc) • 14.1 kB
HTML
<!-- get_data.xml -->
<!-- Author: Ian Smith (imsmith@uw.edu) -->
<html lang="en">
<meta http-equiv="Pragma" content="no-cache">
<head>
<title>Data Inquirer</title>
<!-- ASCOT Basic Style Sheets -->
<link href="/css/960/reset.css" rel="stylesheet" type="text/css">
<link href="/css/960/text.css" rel="stylesheet" type="text/css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js" type="text/javascript"></script>
<script src="/js/astroObjectLib.js" type="text/javascript"></script>
<script src="/js/helpers.js" type="text/javascript"></script>
<script type="text/javascript">
var ga = null;
// 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"
}];
var dataSetList;
var viewportBounds;
// create HR object
function init(){
ga = new GetData();
ga.setFields();
gadget.resize();
}
function GetData(){
var my = new Object();
var _myFields = {};
// CONSTANTS
var PLOT_HEIGHT = 400,
PLOT_WIDTH = 300;
// Status Icons
var ICON_URL_SELECTED = '/gadgets/images/target_yellow.png',
ICON_URL_DEFAULT = '/gadgets/images/target.png',
ICON_URL_SPINNER = '/gadgets/images/spinnerGrey.gif',
ICON_URL_ERROR = '/gadgets/images/errorIcon.gif',
ICON_URL_SUCCESS = '/gadgets/images/successIcon.gif';
var ICON = { SUCCESS : ICON_URL_SUCCESS,
ERROR : ICON_URL_ERROR,
SPINNER : ICON_URL_SPINNER,
NONE : ""}
// PRIVATE
var _catalogs = [ { name: "SDSS", url: "http://cas.sdss.org/public/en/tools/search/x_sql.asp" } ]; // contains info for catalogs and thier urls
gadget.dashboard.bind('viewBoundsChanged', setVPBounds);
//gadget.dashboard.bind('dataSetChanged', updateDatasetList);
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 query = getQueryString();
var url;
if (query === "") {
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) {
url = _catalogs[i].url;
}
}
if (url === null) {
showError('Select a catalog');
return;
}
// finishes with callback "queryResponseCB"
makeGETRequest(url, query, 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
if (viewportBounds !== null) {
qString = replaceQueryVars(qString, "{{ra.lower}}", viewportBounds[0].getRa().toFixed(6));
qString = replaceQueryVars(qString, "{{ra.upper}}", viewportBounds[1].getRa().toFixed(6));
qString = replaceQueryVars(qString, "{{dec.lower}}", viewportBounds[1].getDec().toFixed(6));
qString = replaceQueryVars(qString, "{{dec.upper}}", viewportBounds[0].getDec().toFixed(6));
}
setQueryString(qString);
}
}
function replaceQueryVars(str, replacee, replacer) {
return str.replace(replacee, replacer);
}
function insertWhere(str, whereStr) {
// insert in WHERE clause
var splitted = str.split(/where/i);
if (splitted.length === 2) {
return splitted[0] + " WHERE " + whereStr + " AND " + splitted[1];
}
// insert in ORDER BY clause
splitted = str.split(/order by/i);
if (splitted.length === 2) {
return splitted[0] + whereStr + " ORDER BY " + splitted[1];
}
// no WHERE or ORDER BY, so just tack it on the end
return str + " WHERE " + whereStr;
}
function makeGETRequest(url, query, callback) {
var params = {};
//console.log(encodeURIComponent(url + '?format=html&cmd=' + query) );
console.log(parseURL(url + '?cmd=' + query).url);
$.ajax({
'url': '/XMLHttpRequest/' + encodeURIComponent(url + '?format=xml&cmd=' + encodeURIComponent(query)),
success: queryResponseCB
});
}
function queryResponseCB(obj) {
// parse the XML
if (obj === ""){
// returned empty string
showError('Service returned empty string');
return;
}
xmlDoc = xmlStringToDoc(obj);
// 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);
gadget.dashboard.setDataSet(getDatasetNameText(), ds);
gadget.resize();
}
// 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 = gadget.dashboard.createDataSet();
ds.init(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 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;
}
function setVPBounds(bounds) {
viewportBounds = bounds;
if (bounds !== null) {
getField('spViewportBounds').innerHTML = "ra between " + viewportBounds[0].getRa().toFixed(4) + " and " + viewportBounds[1].getRa().toFixed(4) + " dec between " + viewportBounds[1].getDec().toFixed(4) + " and " + viewportBounds[0].getDec().toFixed(4);
}
}
// 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;
}
</script>
</head>
<body onload="init();">
<div id="content" class="extraPadding">
<div id="divVPBounds" style="float: right">
<div><b>Viewport Bounds</b></div>
<div id="spViewportBounds" class="info"></div>
</div>
<div id="divQuery">
Dataset Name: <input id="txtDatasetName" type="text" />
<div id="divStatusText"></div>
</div>
<div id="divQueryButtons" style="margin-top: 10px; margin-bottom: 10px;"></div>
<div id="divCatalog">
Catalog: <select id="selCatalog"></select>
</div>
<div id="divQueryBox" style="width:100%; margin-top: 10px;">
Query String:
<br/>
<textarea id="txtQueryString" rows="5" style="width:99%;"></textarea>
<br/>
<input id="btGetData" onclick="ga.getData();" type="button" value="Submit"/>
</div>
</div>
</body>
</html>