Сброс зума программно

В экосистеме Chart.js управление масштабом графика чаще всего реализуется через плагин масштабирования и панорамирования chartjs-plugin-zoom, который добавляет состояние зума поверх стандартного рендеринга. При работе с интерактивными графиками возникает необходимость программного сброса масштаба к исходному состоянию без пересоздания экземпляра диаграммы. Это достигается через API самого экземпляра Chart и внутренние методы плагина.

После применения масштабирования плагин изменяет диапазоны шкал (scales) и сохраняет исходные значения, чтобы обеспечить возможность отката. Внутри Chart.js нет отдельного «глобального» состояния зума — изменения выражаются через:

  • модифицированные границы min и max у осей;
  • трансформацию области отрисовки;
  • сохранённые значения исходного диапазона (если они доступны через плагин).

Каждое взаимодействие (колёсико мыши, drag-to-zoom, pinch) фактически приводит к пересчёту scale ticks и обновлению конфигурации без пересоздания графика.

Программный сброс масштаба через resetZoom

Основной механизм сброса реализован методом экземпляра диаграммы:

chart.resetZoom();

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

Внутренне процесс включает:

  • восстановление сохранённых min/max значений шкал;
  • очистку временных трансформаций зума;
  • триггер обновления рендера (update).

Поведение при наличии нескольких осей

Если диаграмма содержит несколько шкал (например, x, y, вторичные оси), сброс применяется ко всем осям, участвующим в зумировании.

Особенности:

  • каждая шкала восстанавливается независимо;
  • кастомные ограничения (min, max, suggestedMin, suggestedMax) учитываются при пересчёте;
  • если ось исключена из zoom configuration, она не изменяется.

Сброс только части масштаба

В ряде случаев требуется восстановление масштаба одной оси без влияния на другие. Для этого используется доступ к объекту scales:

chart.scales.x.resetLimits();
chart.update();

Однако стандартный API плагина чаще ограничивается полным сбросом, поэтому частичное управление обычно реализуется вручную через восстановление диапазонов:

chart.scales.x.min = initialMinX;
chart.scales.x.max = initialMaxX;
chart.update();

Хранение исходного диапазона

Чтобы программный сброс был предсказуемым, исходные границы шкал сохраняются отдельно от состояния графика:

const initialState = {
  xMin: chart.scales.x.min,
  xMax: chart.scales.x.max,
  yMin: chart.scales.y.min,
  yMax: chart.scales.y.max
};

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

chart.scales.x.min = initialState.xMin;
chart.scales.x.max = initialState.xMax;
chart.scales.y.min = initialState.yMin;
chart.scales.y.max = initialState.yMax;

chart.update();

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

Поведение resetZoom при кастомных конфигурациях

Если зум настроен с ограничениями:

zoom: {
  limits: {
    x: { min: 'original', max: 'original' },
    y: { min: 'original', max: 'original' }
  }
}

то сброс опирается на сохранённые «оригинальные» значения, которые фиксируются плагином при первом вычислении диапазонов. В этом случае resetZoom() не требует дополнительного хранения состояния.

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

Интеграция с анимацией обновления

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

chart.options.animation = {
  duration: 300,
  easing: 'easeOutQuart'
};

При вызове resetZoom() анимация применяется к изменению диапазонов осей, а не к самим данным. Это важно при больших наборах точек, где визуальная стабильность зависит от скорости пересчёта scale ticks.

Сброс через обновление конфигурации

Альтернативный способ полного восстановления состояния — пересборка шкал с последующим обновлением:

chart.options.scales.x.min = undefined;
chart.options.scales.x.max = undefined;
chart.options.scales.y.min = undefined;
chart.options.scales.y.max = undefined;

chart.update();

Такой подход приводит к повторному вычислению диапазонов на основе данных datasets и может отличаться от поведения resetZoom, который опирается на сохранённое состояние.

Работа с панорамированием и комбинированным состоянием

Если включено панорамирование, сброс зума не всегда затрагивает смещение (pan offset). В конфигурации плагина:

plugins: {
  zoom: {
    pan: {
      enabled: true
    },
    zoom: {
      wheel: {
        enabled: true
      }
    }
  }
}

состояние панорамирования может требовать отдельного сброса через:

chart.pan({ x: 0, y: 0 });
chart.resetZoom();

или через комбинированный вызов, если API расширен в конкретной версии плагина.

Поведение при обновлении данных

Если набор данных изменяется без пересоздания графика, сохранённый «оригинальный» диапазон может устаревать. В этом случае resetZoom() будет возвращать не к актуальным данным, а к старым границам, зафиксированным при предыдущем состоянии.

Для синхронизации используется принудительное обновление перед сбросом:

chart.data.datasets[0].data = newData;
chart.update();

chart.resetZoom();

Либо пересчёт шкал:

chart.options.scales.x.min = undefined;
chart.options.scales.y.max = undefined;

chart.update();
chart.resetZoom();

Множественные экземпляры диаграмм

При работе с несколькими графиками сброс масштаба выполняется независимо для каждого экземпляра:

charts.forEach(chart => chart.resetZoom());

Каждый объект Chart хранит собственное состояние шкал и не разделяет данные зума с другими экземплярами, даже при одинаковой конфигурации.

Особенности поведения в разных версиях плагина

Различия между версиями chartjs-plugin-zoom влияют на:

  • способ хранения оригинальных диапазонов;
  • наличие внутреннего кеша scale limits;
  • поддержку частичного сброса по осям;
  • поведение при динамическом обновлении данных.

В более ранних версиях сброс мог требовать ручного восстановления min/max, тогда как современные версии стандартизируют метод resetZoom() как основной механизм возврата состояния.