2

我正在研究一些使用 NVD3.js 构建的实时图表。我目前使用以下内容刷新每个图表:

function reDraw(c) {
    d3.json(c.qs, function(data) {
        d3.select(c.svg)
        .datum(data)
        .transition().duration(500)
        .call(c.chart);
    });
}

c看起来像:

function Chart(svg, qs, chart) {
    this.qs = qs;
    this.svg = svg;
    this.ylabel;
    this.chart;
}

这工作得很好,但每次刷新我都会再次获取整个时间序列。只抓取最近的元素并更新每个图表会更有效。有通过附加元素来执行此操作的示例(例如,此答案NVD3 line chart with realtime data本教程),但这对我来说并不理想,因为可能会更新一些不是最新元素的最近元素。

所以我想做的是抓住最近一分钟(通过设置查询字符串(.qs)只获取最近一分钟,然后获取该结果并执行以下操作:

  • 用最新数据覆盖每个系列具有相同 x 值的任何现有元素
  • 当每个系列的更新中有新的 x 值时追加和元素
  • 过期元素超过一定年龄
  • 使用新数据更新 NVD3.js 脚本。也许仍将基准与新的合并对象一起使用?

谁能建议一种优雅的方式来执行上述合并操作?现有数据对象如下所示:

> d3.select(perf.svg).data()[0]
[
Object
key: "TrAvg"
values: Array[181]
__proto__: Object
, 
Object
key: "RedisDurationMsAvg"
values: Array[181]
__proto__: Object
, 
Object
key: "SqlDurationMsAvg"
values: Array[181]
__proto__: Object
]
> d3.select(perf.svg).data()[0][0]['values'][0]
Object {x: 1373979220000, y: 22, series: 0}
> d3.select(perf.svg).data()[0][1]['values'][0]
Object {x: 1373979650000, y: 2, series: 1}

返回的对象如下所示(除了每个对象可能只有 6 个元素左右):

> d3.json(perf.qs, function(data) { foo = data })
Object {header: function, mimeType: function, response: function, get: function, post: function…}
> foo
[
Object
, 
Object
, 
Object
]
> foo[0]
Object {key: "TrAvg", values: Array[181]}
> foo[0]['values'][0]
Object {x: 1373980220000, y: 49}

在这个较新的对象中,缺少系列值 - 也许需要添加,或者 D3 可以做到吗?

4

1 回答 1

-1

暂时我用linq.js来执行这个操作,然后.datum()每次都用来绑定一个新的数据集。该解决方案不是很优雅,但它似乎确实起作用:

function reDraw2(c, partial) {
    if (partial) {
        qs = c.qs.replace(/minago=[0-9]+/, "minago=1")
    } else {
        qs = c.qs
    }
    d3.json(qs, function(new_data) {
        chart = d3.select(c.svg)
        if (c.ctype == "ts" && partial) {
            thirtyminago = new Date().getTime() - (60*30*1000);
            old_data = chart.data()[0]
            var union = new Array();
            for (var i = 0; i < old_data.length; i++) {
                var existing = Enumerable.From(old_data[i]['values']);
                var update = Enumerable.From(new_data[i]['values']);
                oldfoo = existing
                newfoo = update
                var temp = {}
                temp['key'] = old_data[i]['key']
                temp['values'] = update.Union(existing, "$.x").Where("$.x >" + thirtyminago).OrderBy("$.x").Select().ToArray();
                union[i] = temp

            }
            chart.datum(union)
        } else {
            chart.datum(new_data)
        }
        chart.call(c.chart)
    });
于 2013-07-17T17:09:48.450 回答