Reputation: 14871
I am trying to create a realtime barchart that plots values over time, using d3.js
This is how I am doing it.
var dataset = [ 5, 10, 15, 20, 25 ];
var w = 1800;
var h = 500;
var barPadding = 1;
setInterval(function(){
dataset.push(Math.floor(Math.random()*51));
draw();
},1000);
function draw(){
d3.select("svg").remove();
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
svg.selectAll("rect").data(dataset)
.enter()
.append("rect")
.attr("x", function(d, i){return 12*i;})
.attr("y", function(d){return h -d*4; })
.attr("width", 11)
.attr("height", function(d) { return d * 4; })
.attr("fill", "teal")
.attr("fill", function(d) { return "rgb(0, 0, " + (d * 10) + ")";});
}
The problem is that I am redrawing the whole graph every time a new value is added to the data array.
How do I append a bar to the bar graph that is already drawn, every time a new value is added to the array, rather than redrawing it every time?
Upvotes: 5
Views: 3471
Reputation: 16659
Not sure what kind of effect you're looking for, but have a look at this fiddle.
The following redraw
function will keep adding to the barchart so it will continue to grow to the right:
function redraw() {
var rect = svg.selectAll("rect")
.data(dataset);
rect.enter().insert("rect", "line")
.attr("x", function(d, i) { return 12*(i+1); })
.attr("y", function(d) { return h -d*4 })
.attr("width", 11)
.attr("height", function(d) { return d * 4; })
.attr("fill", "teal")
.attr("fill", function(d) { return "rgb(0, 0, " + (d * 10) + ")";})
rect.transition()
.duration(800)
.attr("x", function(d, i) { return 12*i; });
}
Borrowed from an mbostock tutorial.
Upvotes: 2
Reputation: 15695
You're close, just stop redrawing the svg
element. If you only need to add new elements, then that's what your draw function should do when it's called.
var dataset = [ 5, 10, 15, 20, 25 ];
var w = 1800;
var h = 300;
var barPadding = 1;
var container = d3.select("body").append("svg").attr("width", w).attr("height", h).append("g");
setInterval(function(){
dataset.push(Math.floor(Math.random()*51));
draw();
},1000);
function draw(){
container.selectAll("rect").data(dataset).enter().append("rect")
.attr("x", function(d, i){return 12*i;})
.attr("y", function(d){return h -d*4; })
.attr("width", 11)
.attr("height", function(d) { return d * 4; })
.attr("fill", "teal")
.attr("fill", function(d) { return "rgb(0, 0, " + (d * 10) + ")";});
}
http://jsfiddle.net/Wexcode/LYqfU/
Upvotes: 4