Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Appending an element to an existing element in d3.js

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?

like image 853
ashwnacharya Avatar asked Dec 13 '12 22:12

ashwnacharya


People also ask

What does append do in d3?

append() function is used to append a new element to the HTML tag name as given in the parameters to the end of the element. If the type that is given is a function then it must be evaluated for each element that is in the selection. Syntax: selection.

How to append HTML in d3?

We can add a new HTML element in D3. js by using the append() method. It creates a new HTML element and inserts it at the end of the selected element. Let's create a new div element inside the body tag and add text to it using the text() method.

What is use of DOM and SVG in d3?

SVG is text-based, and it is an image format that is vector-based. SVG is the same as the HTML structure. It can be illustrated as the DOM (Document Object Model). The properties of SVG can be described as attributes.


2 Answers

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/

like image 110
Wex Avatar answered Sep 28 '22 00:09

Wex


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.

like image 24
mccannf Avatar answered Sep 27 '22 22:09

mccannf