Добавление точек через push и splice

Работа с динамическими данными в Chart.js основана на изменении массива data внутри набора данных (datasets). Любое обновление структуры массива напрямую влияет на отображение графика после вызова chart.update().

В основе механизма лежит обычный JavaScript-массив, поэтому применяются стандартные методы работы с массивами, включая push и splice. Эти методы позволяют как наращивать поток данных, так и реализовывать ограниченные по длине графики, где старые значения удаляются по мере поступления новых.

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

const data = {
  labels: ['1', '2', '3', '4'],
  datasets: [
    {
      label: 'Температура',
      data: [12, 19, 3, 5],
      borderColor: 'blue'
    }
  ]
};

const config = {
  type: 'line',
  data,
};

const chart = new Chart(document.getElementById('canvas'), config);

Массив data внутри datasets[0] является ключевой точкой модификации при работе с динамическими значениями.

Добавление точек с использованием push

Метод push используется для добавления новых значений в конец массива. В контексте Chart.js это приводит к расширению графика по оси X при условии синхронного обновления меток labels.

chart.data.labels.push('5');
chart.data.datasets[0].data.push(10);

chart.update();

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

При работе с потоковыми данными часто применяется одновременное обновление нескольких наборов данных:

function addPoint(label, value) {
  chart.data.labels.push(label);
  chart.data.datasets[0].data.push(value);

  chart.update();
}

Особенность заключается в необходимости поддержания синхронности массивов labels и data. Несоответствие длины приводит к некорректному отображению точек.

Управление памятью и ограничение длины данных

При длительной работе графика массивы могут бесконечно увеличиваться. Это приводит к ухудшению производительности. Для ограничения длины используется комбинация push и splice.

Подход реализуется как «скользящее окно данных», где новые значения добавляются в конец, а старые удаляются из начала.

const MAX_POINTS = 20;

function addPoint(label, value) {
  chart.data.labels.push(label);
  chart.data.datasets[0].data.push(value);

  if (chart.data.labels.length > MAX_POINTS) {
    chart.data.labels.splice(0, 1);
    chart.data.datasets[0].data.splice(0, 1);
  }

  chart.update();
}

Метод splice(0, 1) удаляет первый элемент массива, сдвигая остальные значения влево. В результате график сохраняет фиксированную длину, отображая только актуальный диапазон данных.

Метод splice для удаления и замены данных

Метод splice позволяет не только удалять элементы, но и заменять их. В Chart.js это применяется для корректировки уже существующих точек без полной перерисовки структуры массива.

Удаление диапазона значений

chart.data.datasets[0].data.splice(2, 3);
chart.update();

В данном случае удаляются три элемента, начиная с индекса 2.

Замена значений

chart.data.datasets[0].data.splice(1, 1, 99);
chart.update();

Элемент с индексом 1 заменяется на значение 99. Такая операция используется при корректировке данных, поступивших с задержкой или требующих пересчёта.

Сценарии потокового обновления данных

При построении графиков реального времени методы push и splice используются совместно с таймерами или WebSocket-потоками.

Пример с интервалом:

setInterval(() => {
  const label = new Date().toLocaleTimeString();
  const value = Math.floor(Math.random() * 100);

  chart.data.labels.push(label);
  chart.data.datasets[0].data.push(value);

  if (chart.data.labels.length > 30) {
    chart.data.labels.splice(0, 1);
    chart.data.datasets[0].data.splice(0, 1);
  }

  chart.update();
}, 1000);

Такая схема обеспечивает непрерывное движение графика, где отображается только последние 30 значений.

Оптимизация обновлений

Частые вызовы chart.update() могут снижать производительность. В Chart.js поддерживается частичное обновление с указанием режима:

chart.update('none');

Это позволяет избежать анимации и ускоряет рендеринг при частых изменениях массива данных.

Дополнительно используется пакетное обновление данных:

chart.data.datasets[0].data.push(42);
chart.data.datasets[0].data.push(43);
chart.data.datasets[0].data.push(44);

chart.update();

Группировка операций перед единственным обновлением уменьшает нагрузку на перерисовку.

Работа с несколькими наборами данных

При наличии нескольких линий необходимо синхронно изменять каждый dataset:

chart.data.labels.push('6');

chart.data.datasets[0].data.push(10);
chart.data.datasets[1].data.push(20);

chart.update();

При использовании splice удаление также должно применяться ко всем наборам данных:

chart.data.labels.splice(0, 1);

chart.data.datasets.forEach(dataset => {
  dataset.data.splice(0, 1);
});

chart.update();

Несогласованное изменение массивов приводит к смещению точек между сериями.

Особенности работы с категориальной осью

При использовании категориальной шкалы (type: 'category') массив labels играет роль координатной сетки. Каждое добавление через push фактически расширяет ось X.

Если используется временная шкала (time), метки могут быть объектами даты:

chart.data.labels.push(new Date());
chart.data.datasets[0].data.push(15);

chart.update();

В этом случае splice продолжает работать аналогично, удаляя старые точки независимо от их типа.

Синхронизация данных и меток

Критическим условием корректной работы является строгая синхронизация:

  • длина labels равна длине data
  • операции push и splice применяются одновременно
  • обновление графика выполняется после завершения всех изменений

Нарушение синхронизации приводит к визуальным артефактам: смещению точек, пропускам значений или неверной интерпретации оси X.

Комбинированные операции над массивом

В сложных сценариях применяются цепочки операций:

function updateChart(label, value) {
  chart.data.labels.push(label);
  chart.data.datasets[0].data.push(value);

  if (chart.data.labels.length > 50) {
    chart.data.labels.splice(0, 1);
    chart.data.datasets[0].data.splice(0, 1);
  }

  chart.data.datasets[0].data[chart.data.datasets[0].data.length - 1] =
    chart.data.datasets[0].data.at(-1) * 1.1;

  chart.update();
}

Такая логика демонстрирует возможность сочетания добавления, удаления и модификации значений в одном цикле обновления.

Поведение при анимации

Chart.js использует анимацию переходов между состояниями массива. При использовании push добавление новой точки отображается как движение линии вправо. При splice происходит перерасчёт сегмента графика с плавным исчезновением удалённых значений.

При необходимости отключения анимации используется:

const config = {
  type: 'line',
  data,
  options: {
    animation: false
  }
};

Отключение анимации ускоряет работу при интенсивных обновлениях массива данных.

Работа с буферными структурами данных

Для более сложных систем потоковой обработки применяется промежуточный буфер:

const buffer = [];

function receiveData(value) {
  buffer.push(value);

  if (buffer.length >= 10) {
    chart.data.labels.push(Date.now());
    chart.data.datasets[0].data.push(buffer.shift());

    if (chart.data.labels.length > 30) {
      chart.data.labels.splice(0, 1);
      chart.data.datasets[0].data.splice(0, 1);
    }

    chart.update();
  }
}

Буферизация позволяет сглаживать поток данных и контролировать частоту обновления графика.

Работа с push и splice формирует основу динамических визуализаций в Chart.js, обеспечивая гибкое управление временными рядами и непрерывными потоками значений.