Created
April 12, 2016 14:06
-
-
Save irjudson/53b44de27b8f8f294df7616b9fa709c4 to your computer and use it in GitHub Desktop.
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
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<meta name="description" content=""> | |
<meta name="author" content=""> | |
<title>ThingLabs</title> | |
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"> | |
<style> | |
body { | |
padding: 50px; | |
font: 10px sans-serif; | |
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; | |
} | |
a { | |
color: #00B7FF; | |
} | |
svg { | |
font: 10px sans-serif; | |
} | |
.graph .axis { | |
stroke-width: 1; | |
} | |
.graph .axis .tick line { | |
stroke: black; | |
} | |
.graph .axis .tick text { | |
fill: black; | |
font-size: 0.7em; | |
} | |
.graph .axis .domain { | |
fill: none; | |
stroke: black; | |
} | |
.graph .group { | |
fill: none; | |
stroke: black; | |
stroke-width: 1.5; | |
} | |
#wrapper { | |
padding-left:312px; | |
position:relative; | |
} | |
#userList { | |
margin:0 0 30px 0; | |
} | |
#userList table { | |
border-collapse:separate; | |
border-spacing:1px; | |
background:#CCC; | |
} | |
#userList table th { | |
background:#EEE; | |
font-weight:600; | |
padding:10px 20px; | |
text-align:center; | |
} | |
#userList table tbody { | |
padding:0; margin:0; | |
border-collapse:collapse; | |
border-spacing:0px; | |
} | |
#userList table td { | |
background:#FFF; | |
padding:5px 10px; | |
text-align:center; | |
} | |
#userInfo { | |
width:250px; | |
position:absolute; | |
top:0; left:0; | |
} | |
#userInfo p { | |
padding:15px; | |
border:1px solid #CCC; | |
background:rgba(80,120,255,0.05); | |
} | |
fieldset { | |
border:0; | |
padding:0; margin:0; | |
} | |
</style> | |
<script src="/socket.io/socket.io.js"></script> | |
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script> | |
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script> | |
</head> | |
<body data-spy="scroll" data-target=".scrollspy"> | |
<nav role="navigation" class="navbar navbar-inverse"> | |
<div class="navbar-header"> | |
<button type="button" data-toggle="collapse" data-target="#dropdown_menu" aria-expanded="false" aria-controls="navbar" | |
class="navbar-toggle collapsed"><span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span> | |
<span | |
class="icon-bar"></span> | |
</button><a class="navbar-brand">ThingLabs</a></div> | |
<div id="dropdown_menu" class="collapse navbar-collapse"> | |
<ul class="nav navbar-nav"></ul> | |
</div> | |
</nav> | |
<div class="container"> | |
<p>Welcome to ThingLabs</p> | |
<div class="graph"></div> | |
</div> | |
<script> | |
// Variables | |
var duration = 1000, | |
timeWindow = 5000, | |
width = 500, | |
height = 200, | |
now = new Date(Date.now() - timeWindow), | |
line = null, | |
io = io.connect(), | |
last = new Date(), | |
limit = 60 * 1, | |
groups = { | |
max: { | |
value: 0, | |
color: 'red', | |
data: new Array(limit).join('0').split('').map(parseFloat) | |
}, | |
avg: { | |
value: 0, | |
color: 'green', | |
data: new Array(limit).join('0').split('').map(parseFloat) | |
}, | |
min: { | |
value: 0, | |
color: 'blue', | |
data: new Array(limit).join('0').split('').map(parseFloat) | |
} | |
}; | |
// Listen for session event. | |
io.emit('ready'); | |
var x = d3.time.scale() | |
.domain([now - (limit - 2), now - timeWindow]) | |
.range([0, width]) | |
var y = d3.scale.linear() | |
.domain([0, 100]) | |
.range([height, 0]) | |
line = d3.svg.line() | |
.interpolate('basis') | |
.x(function(d, i) { | |
return x(now - (limit - 1 - i) * timeWindow) | |
}) | |
.y(function(d) { | |
return y(d) | |
}) | |
io.on('data', function(data) { | |
console.log("Got data: " + JSON.stringify(data, null, 2)); | |
groups['max'].data.push(data['maxtempf']); | |
groups['avg'].data.push(data['avgtempf']); | |
groups['min'].data.push(data['mintempf']); | |
last = new Date(); | |
}); | |
var svg = d3.select('.graph').append('svg') | |
.attr('class', 'chart') | |
.attr('width', width) | |
.attr('height', height + 50) | |
var axis = svg.append('g') | |
.attr('class', 'x axis') | |
.attr('transform', 'translate(0,' + height + ')') | |
.call(x.axis = d3.svg.axis().scale(x).orient('bottom')) | |
var paths = svg.append('g') | |
for (var name in groups) { | |
var group = groups[name] | |
group.path = paths.append('path') | |
.data([group.data]) | |
.attr('class', name + ' group') | |
.style('stroke', group.color) | |
} | |
// Update everything every tick | |
function tick() { | |
var now = new Date(); | |
// Console update | |
console.log("Firing tick() at: " + now.toString()); | |
// Add new values | |
for (var name in groups) { | |
var group = groups[name] | |
group.path.attr('d', line) | |
} | |
// Shift domain | |
x.domain([now - (limit - 2) * timeWindow, now - timeWindow]) | |
// Slide x-axis left | |
axis.transition() | |
.duration(duration) | |
.ease('linear') | |
.call(x.axis) | |
// Slide paths left | |
paths.attr('transform', null) | |
.transition() | |
.duration(duration) | |
.ease('linear') | |
.attr('transform', 'translate(' + x(now - (limit - 1) * timeWindow) + ')') | |
.each('end', tick) | |
// Drop old data | |
if(groups['max'].data.length > 60) { | |
groups['max'].data.shift(); | |
groups['avg'].data.shift(); | |
groups['min'].data.shift(); | |
} | |
} | |
tick(); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment