2013-07-16 91 views
2

我正在製作一些使用NVD3.js構建的實時圖。我現在刷新每個圖表有以下:通過合併更新D3.js(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 datathis tutorial),但這對我來說並不理想,因爲一些最近的元素可能會被更新而不是最近的元素。

那麼我現在希望做的是搶說最近分鐘(通過查詢字符串(.qs)設置爲僅獲得最新分鐘,然後拿這個結果並執行以下操作:

  • 覆蓋有每個系列採用了最新的數據
  • 追加和元素相同的x值當在每個系列都在更新新的x值的任何現有元素
  • 到期元素過去某個年齡
  • 更新NVD3.js腳本w ith新數據。也許仍然使用新的合併對象的基準?

任何人都可以提出一個優雅的方式來執行上述合併操作?現有的數據對象,如下所示:

> 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可以做到這一點?

回答

-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) 
    });