按 socket.io 更新实时 d3 图表

Update real time d3 chart by socket.io

我正在编写一个基于 d3.js 的实时图表指令。结构如下所示:

myDirective.js:

app.directive('myDirective', function(socketio) {

  return {
    restrict: 'EA',
    templateUrl: '../../views/partials/chart.html',
    controller: DataController,

    link: function(scope, elem, attrs, ctrl) {

      scope.Watch = scope.$watch(function() {
        return ctrl.data;
      }, function(newVal) {
        // d3 code part
      });

      socketio.on(event, function(newdata) {
        ctrl.data.push(newdata);
        // redraw chart
      });
    }
  };
});

上面d3代码部分,我参考了http://bl.ocks.org/gniemetz/4618602。主要代码几乎相同,图表显示也很好。

现在我想使用socket.io通过代码更新图表

socketio.on(event, function(newdata) {
  ctrl.data.push(newdata);
  // redraw chart
});

但不知道如何使用更新后的 'ctrl.data' 有效地重绘图表。我知道在 Morris.js 中,我们可以通过 '.setData(ctrl.data)' 方法做到这一点,但不知道如何在 d3 中更新。有什么想法吗?

ps:我试过copy/paste上面的d3代码到这个地方,但是一直报错说:"TypeError: t.slice is not a function"

谢谢,

快速而肮脏的方法:每次有更新时,清空<div>并重新绘制整个图形。

更优雅的方式:编写自己的update函数来添加新数据。这是迄今为止视觉上最吸引人的方式,因为图形实际上是动画的。 D3 是为这类事情而构建的,所以它绝不是它的功能的延伸。这将花费更长的时间,但通常会提供更令人愉悦的体验,如 D3 画廊中的一些图表所示(示例:http://square.github.io/crossfilter/ , http://bl.ocks.org/NPashaP/96447623ef4d342ee09b)以下是我如何使用您想要的图表来完成此操作:

  • 保持代码不变
  • 添加一个更新函数,比如命名为 Update(),它在您评论 // redraw chart
  • socketio.on(...) 部分调用
  • Update() 将重新定义所有 D3 变量并为变化设置动画

Update() 将通过执行从头开始创建图表所用步骤的子集来完成上述项目。下面概述了它将执行的操作:重新缩放 x 轴和 y 轴,以图形方式更新轴,将原始点和线平移到新轴上的新位置,添加新点,并添加可能需要完成的任何线图

我正在为您开发一个 jsFiddle,其中包含一个可用的 Update 来演示上述内容,希望在您的代码中实现它会很简单。完成后我会编辑此 post,但我想在我处理它的同时给你 "quick" 答案,同时尝试帮助你。如果您想同时阅读一些内容,请查看 http://blog.visual.ly/creating-animations-and-transitions-with-d3-js/


更新

https://jsfiddle.net/npzjLng9/2/。我以您提供的示例为例,必须将要加载的数据修改为本地数据,而不是来自文本文件;但是,它采用相同的格式,并且为了可读性也少了很多条目。除此之外,我没有对示例进行任何更改。这是我添加的内容:向下滚动并找到最后一个函数 Update。这是更新和动画发生的地方。注意函数的流程:

  1. "update" 数据就好像您的 socket.io 是接收数据然后将其附加到数据集的人。
  2. 重新定义轴
  3. 重新定义点和路径
  4. 指定过渡持续时间(随意选择适合您的数字)
  5. 实际更新和动画更改情节

我添加了一个按钮来模拟 socket.io 接收事件。

对于您的应用程序,请忽略 Update() 函数中的 data.pushconsole.log,我认为这就是您所需要的——除了将数据指向您的 ctrl.data 数组和 运行 当然是 socketio.on(...) 中的 Update() 函数。

相同的基本轮廓适用于 animating/updating 大多数图表。

希望对您有所帮助!