Изменить несколько Highcharts в последовательном цикле - PullRequest
2 голосов
/ 28 марта 2019

Сводка

В настоящее время я работаю в среде, имеющей около 14+ графиков акций на данной странице (каждая с 20 000+ уникальными точками данных, некоторые намного больше).У меня есть определенные глобальные «переключатели», которые влияют, например, на то, какие серии отображаются, параметры диаграммы или крайние значения осей (на всех графиках).Учитывая, что только один график виден пользователю за один раз, я хотел бы рассматривать обновление графиков как очередь, в которой я сначала обновляю один график, а затем - вторую и т. Д.

Моя цель:Вызывайте Highcharts.Chart.redraw () последовательно в цикле (т. е. вызывайте перерисовку для каждого графика на странице, по одному - так, чтобы первый график в моем списке графиков перерисовывался первым).Обратите внимание, что упорядочение списка графиков создается динамически, и о нем уже позаботились.

Фон

До сих пор я много читал об обещаниях JavaScript, которые я использовалв прошлом для объединения вызовов AJAX.Как обсуждается в следующих ссылках:

Я также прочитал некоторые более общие вопросы, связанные с Обещаниями в циклах:

Код / Подробности

Я пробовал множество решений, иполагаю, что проблема заключается в том, чтобы заставить функцию перерисовки Highcharts - или действия, вызывающие ее (например, Chart.update (), Series.setVisible (), Axis.setExtremes ()) - вернуть обещание.

Я загрузил что-то вроде оболочки здесь , которая позволяет запускать событие и видеть, что каждый график по сути обновляется сразу.


ДляНапример, что-то вроде следующего:

$(Highcharts.charts).each(function(i, chart) {
    console.log(i);
    // decide what to do with the chart
    // update Series, Chart options, Axis extremes... etc.
    chart.redraw(); // call redraw at the end
})

будет выводить:

> 1, 2, 3, ..., n // pause, then charts would redraw()

Вероятно, важно упомянуть, что, хотя приведенное выше выглядит отзывчивым, в моей среде, вероятно, где-то естьмежду 2-5 секундной задержкой между нажатием переключателя и окончанием события перерисовки для графиков.

Я не могу понять, как заставить цикл ждать, пока каждый график завершит перерисовку, прежде чем перейти к следующему графику в списке.

Любая помощь, которая может быть оказана, будет принята с благодарностью.

Ответы [ 2 ]

2 голосов
/ 28 марта 2019

Если я понимаю, что вы имеете в виду, вы можете достичь этого, обернув код, который вы имеете в триггере, в setTimeout (со значением времени ожидания 0), в свою очередь обернутый в новое Обещание

с использованием async / await это будет что-то вроде

$('#trigger').click(async (e) => {
    for (let chart of Highcharts.charts) {
        await new Promise(resolve => setTimeout(() => {
            chart.series.forEach(series => series.setVisible(undefined, false));
            chart.redraw();
            resolve();
        }, 0));
    }
});
1 голос
/ 28 марта 2019

ОБЩЕЕ РЕШЕНИЕ

Обычно, если вы хотите последовательно соединять обещания в цикле, вы можете использовать следующий формат

function promiseChain(i) {
    return new Promise(resolve => {
        /* DO ASYNC STUFF */

        // Resolve with some result if the next item in the chain needs it
        return resolve("OK");
    });
}

let p = Promise.resolve(null);

for (let i = 0; i < 5; i++) {
    p = p.then(prevResult => {
        if (prevResult) {
            // Do stuff with prevResult if needed
        }

        // Chain next item
        return promiseChain(i);
    });
}

Пример с логами

Это будет записывать номера 0-4, по одному, ожидая одну секунду между каждым.

function promiseChain(i) {
    return new Promise(resolve => {
        setTimeout(() => {
            console.log(i);
            return resolve("OK");
        }, 1000)
    });
}

let p = Promise.resolve(null);

for (let i = 0; i < 5; i++) {
    p = p.then(prevResult => {
        if (prevResult) {
            // Do stuff with prevResult if needed
        }

        return promiseChain(i);
    });
}
...