График в реальном времени не обновляется в Rickshaw Graph

Мой код для создания графика выглядит следующим образом:

var allVenues = [];
var seriesData = [];

var callGraph = function () {
    var where = jQuery('#hdnVal').val();
    jQuery.ajax({
           url: "PopulateTable",
           type: 'GET',
           data: {
                 'where': where
           },
           dataType: "json",
           async: false,
           success: function (responseJson) {
                  if (responseJson != null) {
                     jQuery.each(responseJson, function (key, value) {
                            jQuery('#hdnVal').val(value['date']);
                     });
                     allVenues.push(responseJson);
                  }
              }
     });
     var length = 0;
     var length1 = 0;

     var dataXY = [];

     var dataX = [];
     length = allVenues.length;
     for (var i = 0; i < length; i++) {
         length1 = allVenues[i].length;
         for (var j = 0; j < length1; j++) {
             dataX.push([returnTimestamp(allVenues[i][j].date), returnDate(allVenues[i][j].date)]);
             dataXY.push({x: returnTimestamp(allVenues[i][j].date), y: allVenues[i][j].price});
         }
     }
     seriesData = [dataXY];
} ;
callGraph() ;
var palette = new Rickshaw.Color.Palette({scheme: 'classic9'});
var graph = new Rickshaw.Graph({
   element: document.getElementById("chart"),
   width: 900,
   height: 500,
   renderer: 'area',
   stroke: true,
   preserve: true,
   series: [
     {
        color: palette.color(),
        data: seriesData[0],
        name: 'Price'
     }
   ]
});
graph.render();

setInterval(function () {
   callGraph();
   graph.series.addData(seriesData);
   graph.render();
}, 5000);

В этом коде мой массив "seriesData" обновляется, но график не обновляется. Сгенерированный массив json хорош для графика во время загрузки страницы, но когда я применяю интервал, график не обновляется.


person Navin Nakum    schedule 27.02.2016    source источник
comment
Вы уверены, что хотите повторить allVenues и выполнить graph.series.addData()? Это может привести к дублированию данных в graph.series.   -  person Roamer-1888    schedule 27.02.2016
comment
Да, я просто каждый раз получаю новые данные в allVenues. Но не получать обновления на графике.   -  person Navin Nakum    schedule 27.02.2016


Ответы (1)


В отсутствие достойной документации Rickshaw и примеров асинхронного обновления трудно сказать, что будет работать, а что нет.

Представляется ненужным поддерживать массив allVenues, если только вы не хотите перестраивать график с нуля при каждом обновлении. Достаточно добавить данные серии и вызвать .render().

Вы, вероятно, хотите что-то вроде этого:

(function() { // IIFE to isolate from the Global name space, if not otherwise wrapped.
    var jqXHR;
    var errors = {
        count = 0,
        threshold: 10 // number of consecutive error after which the update cycle should die
    }
    var palette = new Rickshaw.Color.Palette({ scheme: 'classic9' });
    var lastDate = jQuery('#hdnVal').val();
    var seriesData = []; // <<<<<<<<<<<< add
    var graph = new Rickshaw.Graph({
        element: document.getElementById('chart'),
        width: 900,
        height: 500,
        renderer: 'area',
        stroke: true,
        preserve: true,
        series: [{
            color: palette.color(),
            data: seriesData, // <<<<<<<<<<<< change
            name: 'Price'
        }];
    });

    var callGraph = function (val) {
        if(jqXHR) {
            // In case previous ajax has not responded.
            jqXHR.abort(); // Abort previous ajax and force its error handler to fire.
            return; // Allow the error handler to report the abort error then retry/die.
        }
        jqXHR = jQuery.ajax({
            url: "PopulateTable",
            type: 'GET',
            data: { 'where': val },
            dataType: "json"
        }).then(function (responseJson) { // ajax success handler
            if (responseJson) {
                // Here's the major guess!
                // ***** start: delete *****
                // graph.series.addData(responseJson.map(function(item) {
                    // lastDate = item.date;
                    // return { x: returnTimestamp(item.date), y: item.price };
                // }));
                // ***** end: delete *****

                // ***** start: add *****
                responseJson.forEach(function(item) {
                    lastDate = item.date;
                    seriesData.push({ x: returnTimestamp(item.date), y: item.price });
                });
                // ***** end: add *****
            }
            graph.render();
            errors.count = 0; //reset errorCount
            setTimeout(function() {
                callGraph(lastDate);
            }, 5000);
        }, function(jqXHR, textStatus, errorThrown) { // ajax error handler
            errors.count += 1;
            console.log("callGraph()", textStatus, "errorCount: " + errorCount);
            if(error.count < errors.threshold) {
                setTimeout(function() {
                    callGraph(lastDate); // retry with same lastDate as previous ajax call.
                }, 5000);
            } else {
                // Allow the update cycle to die
                console.log("callGraph() errorTheshold reached");
            }
        });
    };

    callGraph(lastDate);
})();

Обратите внимание, что из-за асинхронности AJAX обновление графа и стимулирование следующего этапа цикла обновления выполняется в обработчике успеха AJAX. setTimeout() используется вместо setInterval(), что более громоздко, когда дело доходит до уничтожения цикла.

Если он по-прежнему не работает, то, вероятно, виновата часть graph.series.addData(...). Возможно, вам просто потребуется отладка, но в качестве альтернативы вы можете попробовать два предложения здесь: /а>

person Roamer-1888    schedule 27.02.2016
comment
Привет, спасибо за ответ, но я получаю эту ошибку graph.series.addData is undefined - person Navin Nakum; 28.02.2016
comment
Моя ссылка на эту строку - это код в вопросе. Если это не сработает, попробуйте два предложения здесь - stackoverflow.com/a/19126145/3478010. Я бы посоветовал вам сначала попробовать второе предложение. - person Roamer-1888; 28.02.2016
comment
Да, я понял вашу точку зрения, но как применить ее к моему коду. Можете ли вы помочь мне с тем же, пожалуйста? - person Navin Nakum; 28.02.2016
comment
Хорошо, я внес несколько правок выше, но имейте в виду, что я только предлагаю. Я не специалист по рикше и ничего не проверял. Возможно, вам потребуется отладка. - person Roamer-1888; 28.02.2016
comment
Хорошо, но функция callGraph не вызывается каждые 5 секунд. Он просто звонит в первый раз, а потом ничего. пожалуйста, посоветуйте это. Спасибо - person Navin Nakum; 29.02.2016
comment
Навин, только потому, что я сделал несколько предложений, не переставай думать сам. Это все еще твоя проблема, а не моя. - person Roamer-1888; 29.02.2016
comment
Эй, Роамер, я решил эту проблему. Большое спасибо. - person Navin Nakum; 29.02.2016
comment
Навин, когда у тебя будет время, ты сможешь опубликовать и принять свой собственный ответ. Это совершенно нормально при переполнении стека. С наилучшими пожеланиями. - person Roamer-1888; 29.02.2016