KDE
Smoothed kernel-density estimate over a pitch. Use it when the story is spatial concentration rather than exact bin counts. The hero shows a real touch sample normalized through the adapter layer.
Interactive props.
Canonical behaviors.
Alternative ramp for the same density model. Good when the page needs a cooler analytical read.
Narrow smoothing creates more localized hotspots and preserves smaller clusters.
Broader smoothing creates a more generalized shape and hides secondary peaks.
Portrait layout proves the density surface and tooltip coordinates still read cleanly off the same model.
Small samples are where smoothing choices matter most. This is a useful honesty check, not just a fallback.
No density surface and no fake tooltip region when nothing is plottable.
Shared concerns.
Choose KDE
Use KDE when you want a smoothed spatial estimate. Use Heatmap for inspectable
bins, and use Territory when the chart should collapse into editorial
zones.
Interaction
Hover and focus report the pitch coordinate and normalized density under the cursor. That is the main reason this component stays interactive in docs.
Themeability
Pitch theming comes from Stadia. Dark ramps automatically switch pitch lines to
a light contrast treatment unless autoPitchLines is disabled.
Export
KDE is not part of the current static-export surface. The rasterized density image is fine in the browser, but it is not yet wired into the Phase 1 export contract.
Composition
KDE is strongest as a standalone surface. If the story needs exact cell semantics or visible percentages, that usually means Heatmap or Territory is the better component.
Normal, small, smallest.
Pitch-based charts scale fluidly to whatever width the parent gives them. The 'smallest' cell is sized for a 5×4 small-multiples grid (~140px wide). Vertical orientation only — horizontal pitches are too wide for small-multiples.
Best-practice examples.
Minimal usage
Use KDE when you want a smoothed estimate of where events cluster rather than explicit bins.
import { KDE } from "@withqwerty/campos-react";
type EventPoint = {
x: number | null;
y: number | null;
};
type Props = {
events: EventPoint[];
};
export function TeamKDE({ events }: Props) {
return <KDE events={events} />;
}
Controlled smoothing
Bandwidth is the first meaningful customization. Keep the event shape unchanged.
import { KDE } from "@withqwerty/campos-react";
type EventPoint = {
x: number | null;
y: number | null;
};
type Props = {
events: EventPoint[];
};
export function TeamKDESmoothed({ events }: Props) {
return (
<KDE
events={events}
areas={{ palette: "viridis" }}
bandwidth={3}
/>
);
}
Public surface.
| Prop | Type | Default | Description |
|---|---|---|---|
events | readonly { x: number | null; y: number | null }[] | required | Array of positional events in canonical Campos pitch coordinates. |
bandwidth | "auto" | number | "auto" | Smoothing bandwidth in pitch-coordinate units. |
resolution | number | 100 | Density grid resolution before rasterization into the SVG image surface. |
threshold | number | 0.05 | Values below this density threshold are rendered transparent. |
normalize | boolean | true | Normalizes density into a 0..1 readout for the tooltip and scale. |
orientation | "horizontal" | "vertical" | "horizontal" | Pitch orientation for the density surface. |
crop | "full" | "half" | "full" | Pitch crop. |
pitchTheme | "primary" | "secondary" | "primary" | Delegated Stadia surface preset. |
pitchColors | PitchColors | — | Direct pitch color overrides for branded or editorial surfaces. |
autoPitchLines | boolean | true | Automatically switches pitch lines to white on dark density ramps so markings stay visible. |
areas | { palette?, colorStops?, opacity?, show? } | — | Area styling surface for the density raster. Use `palette` or `colorStops` for the ramp and `opacity` / `show` for presentation. |
guides | { showScaleBar?, label? } | — | Guide styling surface for the scale bar. Hide it or rename it through constant, map, or callback style values. |
Create a React component using Campos KDE. Import KDE from @withqwerty/campos-react, keep data parsing outside the component, show the smallest good usage first, then show one variant with a custom bandwidth.