<div id="overview" style="height:80px;"></div>
<div id="graph" style="height:400px;"></div>
<p>Download view data as <a href="#" onclick="on_download('text')">ASCII</a> or <a href="#" onclick="on_download('json')">JSON</a></p>
+<p><a href="#" onclick="fetch_more_days(7)">Fetch another week</a>: update with an additional weeks historical data.</p>
+<p><a href="#" onclick="fetch_more_days(30)">Fetch another 30 days</a>: update with an additional month historical data.</p>
<p id="result"/>
<div id="tooltip"></div>
</div><!-- /content -->
r.appendTo(t);
t.appendTo('#result');
}
-function on_draw_graph(data) {
- document.custom.data = data;
- if (data.response == "error") {
- $("#status").text(data.message);
- return;
- }
- var now = new Date();
- var plotA = [];
- var plotB = [];
- var plotC = [];
-
- var colors = ["#a040b0","#00a040","#0040a0"];
- var plotdata = [];
- $.each(data.result[10].sensors, function(n, sensor) {
- plotdata.push({data: [], label: sensor.id, color: colors[n]});
- });
- $.each(data.result, function(i,item) {
- var t = item.timestamp*1000;
- $.each(item.sensors, function(n, sensor) {
- var v = sensor.value;
- if (v < -100)
- v = plotdata[n].data[plotdata[n].data.length - 1];
- plotdata[n].data.push([t,v]);
- });
- });
- $('#status').html('');
- if (typeof(document.custom.recent) != typeof(undefined)) {
- $('#timestamp').html("Last collection at " + displayTime(document.custom.recent.response.timestamp * 1000));
- }
- var options = {
+function graph_init() {
+ document.custom.graph_main = {plot: {}, options: {}};
+ document.custom.graph_overview = {plot: {}, options: {}};
+ document.custom.graph_main.options = {
series: {
shadowSize: 0,
bars: { show: false },
xaxis: { mode: "time", timezone: "browser", timeformat: "%d-%b<br/>%H:%M" },
yaxis: { }
};
- var plot = $.plot($('#graph'), plotdata, options);
- document.custom.graph = plot;
- var ovopt = {
+ document.custom.graph_overview.options = {
series: { lines: { show: true, lineWidth: 1 }, shadowSize: 0 },
legend: { show: false },
grid: { markings: weekend_markings },
yaxis: { ticks: [], autoscaleMargin: 0.1 },
selection: { mode: "x" }
};
- var ovplot = $.plot("#overview", plotdata, ovopt);
$("#graph").bind("plotselected", function (event, ranges) {
+ var plot = document.custom.graph_main.plot;
$.each(plot.getXAxes(), function (_, axis) {
var opts = axis.options;
opts.min = ranges.xaxis.from;
plot.setupGrid();
plot.draw();
plot.clearSelection();
- ovplot.setSelection(ranges, true); // avoid event loop
+ document.custom.graph_overview.plot.setSelection(ranges, true); // avoid event loop
});
$("#overview").bind("plotselected", function (event, ranges) {
- plot.setSelection(ranges);
+ var plot = document.custom.graph_overview.plot;
+ var mainPlot = document.custom.graph_main.plot;
+ if (mainPlot.getData()[0].data.length != plot.getData()[0].data.length) {
+ mainPlot.setData(document.custom.plotdata);
+ }
+ $.each(plot.getXAxes(), function (_, axis) {
+ var opts = axis.options;
+ opts.min = ranges.xaxis.from;
+ opts.max = ranges.xaxis.to;
+ });
+ mainPlot.setSelection(ranges);
});
}
-function main() {
+function replot(both) {
+ var ovplot = $.plot("#overview", document.custom.plotdata, document.custom.graph_overview.options);
+ document.custom.graph_overview.plot = ovplot;
+ if (both) {
+ var plot = $.plot($('#graph'), document.custom.plotdata, document.custom.graph_main.options);
+ document.custom.graph_main.plot = plot;
+ }
+}
+function on_draw_graph(data) {
+ document.custom.data = data;
+ if (data.response == "error") {
+ $("#status").text(data.message);
+ return;
+ }
+ $('#status').html('');
+ if (typeof(document.custom.recent) != typeof(undefined)) {
+ $('#timestamp').html("Last collection at " + displayTime(document.custom.recent.response.timestamp * 1000));
+ }
+ graph_init();
+ add_data(data);
+ replot(true);
+}
+function on_received_sensors(data) {
+ // data is array of sensor names, create all the plotdata array elements
+ document.custom.plotdata = [];
+ document.custom.sensors = data.response;
+ $.each(data.response, function(n, sensorName) {
+ document.custom.plotdata.push({data: [], label: sensorName, color: document.custom.colors[n]});
+ });
+ fetch_initial_data();
+}
+function add_data(data) {
+ var plotdata = []; // one element per sensor
+ $.each(document.custom.plotdata, function(n,plot) {
+ plotdata.push([]);
+ });
+ var oldest = document.custom.oldest;
+ var newest = document.custom.newest;
+ // update each sensor in plotdata adding new values
+ $.each(data.result, function(i,item) {
+ var t = item.timestamp*1000;
+ if (newest < t) newest = t;
+ if (oldest > t) oldest = t;
+ $.each(item.sensors, function(n, sensor) {
+ var v = sensor.value;
+ if (v < -100)
+ v = plotdata[n][plotdata[n].length - 1];
+ plotdata[n].push([t,v]);
+ });
+ });
+ $.each(document.custom.plotdata, function(n,plot) {
+ document.custom.plotdata[n].data = plotdata[n].concat(plot.data);
+ });
+ window.setTimeout(function() {replot(false);}, 20);
+ if (oldest < document.custom.oldest) {
+ if (((newest - oldest) / 1000 / (60*60*24)) < document.custom.days) {
+ var one_day = 60 * 60 * 24 * 1000;
+ window.setTimeout(function() {fetch_more((oldest - one_day)/1000, oldest/1000);}, 50);
+ }
+ document.custom.oldest = oldest;
+ }
+ document.custom.newest = newest;
+}
+function fetch_more_days(count) {
+ document.custom.days = document.custom.days + count;
+ var one_day = 60 * 60 * 24 * 1000;
+ var oldest = document.custom.oldest;
+ window.setTimeout(function() {fetch_more((oldest - one_day)/1000, oldest/1000);}, 50);
+}
+function fetch_more(from_unixtime, until_unixtime) {
+ when_from = (new Date(from_unixtime * 1000)).toISOString();
+ when_until = (new Date(until_unixtime * 1000)).toISOString();
$.ajax({
- url: 'recent',
+ url: 'since',
dataType: 'json',
- complete: function(jqqxhr, msg) { $('#result').removeClass("loading"); },
- beforeSend: function(jqxhr, opt) { $('#result').addClass("loading"); },
- success: on_received_recent,
- error: function(jqqxhr, err, evt) { alert("recent: "+err); }
+ data: { from: when_from, until: when_until },
+ beforeSend: function (jqxhr, opts) { $('#status').text("fetching more data..."); },
+ complete: function(jqxhr,msg) { $('#status').text(""); },
+ error: function(jqxhr,err,evt) { $('#status').text("error: " + err); },
+ success: add_data,
});
+}
+function fetch_initial_data() {
var now = ((new Date() - 0) / 1000);
- var when = now - (60 * 60 * 24 * 28); // 28 days
- when = (new Date(when * 1000)).toISOString();
+ var when_from = now - (60 * 60 * 24 * 1); // 28 days
+ when_from = (new Date(when_from * 1000)).toISOString();
$.ajax({
url: 'since',
dataType: 'json',
- data: { when: when },
+ data: { from: when_from },
beforeSend: function (jqxhr, opts) {
$("#graph").addClass("loading");
$("#overview").addClass("loading");
success: on_draw_graph,
});
}
+function main() {
+ document.custom = {plotdata: [], data: [], recent: {}, oldest: Infinity, newest: 0, days: 7};
+ document.custom.colors = ["#a040b0","#00a040","#0040a0"];
+ $.ajax({
+ url: 'recent',
+ dataType: 'json',
+ complete: function(xhr, msg) { $('#result').removeClass("loading"); },
+ beforeSend: function(xhr, opt) { $('#result').addClass("loading"); },
+ success: on_received_recent,
+ error: function(xhr, err, evt) { alert("recent: "+err); }
+ });
+ $.ajax({
+ url: 'sensors',
+ dataType: 'json',
+ data: {hostname: 'spd-office'},
+ success: on_received_sensors,
+ beforeSend: function(xhr,o) { $('#status').text("Fetching sensor list"); },
+ complete: function(xhr,msg) { $('#status').text(msg); }
+ })
+}
$("#graph").bind("plothover", function(event, pos, item) {
if (item) {
var x = item.datapoint[0].toFixed(2),
}
});
$(document).ready(function () {
- document.custom = {};
main();
});
</script>