Hexbin Density
Hexagonal density binning that turns an overplotted scatter into a readable heat field, surfacing the modal cluster and the x↔y correlation in plain language.
Pipeline velocity
170
records · 86 cells
170 records across 86 cells; the densest cluster sits around $20k / 33d (3% of points) — higher deal size (usd) tends toward higher days to close (r = +0.91).
| Deal size (USD) ≈ | Days to close ≈ | Records |
|---|---|---|
| $20k | 33d | 5 |
| $8k | 24d | 5 |
| $15k | 33d | 5 |
| $57k | 57d | 5 |
| $25k | 16d | 4 |
| $3k | 8d | 4 |
| $59k | 66d | 4 |
| $47k | 41d | 4 |
| $3k | 24d | 4 |
| $35k | 33d | 4 |
| $32k | 41d | 3 |
| $40k | 49d | 3 |
| $28k | 24d | 3 |
| $18k | 24d | 3 |
| $86k | 74d | 3 |
| $71k | 41d | 3 |
| $64k | 49d | 3 |
| $37k | 41d | 3 |
| $6k | 16d | 3 |
| $84k | 66d | 3 |
| $52k | 57d | 3 |
| $115k | 74d | 3 |
| $50k | 49d | 3 |
| $76k | 57d | 3 |
Acme CRM · closed deals Jan–Jun 2026 · updated daily
Demo data is illustrative. Replace with your own typed data prop.
Use it with your data
Data contract
Passed via the data prop — an object: validated at runtime, so a bad shape degrades to the error state rather than crashing.
| Field | Type | Required |
|---|---|---|
| points | array | yes |
| xLabel | string | no |
| yLabel | string | no |
Static props
import { ChartHexbinDensity } from "@/components/blocks/chart-hexbin-density/chart-hexbin-density";
<ChartHexbinDensity data={myData} />Client fetch (SWR)
const { data, isLoading, error } = useSWR("/api/metric", fetcher);
// route isLoading/error through <ChartStates>, then:
<ChartHexbinDensity data={data} />Server component (RSC)
const data = await fetch(url, {
next: { revalidate: 3600 },
}).then((r) => r.json());
<ChartHexbinDensity data={data} />Map arbitrary rows
import { mapRows } from "@/lib/sextant/column-map";
const out = mapRows(rows, { /* contractKey: "yourColumn" */ }, dataSchema);
if (out.ok) <ChartHexbinDensity data={out.data} />;Make it yours
Every customization below is an optional prop — omit them all and you get the defaults shown above. Recolor, reformat, restyle, or drop the card chrome without forking the component.
Recolor or rename a series (bin)
<ChartHexbinDensity
series={{ bin: { color: "var(--chart-3)", label: "…" } }}
/>Replace or hide the narrative
<ChartHexbinDensity narrative="Your own one-liner." />
// …or hide it entirely:
<ChartHexbinDensity narrative={false} />Restyle any region
<ChartHexbinDensity
className="max-w-xl"
classNames={{ body: "bg-muted/20" }}
/>Drop the card chrome (headless plot)
import { ChartHexbinDensityPlot } from "@/components/blocks/chart-hexbin-density/chart-hexbin-density";
// Just the chart body — bring your own card/layout:
<ChartHexbinDensityPlot data={data} config={config} />