CortexcnCortexcn

Brush

Time-range brush for zooming area and line charts with a mini-chart strip and draggable selection handles

Installation

ChartBrush and ChartBrushLayout ship with time-series charts. Install the area chart (or line chart) registry item, then import from your charts package:

import {
  AreaChart,
  Area,
  ChartBrush,
  ChartBrushLayout,
  Grid,
  XAxis,
  ChartTooltip,
} from "@/components/charts";

Usage

Wrap the main chart in ChartBrushLayout. Render a simplified mini chart in brushStrip with ChartBrush as a child. Pass xDomain, xDomainSlotCount, and tweenYDomainOnXDomainChange to the main chart so it zooms and tweens the y-scale as the brush changes.

<ChartBrushLayout
  data={data}
  enabled
  height={72}
  brushStrip={(layout) => (
    <AreaChart
      animationDuration={0}
      data={data}
      status="ready"
      style={{ aspectRatio: "unset", height: "100%" }}
    >
      <Area
        dataKey="value"
        fillOpacity={0.15}
        animate={false}
        showHighlight={false}
      />
      <ChartBrush
        initialSelection={layout.brushSelection ?? undefined}
        onSelectionChange={layout.onBrushSelectionChange}
      />
    </AreaChart>
  )}
>
  {(layout) => (
    <AreaChart
      data={data}
      tweenYDomainOnXDomainChange
      xDomain={layout.xDomain}
      xDomainSlotCount={layout.xDomainSlotCount}
      yDomainTween
    >
      <Grid horizontal />
      <Area dataKey="value" fillOpacity={0.35} />
      <XAxis />
      <ChartTooltip />
    </AreaChart>
  )}
</ChartBrushLayout>

Works the same with LineChart and Line in the brush strip and main chart. See Area Chart and Line Chart for chart-specific notes.

ChartBrushLayout

Orchestrates the main chart and optional brush strip. Owns brush selection state and derives xDomain for the main chart.

PropTypeDefaultDescription
dataRecord<string, unknown>[]requiredFull dataset for the brush strip and main chart
xDataKeystring"date"Key in data for x-axis values
enabledbooleanrequiredWhen false, children render without brush zoom
heightnumberrequiredBrush strip height in pixels
brushStrip(layout) => ReactNode—Mini chart + ChartBrush below the main chart
children(layout) => ReactNoderequiredMain chart render function
classNamestring—Wrapper class name

The layout argument provides:

FieldTypeDescription
xDomain[Date, Date] | undefinedVisible x-range for the main chart
xDomainSlotCountnumber | undefinedFull dataset length for x-scale padding
brushSelection{ start: Date; end: Date } | nullCurrent brush window
onBrushSelectionChange(selection) => voidPass to ChartBrush onSelectionChange

ChartBrush

Renders inside a time-series chart (typically the brush strip). Drag handles to pan and resize; the main chart zooms via ChartBrushLayout.

PropTypeDefaultDescription
onSelectionChange(domain) => void—Fires while dragging with the selected date range
initialSelection{ start: Date; end: Date }—Initial brush window
selection{ start: Date; end: Date }—Controlled selection
brushDirection"horizontal" | "vertical" | "both""horizontal"Brush axis
blurPxnumber1.5Backdrop blur on dimmed track (0–5 px)
fadeOuterEdgesbooleantrueFade dimmed regions at outer track edges
selectionPattern{ preset; color }—Pattern fill inside the selection window
useWindowMoveEventsbooleantrueUse window move events (recommended for brush strips)

Selection pattern presets

selectionPattern.preset accepts: diagonal, horizontal, vertical, cross, dots, or accent. Omit selectionPattern for a solid selection fill.

Main chart props

When brush zoom is active, pass these to AreaChart or LineChart:

PropTypeDefaultDescription
xDomain[Date, Date]—Visible x-range from layout.xDomain
xDomainSlotCountnumber—layout.xDomainSlotCount (full data length)
tweenYDomainOnXDomainChangebooleanfalseTween y-domain when the brush changes the visible range

CSS variables

VariableDefaultDescription
--chart-brush-bordervar(--chart-grid)Brush handle border color