Skip to content

Instantly share code, notes, and snippets.

@RandomEtc
Created August 12, 2013 16:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RandomEtc/6212599 to your computer and use it in GitHub Desktop.
Save RandomEtc/6212599 to your computer and use it in GitHub Desktop.
Sketch for a 'watch' function on d3 selctions...
var data = [ ],
width = 500,
height = 500,
id = 0;
function addRandom() {
data.push({
x: width * Math.random(),
y: height * Math.random(),
r: 10 * Math.random(),
id: id++
});
}
setInterval(function() {
if (data.length == 10) {
data.shift();
}
addRandom();
}, 100);
var svg = d3.select('body').append('svg')
.attr('width', width)
.attr('height', height);
var key = function(d) { return d.id; };
var circles = svg.selectAll('circle').watch(data, key);
circles.exit().remove();
circles.enter().append('circle');
circles.attr('cx', function(d) { return d.x; });
circles.attr('cy', function(d) { return d.y; });
circles.attr('r', function(d) { return d.r; });
circles.style('fill', function(d) { return 'red'; });
d3.selection.prototype.watch = function(data, key) {
var selection = this,
watch = {},
exit = {},
enter = {},
watchCommands = [],
enterCommands = [],
exitCommands = [];
watch.attr = function(name, value) {
watchCommands.push([ 'attr', [ name, value ]]);
return this;
};
watch.style = function(name, value) {
watchCommands.push([ 'style', [ name, value ]]);
return this;
};
watch.enter = function() {
return enter;
};
watch.exit = function() {
return exit;
};
exit.remove = function() {
exitCommands.push(['remove']);
return this;
};
enter.append = function(selector) {
enterCommands.push(['append', [ selector ]]);
return this;
};
d3.timer(function(){
selection = selection.data(data, key);
var exitElements = selection.exit();
if (!exitElements.empty()) {
exitCommands.forEach(function(cmd){
exitElements[cmd[0]].apply(exitElements, cmd[1]);
});
}
var enterElements = selection.enter();
if (!enterElements.empty()) {
enterCommands.forEach(function(cmd){
enterElements[cmd[0]].apply(enterElements, cmd[1]);
});
}
if (!selection.empty()) {
watchCommands.forEach(function(cmd){
selection[cmd[0]].apply(selection, cmd[1]);
});
}
});
return watch;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment