From a5c9d55b61d6a3735af5dc76cd48d1a032f2eb69 Mon Sep 17 00:00:00 2001 From: Pat Thoyts Date: Mon, 16 May 2016 12:59:44 +0100 Subject: [PATCH] Support incremental download of sensor data. Break up the data download into 1 day chunks and display all in the top overview plot and let the user update the lower plot. --- static/sensor-hub.html | 169 ++++++++++++++++++++++++++++++----------- 1 file changed, 123 insertions(+), 46 deletions(-) diff --git a/static/sensor-hub.html b/static/sensor-hub.html index 1aa39fa..801efa5 100644 --- a/static/sensor-hub.html +++ b/static/sensor-hub.html @@ -27,6 +27,8 @@ div.loading { background: rgba(255,255,255,.8) url('loading.gif') 50% 50% no-rep

Download view data as ASCII or JSON

+

Fetch another week: update with an additional weeks historical data.

+

Fetch another 30 days: update with an additional month historical data.

@@ -93,36 +95,10 @@ function on_received_recent(recent) { 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 }, @@ -134,9 +110,7 @@ function on_draw_graph(data) { xaxis: { mode: "time", timezone: "browser", timeformat: "%d-%b
%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 }, @@ -144,8 +118,8 @@ function on_draw_graph(data) { 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; @@ -154,28 +128,112 @@ function on_draw_graph(data) { 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"); @@ -185,6 +243,26 @@ function main() { 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), @@ -198,7 +276,6 @@ $("#graph").bind("plothover", function(event, pos, item) { } }); $(document).ready(function () { - document.custom = {}; main(); }); -- 2.23.0