Created
January 24, 2013 08:59
-
-
Save cynici/4618897 to your computer and use it in GitHub Desktop.
firedanger plot using jquery flot library written as python django template
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{% extends "base.html" %} | |
{% load i18n %} | |
{% block css %} | |
<style type="text/css"> | |
.calendar { | |
font-family: 'Trebuchet MS', Tahoma, Verdana, Arial, sans-serif; | |
font-size: 0.9em; | |
background-color: #EEE; | |
color: #333; | |
border: 1px solid #DDD; | |
-moz-border-radius: 4px; | |
-webkit-border-radius: 4px; | |
border-radius: 4px; | |
padding: 0.2em; | |
width: 14em; | |
} | |
.calendar a { | |
outline: none; | |
} | |
.calendar .months { | |
background-color: #F6AF3A; | |
border: 1px solid #E78F08; | |
-moz-border-radius: 4px; | |
-webkit-border-radius: 4px; | |
border-radius: 4px; | |
color: #FFF; | |
padding: 0.2em; | |
text-align: center; | |
} | |
.calendar .prev-month, | |
.calendar .next-month { | |
padding: 0; | |
} | |
.calendar .prev-month { | |
float: left; | |
} | |
.calendar .next-month { | |
float: right; | |
} | |
.calendar .current-month { | |
margin: 0 auto; | |
} | |
.calendar .months a { | |
color: #FFF; | |
text-decoration: none; | |
padding: 0 0.4em; | |
-moz-border-radius: 4px; | |
-webkit-border-radius: 4px; | |
border-radius: 4px; | |
} | |
.calendar .months a:hover { | |
background-color: #FDF5CE; | |
color: #C77405; | |
} | |
.calendar table { | |
border-collapse: collapse; | |
padding: 0; | |
font-size: 0.8em; | |
width: 100%; | |
} | |
.calendar th { | |
text-align: center; | |
} | |
.calendar td { | |
text-align: right; | |
padding: 1px; | |
width: 14.3%; | |
} | |
.calendar td a { | |
display: block; | |
color: #1C94C4; | |
background-color: #F6F6F6; | |
border: 1px solid #CCC; | |
text-decoration: none; | |
padding: 0.2em; | |
} | |
.calendar td a:hover { | |
color: #C77405; | |
background-color: #FDF5CE; | |
border: 1px solid #FBCB09; | |
} | |
.calendar td.today a { | |
background-color: #FFF0A5; | |
border: 1px solid #FED22F; | |
color: #363636; | |
} | |
</style> | |
{% endblock %} | |
{% block js %} | |
<script language="javascript" type="text/javascript" src="/static/js/datefunc.js"></script> | |
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="excanvas.min.js"></script><![endif]--> | |
<script type="text/javascript" src="/static/js/jquery-1.8.1.min.js"></script> | |
<script language="javascript" type="text/javascript" src="/static/js/flot/jquery.flot.js"></script> | |
<script language="javascript" type="text/javascript" src="/static/js/flot/jquery.flot.time.js"></script> | |
<script language="javascript" type="text/javascript" src="/static/js/flot/jquery.flot.threshold.js"></script> | |
<script language="javascript" type="text/javascript" src="/static/js/flot/jquery.flot.selection.js"></script> | |
<script language="javascript" type="text/javascript" src="/static/js/flot/jquery.flot.symbol.js"></script> | |
<script language="javascript" type="text/javascript" src="/static/js/datepickr/datepickr.js"></script> | |
{% endblock %} | |
{% block body %} | |
<h1>{{ fdi_type|default:"Fire Danger Indices" }} at {{ lon }},{{ lat }}</h1> | |
<h2>Usage</h2> | |
<ul> | |
<li>To display exact value of a data point and weather conditions, click on it.</li> | |
<li>To zoom in to a date range, left-click on the chart and move horizontally</li> | |
</ul> | |
<h2>Selection Criteria</h2> | |
<div id="form"> | |
<form id="param_form" method="GET"> | |
<p>Coordinate (lon,lat): <span id="lon"><input id="lon" name="lon" value="{{ lon }}" size="8" /></span>,<span id="lat"><input id="lat" name="lat" value="{{ lat }}" size="8" /></span></p> | |
<p>Start date (yyyy-mm-dd): <input id="datepick" name="date" value="{{ date }}" class="date-pick" /> | |
<script type="text/javascript"> | |
new datepickr('datepick', { dateFormat: 'Y-m-d' }); | |
</script> | |
</p> | |
<p>Number of days: <input id="days" name="days" value="{{ days }}" /></p> | |
<p>Type: <select size="1" name="fdi_type"> | |
<option value="">Both</option> | |
<option{% ifequal fdi_type "FWI" %} selected="selected"{% endifequal %}>FWI</option> | |
<option{% ifequal fdi_type "LFDI" %} selected="selected"{% endifequal %}>LFDI</option> | |
</select> | |
</p> | |
<p><input id="submit" value="submit" type="submit" /></p> | |
</form> | |
</div> | |
<p> | |
<div id="placeholder" style="width:{{ width|default:'600px' }};height:{{ height|default:'300px' }}"></div> | |
</p> | |
<p id="hoverdata">Mouse hovers at <span id="x">0</span> where <span id="y">0</span></p> | |
<p><pre id="clickdata"></pre></p> | |
<p><input id="enableTooltip" type="checkbox">Enable tooltip</p> | |
<p>You zoomed to date range: <span id="selection"></span></p> | |
<p> | |
<input id="clearSelection" type="button" value="Unset zoom" /> | |
</p> | |
<H2>To Do</H2> | |
<ol> | |
<li>Specify coordinates by clicking on a map</li> | |
<li>Display legend</li> | |
</ol> | |
<script type="text/javascript"> | |
$(function () { | |
var placeholder = $("#placeholder"), | |
thresholds = { | |
'FWI': [ | |
{ below: 4, color: '#0000ff' }, | |
{ below: 14, color: "rgb(0,255,0)" }, | |
{ below: 39, color: "rgb(255,255,0)" }, | |
{ below: 91, color: '#ffa500' }, | |
{ below: 500, color: '#ff0000' } | |
], | |
'LFDI': [ | |
{ below: 21, color: '#0000ff' }, | |
{ below: 45, color: "rgb(0,255,0)" }, | |
{ below: 60, color: "rgb(255,255,0)" }, | |
{ below: 75, color: '#ffa500' }, | |
{ below: 500, color: '#ff0000' } | |
]}, | |
api_options = { | |
xaxis: { | |
mode: "time", | |
minTickSize: [1, "day"], | |
}, | |
series: { | |
lines: { show: true }, | |
points: { show: true } | |
}, | |
grid: { hoverable: true, clickable: true }, | |
selection: { mode: "x" }, | |
legend: { show: false } | |
}, | |
xy_data = {'FWI': [], 'LFDI': []}, | |
api_data, | |
weather_data = []; | |
if ('{{ fdi_type }}'=='FWI' || '{{ fdi_type }}'=='LFDI') { | |
api_data = [{ | |
label: '{{ fdi_type }}', | |
data: xy_data['{{ fdi_type }}'], | |
threshold: thresholds['{{ fdi_type }}'], | |
points: { symbol: "diamond" } | |
}]; | |
} else { | |
api_data = [ | |
{ | |
label: 'FWI', | |
data: xy_data['FWI'], | |
threshold: thresholds['FWI'], | |
points: { symbol: "circle" } | |
}, | |
{ | |
label: 'LFDI', | |
data: xy_data['LFDI'], | |
threshold: thresholds['LFDI'], | |
points: { symbol: "cross" } | |
} | |
]; | |
} | |
// AJAX callback function | |
function plot_data(data) { | |
var dates = []; | |
for (var ymd in data) { | |
if (data.hasOwnProperty(ymd)) { | |
dates.push(ymd); | |
} | |
} | |
dates.sort(); | |
for (i in dates) { | |
var ymd = dates[i]; | |
var epoch_ms = getEpochMillis(ymd+' 12:00:00 UTC'); | |
xy_data['FWI'].push([ epoch_ms, data[ymd]['FWI'][0] ]); | |
xy_data['LFDI'].push([ epoch_ms, data[ymd]['LFDI'][0] ]); | |
weather_data.push( | |
'Rain (mm): ' + data[ymd]['rain_mm'].toFixed(2) + "\n" + | |
'Humidity (%): ' + data[ymd]['rh_pct'].toFixed(2) + "\n" + | |
'Temperature (C): ' + data[ymd]['temp_c'].toFixed(2) + "\n" + | |
'U-wind (m/s): ' + data[ymd]['uwind_ms'].toFixed(2) + "\n" + | |
'V-wind (m/s): ' + data[ymd]['vwind_ms'].toFixed(2) + "\n" + | |
'Wind speed (km/h):' + data[ymd]['ws_kmh'].toFixed(2) | |
); | |
} | |
$.plot(placeholder, api_data, api_options); | |
//$("#placeholder div.legend table").css({ border: "1px solid #888888", background: "#ffffee" }); | |
//var legendlabels = $("#placeholder td.legendLabel") | |
} | |
function showTooltip(x, y, contents) { | |
$('<div id="tooltip">' + contents + '</div>').css( { | |
position: 'absolute', | |
display: 'none', | |
top: y + 5, | |
left: x + 5, | |
border: '1px solid #fdd', | |
padding: '2px', | |
'background-color': '#fee', | |
opacity: 0.80 | |
}).appendTo("body").fadeIn(200); | |
} | |
var previousPoint = null; | |
placeholder.bind("plothover", function (event, pos, item) { | |
if (item==null) return; | |
//$("#x").text(pos.x.toFixed(2)); | |
var d = new Date(pos.x); // Convert from UTC epoch milliseconds | |
var label = item.series.originSeries.label; | |
$("#x").text(d.toUTCString()); | |
$("#y").text(label + '=' + pos.y.toFixed(0)); | |
if ($("#enableTooltip:checked").length > 0) { | |
if (item) { | |
if (previousPoint != item.dataIndex) { | |
previousPoint = item.dataIndex; | |
$("#tooltip").remove(); | |
/* | |
var x = item.datapoint[0].toFixed(2), | |
y = item.datapoint[1].toFixed(2); | |
*/ | |
var y = item.datapoint[1].toFixed(0); | |
var d = new Date(item.datapoint[0]), // Convert from UTC epoch milliseconds | |
x = d.toUTCString(); | |
// item.series.label cleared by flot.threshold | |
showTooltip(item.pageX, item.pageY, | |
item.series.originSeries.label + " at " + x + ": " + y); | |
} | |
} | |
else { | |
$("#tooltip").remove(); | |
previousPoint = null; | |
} | |
} | |
}); | |
placeholder.bind("plotclick", function (event, pos, item) { | |
if (item) { | |
$("#clickdata").text("You clicked point " + item.dataIndex + '\n' + weather_data[item.dataIndex]); | |
plot.highlight(item.series, item.datapoint); | |
} | |
}); | |
placeholder.bind("plotselected", function (event, ranges) { | |
var startdate = new Date(ranges.xaxis.from); // Convert from UTC epoch milliseconds | |
var enddate = new Date(ranges.xaxis.to); // Convert from UTC epoch milliseconds | |
$("#selection").text(startdate.toUTCString() + " to " + enddate.toUTCString()); | |
$.plot(placeholder, api_data, | |
$.extend(true, {}, api_options, { | |
xaxis: { min: ranges.xaxis.from, max: ranges.xaxis.to } | |
})); | |
}); | |
placeholder.bind("plotunselected", function (event) { | |
$("#selection").text(""); | |
}); | |
$("#clearSelection").click(function () { | |
$("#selection").text(""); | |
var plot = $.plot(placeholder, api_data, api_options); | |
plot.clearSelection(); | |
}); | |
$("#enableTooltip").change(function () { | |
if (!$(this).is(':checked')) { | |
$("#tooltip").remove(); | |
previousPoint = null; | |
} | |
}); | |
$.ajax({ | |
type: 'GET', | |
url: '/firedanger/?lat={{ lat }}&lon={{ lon }}&date={{ date }}&days={{ days|default:"7" }}', | |
dataType: 'json', | |
aysync: true, | |
success: plot_data | |
}); | |
}); | |
</script> | |
{% endblock %} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment