更新通过socket.io实时D3图

问题描述:

我写一个基于d3.js实时图表指令。其结构是这样的:

I am writing a d3.js-based real time chart directive. The structure looks like this:

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 code而言,我指的 的http:// BL。 ocks.org/gniemetz/4618602 的。主code是几乎相同的,并显示良好的图表。

In the above d3 code part, I refer to http://bl.ocks.org/gniemetz/4618602. The main code is almost the same and the chart is displayed well.

现在我想用socket.io通过code到更新图表

Now I want to use socket.io to update the chart via code

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

但不知道如何与更新ctrl.data有效重绘图表。我知道Morris.js,我们可以通过'.setData(ctrl.data)的方法做到这一点,但不知道如何在D3更新。任何想法?

but do not know how to redraw the chart efficiently with the updated 'ctrl.data'. I know in Morris.js, we could do this by '.setData(ctrl.data)' method, but do not know how to update in d3. Any idea?

PS:我试图复制/粘贴D3 code以上这个地方,但总有一个错误说:类型错误:t.slice不是一个函数

ps: I tried to copy/paste the d3 code above to this place, but there was always an error said: "TypeError: t.slice is not a function"

谢谢,

的快速和肮脏的方式:每一次你有一个更新,空< D​​IV> 和重绘整个图形。

The quick and dirty way: every time you have an update, empty the <div> and redraw the entire graph.

更优雅的方式:编写自己的更新函数来添加新的数据。这是迄今为止最具有视觉吸引力的方式,因为该图将实际动画。 D3精心打造了这样的事情,所以它绝不是其功能的延伸。这将需要更长的时间,但通常提供一个更加赏心悦目的体验,一些在D3的画廊图表所见(例如: HTTP: //square.github.io/crossfilter/ ,http://bl.ocks.org/NPashaP/96447623ef4d342ee09b)下面是我将如何使用您所需的图形做到这一点:

The more elegant way: write your own update function to add new data. This is by far the most visually appealing way, since the graph will actually be animated. D3 is well built for this sort of thing, so its by no means a stretch of its capabilities. This will take a bit longer, but usually provides a much more pleasing experience, as seen on some of the graphs in D3's gallery (examples: http://square.github.io/crossfilter/ , http://bl.ocks.org/NPashaP/96447623ef4d342ee09b) Here's how I would do it using your desired graph:


  • 让您的$ C $相同c

  • 添加一个更新功能,说名为更新(),这就是所谓的 socketio.on(...)部分,在那里你注释 //重绘图

  • 更新()然后将重新定义所有变量D3和动画的变化

  • Keep your code the same
  • Add an update function, say named Update(), that's called in the socketio.on(...) section where you commented // redraw chart
  • Update() will then redefine all D3 variables and animate the change

更新()将主要通过执行在从头开始创建图表使用的步骤的一个子集上面做子弹。这儿是它会做一个概述:重新调整x和y轴上,图形更新轴,翻译原来的点和线在新的坐标轴的新位置,增加新的点,并将其添加可能需要完成的任何行图

Update() will essentially do the above bullet by performing a subset of the steps used in creating the graph from scratch. Here's an overview of what it'll do: rescale both the x and y axes, graphically update the axes, translate the original points and lines to their new positions on new axes, add new points, and add any lines it may need to complete the graph

我工作的一对的jsfiddle你工作更新试玩上面,并希望在你的code实现它就会很简单。其完成时,我会编辑这个职位,但我想给你的快速的答案,而我在试图帮助您同时进行这项工作。如果你想阅读一些与此同时,退房
http://blog.visual.ly/creating-animations-and-transitions-with-d3-js/

I'm working on a jsFiddle for you with a working Update to demo the above and, hopefully, implementing it in your code will be simple. I'll edit this post when its done, but I wanted to give you the "quick" answer while I work on it in an attempt to help you meanwhile. If you want some reading meanwhile, check out http://blog.visual.ly/creating-animations-and-transitions-with-d3-js/

更新

https://jsfiddle.net/npzjLng9/2/ 。我把你提供的例子,不得不修改数据加载是本地,而不是从一个文本文件;但是,它是在相同的格式,以及用于可读性也少了很多的条目。除此之外,我没有对这个例子的任何更改。这是我补充说:向下滚动,找到最后的功能,更新。这里就是更新和动画发生。注意函数的流程:

https://jsfiddle.net/npzjLng9/2/. I took the example you provided and had to modify the data to be loaded to be local, not from a text file; however, it is in the same format, and also a lot less entries for readability. Other than that, I did not make any changes to the example. Here's what I added: scroll down and find the last function, Update. Here is where the update and animation happens. Notice the flow of the function:


  1. 更新的数据,如果你的 socket.io 是谁收到,然后将其附加到数据集之一。

  2. 重新定义轴

  3. 重新定义点和路径

  4. 指定一个过渡时间(随​​时与任何数字适合你玩)

  5. 实际更新和动画的剧情变化

  1. "update" the data as if your socket.io was the one who received it and then appended it to the dataset.
  2. Redefine the axes
  3. Redefine the points and paths
  4. Specify a transition duration (feel free to play with whatever number suits you)
  5. Actually update and animate changes on the plot

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

I added a button to simulate a socket.io receiving event.

有关您的应用程序,忽略 data.push 的console.log 更新()功能,我想这是所有你需要 - 比数据指向您的 ctrl.data ​​ code>阵列和运行的其他 code>更新()函数socketio.on(...),当然。

For your application, ignore the data.push and console.log in the Update() function and I think that's all you'd need -- other than pointing the data to your ctrl.data array and running the Update() function in your socketio.on(...), of course.

同样的基本轮廓适用于动画/更新最图表。

The same basic outline applies to animating/updating most graphs.

我希望这可以帮助你!