Порядок выполнения хуков в Chart.js определяется жизненным циклом графика и тем, на каком этапе происходит подготовка данных, расчёт геометрии и отрисовка на canvas. Плагины и внутренние механизмы библиотеки используют строго фиксированную последовательность вызовов, что позволяет предсказуемо вмешиваться в процесс рендеринга.
Жизненный цикл графика делится на несколько крупных фаз:
Каждая фаза содержит собственные хуки, которые вызываются в строго
определённом порядке. Нарушение логики последовательности невозможно,
так как Chart.js управляет вызовами централизованно через ядро
Animator и систему плагинов.
На этапе создания экземпляра графика выполняется следующий порядок:
beforeInitafterInitbeforeInit вызывается до того, как создаются масштабы,
элементы данных и layout. На этом этапе допустимо модифицировать входной
конфиг, добавлять или удалять плагины, подменять наборы данных.
afterInit срабатывает после завершения базовой
подготовки структуры графика. В этот момент уже существуют scales,
datasets и элементы представления, но рендер ещё не начался.
Обновление графика инициируется при изменении данных, опций или внешнего состояния. Последовательность выглядит следующим образом:
beforeUpdateafterUpdatebeforeUpdate используется для вмешательства в процесс до
перерасчёта метрик. Важно, что изменения, сделанные здесь, влияют на
весь последующий pipeline.
После перерасчёта данных и пересборки элементов вызывается
afterUpdate. На этом этапе уже готовы новые координаты, но
отрисовка ещё не выполнена.
Фаза layout отвечает за распределение пространства и вычисление размеров элементов.
Порядок выполнения:
beforeLayoutafterLayoutbeforeLayout позволяет вмешиваться в размеры осей,
padding, area chart bounds. Изменения здесь могут привести к перерасчёту
геометрии.
afterLayout фиксирует результат вычислений макета. Все
элементы получают финальные размеры, но canvas ещё не рисуется.
Отдельная подфаза связана с пересчётом dataset-ов:
beforeDatasetsUpdateafterDatasetsUpdateЭта часть особенно важна для кастомных элементов и сложных визуализаций, где каждый dataset имеет собственную логику преобразования данных в графические элементы.
beforeDatasetsUpdate позволяет вмешаться до пересчёта
элементов линий, баров, точек и других визуальных примитивов.
afterDatasetsUpdate фиксирует результат подготовки
наборов данных перед отрисовкой.
Самая сложная и важная часть жизненного цикла связана с отрисовкой на canvas. Здесь порядок строго детерминирован:
beforeDrawbeforeDatasetsDrawafterDatasetsDrawafterDrawbeforeDraw вызывается перед началом любой графической
операции. В этот момент canvas уже очищен, но ничего ещё не нарисовано.
Этот хук часто используется для кастомного фона или подготовительных
эффектов.
beforeDatasetsDraw срабатывает непосредственно перед
отрисовкой всех dataset-ов. Именно здесь находятся линии, бары, точки и
другие основные элементы графика.
afterDatasetsDraw вызывается сразу после завершения
отрисовки данных, но до финальных декоративных слоёв.
afterDraw завершает полный цикл рендеринга. В этот
момент canvas полностью готов и может быть дополнен внешними слоями,
аннотациями или сторонними эффектами.
Помимо основных фаз существуют вспомогательные события, которые встроены в жизненный цикл:
resize — вызывается при изменении размеров
контейнераdestroy — вызывается при удалении экземпляра
графикаresize запускает частичный пересчёт layout и перерисовку
без полной переинициализации. Порядок выполнения внутри resize повторяет
часть pipeline: layout → datasets update → draw.
destroy очищает ресурсы, удаляет обработчики событий и
освобождает память. После него никакие хуки больше не вызываются.
Каждый хук может быть реализован в плагинах, и порядок их вызова зависит от регистрации. Chart.js вызывает плагины последовательно в порядке их подключения:
Если несколько плагинов реализуют один и тот же хук, они выполняются строго по очереди, без параллельных или асинхронных пересечений.
Полный цикл одного обновления графика объединяет все фазы:
Каждая фаза может быть прервана или модифицирована через соответствующий хук, но порядок фаз остаётся неизменным.
Все хуки выполняются синхронно в рамках одного call stack. Асинхронные операции внутри хуков не блокируют сам Chart.js pipeline, но могут привести к рассинхронизации состояния, если изменяют данные после завершения текущего кадра.
Из-за синхронной природы выполнения порядок строго линейный:
Конфигурация графика не меняет порядок хуков, но влияет на их количество и глубину:
Структура pipeline остаётся неизменной, изменяется только объём вычислений внутри каждого этапа