В библиотеке Kepler.gl интерфейс построен вокруг набора управляемых панелей, каждая из которых отвечает за отдельный аспект конфигурации карты: слои, фильтры, стили, взаимодействия и экспорт. Панели реализованы как React-компоненты и тесно связаны с состоянием Redux, где хранится вся логика визуализации.
Ключевая особенность системы панелей заключается в том, что она не является жёстко зафиксированной. Интерфейс допускает расширение и переопределение стандартных компонентов, включая добавление собственных панелей, модификацию существующих и полную замену UI-структуры.
Основные контейнеры, влияющие на панели:
uiState — отвечает за состояние интерфейса
(открытие/закрытие панелей, режимы отображения)visState — хранит слои, фильтры, взаимодействияmapState — параметры камеры и позиционирования
картыmapStyle — визуальное оформление картыПанели в Kepler.gl представляют собой визуальные проекции этих слоёв состояния.
Основной способ создания собственных панелей основан на механизме
внедрения компонентов через injectComponents. Эта функция
позволяет переопределять внутренние части интерфейса без изменения
исходного кода библиотеки.
Структура переопределения выглядит следующим образом:
import KeplerGl from 'kepler.gl';
import {injectComponents} from 'kepler.gl/components';
const CustomPanel = () => {
return (
<div className="custom-panel">
<h3>Дополнительная панель</h3>
</div>
);
};
const myInjectedComponents = injectComponents([
[KeplerGl.Panels.LayerPanel, CustomPanel]
]);
При такой конфигурации стандартная панель слоёв заменяется на пользовательскую реализацию.
Внутренняя структура Kepler.gl разделяет панели на несколько ключевых типов:
Каждый из этих компонентов может быть заменён или расширен.
Пример замены заголовка панели:
import {injectComponents} from 'kepler.gl/components';
import KeplerGl from 'kepler.gl';
const CustomHeader = ({title}) => {
return (
<div className="custom-header">
<span>{title}</span>
<button>Действие</button>
</div>
);
};
export default injectComponents([
[KeplerGl.PanelHeaderFactory, CustomHeader]
]);
Переопределение фабрик компонентов обеспечивает сохранение внутренней логики Kepler.gl при изменении визуального слоя.
Добавление новой панели требует не только визуального компонента, но и интеграции с состоянием Redux и системой UI-стейта.
Основной подход включает три шага:
uiStateimport React from 'react';
import {connect} from 'react-redux';
const AnalysisPanel = ({datasets}) => {
return (
<div className="analysis-panel">
<h4>Аналитика данных</h4>
<div>Количество наборов: {datasets.length}</div>
</div>
);
};
const mapStateToProps = state => ({
datasets: state.keplerGl.map.datasets
});
export default connect(mapStateToProps)(AnalysisPanel);
Для отображения новой панели требуется зарегистрировать её в
uiState:
dispatch({
type: 'ADD_CUSTOM_PANEL',
payload: {
panelId: 'analysis',
title: 'Аналитика',
component: 'AnalysisPanel'
}
});
Далее UI должен быть расширен так, чтобы учитывать новый
panelId при рендеринге боковой панели.
SidePanel является контейнером, внутри которого отображаются вкладки стандартных и пользовательских панелей.
Ключевые аспекты:
uiState.activeSidePanelПример логики выбора вкладки:
const mapStateToProps = state => ({
activePanel: state.keplerGl.uiState.activeSidePanel
});
Расширение списка вкладок требует модификации конфигурации интерфейса:
const panels = [
{id: 'layers', label: 'Слои'},
{id: 'filters', label: 'Фильтры'},
{id: 'analysis', label: 'Аналитика'}
];
Панели часто взаимодействуют с visState, поскольку
именно он содержит ключевую информацию о слоях и фильтрах.
Пример доступа к слоям внутри кастомной панели:
const mapStateToProps = state => ({
layers: state.keplerGl.map.visState.layers
});
Типичные операции, выполняемые через панели:
Расширение стандартной панели слоёв позволяет добавлять дополнительные настройки, например бизнес-логику поверх геоданных.
const ExtendedLayerPanel = ({layers}) => {
return (
<div>
{layers.map(layer => (
<div key={layer.id}>
<strong>{layer.config.label}</strong>
<div>Тип: {layer.type}</div>
</div>
))}
</div>
);
};
Такой подход используется для построения специализированных аналитических интерфейсов поверх базовой геовизуализации.
Панели Kepler.gl используют CSS-in-JS и классовую систему. Для кастомных панелей обычно применяется изолированная стилизация, чтобы избежать конфликтов с базовой темой.
Ключевые подходы:
mapStyleПример:
.custom-panel {
padding: 12px;
background: #1a1a1a;
color: #ffffff;
}
Панели могут содержать сложные UI-элементы: формы, графики, переключатели режимов визуализации.
Пример интерактивного элемента:
const ControlPanel = ({setFilter}) => {
return (
<div>
<button onCl ick={() => setFilter('date')}>
Фильтр по дате
</button>
</div>
);
};
Связь с Redux action:
dispatch({
type: 'ADD_FILTER',
payload: {
dataId,
filter: {
name: 'date'
}
}
});
Для ускорения разработки часто используются внутренние компоненты библиотеки:
Такой подход обеспечивает визуальную и поведенческую консистентность между стандартными и пользовательскими панелями.
В сложных случаях панели не ограничиваются UI и напрямую взаимодействуют с middleware:
Пример middleware:
const customMiddleware = store => next => action => {
if (action.type === 'ADD_LAYER') {
console.log('Добавление слоя:', action.payload);
}
return next(action);
};
Любая кастомная панель должна учитывать синхронизацию с основным состоянием карты, включая:
visStateБез синхронизации интерфейс быстро теряет согласованность с визуализацией, особенно при работе с большими геоданными и динамическими источниками данных.