Thursday, May 23, 2024
 Popular · Latest · Hot · Upcoming
39
rated 0 times [  43] [ 4]  / answers: 1 / hits: 50096  / 12 Years ago, tue, february 19, 2013, 12:00:00

I'm working on a real-time visualization of incoming data. I use D3 for the visualization and started based on this example: http://bl.ocks.org/mbostock/3883195



This is the version I'm currently working on:



  var margin = {top: 20, right: 20, bottom: 30, left: 50},
width = 500 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;

var x = d3.time.scale().range([0, width]);
var y = d3.scale.linear().range([height, 0]);

var xAxis = d3.svg.axis().scale(x).orient(bottom);
var yAxis = d3.svg.axis().scale(y).orient(left);

var area = d3.svg.area()
.x(function(d) { return x(d.x); })
.y0(height)
.y1(function(d) { return y(d.y); });

var svg = d3.select(div#chart).append(svg)
.attr(width, width + margin.left + margin.right)
.attr(height, height + margin.top + margin.bottom)
.append(g)
.attr(transform, translate( + margin.left + , + margin.top + ));

var data = [[1,1],[2,3],[3,2],[4,4]];

var dataCallback = function(d) {
d.x = +d[0];
d.y = +d[1];
};
data.forEach(dataCallback);

x.domain(d3.extent(data, function(d) { return d.x; }));
y.domain([0, d3.max(data, function(d) { return d.y; })]);

svg.append(path)
.datum(data)
.attr(class, area)
.attr(d, area);

svg.append(g)
.attr(class, x axis)
.attr(transform, translate(0, + height + ))
.call(xAxis);

svg.append(g)
.attr(class, y axis)
.call(yAxis)
.append(text)
.attr(transform, rotate(-90))
.attr(y, 6)
.attr(dy, .71em)
.style(text-anchor, end)
.text(Number of Messages);


This produces the following graph:



simple



Now, as it should update itself regularly, I wanted to dynamically update the data in the graph using the following code:



  var n = svg.selectAll(path).data([5,20])
n.enter();
n.exit().remove();


However, that does not work. I'm new to D3 and still learning the basics. Ideally, the graph visualization shifts to the left and the new data is shown in the graph. But so far I can't even add new data to it. Could someone help me with that? I also searched for examples similar to this, but did not found anything which really helped me so far.


More From » charts

 Answers
213

d3 is pretty good at keeping track of what data's been added and what's being removed - it does this with joins. Take a look at http://bl.ocks.org/mbostock/3808218



IF we use the data binding (instead of datum)



svg.append(path)
.data([data])
.attr(class, area)
.attr(d, area);


and then on update do something like:



// update the list of coordinates
data.splice(0,1);
data.push([5,20]);

// re-decorate the last, newly added item
dataCallback(data[data.length - 1]);

// You will also need to update your axes
x.domain(d3.extent(data, function(d) { return d.x; }));
y.domain([0, d3.max(data, function(d) { return d.y; })]);

// update the data association with the path and recompute the area
svg.selectAll(path).data([data])
.attr(d, area);


And you should get your area to update.



You can try it out here



With the way your data is organized using the joined data (instead of datum) may not make much difference. Note that here the (single) data element you are associating with the path is the full list of coordinates so to update the area you need to pass in a new full list of coordinates.



If you really want to minimized the amount you need to redraw you could break up the area and draw each line segment. Then essentially you fall back to the bar chart example but with not-flat bars and no spacing.


[#80133] Monday, February 18, 2013, 12 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
theodore

Total Points: 318
Total Questions: 97
Total Answers: 119

Location: Turks and Caicos Islands
Member since Sun, Mar 7, 2021
3 Years ago
;