Dynamic Dashboards: новый движок вёрстки¶
До Grafana 13 дашборд был статичным. Мы расставляли панели вручную в сетке 24×N и они оставались на своих местах навсегда. Изменили ширину экрана? Панели не подстроились и поехали. Добавили новую панель между двумя существующими? Опять поехали.
Dynamic Dashboards это принципиально новый движок вёрстки, встроенный в ядро Grafana и основанный на архитектуре Scenes. Начиная с 13.0 он включён по умолчанию для всех: и новых, и существующих дашбордов.
Что изменилось¶
Старый движок (Fixed Layout):
- Панели жёстко привязаны к координатам сетки (
gridPos). - При изменении ширины экрана панели не перекомпоновываются.
- Переместить панель между rows можно только вручную, по одной.
- Нет вложенности строк.
Новый движок (Dynamic Dashboards / Scenes):
- Панели внутри row автоматически распределяются по сетке.
- Responsive-дизайн: открыли дашборд на ноутбуке (1920px) и на ультрашироком мониторе (5120px) — панели перекомпоновались под ширину.
- Auto layout: Grafana сама управляет размерами и позициями панелей внутри row. Вы задаёте логическую структуру (row → панель), а движок сам решает физическое расположение.
- Вложенность строк до 3 уровней.
- Multi-select grouping: выделили несколько панелей → сгруппировали в row или tab одним действием.
- Section-level variables: переменные, которые действуют только в пределах одной строки или вкладки.
Auto Layout vs Custom Layout¶
У каждой строки (row) есть переключатель Layout:
Auto Layout¶
Grafana автоматически укладывает панели в сетку. Вы не управляете gridPos вручную. При ресайзе окна панели перекомпоновываются. Это суть Dynamic Dashboards.
Когда использовать: - Дашборд смотрят с разных устройств (ноутбук, монитор 32:9, телевизор в NOC). - Дашборд часто редактируется и панели добавляются/удаляются и не хочется каждый раз перетасовывать сетку. - Командные дашборды, где важна адаптивность, а не попиксельная точность.
Custom Layout¶
Вы полностью контролируете сетку: x, y, w, h для каждой панели. Ближе к старому поведению. Но даже в этом режиме панели находятся внутри rows и tabs — вы не можете разместить панель «в воздухе» вне контейнера.
Когда использовать: - Две панели должны всегда быть соседями (например, «RPS» и «Errors» друг над другом), и их взаимное расположение критично. - Дашборд, который после создания почти не редактируется.
Multi-select grouping¶
В режиме редактирования можно выделить несколько панелей одновременно: - Shift + клик по каждой панели. - Drag-выделение рамкой как в файловом менеджере.
Затем правый клик → Group into row или Group into tab. Панели мгновенно объединяются. Больше не нужно перетаскивать их по одной, особенно на длинных дашбордах.
Section-level Variables¶
Переменная, привязанная к конкретному row или tab, действует только внутри него. Панели за пределами этого row её не видят.
Зачем это нужно. Допустим, у вас дашборд на два сервиса: API Gateway и Database. У каждого свой row со своими панелями. Без section-level переменных одна переменная $instance влияет на весь дашборд — и в API-панелях, и в DB-панелях вы видите один и тот же инстанс. Чтобы разделить, приходилось делать два отдельных дашборда.
С section-level variables — одна переменная $instance в row «API Gateway», другая $instance в row «Database». Один дашборд, независимые фильтры в каждой секции.
В Grafana можно задать переменную как section-level через поле Scope → выбрать конкретный row.
Вложенность строк¶
Dynamic Dashboards поддерживают до 3 уровней вложенности:
Дашборд
└── Row «Инфраструктура»
├── Row «Базы данных»
│ ├── Row «PostgreSQL»
│ │ ├── Панель «QPS»
│ │ └── Панель «Slow Queries»
│ └── Панель «Redis Memory»
└── Row «Балансировщики»
├── Панель «Nginx RPS»
└── Панель «HAProxy Connections»
Свернули «Базы данных» — скрылись все БД-панели. Раскрыли «PostgreSQL» — увидели QPS и Slow Queries. Это работает как аккордеон: быстрая навигация по дашборду с сотней панелей без бесконечного скролла.
Как это выглядит в JSON¶
В JSON-модели дашборда Dynamic Dashboards не отменили gridPos — панели по-прежнему имеют координаты. Но при Auto Layout движок сам вычисляет gridPos при рендеринге, игнорируя сохранённые значения. При Custom Layout — использует то, что вы задали.
Новые поля, появившиеся с Dynamic Dashboards:
- layout у row: "auto" или "custom".
- sectionId у переменной — ссылка на row, если переменная section-level.
Миграция старых дашбордов¶
При открытии старого дашборда в Grafana 13.x: 1. Все панели автоматически помещаются в один root-row. 2. Layout строки устанавливается в Custom, чтобы сохранить исходное расположение. 3. Вы можете вручную переключить строку в Auto Layout, создать новые rows, перетащить в них панели.
Grafana не меняет JSON автоматически при открытии — миграция происходит в рантайме при рендеринге. Если вы сохраните дашборд, он сохранится в новом формате.
Что такое Scenes под капотом¶
Dynamic Dashboards — это пользовательская сторона. Под ней лежит архитектурное решение, принятое Grafana Labs ещё в 2023 году: переход от классического React-рендеринга дашбордов к библиотеке Scenes.
Почему отказались от React¶
Старый движок рендерил дашборд как одно большое React-дерево компонентов. Каждое изменение — клик по легенде, переключение переменной, добавление панели — вызывало пересчёт состояния и перерисовку всего дерева. На дашборде со 100 панелями это превращалось в заметные тормоза: интерфейс «думал», анимации дёргались, скролл подлагивал.
Scenes решает эту проблему архитектурно. Дашборд разбивается на независимые сцены (scenes), каждая из которых владеет своим состоянием и перерисовывается только когда затронута. Панель — это сцена. Row — это сцена. Даже легенда графика — это отдельная сцена. Изменение в одной не триггерит пересчёт всех остальных.
Как это работает¶
-
SceneGraph — декларативное дерево сцен. Вы описываете структуру дашборда как граф сцен, а не как набор React-компонентов. Grafana строит граф, когда пользователь открывает дашборд.
-
SceneObject — базовый элемент. Имеет состояние (
SceneObjectState) и модель (SceneObjectModel). PanelScene, RowScene, TabScene — всё это наследники SceneObject. -
Реактивность через SceneObjectState. Когда вы меняете переменную
$instance, состояние переменной обновляется. Все сцены, подписанные на эту переменную, получают уведомление и перерисовывают только себя. -
Вложенность. RowScene содержит PanelScene'ы. TabScene содержит RowScene'ы. Каждая сцена знает только о своих детях — нет глобального пересчёта.
-
SceneQueryRunner — специализированная сцена, которая управляет запросами к источнику данных. При изменении временного диапазона или переменной она перезапрашивает данные и уведомляет подписчиков.
Что это значит для вас¶
Как пользователю, вам всё это не нужно знать в деталях. Но понимание архитектуры помогает ответить на вопросы:
- «Почему дашборд на 200 панелей не тормозит?» — потому что одновременно рендерятся только видимые панели. Остальные ждут, пока пользователь до них доскроллит.
- «Почему section-level переменные работают быстро?» — потому что переменная привязана к состоянию конкретного RowScene, а не к глобальному состоянию дашборда.
- «Почему старые плагины могут сломаться?» — потому что Scenes используют другой API для взаимодействия с дашбордом. Если плагин написан под старый
DashboardModel, он не сможет читать состояние сцен.
Scenes и разработчики плагинов¶
Если вы разрабатываете кастомные визуализации для Grafana, Scenes — это новый фундамент, на котором нужно строить. Старое API панелей (PanelPlugin через React-компоненты) работает, но не интегрируется с реактивностью сцен: кастомная панель не узнает об изменении переменной, пока не будет перерисована целиком.
Для разработчиков есть @grafana/scenes — npm-пакет с инструментами для создания SceneObject'ов и интеграции с графом сцен дашборда.
- Dynamic Dashboards новый фундамент. В 13.x это поведение по умолчанию.
- Auto Layout экономит время при редактировании. Custom Layout — контроль когда он нужен.
- Section-level variables убирают необходимость плодить дашборды ради разных фильтров.
- Вложенность до 3 уровней — для иерархической навигации, не для эстетики.
- Очень хорошо подумайте об обновлении до 13.х на проде! Поднимите отдельный инстанс и там протестируйте. Обратного пути нет!