or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

brushing.mddata-filtering.mdgeometry-operations.mdindex.mdlegacy-experimental.mdstyling.md
tile.json

brushing.mddocs/

Interactive Brushing

GPU-based interactive brushing functionality that enables layers to show/hide objects based on the current pointer position, allowing for real-time data exploration and filtering.

Capabilities

BrushingExtension

Adds GPU-based data brushing functionalities to layers, allowing interactive show/hide of objects based on pointer position.

/**
 * Adds GPU-based data brushing functionalities to layers
 * Allows layers to show/hide objects based on current pointer position
 */
class BrushingExtension extends LayerExtension {
  static extensionName: 'BrushingExtension';
  static defaultProps: BrushingExtensionDefaultProps;
  
  constructor();
  
  getShaders(): any;
  initializeState(context: LayerContext, extension: this): void;
  finalizeState(context: LayerContext, extension: this): void;
  draw(params: any, extension: this): void;
}

interface BrushingExtensionProps<DataT = any> {
  /**
   * Called to retrieve an arbitrary position for each object that it will be filtered by.
   * Only effective if `brushingTarget` is set to `custom`.
   * @default {type: 'accessor', value: [0, 0]}
   */
  getBrushingTarget?: Accessor<DataT, [number, number]>;
  
  /**
   * Enable/disable brushing. If brushing is disabled, all objects are rendered.
   * @default true
   */
  brushingEnabled?: boolean;
  
  /**
   * The position used to filter each object by.
   * - 'source': Use source position of objects
   * - 'target': Use target position of objects  
   * - 'source_target': Use both source and target positions
   * - 'custom': Use position from getBrushingTarget accessor
   * @default 'source'
   */
  brushingTarget?: 'source' | 'target' | 'source_target' | 'custom';
  
  /**
   * The brushing radius centered at the pointer, in meters. 
   * If a data object is within this circle, it is rendered; otherwise it is hidden.
   * @default 10000
   */
  brushingRadius?: number;
}

interface BrushingExtensionDefaultProps {
  getBrushingTarget: {type: 'accessor', value: [number, number]};
  brushingTarget: 'source';
  brushingEnabled: boolean;
  brushingRadius: number;
}

Usage Examples:

import { ScatterplotLayer } from "@deck.gl/layers";
import { BrushingExtension } from "@deck.gl/extensions";

// Basic brushing with default settings
const basicBrushingLayer = new ScatterplotLayer({
  id: "brushing-points",
  data: points,
  extensions: [new BrushingExtension()],
  getPosition: d => d.coordinates,
  getRadius: 50,
  brushingEnabled: true,
  brushingRadius: 25000 // 25km radius
});

// Custom brushing target
const customBrushingLayer = new ScatterplotLayer({
  id: "custom-brushing",
  data: connections,
  extensions: [new BrushingExtension()],
  getPosition: d => d.start,
  brushingTarget: 'custom',
  getBrushingTarget: d => d.center, // Use center point for brushing
  brushingRadius: 50000
});

// Brushing with source and target positions (for arc layers)
const arcBrushingLayer = new ArcLayer({
  id: "brushing-arcs",
  data: flights,
  extensions: [new BrushingExtension()],
  getSourcePosition: d => d.origin,
  getTargetPosition: d => d.destination,
  brushingTarget: 'source_target', // Brush based on both endpoints
  brushingRadius: 100000
});

Integration with Mouse Events

The BrushingExtension automatically integrates with deck.gl's event system:

  • Listens to pointermove and pointerleave events
  • Automatically triggers layer redraws when the pointer moves
  • Uses the current mouse/pointer position as the center of the brushing circle
  • Event listeners are automatically cleaned up when the layer is destroyed

Performance Considerations

  • Brushing calculations are performed entirely on the GPU for optimal performance
  • Objects outside the brushing radius are culled during rendering, not filtered from data
  • Works efficiently with large datasets (millions of objects)
  • Minimal CPU overhead as mouse position is passed directly to shaders

Shader Integration

The extension injects a custom shader module that:

  • Calculates distance from each object to the current pointer position
  • Applies brushing radius filtering in the vertex shader
  • Supports different coordinate systems and projection modes
  • Handles the different brushing target modes (source, target, custom)

Compatibility

  • Works with all deck.gl layers that support extensions
  • Particularly useful with: ScatterplotLayer, IconLayer, TextLayer, ArcLayer, LineLayer
  • Compatible with other extensions (can be combined with DataFilterExtension, etc.)
  • Supports both WebGL and WebGPU rendering backends