Skip to content

Instantly share code, notes, and snippets.

@mbostock
Created January 7, 2012 00:31
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mbostock/1573240 to your computer and use it in GitHub Desktop.
Save mbostock/1573240 to your computer and use it in GitHub Desktop.
Cube Realtime Map
var options = require("./evaluator-config"),
cube = require("cube"),
server = cube.server(options);
server.register = function(db, endpoints) {
cube.evaluator.register(db, endpoints);
cube.visualizer.register(db, endpoints);
endpoints.http.push(cube.endpoint.exact("/us/map", cube.endpoint.file("static/us/map.html")));
endpoints.http.push(cube.endpoint.exact("/us/states.json", cube.endpoint.file("static/us/states.json")));
};
server.start();
<!DOCTYPE html>
<script src="/d3/d3.js?2.7.1"></script>
<style>
body {
margin: 0 auto 0 auto;
width: 1920px;
}
svg, canvas {
position: absolute;
}
path {
fill: none;
stroke: #ccc;
}
</style>
<svg width="1920" height="1080"></svg>
<canvas width="1920" height="1080"></canvas>
<script>
var canvas = d3.select("canvas"),
w = +canvas.attr("width"),
h = +canvas.attr("height");
var duration = 1000 * 60 * 30, // 30 minutes
start = new Date(Date.now() - duration),
utc = d3.time.format.iso;
var socket = new WebSocket("ws://localhost:1081/1.0/event/get"),
events = []; // cache of visible events
var context = canvas.node().getContext("2d"),
image = context.createImageData(w, h);
var projection = d3.geo.albersUsa()
.scale(2000)
.translate([w / 2, h / 2]);
// Save as on alt-click.
canvas.on("click", function() {
if (d3.event.altKey) window.open(this.toDataURL());
});
// Display the states in the background.
d3.json("/us/states.json", function(collection) {
d3.select("svg").selectAll("path")
.data(collection.features)
.enter().append("path")
.attr("d", d3.geo.path()
.projection(projection));
});
// On open, send the event request. Here, a generic event type called "event".
socket.onopen = function() {
socket.send(JSON.stringify({
expression: "event(location)",
start: utc(start)
}));
};
// On message, record the event.
socket.onmessage = function(message) {
var d = JSON.parse(message.data),
l = d.data.location,
p = projection(l),
x = Math.max(0, Math.min(w - 1, Math.round(p[0]))),
y = Math.max(0, Math.min(h - 1, Math.round(p[1]))),
i = w * y + x,
j = i << 2;
d.time = new Date(d.time);
d.next = events[i];
events[i] = d;
image.data[j + 3] = 255;
d3.timer(draw);
};
// Expire old events.
setInterval(function() {
var i = -1,
n = w * h,
o,
j,
expire = new Date(Date.now() - duration);
while (++i < n) {
if ((o = events[i]) && (o.time < expire)) {
image.data[(i << 2) + 3] = 0;
events[i] = null;
d3.timer(draw);
}
}
}, 5000);
function draw() {
context.putImageData(image, 0, 0);
return true;
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment