Skip to content

Instantly share code, notes, and snippets.

@byrongibson
Created March 24, 2013 17:55
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save byrongibson/5232838 to your computer and use it in GitHub Desktop.
Save byrongibson/5232838 to your computer and use it in GitHub Desktop.
Realtime d3.js streamgraph that converts mouse coordinates into input data
<!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