You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
209 lines
8.1 KiB
209 lines
8.1 KiB
<!doctype html> |
|
<html lang="en"> |
|
|
|
<head> |
|
<meta charset="utf-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<meta name="description" content="IoT around the house"> |
|
<title>Life Around</title> |
|
|
|
<link rel="stylesheet" href="https://unpkg.com/purecss@1.0.0/build/pure-min.css" integrity="sha384-nn4HPE8lTHyVtfCBi5yW9d20FjT8BJwUXyWZT9InLYax14RDjBj46LmSztkmNP9w" crossorigin="anonymous"> |
|
|
|
<!--[if lte IE 8]> |
|
<link rel="stylesheet" href="https://unpkg.com/purecss@1.0.0/build/grids-responsive-old-ie-min.css"> |
|
<![endif]--> |
|
<!--[if gt IE 8]><!--> |
|
<link rel="stylesheet" href="https://unpkg.com/purecss@1.0.0/build/grids-responsive-min.css"> |
|
<!--<![endif]--> |
|
|
|
|
|
<!--[if lte IE 8]> |
|
<link rel="stylesheet" href="/combo/1.18.13?/css/layouts/blog-old-ie.css"> |
|
<![endif]--> |
|
<!--[if gt IE 8]><!--> |
|
<link rel="stylesheet" href="http://hq.10ninox.com/styles/blog.css"> |
|
<!--<![endif]--> |
|
<!--[if lt IE 9]> |
|
<script src="http://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7/html5shiv.js"></script> |
|
<![endif]--> |
|
<style> |
|
path { |
|
stroke: rgb(237, 40, 1); |
|
stroke-width: 2; |
|
fill: none; |
|
} |
|
|
|
.dash { |
|
padding: 1em; |
|
font-size: 16px; |
|
} |
|
.dash-container { |
|
display: flex; |
|
flex-wrap: wrap; |
|
justify-content: space-evenly; |
|
} |
|
.graph { |
|
position: relative; |
|
width: 250px; |
|
height: 50px; |
|
} |
|
.dash-one { |
|
width: 250px; |
|
text-align: center; |
|
font-size: 1em; |
|
background: #33333322; |
|
padding: 10px 0; |
|
overflow: wrap; |
|
} |
|
.dash-one p { |
|
font-size: 4em; |
|
margin: 0em; |
|
} |
|
.dash-one h2 { |
|
font-size: 1.1em; |
|
margin: 2px 5px; |
|
} |
|
h1 small { |
|
font-size: 0.8rem; |
|
margin: 0 10px; |
|
color: #666; |
|
} |
|
</style> |
|
</head> |
|
|
|
<body> |
|
<div id="layout" class="pure-g"> |
|
<!-- <div class="sidebar pure-u-1 pure-u-md-1-4"> |
|
<ul class="device-list"></ul> |
|
</div> --> |
|
<div id="content" class="pure-u-1"></div> |
|
</div> |
|
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script> |
|
<script src="http://code.highcharts.com/highcharts.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.1/moment.min.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.14/moment-timezone.min.js"></script> |
|
<script src="https://d3js.org/d3.v4.js"></script> |
|
<script> |
|
|
|
function displayGraph(id, data, width, height, interpolation) { |
|
//, animate, updateDelay, transitionDelay) { |
|
var animate = true, updateDelay = 1000, transitionDelay = 1000; |
|
// create an SVG element inside the #graph div that fills 100% of the div |
|
var graph = d3.select(id).append("svg:svg"); |
|
// X scale will fit values from 0-10 within pixels 0-100 |
|
var x = d3.scaleLinear().domain([0, 152]).range([0, width]); // starting point is -5 so the first value doesn't show and slides off the edge as part of the transition |
|
// Y scale will fit values from 0-10 within pixels 0-100 |
|
var y = d3.scaleLinear().domain([0, 80]).range([0, height]); |
|
|
|
// create a line object that represents the SVN line we're creating |
|
var line = d3.line() |
|
// assign the X function to plot our line as we wish |
|
.x(function (d, i) { |
|
// verbose logging to show what's actually being done |
|
//console.log('Plotting X value for data point: ' + d + ' using index: ' + i + ' to be at: ' + x(i) + ' using our xScale.'); |
|
// return the X coordinate where we want to plot this datapoint |
|
return x(i); |
|
}) |
|
.y(function (d) { |
|
// verbose logging to show what's actually being done |
|
//console.log('Plotting Y value for data point: ' + d + ' to be at: ' + y(d) + " using our yScale."); |
|
// return the Y coordinate where we want to plot this datapoint |
|
return y(d); |
|
}) |
|
if (interpolation == "basis") { |
|
line.curve(d3.curveCatmullRom.alpha(0.5)) |
|
} |
|
|
|
// display the line by appending an svg:path element with the data line we created above |
|
graph.append("svg:path").attr("d", line(data)); |
|
// or it can be done like this |
|
//graph.selectAll("path").data([data]).enter().append("svg:path").attr("d", line); |
|
|
|
function redrawWithAnimation() { |
|
// update with animation |
|
graph.selectAll("path") |
|
.attr("transform", "translate(" + x(1) + ")") // set the transform to the right by x(1) pixels (6 for the scale we've set) to hide the new value |
|
.data([data]) // set the new data |
|
.attr("d", line) // apply the new data values ... but the new value is hidden at this point off the right of the canvas |
|
.transition() // start a transition to bring the new value into view |
|
.ease(d3.easeLinear) |
|
.duration(transitionDelay * 0.95) // for this demo we want a continual slide so set this to the same as the setInterval amount below |
|
.attr("transform", "translate(" + x(0) + ")"); // animate a slide to the left back to x(0) pixels to reveal the new value |
|
|
|
/* thanks to 'barrym' for examples of transform: https://gist.github.com/1137131 */ |
|
} |
|
|
|
function redrawWithoutAnimation() { |
|
// static update without animation |
|
graph.selectAll("path") |
|
.data([data]) // set the new data |
|
.attr("d", line); // apply the new data values |
|
} |
|
redrawWithoutAnimation(); |
|
} |
|
(function () { |
|
var baseUrl = '', |
|
allUrl = baseUrl + '/all', |
|
$sidebar = $('.sidebar'), |
|
$list = $sidebar.find('.device-list'), |
|
$content = $('#content'); |
|
|
|
var addToList = function(item) { |
|
$list.append( |
|
`<li><a href="#${item['device']}">` + |
|
`${item["device"]}</a></li>`); |
|
}; |
|
|
|
var addEleToDashBoard = function(item) { |
|
var data = item['data']; |
|
var xid = item['device'].replace(/:/g, '_') |
|
var tmsp = moment.tz(item['timestamp'], "utc").fromNow() |
|
var str = `<div class="pure-u-md-1-2 dash" id="${xid}">` + |
|
`<h1>${item['info']['name']}<small>${tmsp}</small></h1>` + |
|
`<div class="dash-container">` + |
|
`<div class="dash-one temperature"><h2>Temp</h2><p>${data['temperature']}</p> <div class="graph" id="${xid}-temperature"></div></div>` + |
|
`<div class="dash-one moisture"><h2>Moisture</h2><p>${data['moisture']}</p> <div class="graph" id="${xid}-moisture"></div></div>` + |
|
`<div class="dash-one humidity"><h2>Humidity</h2><p>${data['humidity']}</p> <div class="graph" id="${xid}-humidity"></div></div>` + |
|
`</div>` + |
|
`</div>`; |
|
$content.append(str); |
|
}; |
|
|
|
var reloadListener = function() { |
|
|
|
$('.dash').on('click', function () { |
|
var that = $(this), |
|
id = that.attr('id').replace(/_/g, ':'), |
|
oneUrl = `${baseUrl}/id/${id}?limit=150`; |
|
that.off('click'); |
|
$.getJSON(oneUrl, function(data, textStatus, xhr) { |
|
var isFlora = data[0]['info']['sensor'].toLowerCase().indexOf("flora") > -1; |
|
var extra = (isFlora ? 'humidity' : 'moisture'); |
|
var ks = ['temperature', extra]; |
|
for (var ik in ks) { |
|
var key = ks[ik]; |
|
var ll = data.map(function(ele, i) { |
|
return ele['data'][key] |
|
}); |
|
var tid = `#${that.attr('id')}-${key}`; |
|
displayGraph(tid, ll, 250, 50, "basic"); |
|
} |
|
}); |
|
}); |
|
} |
|
|
|
$.getJSON(allUrl, function(data, textStatus, xhr) { |
|
for (var i=0; i<data.length; i++) { |
|
var x = data[i]; |
|
addToList(x); |
|
addEleToDashBoard(x); |
|
var isFlora = x['info']['sensor'].toLowerCase().indexOf("flora") > -1; |
|
var toHide = (isFlora ? 'humidity' : 'moisture'); |
|
$('#' + x['device'].replace(/:/g, '_')).find('.'+ toHide).hide(); |
|
} |
|
reloadListener(); |
|
}); |
|
})(jQuery); |
|
</script> |
|
</body> |
|
</html>
|
|
|