Switch to a dygraph temperature graph and add extremes

This commit is contained in:
Wesley Moore 2011-05-05 07:24:46 +10:00
parent 71f2d3d65c
commit 503380c8f5
4 changed files with 243 additions and 148 deletions

View file

@ -442,9 +442,22 @@ body.weather
width: 100% width: 100%
height: 320px height: 320px
section.rain section, section > .temperature
clear: both
margin-top: 2em margin-top: 2em
.extreme
float: left
margin: 0 2em 2em 0
time.day
display: block
text-align: center
div, time
margin: 0.5em 0
font-family: $ans-serif
small small
display: block display: block
font-size: smaller font-size: smaller

View file

@ -5,7 +5,13 @@
<div class="loading"><img src="/images/spinner.gif" width="64" height="64" alt="Loading" /> Loading</div> <div class="loading"><img src="/images/spinner.gif" width="64" height="64" alt="Loading" /> Loading</div>
<div class="temperature chart"></div> <section class="extremes"></section>
<div class="temperature">
<h3>History</h3>
<button id="today">Today</button>
<div class="chart"></div>
</div>
</section> </section>
<section class="rain"> <section class="rain">
@ -23,3 +29,33 @@
</section> </section>
<small>Forecast icons by <a href="http://lavana.deviantart.com/art/Flat-Weather-Icons-32021664">LavAna</a></small> <small>Forecast icons by <a href="http://lavana.deviantart.com/art/Flat-Weather-Icons-32021664">LavAna</a></small>
<script id="current-template" type="text/x-handlebars-template">
<div id="current">
<figure class="forecast">
<img src="/images/weather/{{forecast}}.png" width="48" height="48" alt="{{forecast}}" />
<figcaption>Forecast</figcaption>
</figure>
<div class="temperature">
<div class="current temperature">{{temperature}}&deg;C</div>
</div>
</div>
</script>
<script id="extremes-template" type="text/x-handlebars-template">
<section class="extremes">
<h3>Extremes</h3>
{{#extremes}}
<div class="extreme">
<time datetime="{{isoDate date}}" class="day">{{day date}}</time>
<div class="min">
Min <span class="temperature">{{min/temperature}}&deg;C</span> at
<time datetime="{{isoDate min/time}}">{{time min/time}}</time>
</div>
<div class="max">
Max <span class="temperature">{{max/temperature}}&deg;C</span> at
<time datetime="{{isoDate max/time}}">{{time max/time}}</time>
</div>
</div>
{{/extremes}}
</section>
</script>

View file

@ -3,6 +3,7 @@
<head> <head>
<%= render '_head' %> <%= render '_head' %>
<script src="/js/jquery.flot.min.js" type="text/javascript" charset="utf-8"></script> <script src="/js/jquery.flot.min.js" type="text/javascript" charset="utf-8"></script>
<script src="/js/dygraph-combined.js" type="text/javascript" charset="utf-8"></script>
<!--[if IE lt 9]><script language="javascript" type="text/javascript" src="/js/excanvas.min.js"></script><![endif]--> <!--[if IE lt 9]><script language="javascript" type="text/javascript" src="/js/excanvas.min.js"></script><![endif]-->
<script src="/js/handlebars.js" type="text/javascript" charset="utf-8"></script> <script src="/js/handlebars.js" type="text/javascript" charset="utf-8"></script>
<script src="/js/weather.js" type="text/javascript" charset="utf-8"></script> <script src="/js/weather.js" type="text/javascript" charset="utf-8"></script>

View file

@ -1,22 +1,4 @@
function render_current(o) { (function() {
return '<div id="current">\n\
<figure class="forecast">\n\
<img src="/images/weather/' + (Mojo.escape(Mojo.normalize(o, "forecast"))) + '.png" width="48" height="48" alt="' + (Mojo.escape(Mojo.normalize(o, "forecast"))) + '" />\n\
<figcaption>Forecast</figcaption>\n\
</figure>\n\
\n\
<div class="temperature">\n\
<div class="current temperature">' + (Mojo.escape(Mojo.normalize(o, "temperature"))) + '&deg;C</div>\n\
<div class="minmax">\n\
Minimum <span class="min temperature">' + (Mojo.escape(Mojo.normalize(o, "min_temp"))) + '&deg;C</span> at\n\
<time datetime="' + (Mojo.escape(Mojo.normalize(o, "min_datetime"))) + '">' + (Mojo.escape(Mojo.normalize(o, "minDateString"))) + '</time>\n\
Maximum <span class="max temperature">' + (Mojo.escape(Mojo.normalize(o, "max_temp"))) + '&deg;C</span> at\n\
<time datetime="' + (Mojo.escape(Mojo.normalize(o, "max_datetime"))) + '">' + (Mojo.escape(Mojo.normalize(o, "maxDateString"))) + '</time>\n\
</div>\n\
</div>\n\
</div>';
};
// {"wind_angle":270,"rel_humidity_in":51,"rain_1h":0,"temperature_out":9.9,"forecast":"Sunny","rain_24h":0,"dewpoint":7.11,"wind_chill":9.9,"temperature_in":20.8,"rel_humidity_out":83,"tendency":"Rising","wind_speed":0,"rel_pressure":970.7,"rain_total":1.55,"datetime":"2010-09-20 11:30:13","wind_direction":"W"} // {"wind_angle":270,"rel_humidity_in":51,"rain_1h":0,"temperature_out":9.9,"forecast":"Sunny","rain_24h":0,"dewpoint":7.11,"wind_chill":9.9,"temperature_in":20.8,"rel_humidity_out":83,"tendency":"Rising","wind_speed":0,"rel_pressure":970.7,"rain_total":1.55,"datetime":"2010-09-20 11:30:13","wind_direction":"W"}
// forecaset is Rainy, Cloudy or Sunny // forecaset is Rainy, Cloudy or Sunny
@ -37,6 +19,10 @@ function isoString(date) {
// YYYY-MM-DDTHH:MM:SS // YYYY-MM-DDTHH:MM:SS
if(!date) return ''; if(!date) return '';
if (typeof date.toISOString == 'function') {
return date.toISOString();
}
return [ return [
[ [
date.getUTCFullYear(), date.getUTCFullYear(),
@ -48,7 +34,8 @@ function isoString(date) {
padNumber(date.getUTCHours()), padNumber(date.getUTCHours()),
padNumber(date.getUTCMinutes()), padNumber(date.getUTCMinutes()),
padNumber(date.getUTCSeconds()) padNumber(date.getUTCSeconds())
].join(':') ].join(':'),
'Z'
].join('') ].join('')
} }
@ -63,14 +50,38 @@ function datetimeString(date) {
function timeString(date) { function timeString(date) {
return [ return [
padNumber(date.getUTCHours()), padNumber(date.getHours()),
padNumber(date.getUTCMinutes()) padNumber(date.getMinutes())
].join(':') ].join(':')
} }
//function newUTCDate() function dateWindowToday() {
var now = new Date();
var start = new Date(now.getFullYear(), now.getMonth(), now.getDate());
var end = new Date(start.getTime() + (1000 * 60 * 60 * 24) - 1) // 1 day minus a millisecond
return [start, end];
}
// Register Handlebars date helpers
var days = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
Handlebars.registerHelper('day', function(date) {
return days[date.getDay()];
});
Handlebars.registerHelper('time', function(date) {
return timeString(date);
});
Handlebars.registerHelper('isoDate', function(date) {
return isoString(date);
});
jQuery(function() { jQuery(function() {
// Compile templates
var currentTemplate = Handlebars.compile($('#current-template').html());
var extremesTemplate = Handlebars.compile($('#extremes-template').html());
var now = new Date(); var now = new Date();
jQuery.getJSON("/weather.json", function(data, status) { jQuery.getJSON("/weather.json", function(data, status) {
// Populate the current conditions // Populate the current conditions
@ -80,43 +91,76 @@ jQuery(function() {
var d = new Date(data.current.timestamp); var d = new Date(data.current.timestamp);
return datetimeString(d); return datetimeString(d);
}, },
min_temp: data.current.min.temperature, // min_temp: data.current.min.temperature,
min_date: new Date(data.current.min.timestamp), // min_date: new Date(data.current.min.timestamp),
min_datetime: function() { // min_datetime: function() {
return isoString(this.min_date) // return isoString(this.min_date)
}, // },
minDateString: function() { // minDateString: function() {
return timeString(current.min_date) // return timeString(current.min_date)
}, // },
max_temp: data.current.max.temperature, // max_temp: data.current.max.temperature,
max_date: new Date(data.current.max.timestamp), // max_date: new Date(data.current.max.timestamp),
max_datetime: function() { // max_datetime: function() {
return isoString(this.max_date) // return isoString(this.max_date)
}, // },
maxDateString: function() { // maxDateString: function() {
return timeString(current.max_date) // return timeString(current.max_date)
}, // },
forecast: data.current.forecast forecast: data.current.forecast
}; };
var current_div = render_current(current); var current_div = currentTemplate(current);
$('.loading').replaceWith(current_div) $('.loading').replaceWith(current_div)
// Populate the extremes
var extremes = [];
var len = data.extremes.length;
for(var i = 0; i < len; i++) {
var e = data.extremes[i];
var extreme = {
date: new Date(e.date),
min: {
temperature: e.min.temperature,
time: new Date(e.min.timestamp)
},
max: {
temperature: e.max.temperature,
time: new Date(e.max.timestamp)
}
};
extremes.push(extreme);
}
var extremes_div = extremesTemplate({extremes: extremes});
$('section.extremes').replaceWith(extremes_div);
// Populate the charts // Populate the charts
// Temperature history
var count = data.history.length; var count = data.history.length;
for(var i = 0; i < count; i++) { for(var i = 0; i < count; i++) {
data.history[i][0] = new Date(data.history[i][0] - (now.getTimezoneOffset() * 60 * 1000)); // Convert timestamps to Date objects
} data.history[i][0] = new Date(data.history[i][0]);
jQuery.plot('.temperature.chart', data.history, {
xaxis: {
mode: "time"
} }
var chart = $('.temperature .chart');
chart.css('width', chart.width()); // TODO: bind to resize event and redraw
var temperatureGraph = new Dygraph(chart[0], data.history, {
rollPeriod: 5,
showRoller: true,
labels: ['Date', 'Inside Temperature', 'Outside Temperature']
});
$('#today').click(function() {
temperatureGraph.updateOptions({
dateWindow: dateWindowToday()
});
}); });
// Rain // Rain
var total_rain_today = 0; var total_rain_today = 0;
jQuery.each(data.rain.today, function(idx, reading) { jQuery.each(data.rain.today, function(idx, reading) {
total_rain_today += reading[1]; total_rain_today += reading[1];
// Convert the hour value into a date
reading[0] = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), reading[0])); reading[0] = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), reading[0]));
}); });
$("section.rain .total").html(Math.round(total_rain_today * 10) / 10) $("section.rain .total").html(Math.round(total_rain_today * 10) / 10)
@ -156,3 +200,4 @@ jQuery(function() {
}); });
}); });
}); });
})();