Skip to content

Instantly share code, notes, and snippets.

@dechov
Last active December 22, 2015 20:08
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 dechov/6523886 to your computer and use it in GitHub Desktop.
Save dechov/6523886 to your computer and use it in GitHub Desktop.
Dynamic D3: the playback support plugin

Dynamic D3: playback plugin

d3.time.clock()

clock.speed([speed])

clock.extent([extent])

clock.init()

clock.run()

clock.pause()

clock.seek

d3.svg.dial()

dial.clock([clock])

d3.time.clock = function () {
return d3_time_clock(0, 1, null);
};
function d3_time_clock(t, speed, interval) {
var dispatch = d3.dispatch('tick', 'run', 'pause', 'complete');
function clock() {}
clock.speed = function(x) {
if (!arguments.length) return speed;
speed = x;
return clock;
};
// Tie to a scale instead, with default linear?
clock.extent = function(x) {
if (!arguments.length) return extent;
extent = x;
return clock;
};
clock.run = function() {
interval = window.setInterval(function() {
dispatch.tick(++t);
if (t >= extent) {
clock.pause();
dispatch.complete();
}
}, 1000 / speed);
dispatch.run();
return clock;
};
clock.pause = function() {
window.clearInterval(interval);
interval = null;
dispatch.pause();
return clock;
};
clock.init = function() {
dispatch.tick(t = 0);
return clock;
};
clock.seek = function(dt) {
t += Math.round(dt * speed);
if (t >= extent) {
clock.pause();
dispatch.complete();
}
t = Math.max(0, Math.min(extent, t));
dispatch.tick(t);
return clock;
};
return d3.rebind(clock, dispatch, 'on');
}
d3.svg.dial = function() {
var clock = d3.time.clock(),
state = null;
function pop(x) {
x.attr('transform', 'scale(0)')
.transition()
.ease('elastic')
.attr('transform', 'scale(1)');
}
function dial(g) {
g.each(function() {
var g = d3.select(this);
g.call(d3.behavior.drag()
.origin(function() { return { x: 0, y: 0}; })
.on('drag', function() {
console.log(d3.event)
clock.pause();
clock.seek(Math.floor(d3.event.dx / 5));
})
);
g.style('cursor', 'e-resize');
g.append('circle')
.attr('r', 42)
.attr('fill', '#f6f6f6');
g.append('path')
.attr('fill', '#cccccc')
.attr('class', 'arc');
var btn = g.append('g')
.attr('class', 'btn')
.attr('transform', 'translate(0, 22)')
.style('cursor', 'pointer')
.on('click', function() {
switch (state) {
case 'running':
clock.pause();
break;
case 'paused':
clock.run();
break;
case 'complete':
clock.init().run();
break;
}
});
btn.append('rect')
.attr('width', 12)
.attr('height', 12)
.style('fill', 'transparent')
.attr('transform', 'translate(-6,-6)');
var btn_d = {
pause: 'M-5 -6V6H-1V-6H-5M5 -6V6H1V-6H5',
play: 'M-4 -7V7L7 0Z',
replay: 'M1 -7L7 -3L1 1V-2A4 4 0 1 0 4 1H 6A6 6 0 1 1 1 -5Z'
};
var path = btn.append('path').attr('d', btn_d.play);
clock.on('run.dial', function() {
state = 'running';
path.attr('d', btn_d.pause).call(pop);
});
clock.on('pause.dial', function() {
if (state == 'paused') return;
state = 'paused';
path.attr('d', btn_d.play).call(pop);
});
clock.on('complete.dial', function() {
state = 'complete';
path.attr('d', btn_d.replay).call(pop);
});
clock.on('tick.dial', function(t) {
g.select('path')
.datum(t)
.attr('d', d3.svg.arc()
.outerRadius(42)
.innerRadius(0)
.startAngle(0)
.endAngle(function(d) {
return 2 * Math.PI * d / clock.extent();
})
);
});
});
}
dial.clock = function(x) {
if (!arguments.length) return clock;
clock = x;
return dial;
};
return dial;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment