1

複数のxilyフィードからデータを取得し、人力車でプロットするプロットWebページを構築しようとしています( D3に基づく)。私が抱えている問題は、呼び出し関数の外でサーバーから返されたデータにアクセスできないことです。私はjsが初めてなので、呼び出しの非同期の性質を処理する方法がわかりません。を呼び出してxively.feed.history()履歴データのさまざまなセクションを取得し、それらを 1 つのグラフに連結したいと思います。とにかく、ここに私が試したことに似たものがあります。xivelyチュートリアルに基づいています

xively.setKey('xxxx my key ')
// Replace with your own values  
var feedID        = 12345678,          // Feed ID  
    selector      = "#myelement";   // Your element on the page  

var series = [];
xively.feed.history(feedID, {  duration: "10days", interval: 1800 ,limit: 1000}, function (mydata) {
    mydata.datastreams.forEach( function(stream){
        if ((stream.id == "tempinside") || (stream.id == "tempoutside")) {
            var points = [];
           stream.datapoints.forEach( function(datapoint){
                points.push({x: new Date(datapoint.at).getTime()/1000.0, y: parseFloat(datapoint.value)});
            // Add Datapoints Array to Graph Series Array
            });
            series.push({
                name: stream.id,
                data: points
            });
        };
    });


    var graph2 = new Rickshaw.Graph( {
        element: document.querySelector("#chart2"), 
        width: 600, 
        height: 400, 
        renderer: 'line',
        series: [{
            data: series[0].data,
            name: series[0].name,
            color: 'red'
            },{
            data: series[1].data,
            name: series[1].name,
            color: 'blue'
            }]
     })
})

私が言ったように、私はJavaScriptが初めてなので、何かが足りないかもしれません。関数のコールバック部分内にグラフを配置すると、グラフは正常にxively.feed.history機能します。関数を複数回呼び出そうとすると、グラフ コードが実行されるまでにデータの準備ができていません。

4

1 に答える 1

0

わかりましたので、私はそれを機能させ、そのサブセットをここに置いて、他の人が私がどのようにそれを行ったかを見ることができるようにしました.

var starttime = moment().subtract("day", 3);
series['tempoutside']=[
 {x:starttime.subtract("second",2).unix(),y:15},
 {x:starttime.subtract("second",1).unix(),y:15}
 ];


graph = new Rickshaw.Graph({
    element: document.querySelector("#chart"),
    height: 400,
    width: 600,
    renderer: 'line',
    interpolation: 'step-before',
    series: new Rickshaw.Series([
        {
            name: 'temperature',
            data: series['tempoutside'],
            color: 'blue',
        }
    ], series)
});

xively.datastream.history( "123456789", "tempoutside", query, loadData);

function loadData(data) {
    //console.log('Getting ' + data.id + 'data from Xively');
    if (data.datapoints != undefined){
        //console.log('received ' + data.datapoints.length +' datapoints');
        lastdata=data;
        var filtedData = data.datapoints.filter(function(x) { return (x.value >0.005); });
        for (var i=0; i < filtedData.length; i++ ) {
            var date = moment(filtedData[i].at);
            var value = parseFloat(filtedData[i].value+0.000001);
        series[data.id].push({x: date.unix(), y: value});
        }
        graph.render();
    }
}

私の最終的なコードでは、series['tempoutside']配列からダミーの初期化値も削除しました.pop()。データがxilyから返される前にグラフが最初に構築されるため、配列にそれらが必要でした。データが返されると、xively.datastream.history()関数はデータを配列loaddata()にプッシュするコールバックを呼び出します。seriesまた、グラフの構築時に配列が参照として渡されるため、データをグラフ系列配列にプッシュする必要がないことも理解していませんでした。配列を更新してから呼び出すgraph.render()と、すべて再プロットされます。勝つ!これは、1 回の API 呼び出し (1000 データ ポイントに制限) で利用できるよりも多くのデータを取得するために、Xively に対して複数の呼び出しを行うことができることを意味します。プロットする前に x 値でデータをソートすることを忘れないでください....

于 2013-12-06T15:23:20.797 に答える