Skip to content

Hexbin Layer

Visualizing shot density using hexogonal binning.

Basic Density

The simplest usage aggregates shot locations into hexogonal bins.

typescript
import { Rink, NHLDataManager } from "d3-hockey";

// 1. Load Data
const manager = await NHLDataManager.fromGameId("2022020195");
const shots = manager.getAllEvents({ shotsOnly: true });

// 2. Render Rink with Hexbin Layer
new Rink("#container").render().addHexbin(shots, {
  radius: 4, // 4ft bins
  opacity: 0.8,
  aggregation: "count",
});

Custom Bin Size

You can adjust the radius to change the granularity of the bins. Larget radii (e.g., 8ft) provide a smoother, more generalized view, while smaller radii (e.g., 2.5ft) show precise hotspots.

typescript
new Rink("#container").render().addHexbin(shots, {
  radius: 8, // Larger 8ft bins
  opacity: 0.7,
  stroke: "#fff", // Add white borders
  strokeWidth: 1,
});

Aggregation by Value

Instead of just counting shots, you can aggregate by a metric (like average shot distance, expected goals, or speed) using the value accessor and aggregation: "mean".

typescript
// Calculate distance for each shot
new Rink("#container").render().addHexbin(shots, {
  radius: 5,
  // Calculate distance from center ice (0,0) as a mock metric (this mock metric isn't very 
  // practically useful but just serves as an example in using the aggregation functionality)
  value: (d) => Math.sqrt(d.coordinates.x ** 2 + d.coordinates.y ** 2),
  aggregation: "mean",
  colorScale: d3.scaleSequential(d3.interpolateViridis),
  opacity: 0.9,
});