Создание фильтров

Фильтры в Kepler.gl являются частью состояния приложения и позволяют динамически ограничивать отображаемые данные на карте без изменения исходного датасета. Механизм построен поверх Redux-состояния и тесно связан с конфигурацией слоёв, интерактивной панелью и системой временных шкал.

Каждый фильтр описывает правило отбора строк из таблицы данных на основе значений одного или нескольких полей. Фильтрация выполняется на уровне вычисляемых данных слоя, что обеспечивает синхронное обновление визуализации.


Структура фильтров в состоянии Kepler.gl

Фильтры хранятся в разделе visState.filters:

visState: {
  filters: [
    {
      id: 'filter_1',
      dataId: ['dataset_1'],
      name: 'speed',
      type: 'range',
      value: [10, 100],
      animationWindow: 'free',
      enabled: true
    }
  ]
}

Каждый объект фильтра содержит набор обязательных и опциональных полей:

  • id — уникальный идентификатор фильтра
  • dataId — массив идентификаторов датасетов
  • name — имя поля, к которому применяется фильтр
  • type — тип фильтра
  • value — текущее значение фильтра
  • enabled — активность фильтра
  • animationWindow — режим временной анимации (если применимо)

Типы фильтров

Kepler.gl поддерживает несколько базовых типов фильтрации данных.

Диапазонный фильтр (range filter)

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

{
  id: 'speed_filter',
  dataId: ['trips'],
  name: 'speed',
  type: 'range',
  value: [20, 80],
  min: 0,
  max: 120
}

Диапазонный фильтр активно применяется для:

  • скорости движения объектов
  • высоты, глубины, расстояния
  • любых непрерывных числовых признаков

Категориальный фильтр (select / multi-value filter)

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

{
  id: 'category_filter',
  dataId: ['points'],
  name: 'type',
  type: 'multiSelect',
  value: ['bus', 'train']
}

Применяется для:

  • типов объектов
  • категорий событий
  • идентификаторов групп

Временной фильтр (time filter)

Специальный тип фильтра, работающий с временными данными. Поддерживает анимацию и интервал времени.

{
  id: 'time_filter',
  dataId: ['events'],
  name: 'timestamp',
  type: 'timeRange',
  value: [1609459200000, 1612137600000],
  timeConfig: {
    mode: 'interval',
    speed: 1
  }
}

Особенности:

  • работа с UNIX timestamp
  • поддержка анимации движения времени
  • интеграция с playback-контролями

Привязка фильтра к данным

Фильтр не действует глобально, а применяется к конкретным датасетам через dataId. Один фильтр может одновременно воздействовать на несколько источников данных.

dataId: ['dataset_a', 'dataset_b']

При вычислении слоя Kepler.gl пересчитывает только те строки, которые принадлежат указанным наборам данных.


Механизм применения фильтров

Фильтрация выполняется в несколько этапов:

  1. Извлечение активных фильтров из visState
  2. Определение соответствующих датасетов
  3. Построение предикатов фильтрации
  4. Применение предикатов к данным слоя
  5. Кэширование результата для оптимизации рендеринга

Логика предикатов зависит от типа фильтра:

  • range → проверка min <= value <= max
  • multiSelect → проверка принадлежности множеству
  • timeRange → проверка попадания во временной интервал

Redux-операции для управления фильтрами

Добавление фильтра

dispatch(addFilter({
  dataId: 'trips',
  name: 'speed',
  type: 'range'
}));

Создаётся новый фильтр с дефолтными значениями, определёнными типом поля.


Обновление фильтра

dispatch(updateFilter({
  id: 'filter_1',
  value: [30, 90]
}));

Обновление может затрагивать:

  • диапазон значений
  • список выбранных категорий
  • параметры временной анимации
  • состояние активности

Удаление фильтра

dispatch(removeFilter('filter_1'));

Удаление полностью исключает фильтр из состояния и пересчитывает связанные слои.


Автоматическое создание фильтров

Kepler.gl способен автоматически генерировать фильтры при загрузке датасета. Алгоритм анализирует типы полей:

  • числовые поля → range filter
  • строковые поля с низкой кардинальностью → multiSelect
  • временные поля → timeRange

Пример структуры автофильтра:

{
  name: 'timestamp',
  type: 'timeRange',
  domain: [start, end],
  value: [start, end]
}

Синхронизация фильтров с UI

Фильтры отображаются в панели управления и синхронизируются с интерактивными элементами:

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

Изменения UI немедленно диспатчат соответствующие Redux actions, обновляя состояние визуализации.


Связь фильтров и слоёв

Фильтры могут применяться как глобально, так и на уровне конкретных слоёв.

Слой может:

  • наследовать все фильтры датасета
  • игнорировать часть фильтров
  • использовать переопределённую логику отбора

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

layer.config.filterByLayer = true
layer.config.filterList = ['speed_filter']

Временная анимация и фильтры

Временные фильтры тесно связаны с системой анимации Kepler.gl.

Ключевые параметры:

  • animationWindow — способ интерпретации интервала
  • speed — скорость проигрывания
  • trailLength — длина следа для движущихся объектов

Режимы окна:

  • point — одиночная временная точка
  • interval — интервал времени
  • continuous — непрерывное движение окна

Производительность фильтрации

Фильтрация оптимизирована через:

  • мемоизацию вычисленных наборов данных
  • предварительную индексацию полей
  • частичное обновление слоёв
  • lazy recalculation при изменении фильтра

При больших датасетах ключевым фактором становится количество активных фильтров и их тип.


Композиция нескольких фильтров

При наличии нескольких фильтров применяется логическое пересечение условий.

Формально:

result = filter1 AND filter2 AND filter3

Каждый дополнительный фильтр уменьшает пространство отображаемых данных, что влияет на плотность визуализации и производительность рендера.


Конфигурация фильтров при инициализации

При создании Kepler.gl instance фильтры могут быть переданы через initial state:

const initialState = {
  visState: {
    filters: [
      {
        name: 'speed',
        type: 'range',
        value: [0, 50]
      }
    ]
  }
};

Это позволяет заранее подготовить сцену визуализации с заданными ограничениями данных.


Интеграция с пользовательскими расширениями

Фильтры могут быть расширены через кастомные плагины:

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

Кастомный фильтр реализует интерфейс:

filterType: {
  name: 'customFilter',
  getValue: (data, field) => {},
  apply: (rows, value) => {}
}