Backbone.js 使用主干的实时D3时间序列——图形移动速度比axis慢
我正在尝试用D3和主干构建一个实时时间序列。我遇到的问题是图形的移动速度比x轴慢。x轴准确地跟踪当前时间,所以我知道这是图形线的问题。我是根据Mike Bostock的示例(文章底部的最后一个图表)编写代码的。我似乎找不到问题所在——我的代码紧跟示例,只是用主干实现的 该应用程序使用websocket和事件聚合器进行设置,以便在接收到新数据点时,将数据点的模型添加到集合中,添加模型将触发“TimeseriesView”视图中的函数“newPoint”。“newPoint”将一个数字推送到一个数组“data”,这就是绘制线的数据的来源。以下是相关观点。(如果代码有点凌乱,请原谅——我是主干网新手,所以我怀疑有更干净的方法可以做到这一点)Backbone.js 使用主干的实时D3时间序列——图形移动速度比axis慢,backbone.js,d3.js,Backbone.js,D3.js,我正在尝试用D3和主干构建一个实时时间序列。我遇到的问题是图形的移动速度比x轴慢。x轴准确地跟踪当前时间,所以我知道这是图形线的问题。我是根据Mike Bostock的示例(文章底部的最后一个图表)编写代码的。我似乎找不到问题所在——我的代码紧跟示例,只是用主干实现的 该应用程序使用websocket和事件聚合器进行设置,以便在接收到新数据点时,将数据点的模型添加到集合中,添加模型将触发“TimeseriesView”视图中的函数“newPoint”。“newPoint”将一个数字推送到一个数组
您基于代码的示例将x轴滑动和添加数据深深地交织在一起。当您像示例中那样轮询某个内容时,它工作得很好,不像我认为在websocket设置中那样,数据以不同的间隔或随机到达(请参阅以获得代码的准确复制) 要做的第一件事是分离滑动(勾选函数)和数据注入::每个数据都有一个时间戳,用于提取x值,数据最初是空的,
勾选
仅滑动图形
将这些修改应用到您的代码中,我们得到
TimeseriesView = Backbone.View.extend({
initialize: function (options) {
_.bindAll(this, 'tick');
// ...
self.dataSet = options.dataSet;
self.dataSet.on('add', this.newPoint, this);
self.tick();
},
newPoint: function(model) {
this.data.push(model);
},
tick: function () {
var self = this;
self.now = new Date();
var now = self.now;
var duration = self.duration;
var n = self.n;
var x = self.x;
var y = self.y;
var width = this.width;
var height = this.height;
x.axis = d3.svg.axis().scale(x).orient("bottom");
// update the domains
self.x.domain([now - (n - 2) * duration,
now - duration]);
self.y.domain([0, d3.max(self.dataSet.pluck('auth_amt'))]);
self.line = d3.svg.line()
.x(function(d) { return x(d.get('stamp')); })
.y(function(d) { return y(d.get('auth_amt')); });
// redraw the line
d3.select(".line")
.attr("d", self.line)
.attr("transform", null);
// slide the x-axis to the left
self.axis.transition()
.duration(duration)
.ease("linear")
.call(x.axis);
self.x = d3.time.scale()
.domain([now - (n-2) * duration, now - duration])
.range([0, width]);
var x = self.x;
// slide the line left
self.path.transition()
.duration(duration)
.ease("linear")
.attr("transform", "translate(" + x(now - (n - 1) * duration) + ")")
.each("end", self.tick);
}
});
我注意到您的代码中有这一部分:self.x=d3.time.scale().domain([now-(n-2)*duration,now-duration])。range([0,width]);移动到更新部分,而在示例中,它是设置的一部分。这是否会导致轴的更新速度快于数据?似乎无法修复它。不过,谢谢你的建议
TimeseriesView = Backbone.View.extend({
initialize: function (options) {
_.bindAll(this, 'tick');
// ...
self.dataSet = options.dataSet;
self.dataSet.on('add', this.newPoint, this);
self.tick();
},
newPoint: function(model) {
this.data.push(model);
},
tick: function () {
var self = this;
self.now = new Date();
var now = self.now;
var duration = self.duration;
var n = self.n;
var x = self.x;
var y = self.y;
var width = this.width;
var height = this.height;
x.axis = d3.svg.axis().scale(x).orient("bottom");
// update the domains
self.x.domain([now - (n - 2) * duration,
now - duration]);
self.y.domain([0, d3.max(self.dataSet.pluck('auth_amt'))]);
self.line = d3.svg.line()
.x(function(d) { return x(d.get('stamp')); })
.y(function(d) { return y(d.get('auth_amt')); });
// redraw the line
d3.select(".line")
.attr("d", self.line)
.attr("transform", null);
// slide the x-axis to the left
self.axis.transition()
.duration(duration)
.ease("linear")
.call(x.axis);
self.x = d3.time.scale()
.domain([now - (n-2) * duration, now - duration])
.range([0, width]);
var x = self.x;
// slide the line left
self.path.transition()
.duration(duration)
.ease("linear")
.attr("transform", "translate(" + x(now - (n - 1) * duration) + ")")
.each("end", self.tick);
}
});