Вопрос

I am trying to build a plotting webpage which gets data from multiple xively feeds and plots them with Rickshaw (based on D3). The problem I have is that I can't access the data which is returned from the server outside of the calling function. I'm new to js so I'm not sure how to deal with the asynchronous nature of the calls. I would like to call the xively.feed.history() to get various sections of historical data and them concatenate them onto a single graph. Anyway, here is something similar to what I've tried. It based on the xively tutorial

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'
            }]
     })
})

As I said, I'm new to javascript so maybe I'm missing something. The graph works fine if it is placed inside the callback part of the xively.feed.history function. If I try to make multiple calls to the function then the data isn't ready by the time the graph code runs.

Это было полезно?

Решение

Ok, so I made it work and I've put a subset of it here so others can see how I did it.

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

In my final code I also removed the dummy initialisation values from the series['tempoutside'] array with .pop(). I needed them in the array because the graph gets built first off before the data has been returned from xively. When the data does return, the xively.datastream.history() function calls the loaddata() callback which pushes the data into the series array. Also, I'd not understood that you don't need to push data into the graph series array, because the array is passed as a reference when the graph is built. Update the array and then call graph.render() and it replots it all. Win! This means that multiple calls can be made to Xively to get more data than is available with one API call (limited to 1000 data points). Remember to sort the data by x value before plotting....

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top