通过socket.io更新实时d3图表 [英] Update real time d3 chart by socket.io

查看:252
本文介绍了通过socket.io更新实时d3图表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写一个基于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:我试图将d3代码复制/粘贴到这个地方,但总是有一个错误说:TypeError:t.slice不是函数



感谢,

解决方案

和脏方式:每次有更新时,请清空< div> 并重新绘制整个图表。



更优雅的方式:编写自己的更新函数来添加新数据。这是迄今为止最具视觉吸引力的方式,因为图形实际上是动画。 D3是为这种事情构建的,所以它绝不意味着它的能力。这将需要一点时间,但通常提供了一个更加愉快的经验,如在D3的图片中的一些图表所示(示例: http://square.github.io/crossfilter/ http:// bl .ocks.org / NPashaP / 96447623ef4d342ee09b )下面是我如何使用你想要的图形:




  • c $>
  • 添加一个更新函数,名为 Update() ...)您评论过的部分 //重绘图

  • ()将重新定义所有D3变量并动画更改



将通过执行从头创建图形所使用的步骤的子集来实现上述项目符号。这里是它将做什么的概述:重新缩放x和y轴,图形更新轴,将原点和线转换到新轴上的新位置,添加新点,并添加任何可能需要完成的线图表



我正在使用一个jsFiddle工作更新演示上述内容,希望,在你的代码中实现它将很简单。我将编辑这篇文章,当它完成,但我想给你快速的答案,而我的工作,以期同时帮助你。如果您想同时阅读一些资料,请查看
http ://blog.visual.ly/creating-animations-and-transitions-with-d3-js/






UPDATE



https://jsfiddle.net/npzjLng9/2/ 。我采取了你提供的例子,不得不修改要加载到本地的数据,而不是从文本文件;然而,它是在相同的格式,并且更少的条目为可读性。除此之外,我没有对示例做任何更改。这里是我添加的:向下滚动并找到最后一个函数,更新。这里是更新和动画发生的地方。注意函数的流程:


  1. 更新数据,就像你的 socket.io
  2. 重新定义轴

  3. 重新定义点和路径
  4. >
  5. 指定转换持续时间(可随意使用任何数字适合您)

  6. 实际更新和设置图表上的变化

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



对于您的应用程序,忽略<$ c中的 data.push console.log $ c> Update()函数,我认为这是所有你需要 - 除了将数据指向你的 ctrl.data 当然,在 socketio.on(...)中运行 Update()



同样的基本大纲适用于动画/更新大多数图形。



我希望这可以帮助你! p>

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
      });
    }
  };
});

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.

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

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

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: 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"

Thanks,

解决方案

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

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:

  • 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

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

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/


UPDATE

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. "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

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

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.

I hope this helps you!

这篇关于通过socket.io更新实时d3图表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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