3

Meteor 0.8.0を使用している場合、新しいデータが到着したときにどのようにフロー チャートを更新しますか? Meteor-flotの例を見ましたが、ページのタイマーを介して偽のデータで更新されています。コレクションからのリアクティブなデータではありません。

これまでのところ、次のようなものがあります。

// returns an object with a label and an array of timestamp, value
// like { label:'test', data:[[1397605016000, 1332],[1397605616000,1356],[1397606216000,1380]]}
Template.example.helpers({
  readings: function(){
    DataReadings.find();
  }
});

Template.example.rendered = function() {
  $.plot ($("#flot"), [this.data.data], {
    series: {
      lines: {
        show: true
      },
      points: {
        show: true
      }
    },
    xaxis: {
      mode: 'time',
      timeformat: '%H:%M'
    }
  });
};

これは最初のレンダリングにはうまく機能しますが、新しいデータが到着した後 (約 5 分ごと) にチャートを更新する方法がわかりません。では、新しいデータが到着したときに plot.setData(newData) & plot.draw() を呼び出す方法は?

4

2 に答える 2

1

これを行う 1 つの方法は、カーソル/コレクション オブザーバーを使用することです。Meteor アプリでこのメソッドを使用して Flot チャートを更新していますが、うまく機能します。

関数で最初のプロットを作成した後Template.example.rendered、コレクションに新しいドキュメントが追加 (または削除) されるたびにチャートを更新するカーソル オブザーバーを追加します。

//  Subscribe to collection (or no need to do this if it's already done on your route)
Meteor.subscribe('dataReadings', someFilterVarOrNot);

//  Add a cursor observer for all documents added with a date greater 
//  than right now (uses moment.js)
//  (If you don't do this, you'll get an "added" fire for every document 
//  that's ALREADY been added - not sure why it does this but it does
dataReadingsObserveHandle = DataReadings.find({
  createdAt: {$gte: moment().toDate()}}).observe({

    //  Fires anytime a new document is added
    added: function(dataReading) {
      $('#flot').data("plot").setData(dataReading.data);
      $('#flot').data("plot").draw();

      //  Or setup whatever query/calculation you need to assemble a 
      //  new data set for your chart, there are also some other observers like
      //  observeChanges() which let you see how a document has changed versus
      //  being added or removed
    },

    //  Fires anytime a document is removed
    removed: function(removedDataReading) {
      //  Update and redraw chart like above...
  }
});

dataReadingsObserveHandleは意図的にグローバルであるため、後で破棄できます。これは、明らかにコレクション オブザーバーがサーバーを集中的に使用するためです。破棄する必要がある場所にスコープ アクセスできる場合、これは必ずしもグローバルである必要はありません。

//  Once your chart no longer needs to be updated call...
dataReadingsObserveHandle.stop();
dataReadingsObserveHandle = null;

ユーザーが別のテンプレートに移動し、チャートを見ていない場合、オブザーバーは自動的に破棄されると思います。詳細については、 http://docs.meteor.com/#observeを参照してください。

ReactiveVarorを使用してこれを行う他の方法について知りたいですDeps.dependency。特にそれらがより効率的である場合

于 2014-10-22T22:40:49.120 に答える
0

私はこのアプローチを試みました。完璧ではありませんが、かなり簡潔に言えば

<template name="data">
<li> A : {{ A }}, B : {{ B }}
 <div id="ph_{{A}}_{{B}}" style="width:100%;height:100px;" ></div>
 {{ PlotMe this }}
</li>
</template>

Handlebars.registerHelper("PlotMe", function(element) {

  setTimeout( function() 
  {
    $.plot( "#ph_"+ element.A+"_"+element.B , [element.data] ,
    {xaxis: {mode: "time", },yaxis: {min: 0, }});
    } , 1 );
});

setTimeout は、まだレンダリングされていないために無効な div のサイズに関する Flot のエラーを回避する場合があります。flot は新しいデータで更新されます。

于 2014-12-19T10:07:07.677 に答える