From 6747a496d800c23af0cd41c96f784fe6bae5667c Mon Sep 17 00:00:00 2001 From: Demo User Date: Tue, 30 Apr 2013 15:55:31 +0000 Subject: wwwroot_laerm --- datastore-leveldb/wwwroot_laerm/src/d3.control.js | 120 +++++++++++++ datastore-leveldb/wwwroot_laerm/src/d3.plot.js | 99 +++++++++++ datastore-leveldb/wwwroot_laerm/src/ebus.js | 196 ++++++++++++++++++++++ 3 files changed, 415 insertions(+) create mode 100644 datastore-leveldb/wwwroot_laerm/src/d3.control.js create mode 100644 datastore-leveldb/wwwroot_laerm/src/d3.plot.js create mode 100644 datastore-leveldb/wwwroot_laerm/src/ebus.js (limited to 'datastore-leveldb/wwwroot_laerm/src') diff --git a/datastore-leveldb/wwwroot_laerm/src/d3.control.js b/datastore-leveldb/wwwroot_laerm/src/d3.control.js new file mode 100644 index 0000000..489edea --- /dev/null +++ b/datastore-leveldb/wwwroot_laerm/src/d3.control.js @@ -0,0 +1,120 @@ +var d3_control = function(element, svgurl, mapping) { + this.mapping = mapping; + this.element = element; + var control = this; + d3.xml(svgurl, "image/svg+xml", function(xml) { + element[0][0].appendChild(xml.documentElement); + element.select("svg") + .style("width","100%").style("height", "100%"); + + // Setup mapping + for (var element_id in this.mapping) { + control.initElement(element_id); + } + d3.json("../all_values", function(response) { + control.process(response.data); + control.reload(response.time_stop); + }); + }); +}; + +d3_control.prototype = { + initElement:function(element_id) { + var options = this.mapping[element_id]; + d3.select(document.getElementById(element_id)) + .on("mouseover", + function() { + if( typeof(options._plot) == "undefined") { + options._plot = d3.select(this.ownerSVGElement) + .append("svg:g") + .classed("d3.control_popup", true); + + var startdate = (new Date().getTime()/1000) - 7*60*60*24; + var enddate = (new Date().getTime()/1000); + var plot = d3.plot(options._plot); + d3.json("../sensor/"+options.sensor+"/" + startdate + "/" + enddate, + function(resp) { + var data = resp.data.map(function(d) { + return [new Date(d[0]), d[1]]; + }); + plot.draw(data); + }); + + options._plot.on("mouseout", + function() { + if (options._plot.node().contains(d3.event.relatedTarget)) + return; + options._plot + .transition() + .duration(1000) + .style("opacity", 0.0) + .remove(); + }); + + var drag = d3.behavior.drag() + .on("dragstart", function() { + options._plot.on("mouseout", null); + options._plot.transition().duration(1000).style("opacity", 1.0); + + delete options._plot; + d3.select(this).select("rect") + .style("stroke", "gray") + .style("stroke-width", "3px"); + }) + .on("drag", function(d,i){ + d=[]; + d.x = d3.event.x; + d.y = d3.event.y; + d3.select(this).attr("transform", "translate("+d.x+","+d.y+")"); + }) + .on("dragend", function() { + d3.select(this).on("mousedown.drag", null); + d3.select(this).on("click", function() { d3.select(this).remove(); }); + }); + + options._plot.call(drag); + } else { + this.ownerSVGElement + .appendChild(options._plot.node()); + + options._plot.style("opacity", 1); + } + + var xy = d3.svg.mouse(this.ownerSVGElement); + options._plot.attr("transform", "translate("+xy[0]+","+xy[1]+")"); + }); + }, + process:function(data) { + for (var i in data) { + var row = data[i]; + + if (typeof(console) != "undefined") { + console.log("[" + d3.format("02d")(row.timestamp) + "] " + + row.name + " Value: " + row.value_real + " - " + + row.value_string); + } + + for (var element_id in this.mapping) { + var options = this.mapping[element_id]; + if (row.name == options.sensor){ + d3.select(document.getElementById(element_id)) + .text(""+row.value_real); + } + } + } + }, + reload:function(time_stop) { + var url = "../stream"; + if (time_stop != null) + url += "/" + time_stop; + var control = this; + d3.json(url, function(response) { + control.process(response.data); + control.reload(response.time_stop); + }); + } +}; + +d3.control = function(element, svgurl, mapping) { + return new d3_control(element,svgurl,mapping); +}; diff --git a/datastore-leveldb/wwwroot_laerm/src/d3.plot.js b/datastore-leveldb/wwwroot_laerm/src/d3.plot.js new file mode 100644 index 0000000..d9a7d04 --- /dev/null +++ b/datastore-leveldb/wwwroot_laerm/src/d3.plot.js @@ -0,0 +1,99 @@ +(function(){ + +function d3_plot(container) { + this.opt = { + w:550, h:200, margin:30 + }; + this.element = container.append("svg:g") + .classed("d3.plot_plot",true) + .attr("width", this.opt.w) + .attr("height", this.opt.h); + + this.element.append("svg:rect") + .attr("width", this.opt.w) + .attr("height", this.opt.h) + .style("fill", "white"); + + this.element.append("svg:text") + .classed("d3-plot_wait", true) + .attr("x", this.opt.w/2) + .attr("y", this.opt.h/2) + .attr("text-anchor", "center") + .text("Bitte warten"); +}; + +d3_plot.prototype = { + draw: function(data) { + var x_min = d3.min(data, function(d){return d[0];}), + x_max = d3.max(data, function(d){return d[0];}), + y_min = d3.min(data, function(d){return d[1];}), + y_max = d3.max(data, function(d){return d[1];}); + + var x = d3.time.scale() + .domain([x_min, x_max]) + .range([0+this.opt.margin, this.opt.w-this.opt.margin]); + + var y = d3.scale.linear() + .domain([y_min, y_max]) + .range([0+this.opt.margin, this.opt.h-(this.opt.margin/2)]); + + + var g = this.element.append("svg:g") + .attr("transform", "translate(0, "+this.opt.h+")"); + + var line = d3.svg.line() + .x(function(d,i){ return x(d[0]); }) + .y(function(d) {return -1*y(d[1]);}); + + g.append("svg:path") + .attr("d", line(data)); + + // Axes X-Line + g.append("svg:line") + .attr("x1", 0) + .attr("y1", -1*y(y_min)) + .attr("x2", x(x_max)) + .attr("y2", -1 * y(y_min)); + + + // Tick Labels + var tick_format = d3.time.format("%d.%m"); + g.selectAll(".xlabel") + .data(x.ticks(5)).enter() + .append("svg:text") + .text(function(d){return tick_format(d);}) + .attr("x", function(d) {return x(d);}) + .attr("y", -5) + .attr("text-anchor", "center"); + + g.selectAll(".ylabel") + .data(y.ticks(5)).enter() + .append("svg:text") + .text(String) + .attr("x", 0) + .attr("y", function(d) {return -1*y(d);}) + .attr("text-anchor", "right"); + + // X-Lines + g.selectAll(".xlines") + .data(x.ticks(5)).enter() + .append("svg:line") + .style("fill", "none") + .style("stroke", "#000000") + .style("stroke-width", 0.5) + .style("stroke-dasharray", "6,1") + .attr("x1", function(d){return x(d);}) + .attr("y1", -1*y(y_min)+(this.opt.margin/3)) + .attr("x2", function(d){return x(d);}) + .attr("y2", -1*y(y_max)); + + // + this.element.select(".d3-plot_wait").style("display","none"); + } +}; + +d3.plot = function(container) { + return new d3_plot(container); +}; + +})(); \ No newline at end of file diff --git a/datastore-leveldb/wwwroot_laerm/src/ebus.js b/datastore-leveldb/wwwroot_laerm/src/ebus.js new file mode 100644 index 0000000..1b905c3 --- /dev/null +++ b/datastore-leveldb/wwwroot_laerm/src/ebus.js @@ -0,0 +1,196 @@ +// vim: autoindent tabstop=4 shiftwidth=4 expandtab softtabstop=4 filetype=javascript +var d = new Object(); +d.ms = 1; +d.sec = 1000*d.ms; +d.min = 60 * d.sec; +d.hour = 60 * d.min; +d.day = 24 * d.hour; +d.week = 7 * d.day; +d.month = 30.5 * d.day; +d.now = new Date().getTime(); + +var timeToUTC = function(d) { return d + new Date().getTimezoneOffset() * 60 * 1000; } +var timeToLocal = function(d) { return d - new Date().getTimezoneOffset() * 60 * 1000; } + +$(document).ready(function(){ + var from = d.now - 4*d.day; + var to = d.now; + var fromOverview = d.now - 3 * d.day; + var toOverview = d.now; + var datasetDetail = [] + var datasetOverview = []; + var plotOverview = null; + var plotDetail = null; + var indexFound = null; + var numberOfValues = 1000; + var sensorConfigList = [ + {"sensorname":"arduino.a0.dba", + "description":"Arduino dB(A)", + "show":true, + "color":"red"}, + {"sensorname":"beagleboard.internet.speed", + "description":"Internet Speed", + "mapFunc":function(d) { + return [d[0], d[1]/10000]; + }, + "show":true, + "color":"blue"} + ]; + + var pickSensorConfig = function(sensorname) { + var sensorConfigFound; + $.each(sensorConfigList, function(i,sensorConfig) { + if (sensorConfig.sensorname == sensorname) { + sensorConfigFound = sensorConfig; + return false; + } + }); + return sensorConfigFound; + } + var replot = function() { + plotDetail = $.plot($("#ebusgraph"), + datasetDetail, + { + xaxis: { mode: "time", min: timeToLocal(from), max:timeToLocal(to) }, + yaxis: { min: 10, max: 75 }, + legend: { show : true} + }); + }; + var replotOverview = function() { + if (plotOverview == null) { + plotOverview = $.plot($("#overview"), + datasetOverview, + { // options + series: { + lines: { show: true, lineWidth: 1 }, + shadowSize: 0 + }, + xaxis: { mode: "time", min: timeToLocal(fromOverview), max:timeToLocal(toOverview)}, + yaxis: { ticks: [], min: 10, max: 75, autoscaleMargin: 0.1 }, + legend: { show: false }, + selection: { mode: "x" } + }); + } else { + plotOverview.setData(datasetOverview); + plotOverview.draw(); + } + plotOverview.setSelection({xaxis: {'from': timeToLocal(from), 'to': timeToLocal(to)}}, true); + }; + var plotSensor = function(sensorConfig) { + plotSensorDetail(sensorConfig); + plotSensorOverview(sensorConfig); + }; + var unplotSensor = function(sensorname) { + unplotSensorDetail(sensorname); + unplotSensorOverview(sensorname); + }; + var plotSensorDetail = function(sensorConfig) { + $.getJSON("/api/range/"+escape(sensorConfig.sensorname)+"/"+from+"/"+to+"/" + numberOfValues, + function(response) { + if (!response.error) { + response.data = response.data.map(function(d) { + return [ timeToLocal(d[0]), d[1] ]; + }); + if (sensorConfig.mapFunc) { + response.data = response.data.map( sensorConfig.mapFunc ) + } + datasetDetail.push({'data':response['data'], + 'userData':sensorConfig.sensorname, + 'label':sensorConfig.description, + 'color':sensorConfig.color}); + replot(); + } else { + alert("Fehler: " + response["error"]); + } + }); //.fail(function(a) { console.log(a); }); + }; + + var unplotSensorDetail = function(sensorname) { + $.each(datasetDetail, function(i, sensor) { + if (sensor.userData == sensorname) { + datasetDetail.splice(i,1); + replot(); + return false; + } + }); + }; + + var plotSensorOverview = function(sensorConfig) { + $.getJSON("api/range/"+escape(sensorConfig.sensorname)+"/"+fromOverview+"/"+toOverview+ "/" + numberOfValues, + function(response) { + if (!response.error) { + response.data = response.data.map(function(d) { + return [ timeToLocal(d[0]), d[1] ]; + }); + if (sensorConfig.mapFunc) { + response.data = response.data.map( sensorConfig.mapFunc) + } + datasetOverview.push({'data':response['data'], + 'label':sensorConfig.sensorname, + 'color':sensorConfig.color}); + replotOverview(); + } else { + alert("Overview Fehler: " + response["error"]); + } + }); + + }; + var unplotSensorOverview = function(sensorname) { + $.each(datasetOverview, function(i, sensor) { + if (sensor.label == sensorname) { + datasetOverview.splice(i,1); + replotOverview(); + return false; + } + }); + } + + $("#overview").bind("plotselected", function (event, ranges) { + range_from = Math.round(ranges.xaxis.from); + range_to = Math.round(ranges.xaxis.to); + // max selection range + if (range_to - range_from > d.month) { + // reset selection + plotOverview.setSelection({xaxis: {'from': from, 'to': to}}, true); + return; + } else { + from = timeToUTC(range_from); + to = timeToUTC(range_to); + } + sensors = []; + for (elem in datasetOverview) { + sensor = datasetDetail[elem]["userData"]; + sensors.push(sensor); + } + datasetDetail =[]; + for (i in sensors) { + plotSensorDetail(pickSensorConfig(sensors[i])); + } + }); + + $.each(sensorConfigList, function(i,sensorConfig) { + var pickerDiv = $("
").attr("id","pick_"+sensorConfig.sensorname.replace(/\./g,"_")) + .addClass("picker") + .appendTo("#sensorpicker"); + + var pickerCheckbox = $("").attr("type","checkbox") + .appendTo(pickerDiv); + pickerDiv.append($("").text( sensorConfig.description + " (" + sensorConfig.sensorname + ")") ); + if (sensorConfig.show) { + //Plot + plotSensor(sensorConfig); + $(pickerCheckbox).attr("checked","checked"); + } + }); + // TODO http://people.iola.dk/olau/flot/examples/annotating.html + + + $('.picker input').click( function() { + var sensorname = $(this).parent().attr("id").replace("pick_","").replace(/_/g,"."); + if ($(this).is(":checked")) { + plotSensor(pickSensorConfig(sensorname)); + } else { + unplotSensor(sensorname); + } + }); +}); -- cgit v1.2.1