p5/D3 Cookbook
Combining the power of D3.js with the simplicity of p5.js
var dataContainer;
function setup() {
var margin = {top: 10, right: 30, bottom: 30, left: 30};
width = 600 - margin.left - margin.right;
height = 600 - margin.top - margin.bottom;
createCanvas(width, height);
//Using custom DOM elements to store and access animated variables
dataContainer = d3.select('body').append('custom');
textAlign(CENTER);
//Periodic function that produces a series of D3 transitions.
refresh();
setInterval(refresh, 3000);
//Replace the draw() loop with d3.timer. You can rename drawFunction() draw()
//and use the draw() loop. To my eye, the animation is not as smooth.
d3.timer(drawFunction);
}
//Refresh function contains only D3
function refresh() {
var values;
var rand = Math.random() * 30 + 10;
var slope = Math.random() * 6 - 3;
values = d3.range(20).map(function(i) {
var val = i*slope + rand + Math.random() * 3;
return (val > 50) ? 50 : val;
})
x = d3.scale.linear()
.domain([0, values.length])
.range([0, width]);
y = d3.scale.linear()
.domain([0, 50])
.range([height, 0]);
//bind generated data to custom dom elements
var bars = dataContainer.selectAll('.bars').data(values);
//store variables for visual representation. These will be used
//later by p5 methods.
bars
.enter()
.append('rect')
.attr('height', 120)
.attr('class', 'bars')
.attr('x', function(d, i) { return x(i) })
.attr('dx', function(d) { return width/values.length - 1;})
.attr('y', function(d) { return height; })
bars
.transition()
.duration(2000)
.delay(function(d,i) { return i * 50;})
.attr('height', function(d) { return height - y(d); })
.attr('x', function(d, i) { return x(i) })
.attr('y', function(d) { return y(d); })
}
//Draw function contains no D3.
function drawFunction() {
background(255);
noStroke();
//p5.dom
var bars = getElements('bars');
for(var i = 0; i < bars.length; i++) {
var thisbar = bars[i];
push();
translate(thisbar.attribute('x'), thisbar.attribute('y'));
if((mouseX > thisbar.attribute('x')) && (mouseX < (int(thisbar.attribute('x')) + int(thisbar.attribute('dx'))))) {
fill('brown');
} else {
fill('red');
}
rect(1,1, thisbar.attribute('dx'), thisbar.attribute('height'));
fill('white')
text(int(thisbar.attribute('height')),thisbar.attribute('dx')/2 + 2, 15);
pop();
}
stroke('black');
strokeWeight(3);
line(0,height,width,height);
noStroke();
}