Механизм всплывающих подсказок в Kepler.gl строится вокруг системы
интерактивного слоя визуализации, где каждый объект на карте может
реагировать на наведение курсора и возвращать структурированные данные
из датасета. Основная идея заключается не в «рисовании окна», а в
привязке логики отображения к состоянию визуализации
(visState) и событиям взаимодействия.
Вся интерактивность в Kepler.gl контролируется через
visState.interactionConfig. Этот объект определяет, какие
типы взаимодействий включены, какие данные доступны пользователю и как
они форматируются перед отображением.
Ключевые элементы конфигурации:
tooltip — настройка всплывающих подсказокbrush — выделение областиgeocoder — поиск по картеinteractionConfig.config — общий контейнер параметров
взаимодействияВ контексте tooltip основное значение имеет структура:
interactionConfig: {
tooltip: {
enabled: true,
fieldsToShow: {
layer_id: ['field1', 'field2']
},
compareMode: false,
compareType: 'absolute',
customTitle: null
}
}
Каждый слой в Kepler.gl может иметь собственный набор полей, которые будут отображаться при наведении. Это позволяет гибко управлять информационной плотностью без изменения исходного датасета.
fieldsToShow: {
trips_layer: ['start_time', 'end_time', 'distance']
}
Такой подход разделяет визуализацию и представление данных: слой отвечает за геометрию, а tooltip — за интерпретацию.
При наведении курсора Kepler.gl выполняет запрос к активным слоям
через механизм deck.gl picking. Каждый слой возвращает объект
pickedObject, содержащий:
index — индекс объекта в данныхlayer — ссылка на слойobject — исходная запись данныхcoordinate — географическая позицияpixel — экранные координатыНа основе этого объекта формируется содержимое tooltip.
Внутренняя логика напоминает следующий процесс:
function getTooltipInfo(pickedObject, fieldsToShow) {
const layerId = pickedObject.layer.id;
const fields = fieldsToShow[layerId];
return fields.map(field => ({
name: field,
value: pickedObject.object[field]
}));
}
Kepler.gl поддерживает базовую систему форматирования значений через кастомные форматтеры. Они определяются на уровне датасета или глобальной конфигурации.
Типичные сценарии:
Пример форматтера:
const formatters = {
distance: value => `${value.toFixed(2)} км`,
timestamp: value => new Date(value).toISOString()
};
Форматтеры применяются до рендера tooltip, обеспечивая консистентность отображения независимо от источника данных.
Хотя стандартный tooltip Kepler.gl представляет собой структурированный список полей, возможна кастомизация через HTML-шаблоны. В этом случае разработчик получает полный контроль над содержимым всплывающего окна.
Пример конфигурации:
tooltip: {
enabled: true,
html: object => `
<div class="tooltip-container">
<div class="title">${object.name}</div>
<div class="value">${object.value}</div>
</div>
`
}
Такой подход позволяет реализовывать сложные визуальные элементы: таблицы, мини-графики, индикаторы состояния.
В Kepler.gl важно различать два уровня всплывающей информации:
Tooltip работает внутри rendering pipeline deck.gl и обновляется на каждый mouse move, тогда как popup чаще создаётся как отдельный DOM-слой через Mapbox GL API.
При наличии нескольких слоёв под курсором Kepler.gl формирует стек объектов. Приоритет определяется:
Результирующий tooltip может агрегировать данные:
[
{ layer: 'points', value: {...} },
{ layer: 'heatmap', value: {...} }
]
Режим сравнения (compareMode) позволяет отображать
несколько значений одного и того же поля из разных объектов. Это
используется для анализа изменений во времени или пространстве.
Структура сравнения:
compareMode: true,
compareType: 'relative'
В этом режиме tooltip перестаёт быть привязан к одному объекту и начинает работать как агрегатор выборки.
Tooltip тесно связан с системой событий Kepler.gl:
onLayerHoveronMapHoveronInteractionStateChangeЭти события позволяют перехватывать данные до их рендера и модифицировать поведение всплывающего окна.
Пример обработки:
function onMapHover(info) {
if (info.picked && info.object) {
return transformTooltip(info.object);
}
}
При высокой плотности данных tooltip становится критическим элементом производительности. Основные оптимизации:
fieldsToShowDeck.gl использует WebGL picking, но финальная сборка tooltip происходит в JavaScript, поэтому узким местом становится именно слой представления.
Kepler.gl допускает расширение поведения tooltip через модификацию Redux-состояния. Это позволяет:
Пример динамического обновления:
dispatch(
updateInteractionConfig({
tooltip: {
fieldsToShow: {
layer_1: ['speed', 'altitude', 'heading']
}
}
})
);
Позиционирование tooltip основано на screen-space координатах, вычисляемых из Web Mercator проекции. При этом учитываются:
Tooltip не является частью WebGL сцены, он рендерится поверх канваса, что требует синхронизации координат при каждом обновлении камеры.