Javascript 动态更新 D3 中的图表数据

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14958825/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 18:26:51  来源:igfitidea点击:

Dynamically update chart data in D3

javascriptchartsd3.js

提问by str

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

我正在研究传入数据的实时可视化。我使用 D3 进行可视化并基于此示例开始: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 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 的新手,仍在学习基础知识。理想情况下,图形可视化向左移动,新数据显示在图形中。但到目前为止,我什至无法向其中添加新数据。有人可以帮我吗?我还搜索了与此类似的示例,但到目前为止还没有找到任何真正对我有帮助的内容。

采纳答案by Superboggly

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

d3 非常擅长跟踪添加的数据和删除的数据 - 它通过连接来实现。看看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 coordinatesso 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.

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