Backbone.js 使用主干的实时D3时间序列——图形移动速度比axis慢

Backbone.js 使用主干的实时D3时间序列——图形移动速度比axis慢,backbone.js,d3.js,Backbone.js,D3.js,我正在尝试用D3和主干构建一个实时时间序列。我遇到的问题是图形的移动速度比x轴慢。x轴准确地跟踪当前时间,所以我知道这是图形线的问题。我是根据Mike Bostock的示例(文章底部的最后一个图表)编写代码的。我似乎找不到问题所在——我的代码紧跟示例,只是用主干实现的 该应用程序使用websocket和事件聚合器进行设置,以便在接收到新数据点时,将数据点的模型添加到集合中,添加模型将触发“TimeseriesView”视图中的函数“newPoint”。“newPoint”将一个数字推送到一个数组

我正在尝试用D3和主干构建一个实时时间序列。我遇到的问题是图形的移动速度比x轴慢。x轴准确地跟踪当前时间,所以我知道这是图形线的问题。我是根据Mike Bostock的示例(文章底部的最后一个图表)编写代码的。我似乎找不到问题所在——我的代码紧跟示例,只是用主干实现的

该应用程序使用websocket和事件聚合器进行设置,以便在接收到新数据点时,将数据点的模型添加到集合中,添加模型将触发“TimeseriesView”视图中的函数“newPoint”。“newPoint”将一个数字推送到一个数组“data”,这就是绘制线的数据的来源。以下是相关观点。(如果代码有点凌乱,请原谅——我是主干网新手,所以我怀疑有更干净的方法可以做到这一点)


您基于代码的示例将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);
    }
});