visState

visState — один из центральных разделов состояния приложения Kepler.gl. Именно здесь хранится информация, отвечающая за визуальное представление данных на карте: загруженные наборы данных, слои, фильтры, взаимодействия, настройки отображения, а также конфигурации анимации и разделения карты на несколько представлений.

Если mapState отвечает за положение карты, масштабирование и перемещение, то visState управляет тем, что именно отображается поверх карты и каким образом эти данные визуализируются.

Структура объекта может выглядеть следующим образом:

{
  visState: {
    datasets: [],
    layers: [],
    filters: [],
    interactionConfig: {},
    layerBlending: 'normal',
    splitMaps: [],
    animationConfig: {},
    editor: {},
    layerToBeMerged: [],
    layerOrder: []
  }
}

Каждое поле отвечает за отдельную подсистему визуализации.


Роль visState в жизненном цикле приложения

После загрузки данных Kepler.gl выполняет следующие действия:

  1. Создаёт объект Dataset.
  2. Сохраняет его в visState.datasets.
  3. Автоматически анализирует структуру данных.
  4. Создаёт подходящие слои.
  5. Формирует конфигурацию визуализации.
  6. Обновляет пользовательский интерфейс.

Схематически процесс выглядит так:

CSV / GeoJSON
       ↓
addDataToMap()
       ↓
Dataset
       ↓
visState.datasets
       ↓
Автоматическое создание слоев
       ↓
visState.layers
       ↓
Отрисовка на карте

Все изменения пользовательского интерфейса фактически приводят к изменению содержимого visState.


Свойство datasets

Назначение

Поле datasets хранит все загруженные наборы данных.

Пример:

visState.datasets
[
  {
    id: 'cities',
    label: 'Cities',
    data: {
      fields: [...],
      rows: [...]
    }
  }
]

Каждый набор данных содержит:

Поле Назначение
id Уникальный идентификатор
label Название набора
data.fields Описание колонок
data.rows Строки данных
color Цвет набора
allData Исходные данные

Структура fields

Описание колонок выглядит следующим образом:

fields: [
  {
    name: 'city',
    type: 'string'
  },
  {
    name: 'population',
    type: 'integer'
  },
  {
    name: 'latitude',
    type: 'real'
  },
  {
    name: 'longitude',
    type: 'real'
  }
]

Kepler.gl использует эту информацию для автоматического определения типов данных.


Структура rows

rows: [
  ['London', 9000000, 51.5074, -0.1278],
  ['Paris', 2140000, 48.8566, 2.3522]
]

Массив строк хранится отдельно от описания колонок.

Такой подход обеспечивает:

  • компактность хранения;
  • быструю сериализацию;
  • высокую производительность при работе с большими наборами данных.

Свойство layers

Назначение

Поле layers содержит все визуальные слои карты.

Пример:

visState.layers
[
  {
    id: 'point-layer',
    type: 'point',
    config: {},
    visualChannels: {}
  }
]

Каждый объект описывает один слой.


Типы слоев

Наиболее распространённые типы:

Тип Назначение
point Точки
arc Дуги
line Линии
geojson GeoJSON
polygon Полигоны
grid Grid Aggregation
hexagon Hexbin Aggregation
heatmap Тепловая карта
cluster Кластеры
icon Иконки
trip Анимированные маршруты

Пример слоя:

{
  id: 'cities-layer',
  type: 'point'
}

Конфигурация слоя

Большая часть настроек располагается внутри объекта config.

Пример:

{
  config: {
    label: 'Cities',
    dataId: 'cities',
    columns: {
      lat: 'latitude',
      lng: 'longitude'
    },
    isVisible: true
  }
}

dataId

Указывает источник данных.

{
  dataId: 'cities'
}

Слой будет использовать набор данных с таким идентификатором.


columns

Определяет связь между полями данных и слоем.

{
  columns: {
    lat: 'latitude',
    lng: 'longitude'
  }
}

Для слоя точек обязательны координаты.


label

Название слоя:

{
  label: 'Population'
}

Отображается в панели Layers.


isVisible

Управляет видимостью.

{
  isVisible: true
}

или

{
  isVisible: false
}

Настройки отображения слоя

Внутри visConfig находятся параметры визуализации.

Пример:

{
  visConfig: {
    radius: 20,
    opacity: 0.8,
    filled: true
  }
}

Radius

Размер точек:

{
  radius: 30
}

Opacity

Прозрачность:

{
  opacity: 0.5
}

Filled

Заполнение объекта цветом:

{
  filled: true
}

Stroke Color

Цвет границы:

{
  strokeColor: [255, 0, 0]
}

Формат RGB.


Thickness

Толщина линий:

{
  thickness: 4
}

Visual Channels

Система визуальных каналов связывает значения данных с визуальными свойствами.

Пример:

