Обработка пользовательских действий

Обработка пользовательских действий в Kepler.gl строится вокруг реактивной архитектуры, где каждое взаимодействие пользователя транслируется в состояние приложения через единый поток данных. Это позволяет синхронизировать карту, слои, фильтры и визуализации без прямого императивного управления DOM или WebGL-сценой.

Система взаимодействий в Kepler.gl опирается на связку React + Redux + deck.gl. Пользовательские действия не обрабатываются напрямую внутри визуальных компонентов — они проходят через слой действий (actions), которые изменяют глобальное состояние.

Основные принципы:

  • Единый источник состояния — store Redux
  • Декларативные изменения — через actions
  • Изоляция визуализации — deck.gl отвечает только за рендер
  • Синхронизация UI и карты — через selectors

Каждое событие, будь то клик по объекту или изменение фильтра, превращается в action, который обновляет состояние и вызывает повторный рендер слоёв.

Основные типы пользовательских действий

Навигация по карте

Навигационные действия включают:

  • масштабирование (zoom in/out)
  • перемещение карты (pan)
  • вращение (bearing)
  • наклон (pitch)

Эти изменения фиксируются в состоянии mapState.

Типовой поток:

  1. Пользователь взаимодействует с картой
  2. deck.gl генерирует событие viewStateChange
  3. Kepler.gl dispatch-ит action обновления mapState
  4. UI и слои пересчитываются

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


Клик по объектам слоя

Обработка клика является одной из самых важных частей интерактивности.

События клика проходят через pick-процесс deck.gl:

  • определяется слой
  • вычисляется объект под курсором
  • формируется payload с данными объекта

Далее вызывается action выбора объекта:

  • обновляется selectedFeature
  • активируется side panel с информацией
  • возможна подсветка объекта на карте

Особое внимание уделяется производительности: pick-операции оптимизированы через spatial indexing внутри deck.gl.


Hover-события

Hover реализуется как непрерывный поток событий при движении мыши:

  • отслеживание позиции курсора
  • выполнение lightweight pick
  • обновление hoverInfo в состоянии

Hover используется для:

  • подсветки объектов
  • отображения tooltip
  • предварительного просмотра данных

Для снижения нагрузки применяется throttling, особенно при плотных датасетах.


Система actions и событийный поток

Все пользовательские действия преобразуются в Redux actions.

Основные категории:

  • updateMapState
  • interactionStateChange
  • layerClick
  • setFilter
  • addDataToMap

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

Пример логики:

  • событие → action creator
  • action → reducer
  • reducer → новый state
  • state → re-render UI

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


Управление слоями через взаимодействия

Пользовательские действия напрямую влияют на состояние слоёв:

Включение и отключение слоёв

События UI:

  • toggle visibility
  • изменение порядка слоёв
  • активация редактирования

Каждое изменение обновляет visState.layers.


Интерактивность внутри слоя

Слои могут поддерживать:

  • selection
  • highlight
  • filtering on click
  • aggregation drill-down

Например, при клике по кластеру выполняется:

  • декомпозиция данных
  • обновление фильтра
  • перерисовка слоя

Drag & Drop взаимодействия

Перетаскивание используется в нескольких сценариях:

  • изменение порядка слоёв
  • загрузка данных
  • reposition элементов UI

Система реализована через:

  • HTML5 drag events
  • React handlers
  • Redux actions для синхронизации состояния

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


Обработка фильтров через пользовательский ввод

Фильтры являются одним из ключевых механизмов интерактивности.

Типы взаимодействий:

  • изменение диапазона (slider)
  • выбор категорий (checkbox)
  • временные фильтры (time slider)

Каждое изменение:

  • диспатчит setFilter
  • пересчитывает dataset
  • обновляет визуализацию слоёв

Фильтрация реализована так, чтобы минимизировать пересчёт данных — используется мемоизация и кэширование промежуточных результатов.


События карты и синхронизация состояния

Map events включают:

  • changeViewport
  • onResize
  • onInteractionStateChange

Kepler.gl хранит interactionConfig, который определяет:

  • включены ли hover/click события
  • активные режимы взаимодействия
  • ограничения навигации

Это позволяет гибко управлять UX без изменения логики компонентов.


Кастомизация обработки взаимодействий

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

  • custom action creators
  • middleware в Redux
  • переопределение interactionConfig

Распространённые сценарии:

  • отключение кликов по слоям
  • кастомный tooltip вместо стандартного
  • синхронизация с внешними приложениями

Middleware слой позволяет перехватывать actions до reducer, что удобно для логирования и аналитики.


Оптимизация обработки событий

При интенсивных взаимодействиях ключевыми становятся оптимизации:

Throttling и debouncing

  • mousemove throttled для hover
  • resize debounced
  • filter updates grouped

Spatial indexing

deck.gl использует структуры данных для ускорения pick-операций:

  • grid-based indexing
  • bounding volume hierarchies

Batch updates

Несколько actions могут объединяться в один batch для снижения количества рендеров.


Асинхронные взаимодействия

Некоторые пользовательские действия запускают асинхронные процессы:

  • загрузка данных по клику
  • динамическое добавление слоёв
  • запросы к API на основе viewport

Эти процессы управляются через middleware (например, redux-thunk), а результат возвращается в store как новый dataset.


Взаимодействие с кастомными UI-компонентами

Kepler.gl допускает расширение UI через React-компоненты, которые могут:

  • подписываться на store
  • диспатчить actions
  • слушать изменения mapState и visState

Это позволяет создавать:

  • кастомные панели управления
  • альтернативные фильтры
  • внешние контроллеры карты

Конфликты пользовательских действий

При одновременных взаимодействиях возможны конфликты:

  • pan vs hover
  • click vs drag
  • filter update vs data load

Для решения применяются:

  • приоритеты interactionConfig
  • блокировка событий на уровне состояния
  • очереди событий

Синхронизация нескольких карт

При использовании нескольких экземпляров Kepler.gl:

  • состояния могут синхронизироваться через внешний store
  • actions дублируются между инстансами
  • viewport может быть связан (linked view)

Это особенно важно для сравнительных визуализаций.


Обработка ошибок взаимодействий

Система учитывает возможные сбои:

  • некорректные координаты события
  • отсутствие данных в слое
  • переполнение state при частых обновлениях

Обработка ошибок встроена в reducer и middleware, предотвращая разрушение состояния приложения даже при некорректных действиях пользователя.