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 折れ線グラフこのチュートリアル) が、最新の要素ではないいくつかの最近の要素が更新される可能性があるため、これは私にとって理想的ではありません。

だから私がやろうとしているのは、最新の分を取得することです(クエリ文字列(.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 に答える