Слой (Layer) — центральная абстракция библиотеки Deck.gl, через которую описываются визуализируемые данные, логика их обработки и способ отображения на карте или в трёхмерной сцене. Практически любой объект, появляющийся на экране, является экземпляром некоторого слоя.
В отличие от традиционного подхода, где разработчик вручную управляет объектами WebGL, буферами, шейдерами и отрисовкой, Deck.gl переносит эти задачи внутрь слоя. Разработчик работает на уровне данных и параметров визуализации.
Каждый слой отвечает за:
Слой можно рассматривать как декларативное описание набора объектов.
Например, вместо создания тысяч отдельных маркеров:
new ScatterplotLayer({
data: points,
getPosition: d => d.coordinates,
getRadius: d => d.size
})
создаётся один слой, который самостоятельно отображает все элементы массива.
Любой слой создаётся через конструктор соответствующего класса.
Пример:
import {ScatterplotLayer} from '@deck.gl/layers';
const layer = new ScatterplotLayer({
id: 'cities',
data: cities,
getPosition: d => d.coordinates,
getRadius: 1000,
getFillColor: [255, 0, 0]
});
Здесь:
| Свойство | Назначение |
|---|---|
id |
уникальный идентификатор слоя |
data |
источник данных |
getPosition |
получение координат объекта |
getRadius |
размер объекта |
getFillColor |
цвет объекта |
После создания слой передаётся в массив layers.
const deck = new Deck({
layers: [layer]
});
Deck.gl самостоятельно управляет жизненным циклом объекта.
Одной из ключевых особенностей Deck.gl является декларативная модель.
Вместо команд вида:
drawCircle(x, y);
drawCircle(x2, y2);
drawCircle(x3, y3);
описывается набор данных:
new ScatterplotLayer({
data: dataset
})
Библиотека сама решает:
Подобный подход делает работу с сотнями тысяч и даже миллионами объектов значительно проще.
Каждый слой обязан иметь уникальный идентификатор.
id: 'airports-layer'
Deck.gl использует идентификатор для:
Нежелательно использовать одинаковые идентификаторы.
Некорректно:
new ScatterplotLayer({
id: 'layer'
});
new ArcLayer({
id: 'layer'
});
Правильно:
new ScatterplotLayer({
id: 'airports'
});
new ArcLayer({
id: 'routes'
});
Параметр data определяет набор объектов, который будет
визуализироваться.
Простейший вариант:
data: [
{name: 'A'},
{name: 'B'},
{name: 'C'}
]
Чаще используются массивы объектов:
data: [
{
city: 'London',
coordinates: [-0.12, 51.50]
},
{
city: 'Paris',
coordinates: [2.35, 48.85]
}
]
Также допускаются:
Promise;Пример:
data: '/data/cities.json'
После загрузки слой автоматически обновляется.
Большинство свойств слоя задаются через специальные функции-доступы (accessors).
Пример:
getPosition: d => d.position
Deck.gl вызывает такую функцию для каждого элемента данных.
Пусть массив содержит:
[
{position: [10, 20]},
{position: [30, 40]}
]
Для каждого объекта будет вызван:
d => d.position
Результатом станет набор координат.
Популярные accessor-функции:
getPosition
getColor
getFillColor
getLineColor
getRadius
getWidth
getElevation
getText
Пример:
new ScatterplotLayer({
data: cities,
getPosition: d => d.coordinates,
getRadius: d => d.population / 1000,
getFillColor: d => [
d.red,
d.green,
d.blue
]
});
Deck.gl содержит большое количество готовых слоёв.
Основные категории:
Используются для отображения отдельных объектов.
Примеры:
ScatterplotLayerIconLayerTextLayernew ScatterplotLayer({...})
Предназначены для отображения маршрутов и связей.
Примеры:
LineLayerPathLayerArcLayernew ArcLayer({...})
Работают с областями.
Примеры:
PolygonLayerGeoJsonLayerSolidPolygonLayernew GeoJsonLayer({...})
Используются для трёхмерной визуализации.
Примеры:
ColumnLayerHexagonLayerGridLayernew ColumnLayer({...})
Все слои библиотеки происходят от базового класса
Layer.
Упрощённая схема:
Layer
├─ ScatterplotLayer
├─ ArcLayer
├─ IconLayer
├─ TextLayer
├─ GeoJsonLayer
├─ PathLayer
└─ ColumnLayer
Базовый класс определяет:
Благодаря этому все слои обладают единым интерфейсом.
Практически всё поведение слоя задаётся через свойства (props).
Пример:
new ScatterplotLayer({
id: 'points',
data: dataset,
opacity: 0.7,
visible: true,
pickable: true
});
Наиболее важные свойства:
Управляет отображением слоя.
visible: false
Слой остаётся в памяти, но не рисуется.
Прозрачность.
opacity: 0.5
Диапазон:
0.0 — полностью прозрачный
1.0 — полностью непрозрачный
Разрешает взаимодействие мышью.
pickable: true
После включения становятся доступны события:
onHover
onClick
Автоматическая подсветка объектов.
autoHighlight: true
При наведении курсора объект получает выделение.
Слои поддерживают интерактивность.
Пример обработки клика:
new ScatterplotLayer({
pickable: true,
onClick: info => {
console.log(info.object);
}
});
Объект info содержит сведения о выбранном элементе.
Основные поля:
info.object
info.index
info.coordinate
info.x
info.y
Пример:
onHover: info => {
if (info.object) {
console.log(info.object.name);
}
}
Deck.gl придерживается принципов неизменяемости (immutability).
Вместо изменения существующего слоя создаётся новый экземпляр.
Неправильно:
layer.radius = 100;
Правильно:
new ScatterplotLayer({
...oldProps,
getRadius: 100
});
При обновлении Deck.gl сравнивает:
Если изменились только отдельные свойства, библиотека обновляет лишь необходимые ресурсы GPU.
Каждый слой проходит несколько этапов существования.
Создание объекта.
new ScatterplotLayer({...})
Внутри вызывается:
initializeState()
Создаются:
При изменении свойств выполняется:
updateState()
Происходит пересчёт ресурсов.
Вызывается:
draw()
В этот момент происходит взаимодействие с WebGL.
При уничтожении слоя:
finalizeState()
Освобождаются:
Каждый слой имеет внутреннее состояние.
Доступ осуществляется через:
this.state
Пример пользовательского слоя:
initializeState() {
this.setState({
selectedIndex: -1
});
}
Изменение:
this.setState({
selectedIndex: 5
});
Состояние используется для хранения промежуточных данных, которые не должны находиться в свойствах.
Одним из важнейших механизмов являются атрибуты.
Атрибуты связывают данные приложения с буферами GPU.
Например:
positions
colors
radii
Для массива:
[
{x: 10, y: 20},
{x: 30, y: 40}
]
создаётся массив координат:
[
10, 20,
30, 40
]
который затем отправляется в видеопамять.
Такой подход обеспечивает высокую производительность даже при работе с миллионами объектов.
Несколько слоёв могут работать одновременно.
Пример:
layers: [
airportsLayer,
routesLayer,
labelsLayer
]
Здесь:
Каждый слой независимо управляет своими данными и рендерингом.
Подобная композиция является основой сложных визуализаций в Deck.gl.
При необходимости можно создавать собственные классы.
Пример минимального слоя:
import {Layer} from '@deck.gl/core';
class CustomLayer extends Layer {
initializeState() {
}
draw() {
}
}
Чаще пользовательские слои наследуются от существующих.
class MyScatterLayer extends ScatterplotLayer {
}
Это позволяет расширять функциональность без полного переписывания механизма рендеринга.
Использование концепции слоя обеспечивает ряд преимуществ:
В архитектуре Deck.gl слой выступает фундаментальным строительным блоком системы визуализации, объединяя данные, правила отображения, интерактивность и механизмы рендеринга в единую управляемую сущность.