动态更新 D3 中的图表数据 [英] Dynamically update chart data in D3

查看:23
本文介绍了动态更新 D3 中的图表数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究传入数据的实时可视化.我使用 D3 进行可视化并基于此示例开始:

如果我们使用数据绑定(而不是数据")

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

然后在更新时执行以下操作:

//更新坐标列表数据拼接(0,1);数据推送([5,20]);//重新装饰最后一个新添加的项目dataCallback(data[data.length - 1]);//您还需要更新轴x.domain(d3.extent(data, function(d) { return d.x; }));y.domain([0, d3.max(data, function(d) { return d.y; })]);//更新与路径的数据关联并重新计算区域svg.selectAll("path").data([数据]).attr("d", area);

你应该让你的区域更新.

你可以试试这里

使用连接数据(而不是数据)组织数据的方式可能没有太大区别.请注意,此处与路径关联的(单个)数据元素是完整坐标列表,因此要更新需要传入新的完整坐标列表的区域.

如果你真的想最小化你需要重绘的数量,你可以分解区域并绘制每个线段.然后基本上你会回到条形图的例子,但没有扁平的条形和没有间距.

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:

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.

解决方案

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.

这篇关于动态更新 D3 中的图表数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