按 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
。这是更新和动画发生的地方。注意函数的流程:
- "update" 数据就好像您的
socket.io
是接收数据然后将其附加到数据集的人。
- 重新定义轴
- 重新定义点和路径
- 指定过渡持续时间(随意选择适合您的数字)
- 实际更新和动画更改情节
我添加了一个按钮来模拟 socket.io
接收事件。
对于您的应用程序,请忽略 Update()
函数中的 data.push
和 console.log
,我认为这就是您所需要的——除了将数据指向您的 ctrl.data
数组和 运行 当然是 socketio.on(...)
中的 Update()
函数。
相同的基本轮廓适用于 animating/updating 大多数图表。
希望对您有所帮助!
我正在编写一个基于 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
的 Update()
将重新定义所有 D3 变量并为变化设置动画
socketio.on(...)
部分调用
Update()
将通过执行从头开始创建图表所用步骤的子集来完成上述项目。下面概述了它将执行的操作:重新缩放 x 轴和 y 轴,以图形方式更新轴,将原始点和线平移到新轴上的新位置,添加新点,并添加可能需要完成的任何线图
我正在为您开发一个 jsFiddle,其中包含一个可用的 Update
来演示上述内容,希望在您的代码中实现它会很简单。完成后我会编辑此 post,但我想在我处理它的同时给你 "quick" 答案,同时尝试帮助你。如果您想同时阅读一些内容,请查看
http://blog.visual.ly/creating-animations-and-transitions-with-d3-js/
更新
https://jsfiddle.net/npzjLng9/2/。我以您提供的示例为例,必须将要加载的数据修改为本地数据,而不是来自文本文件;但是,它采用相同的格式,并且为了可读性也少了很多条目。除此之外,我没有对示例进行任何更改。这是我添加的内容:向下滚动并找到最后一个函数 Update
。这是更新和动画发生的地方。注意函数的流程:
- "update" 数据就好像您的
socket.io
是接收数据然后将其附加到数据集的人。 - 重新定义轴
- 重新定义点和路径
- 指定过渡持续时间(随意选择适合您的数字)
- 实际更新和动画更改情节
我添加了一个按钮来模拟 socket.io
接收事件。
对于您的应用程序,请忽略 Update()
函数中的 data.push
和 console.log
,我认为这就是您所需要的——除了将数据指向您的 ctrl.data
数组和 运行 当然是 socketio.on(...)
中的 Update()
函数。
相同的基本轮廓适用于 animating/updating 大多数图表。
希望对您有所帮助!