HexagonLayer aggregates data into a hexagonal grid-based heatmap. It bins data points into hexagonal cells and can visualize both color and elevation based on aggregated values, making it ideal for geographic data visualization with natural spatial distribution.
Creates a layer that aggregates data points into hexagonal bins with configurable radius and optional 3D extrusion.
/**
* Aggregate data into a hexagonal grid-based heatmap
* @param props - Configuration properties for the hexagon layer
*/
class HexagonLayer<DataT = any> extends AggregationLayer<DataT, HexagonLayerProps<DataT>> {
constructor(props: HexagonLayerProps<DataT>);
}
interface HexagonLayerProps<DataT> extends LayerProps {
/** Array of data objects to aggregate */
data: DataT[];
/** Function to extract position from data object (default: d => d.position) */
getPosition?: Accessor<DataT, Position>;
/** Function to extract weight value for color aggregation (default: 1) */
getColorWeight?: Accessor<DataT, number>;
/** Function to extract weight value for elevation aggregation (default: 1) */
getElevationWeight?: Accessor<DataT, number>;
/** After data objects are aggregated into cells, this accessor is called on each cell to get the value that its color is based on. Not supported by GPU aggregation. */
getColorValue?: AggregateAccessor<DataT> | null;
/** After data objects are aggregated into cells, this accessor is called on each cell to get the value that its elevation is based on. Not supported by GPU aggregation. */
getElevationValue?: AggregateAccessor<DataT> | null;
/** Radius of hexagons in meters (default: 1000) */
radius?: number;
/** Cell size multiplier (0-1) (default: 1) */
coverage?: number;
/** Whether to extrude hexagons in 3D (default: false) */
extruded?: boolean;
/** Cell elevation multiplier (default: 1) */
elevationScale?: number;
/** Aggregation operation for color values (default: 'SUM') */
colorAggregation?: AggregationOperation;
/** Aggregation operation for elevation values (default: 'SUM') */
elevationAggregation?: AggregationOperation;
/** Array of colors for the color scale (default: 6-class YlOrRd) */
colorRange?: Color[];
/** Color scale domain, default is set to the extent of aggregated weights in each cell */
colorDomain?: [number, number] | null;
/** Scaling function used to determine the color of the grid cell (default: 'quantize') */
colorScaleType?: 'quantize' | 'linear' | 'quantile' | 'ordinal';
/** Elevation scale output range (default: [0, 1000]) */
elevationRange?: [number, number];
/** Elevation scale input domain, default is set to between 0 and the max of aggregated weights in each cell */
elevationDomain?: [number, number] | null;
/** Scaling function used to determine the elevation of the grid cell (default: 'linear') */
elevationScaleType?: 'linear';
/** Whether to use GPU aggregation (default: true) */
gpuAggregation?: boolean;
/** Filter cells and re-calculate color by lowerPercentile (0-100) (default: 0) */
lowerPercentile?: number;
/** Filter cells and re-calculate color by upperPercentile (0-100) (default: 100) */
upperPercentile?: number;
/** Filter cells and re-calculate elevation by elevationLowerPercentile (0-100) (default: 0) */
elevationLowerPercentile?: number;
/** Filter cells and re-calculate elevation by elevationUpperPercentile (0-100) (default: 100) */
elevationUpperPercentile?: number;
/** Custom accessor to retrieve a hexagonal bin index from each data object. Not supported by GPU aggregation. */
hexagonAggregator?: ((position: number[], radius: number) => [number, number]) | null;
/** Material settings for lighting effect. Applies if extruded: true */
material?: Material;
/** This callback will be called when bin color domain has been calculated */
onSetColorDomain?: (minMax: [number, number]) => void;
/** This callback will be called when bin elevation domain has been calculated */
onSetElevationDomain?: (minMax: [number, number]) => void;
}
interface HexagonLayerPickingInfo<DataT = any> extends PickingInfo<DataT> {
/** The aggregated bin data */
object: AggregatedBin | null;
/** Hexagon coordinates [i, j] */
index: [number, number];
/** Total count of points in the bin */
count: number;
/** Aggregated color value for the bin */
colorValue?: number;
/** Aggregated elevation value for the bin */
elevationValue?: number;
/** Array indices of points in this bin (CPU aggregation only) */
pointIndices?: number[];
}Usage Examples:
import { HexagonLayer } from "@deck.gl/aggregation-layers";
// Basic hexagon layer for population density
const populationLayer = new HexagonLayer({
id: "population-hexagons",
data: censusData,
getPosition: (d) => [d.longitude, d.latitude],
getColorWeight: (d) => d.population,
getElevationWeight: (d) => d.population,
radius: 5000, // 5km radius
extruded: true,
elevationScale: 4,
colorRange: [
[255, 255, 204],
[199, 233, 180],
[127, 205, 187],
[65, 182, 196],
[29, 145, 192],
[34, 94, 168],
[12, 44, 132]
],
pickable: true
});
// Advanced configuration with dual aggregation
const trafficLayer = new HexagonLayer({
id: "traffic-analysis",
data: trafficData,
getPosition: (d) => d.coords,
getColorWeight: (d) => d.accidents, // Color by accident count
getElevationWeight: (d) => d.volume, // Height by traffic volume
radius: 2000,
coverage: 0.8,
extruded: true,
elevationScale: 10,
colorAggregation: 'SUM',
elevationAggregation: 'MEAN',
colorRange: [
[0, 255, 0, 128], // Green for low accidents
[255, 255, 0, 128], // Yellow for medium
[255, 0, 0, 128] // Red for high accidents
],
elevationRange: [0, 500],
colorScaleType: 'quantize',
elevationScaleType: 'linear',
gpuAggregation: true,
pickable: true,
onHover: (info) => {
if (info.object) {
console.log(`Accidents: ${info.colorValue}, Volume: ${info.elevationValue}`);
}
}
});Controls the size and appearance of hexagonal bins.
/** Radius of hexagons in meters (default: 1000) */
radius?: number;
/** Cell size multiplier, 0-1 where 1 = full size (default: 1) */
coverage?: number;
/** Whether to extrude hexagons in 3D (default: false) */
extruded?: boolean;
/** Custom hexagon aggregator function for advanced binning */
hexagonAggregator?: ((position: number[], radius: number) => [number, number]) | null;Controls color mapping for hexagonal cells based on aggregated values.
/** Function to extract weight value for color aggregation */
getColorWeight?: Accessor<DataT, number>;
/** Aggregation operation for color values (default: 'SUM') */
colorAggregation?: AggregationOperation;
/** Array of colors for the color scale */
colorRange?: Color[];
/** Domain for color scale [min, max] */
colorDomain?: [number, number] | null;
/** Scaling function used to determine the color of the grid cell (default: 'quantize') */
colorScaleType?: 'quantize' | 'linear' | 'quantile' | 'ordinal';
/** Filter cells and re-calculate color by lowerPercentile (0-100) (default: 0) */
lowerPercentile?: number;
/** Filter cells and re-calculate color by upperPercentile (0-100) (default: 100) */
upperPercentile?: number;Controls 3D height of hexagons when extruded is true.
/** Function to extract weight value for elevation aggregation */
getElevationWeight?: Accessor<DataT, number>;
/** Aggregation operation for elevation values (default: 'SUM') */
elevationAggregation?: AggregationOperation;
/** Range of elevation values [min, max] (default: [0, 1000]) */
elevationRange?: [number, number];
/** Domain for elevation scale [min, max] */
elevationDomain?: [number, number] | null;
/** Scale factor for elevation values (default: 1) */
elevationScale?: number;
/** Scaling function used to determine the elevation of the grid cell (default: 'linear') */
elevationScaleType?: 'linear';
/** Filter cells and re-calculate elevation by elevationLowerPercentile (0-100) (default: 0) */
elevationLowerPercentile?: number;
/** Filter cells and re-calculate elevation by elevationUpperPercentile (0-100) (default: 100) */
elevationUpperPercentile?: number;
/** Material properties for 3D rendering */
material?: Material;The layer uses a hexagonal binning algorithm that:
// Built-in hexagon utilities (from hexbin.ts)
const HexbinVertices: number[][];
function pointToHexbin([px, py]: Point, radius: number): HexBin;
function getHexbinCentroid([i, j]: HexBin, radius: number): Point;
// GLSL shader functions for GPU computation
const pointToHexbinGLSL: string;
const getHexbinCentroidGLSL: string;// Population density with elevation
const densityLayer = new HexagonLayer({
id: "density",
data: populationData,
getPosition: (d) => d.coordinates,
getColorWeight: (d) => d.population,
getElevationWeight: (d) => d.population,
radius: 10000,
extruded: true,
elevationScale: 2,
colorAggregation: 'SUM',
elevationAggregation: 'SUM'
});
// Temporal analysis with separate metrics
const temporalLayer = new HexagonLayer({
id: "temporal",
data: timeSeriesData,
getPosition: (d) => [d.lng, d.lat],
getColorWeight: (d) => d.dayCount, // Daytime activity
getElevationWeight: (d) => d.nightCount, // Nighttime activity
radius: 3000,
extruded: true,
colorAggregation: 'MEAN',
elevationAggregation: 'MEAN',
colorRange: [[255, 255, 0], [255, 0, 0]], // Yellow to red
elevationScale: 5
});