Theboy
Theboy

Reputation: 393

My D3.js code cause new data to be added as a new graph, I want it to be appended to an existing graph. What did I do wrong?

I have gone through several d3 tutorial briefly but I'm a bit confused about how the animation (ie transform, etc) work.

I have a csv file on server that's being updated by a separate process and I would like my little webpage to graph the data.

Here's what I have.

My question is, as you can see, for every 10 seconds, it appended a new graph, as opposed to update the current graph and just draw the new point. What do I need to change in order to have that effect?

$(document).ready(function() {
    $.ajaxSetup({ cache: false }); 
    setInterval(function() {
        $('#file').load('file.csv', function(){
            var input = $('#file').html();
            var data = $.csv.toObjects(input);
            var price = [];
            var time = [];
            for (var row in data){
                price.push(data[row]["Price"]);
            }
            for (var row in data){
                time.push(data[row]["Time"]);
            }
        var data = price;
        w = 400,
        h = 200,
        margin = 20,
        y = d3.scale.linear().domain([0, d3.max(data)]).range([0 + margin, h - margin]),
        x = d3.scale.linear().domain([0, data.length]).range([0 + margin, w - margin])
        var vis = d3.select("body")
            .append("svg:svg")
            .attr("width", w)
            .attr("height", h);
        var g = vis.append("svg:g")
            .attr("transform", "translate(0, 200)");
        var line = d3.svg.line()
            .x(function(d,i) { return x(i); })
            .y(function(d) { return -1 * y(d); })
        g.append("svg:path").attr("d", line(data));
....

    }, 10000); 
});

Thanks a lot for your comments!

Upvotes: 1

Views: 164

Answers (1)

Lars Kotthoff
Lars Kotthoff

Reputation: 109282

You need to change the code that appends elements. The first time (when there is no graph), it can remain unchanged:

var vis = d3.select("body")
        .append("svg:svg")
        .attr("width", w)
        .attr("height", h);
var g = vis.append("svg:g")
        .attr("transform", "translate(0, 200)");
var line = d3.svg.line()
        .x(function(d,i) { return x(i); })
        .y(function(d) { return -1 * y(d); })
g.append("svg:path").attr("d", line(data));

Subsequent times, it should look as follows:

vis.select("path").attr("d", line(data));

This is assuming that you saved the reference to the generated SVG somewhere, you can of course also select it again each time. You might also need code to update your scales.

Note that a more D3 way is to pass the data to a specialised function that will bind it to an element and then set attributes accordingly. That is, the initial code to append the line would be

g.append("svg:path").datum(data).attr("d", line);

and the code to update would be

vis.select("path").datum(data).attr("d", line);

Upvotes: 2

Related Questions