visualChannels: {
  colorField: {
    name: 'population'
  },
  sizeField: {
    name: 'population'
  }
}

Цветовая шкала

colorField: {
  name: 'population'
}
colorScale: 'quantile'

Чем выше население, тем интенсивнее цвет.


Размер объектов

sizeField: {
  name: 'population'
}
sizeScale: 'sqrt'

Размер точки будет зависеть от значения поля.


Высота объектов

Для трёхмерных слоёв:

heightField: {
  name: 'population'
}

Свойство filters

Назначение

Хранит все фильтры.

visState.filters

Пример:

[
  {
    id: 'population-filter'
  }
]

Диапазонный фильтр

{
  dataId: 'cities',
  name: ['population'],
  type: 'range',
  value: [1000000, 10000000]
}

Будут отображаться только города в указанном диапазоне.


Фильтр по категориям

{
  dataId: 'cities',
  name: ['country'],
  type: 'multiSelect',
  value: ['France', 'Germany']
}

Временной фильтр

{
  dataId: 'events',
  name: ['timestamp'],
  type: 'timeRange',
  value: [
    1680000000000,
    1690000000000
  ]
}

Свойство interactionConfig

Определяет настройки взаимодействия пользователя с картой.

Пример:

interactionConfig: {
  tooltip: {},
  brush: {},
  geocoder: {},
  coordinate: {}
}

Tooltip

Настройки всплывающих подсказок.

tooltip: {
  enabled: true
}

Пример выбора колонок:

tooltip: {
  fieldsToShow: {
    cities: [
      {
        name: 'city'
      },
      {
        name: 'population'
      }
    ]
  }
}

Форматирование подсказок

tooltip: {
  compareMode: false
}
tooltip: {
  compareType: 'absolute'
}

Brush

Инструмент выделения области.

brush: {
  enabled: true
}

Радиус выделения:

brush: {
  size: 50
}

Geocoder

Поиск местоположений.

geocoder: {
  enabled: true
}

После включения появляется строка поиска адресов.


Coordinate

Отображение координат курсора.

coordinate: {
  enabled: true
}

Layer Blending

Параметр смешивания слоёв.

layerBlending: 'normal'

Поддерживаемые режимы:

normal
additive
subtractive

Normal

Стандартный режим.

layerBlending: 'normal'

Additive

Наложение цветов суммированием.

layerBlending: 'additive'

Особенно полезно для тепловых карт.


Subtractive

Вычитание цветов.

layerBlending: 'subtractive'

Используется значительно реже.


Свойство splitMaps

Позволяет отображать несколько карт одновременно.

Пример:

splitMaps: []

После разделения интерфейса:

splitMaps: [
  {
    layers: {}
  },
  {
    layers: {}
  }
]

Синхронизация слоёв

Каждая карта может содержать собственный набор слоёв.

{
  layers: {
    'cities-layer': true,
    'heatmap-layer': false
  }
}

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


Свойство animationConfig

Используется для управления анимацией.

Особенно важно для слоя Trip Layer.

Пример:

animationConfig: {
  currentTime: 0,
  speed: 1
}

Current Time

Текущий момент времени.

{
  currentTime: 120
}

Скорость

{
  speed: 2
}

Анимация будет проигрываться в два раза быстрее.


Свойство editor

Хранит состояние встроенных редакторов.

Пример:

editor: {
  features: []
}

Используется при рисовании объектов непосредственно на карте.


Layer Order

Последовательность отображения слоёв.

layerOrder: [
  'base-layer',
  'cities-layer',
  'heatmap-layer'
]

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

Изменение порядка:

dispatch({
  type: 'LAYER_MOVE_UP',
  payload: {
    layerId: 'cities-layer'
  }
});

Layer To Be Merged

Служебное поле для операций объединения.

layerToBeMerged: [
  'layer-1',
  'layer-2'
]

Используется внутренними механизмами Kepler.gl при создании составных визуализаций.


Сериализация visState

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

Пример экспортируемого состояния:

{
  visState: {
    layers: [...],
    filters: [...],
    interactionConfig: {...},
    layerBlending: 'normal'
  }
}

Такой объект может:

  • сохраняться в базе данных;
  • передаваться по сети;
  • экспортироваться в JSON;
  • восстанавливать состояние интерфейса после перезагрузки страницы.

Связь visState и Config API

При экспорте конфигурации через интерфейс Kepler.gl большая часть информации извлекается именно из visState.

Типичный экспорт содержит:

{
  version: 'v1',
  config: {
    visState: {...},
    mapState: {...},
    mapStyle: {...}
  }
}

Во время импорта:

KeplerGlSchema.load(...)

конфигурация преобразуется обратно в структуру состояния Redux.

Благодаря этому visState выступает главным источником данных для восстановления всей пользовательской визуализации: слоёв, фильтров, интерактивности, анимации, цветовых схем и связей между данными и объектами карты.