|
// A Chiasm plugin for loading data from the Data Canvas Sense Your City API. |
|
// http://map.datacanvas.org/#!/data |
|
define(["model", "jquery", "lodash", "async"], function (Model, $, _, async){ |
|
|
|
return function (runtime) { |
|
|
|
var model = Model({ |
|
publicProperties: [] |
|
}), |
|
|
|
// See API documentation at http://map.datacanvas.org/#!/data |
|
API_URL = "http://sensor-api.localdata.com/api/v1/aggregations.csv", |
|
|
|
// List of all cities with available data. |
|
cities = ["San Francisco", "Bangalore", "Boston", "Geneva", "Rio de Janeiro", "Shanghai", "Singapore"], |
|
|
|
// The default parameters to pass into the API. |
|
defaultParams = { |
|
|
|
// Use averaging as the aggregation operator. |
|
op: "mean", |
|
|
|
// Include temperature only. |
|
fields: "temperature",//,light,airquality_raw,sound,humidity,dust", |
|
|
|
// Get data for every 5 minutes. |
|
resolution: "5m", |
|
} |
|
|
|
// Fetches the latest data for a given city. |
|
function getLatestDataForCity(city, callback){ |
|
|
|
// Get data for the last 24 hours. |
|
// 1000 milliseconds/second, 60 seconds/minute, 5 minutes |
|
var params = _.extend({ |
|
from: new Date(Date.now() - 1000 * 60 * 60 * 24).toISOString(), |
|
before: new Date().toISOString(), |
|
"over.city": city |
|
}, defaultParams); |
|
|
|
// Use jQuery to fetch the data. |
|
// jQuery is used here rather than D3 because of its nice parameter syntax. |
|
$.get(API_URL, params, function(csv) { |
|
|
|
// Parse the CSV string. |
|
callback(null, d3.csv.parse(csv, function(d){ |
|
|
|
// Parse ISO date strings into Date objects. |
|
d.timestamp = new Date(d.timestamp); |
|
|
|
// Parse strings into Numbers for numeric fields. |
|
d.temperature = +d.temperature; |
|
//d.light = +d.light |
|
//d.airquality_raw = +d.airquality_raw |
|
//d.sound = +d.sound |
|
//d.humidity = +d.humidity |
|
//d.dust = +d.dust |
|
|
|
return d; |
|
})); |
|
}); |
|
}; |
|
|
|
// Fetches the current temperature across all cities. |
|
function getLatestData(callback){ |
|
async.map(cities, getLatestDataForCity, function(err, results){ |
|
callback(err, _.flatten(results)); |
|
}); |
|
} |
|
|
|
// Fetch the data and expose it to the model. |
|
getLatestData(function(err, data){ |
|
model.data = data; |
|
|
|
// Extract the most recent timestamp. |
|
model.currentTimestamp = data[data.length - 1].timestamp; |
|
|
|
}); |
|
|
|
// Provide a utility that rounds a given date to a 5-minute interval, |
|
// for use with crossfilter. |
|
model.when("selectedTimeApproximate", function(selectedTimeApproximate){ |
|
var selectedTime = new Date(selectedTimeApproximate); |
|
selectedTime.setMilliseconds(0); |
|
selectedTime.setSeconds(0); |
|
|
|
// Round to 5 minute intervals to match with the data. |
|
selectedTime.setMinutes(Math.round(selectedTime.getMinutes()/5)*5); |
|
|
|
model.selectedTime = selectedTime; |
|
}); |
|
|
|
return model; |
|
}; |
|
}); |