Created
March 24, 2013 17:55
-
-
Save byrongibson/5232838 to your computer and use it in GitHub Desktop.
Realtime d3.js streamgraph that converts mouse coordinates into input data
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> | |
<head> | |
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script> | |
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script> | |
<meta charset="utf-8"> | |
</head> | |
<!-- source: http://lyngbaek.com/real-time-stream-graph.html | |
random number generator replaced with realtime mouse coordinates. --> | |
<!-- also thanks to Mike Bostock's examples for showing how to use an iframe to position | |
the streamgraph on the page the easy way: http://bl.ocks.org/mbostock/4060954 --> | |
<body> | |
<div id="chart"></div> | |
<script> | |
var l = 2; // number of stream channels (layers) | |
var n = 100; // number of samples per layer | |
var random = d3.random.normal(0, .2); | |
var a = []; | |
var b = []; | |
/* Replace Math.random() with realtime mouse coords normalized to a 0:1 range. */ | |
var denom = { x: $(window).width(), y: $(window).height() }; | |
var currentMouseCoord = { x: 1, y: 1 }; | |
/* While mouse is moving over the streamgraph iframe, replace data stream with | |
realtime normalized mouse coordinates */ | |
$(document).mousemove(function(e) { | |
currentMouseCoord.x = e.pageX/denom.x; | |
currentMouseCoord.y = e.pageY/denom.y; | |
}).mouseover(); | |
/* When mouse leaves the streamgraph iframe, reset data stream to constant 1 */ | |
$(document).mouseout(function(e) { | |
currentMouseCoord.x = 1; | |
currentMouseCoord.y = 1; | |
}).mouseout(); | |
function stream_layers(l, m, o) { | |
return d3.range(l).map(function(d,i) { | |
if (i == 0) { | |
//for (idx = 0; idx < m; idx++) a[idx] = .01 + .01 * Math.random(); | |
//for (idx = 0; idx < m; idx++) a[idx] = .01 + .01 * currentMouseCoord.x; | |
for (idx = 0; idx < m; idx++) a[idx] = currentMouseCoord.x; | |
return a.map(stream_index); | |
} else if (i ==1) { | |
//for (idx = 0; idx < m; idx++) b[idx] = .01 + .01 * Math.random(); | |
//for (idx = 0; idx < m; idx++) b[idx] = .01 + .01 * currentMouseCoord.y; | |
for (idx = 0; idx < m; idx++) b[idx] = currentMouseCoord.y; | |
return b.map(stream_index); | |
} | |
}); | |
} | |
function update_layers(l, m, o) { | |
return d3.range(l).map(function(d,i) { | |
if (i == 0) { | |
//a[m] = .01 + .01 * Math.random(); | |
//a[m] = .01 + .01 * currentMouseCoord.x; | |
a[m] = currentMouseCoord.x; | |
return a.map(stream_index); | |
} else if (i == 1) { | |
//b[m] = .01 + .01 * Math.random(); | |
//b[m] = .01 + .01 * currentMouseCoord.y; | |
b[m] = currentMouseCoord.y; | |
return b.map(stream_index); | |
} | |
}); | |
} | |
function stream_index(d, i) { | |
return {x: i, y: Math.max(0, d)}; | |
} | |
var data0 = d3.layout.stack().offset("wiggle")(stream_layers(l,n,0)); | |
var data1 = d3.layout.stack().offset("wiggle")(stream_layers(l,n,0)); | |
//var color = d3.interpolateRgb("#aad", "#556"); | |
var color = d3.interpolateRgb("#f30", "#fdb"); | |
var w = $(window).width(); | |
var h = 150; | |
var mx = n - 1; | |
var my = d3.max(data0.concat(data1), function(d) { | |
return d3.max(d, function(d) { | |
return d.y0 + d.y; | |
}); | |
}); | |
var area = d3.svg.area() | |
.x(function(d) { return d.x * w / mx; }) | |
.y0(function(d) { return h - d.y0 * h / my; }) | |
.y1(function(d) { return h - (d.y + d.y0) * h / my; }); | |
var vis = d3.select("body") | |
.append("svg") | |
.attr("width", w) | |
.attr("height", h); | |
vis.selectAll("path") | |
.data(data0) | |
.enter().append("path") | |
.style("fill", function() { return color(Math.random()); }) | |
.attr("d", area); | |
function transition() { | |
a.push(.01 + .01*Math.random()); | |
b.push(.01 + .01*Math.random()); | |
data0 = d3.layout.stack().offset("wiggle")(update_layers(l,n,0)); | |
vis.selectAll("path").data(data0).attr("d", area).attr("transform", null).transition().duration(40).ease("linear").attr("transform", "translate(" + -w/n + ")").each("end", function (d,i) { if (i==0) transition();}); | |
a.shift(); | |
b.shift(); | |
} | |
$(document).ready(transition()); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment