ScatterplotLayer — один из наиболее востребованных слоёв библиотеки Deck.gl, предназначенный для отображения большого количества точечных объектов на карте или в произвольной координатной системе. Каждый объект визуализируется в виде круга, размеры, цвет, прозрачность и другие характеристики которого могут вычисляться динамически на основе данных.
Слой особенно эффективен для:
ScatterplotLayer относится к числу базовых слоёв Deck.gl и часто используется как отправная точка при построении геопространственных приложений.
После установки Deck.gl слой импортируется следующим образом:
import {ScatterplotLayer} from '@deck.gl/layers';
Создание экземпляра слоя:
const layer = new ScatterplotLayer({
id: 'scatter-layer',
data: []
});
Каждый слой должен иметь уникальный идентификатор через свойство
id.
Минимальный набор данных обычно представляет собой массив объектов с координатами.
const data = [
{
position: [37.6173, 55.7558],
name: 'Москва'
},
{
position: [30.3141, 59.9386],
name: 'Санкт-Петербург'
}
];
Для работы слоя необходимо указать способ получения координат.
const layer = new ScatterplotLayer({
id: 'cities',
data,
getPosition: d => d.position
});
Метод getPosition вызывается для каждого элемента
массива данных.
ScatterplotLayer ожидает массив:
[longitude, latitude]
Пример:
[37.6173, 55.7558]
Также допускается использование высоты:
[37.6173, 55.7558, 100]
Третье значение интерпретируется как высота над поверхностью.
Размер круга задаётся через свойство getRadius.
const layer = new ScatterplotLayer({
id: 'cities',
data,
getPosition: d => d.position,
getRadius: 1000
});
В данном случае все точки будут иметь одинаковый радиус.
Чаще радиус зависит от данных.
const layer = new ScatterplotLayer({
id: 'population',
data,
getPosition: d => d.position,
getRadius: d => d.population
});
Пример структуры объекта:
{
position: [37.6173, 55.7558],
population: 12000
}
Каждая точка получит собственный размер.
Для изменения общего масштаба используется параметр
radiusScale.
const layer = new ScatterplotLayer({
id: 'population',
data,
getPosition: d => d.position,
getRadius: d => d.population,
radiusScale: 10
});
Итоговый радиус вычисляется как:
getRadius × radiusScale
Слишком большие или слишком маленькие значения можно ограничить.
const layer = new ScatterplotLayer({
id: 'population',
data,
getPosition: d => d.position,
getRadius: d => d.population,
radiusMinPixels: 2,
radiusMaxPixels: 50
});
Параметры:
| Свойство | Назначение |
|---|---|
| radiusMinPixels | Минимальный размер точки |
| radiusMaxPixels | Максимальный размер точки |
Цвет задаётся массивом RGBA.
const layer = new ScatterplotLayer({
id: 'points',
data,
getPosition: d => d.position,
getFillColor: [255, 0, 0]
});
Красный цвет для всех объектов.
getFillColor: [255, 0, 0, 120]
Значения:
R = 255
G = 0
B = 0
A = 120
Альфа-канал находится в диапазоне от 0 до 255.
Цвет может зависеть от характеристик объекта.
const layer = new ScatterplotLayer({
id: 'temperature',
data,
getPosition: d => d.position,
getFillColor: d =>
d.temperature > 30
? [255, 0, 0]
: [0, 0, 255]
});
Красный цвет для высоких температур, синий — для остальных.
ScatterplotLayer способен рисовать не только заливку, но и границу.
const layer = new ScatterplotLayer({
id: 'points',
data,
stroked: true
});
const layer = new ScatterplotLayer({
id: 'points',
data,
stroked: true,
getLineColor: [0, 0, 0]
});
Черная обводка вокруг точек.
const layer = new ScatterplotLayer({
id: 'points',
data,
stroked: true,
lineWidthMinPixels: 2
});
const layer = new ScatterplotLayer({
id: 'points',
data,
stroked: true,
getLineColor: d =>
d.active
? [0, 255, 0]
: [255, 0, 0]
});
Одной из важных особенностей ScatterplotLayer является возможность задавать размеры в разных единицах измерения.
По умолчанию:
radiusUnits: 'meters'
Пример:
getRadius: 1000
Радиус составляет один километр.
radiusUnits: 'pixels'
Полный пример:
const layer = new ScatterplotLayer({
id: 'points',
data,
getPosition: d => d.position,
radiusUnits: 'pixels',
getRadius: 10
});
Размер остаётся одинаковым независимо от масштаба карты.
Для обработки событий необходимо включить возможность выбора.
pickable: true
const layer = new ScatterplotLayer({
id: 'points',
data,
pickable: true,
onClick: info => {
console.log(info.object);
}
});
Объект info содержит данные выбранной точки.
const layer = new ScatterplotLayer({
id: 'points',
data,
pickable: true,
onHover: info => {
console.log(info.object);
}
});
Событие вызывается при перемещении курсора.
Deck.gl формирует специальный объект выбора.
onClick: info => {
console.log(info);
}
Основные поля:
| Поле | Описание |
|---|---|
| object | Исходный объект данных |
| x | Координата курсора по X |
| y | Координата курсора по Y |
| coordinate | Географические координаты |
| index | Индекс элемента |
| layer | Слой |
Пример:
{
object: {
name: 'Москва'
},
index: 0
}
Для отображения информации обычно используется свойство
getTooltip.
new Deck({
layers: [layer],
getTooltip: ({object}) =>
object && {
text: object.name
}
});
ScatterplotLayer способен отображать точки в трёхмерном пространстве.
Данные:
{
position: [37.6173, 55.7558, 1000]
}
Слой:
const layer = new ScatterplotLayer({
id: '3d-points',
data,
getPosition: d => d.position
});
Высота будет учитываться при использовании 3D-вида карты.
По умолчанию круги располагаются в плоскости карты.
billboard: false
При включении:
billboard: true
круги всегда поворачиваются лицом к камере.
Это особенно полезно при сильном наклоне карты.
Deck.gl отслеживает изменения данных и обновляет GPU-буферы.
layer = new ScatterplotLayer({
id: 'points',
data: newData,
getPosition: d => d.position
});
При изменении массива происходит автоматический пересчёт атрибутов.
Плохо:
render() {
return new ScatterplotLayer({
getRadius: d => d.value
});
}
Лучше:
const getRadius = d => d.value;
new ScatterplotLayer({
getRadius
});
Это уменьшает количество лишних обновлений.
Когда вычисления зависят от внешних переменных, следует явно указывать триггеры обновления.
const scale = 2;
const layer = new ScatterplotLayer({
id: 'points',
getRadius: d => d.value * scale,
updateTriggers: {
getRadius: scale
}
});
При изменении scale слой автоматически пересчитает
размеры.
Размеры могут плавно изменяться при обновлении данных.
const layer = new ScatterplotLayer({
id: 'animated',
data,
transitions: {
getRadius: 500
},
getRadius: d => d.value
});
Длительность анимации — 500 миллисекунд.
const layer = new ScatterplotLayer({
id: 'animated-colors',
data,
transitions: {
getFillColor: 1000
},
getFillColor: d => d.color
});
Цвет будет плавно интерполироваться.
ScatterplotLayer разработан с расчётом на высокую производительность.
Особенности реализации:
Пример генерации большого набора данных:
const data = Array.from(
{length: 100000},
(_, i) => ({
position: [
30 + Math.random(),
60 + Math.random()
],
value: Math.random() * 100
})
);
Слой:
const layer = new ScatterplotLayer({
id: 'large-dataset',
data,
getPosition: d => d.position,
getRadius: d => d.value,
pickable: true
});
const layer = new ScatterplotLayer({
id: 'population',
data: cities,
pickable: true,
getPosition: d => d.coordinates,
getRadius: d => d.population,
radiusScale: 0.02,
radiusMinPixels: 2,
getFillColor: d => {
if (d.population > 1000000) {
return [255, 0, 0];
}
if (d.population > 500000) {
return [255, 165, 0];
}
return [0, 128, 255];
},
onClick: info => {
console.log(info.object);
}
});
В таком сценарии:
| Свойство | Назначение |
|---|---|
| data | Источник данных |
| getPosition | Координаты точки |
| getRadius | Радиус объекта |
| getFillColor | Цвет заливки |
| getLineColor | Цвет контура |
| stroked | Включение обводки |
| filled | Включение заливки |
| radiusScale | Масштаб радиуса |
| radiusUnits | Единицы измерения |
| radiusMinPixels | Минимальный размер |
| radiusMaxPixels | Максимальный размер |
| lineWidthUnits | Единицы ширины линии |
| lineWidthMinPixels | Минимальная ширина контура |
| lineWidthMaxPixels | Максимальная ширина контура |
| pickable | Возможность выбора |
| autoHighlight | Автоматическая подсветка |
| highlightColor | Цвет подсветки |
| billboard | Поворот к камере |
| transitions | Анимация изменений |
| updateTriggers | Контроль обновлений |
Deck.gl может автоматически выделять объект под курсором.
const layer = new ScatterplotLayer({
id: 'points',
data,
pickable: true,
autoHighlight: true
});
const layer = new ScatterplotLayer({
id: 'points',
data,
pickable: true,
autoHighlight: true,
highlightColor: [255, 255, 0, 120]
});
При наведении точка будет подсвечиваться полупрозрачным жёлтым цветом.
ScatterplotLayer часто используется совместно с другими слоями Deck.gl:
Пример комбинирования:
const layers = [
scatterLayer,
textLayer,
geoJsonLayer
];
Такой подход позволяет строить сложные геоаналитические интерфейсы, где ScatterplotLayer отвечает за быстрое и эффективное отображение большого количества точечных объектов с гибкой настройкой размеров, цветов, интерактивности и анимации.