Band
Shaded range between per-row upper and lower values on a line chart — min/max ranges, confidence intervals, and Bollinger bands
Installation
pnpm dlx shadcn@latest add @bklit/bandBand also ships with @bklit/line-chart, so it is already available if you installed the line chart.
Usage
Band fills the area between two data keys on every row — a min/max range, a forecast interval, or Bollinger bands. Use it inside LineChart and place it before your <Line>s so the lines paint on top.
- It animates in left-to-right with the lines through the shared reveal clip, and morphs with them when
datachanges. - Both edges extend the y-domain, so the band is never clipped at the top or bottom of the plot.
- It is decorative: the tooltip only reports
<Line>series, not the band's edge values. null/ non-numeric edge values break the band into separate segments.
import { Band, ChartTooltip, Grid, Line, LineChart, XAxis } from "@bklitui/ui/charts";
const data = [
{ date: new Date("2024-01-01"), value: 142, valueUpper: 160, valueLower: 125 },
{ date: new Date("2024-01-02"), value: 151, valueUpper: 170, valueLower: 133 },
// ...
];
<LineChart data={data}>
<Grid horizontal />
<Band upperKey="valueUpper" lowerKey="valueLower" />
<Line dataKey="value" />
<XAxis />
<ChartTooltip />
</LineChart>Bollinger bands
withBollingerBands adds a rolling simple moving average (SMA) ± multiplier standard deviations to each row. Rows before the window fills get null for all three keys, which Band renders as a gap (pass minPeriods: 1 to start at the first row instead).
To draw the SMA as a dashed middle line, use a second, zero-height Band with the same key for both edges — unlike Line, it skips the warm-up nulls.
import { Band, withBollingerBands } from "@bklitui/ui/charts";// Adds priceUpper / priceLower / priceSma (null during the warm-up window)const bollingerData = withBollingerBands(data, {dataKey: "price",period: 10,multiplier: 2,});<LineChart data={bollingerData}><Grid horizontal /><Band upperKey="priceUpper" lowerKey="priceLower" fill="var(--chart-1)" fillOpacity={0.12} strokeOpacity={0.5}/><Band upperKey="priceSma" lowerKey="priceSma" fillOpacity={0} stroke="var(--chart-1)" strokeDasharray="4,4" strokeOpacity={0.8} lowerStroke={false}/><Line dataKey="price" strokeWidth={2} /><XAxis /><ChartTooltip /></LineChart>| Option | Type | Default | Description |
|---|---|---|---|
dataKey | string | required | Numeric key to compute bands for |
period | number | 20 | Rolling window length (rows) |
multiplier | number | 2 | Standard deviations above and below the SMA |
minPeriods | number | period | Minimum valid rows in the window before a value is emitted. Set 1 to start the band at the first row using a partial window |
upperKey | string | `${dataKey}Upper` | Key written for the upper band |
lowerKey | string | `${dataKey}Lower` | Key written for the lower band |
middleKey | string | `${dataKey}Sma` | Key written for the SMA |
withBollingerBands returns new rows and leaves the input array untouched. It uses the population standard deviation. Non-numeric values are skipped, and a row yields null when its window has fewer than minPeriods valid values — by default the full window must be numeric. With minPeriods: 1 the first row's spread is zero, so the band starts pinched onto the line and widens as the window fills.
Fill types
fillType switches between a flat "solid" fill, a vertical "gradient" (from fillOpacity at the upper edge to gradientToOpacity at the lower edge), and a "pattern" fill using the Background presets.
<Band upperKey="valueUpper" lowerKey="valueLower" fill="var(--chart-1)" fillType="gradient" // "solid" | "gradient" | "pattern" fillOpacity={0.4} pattern="diagonal" patternOpacity={0.6} strokeOpacity={0.5} />Edges
Faded edges
fadeEdges fades the fill and strokes to transparent. Horizontal fades span the plot width; vertical fades span the band's own pixel height. fadeSize sets how much of that width or height each fade covers.
<Band upperKey="valueUpper" lowerKey="valueLower" fill="var(--chart-3)" fillOpacity={0.2} strokeDasharray="4,4" strokeOpacity={0.7} fadeEdges={{ left: true, right: true }} fadeSize={0.2} />Edge strokes
Both edges share stroke, strokeWidth, strokeDasharray, and strokeOpacity. Override one edge with upperStroke / lowerStroke, or pass false to hide it.
<Band upperKey="valueUpper" lowerKey="valueLower" fill="var(--chart-line-primary)" fillType="gradient" fillOpacity={0.3} upperStroke={{ strokeDasharray: "1,3", strokeWidth: 1.5 }} lowerStroke={false} />Band props
| Prop | Type | Default | Description |
|---|---|---|---|
upperKey | string | required | Data key for the upper edge |
lowerKey | string | required | Data key for the lower edge |
yAxisId | string | "left" | Y-scale group id |
curve | CurveFactory | curveNatural | D3 curve function (match your Line) |
fill | string | var(--chart-line-primary) | Band color |
fillType | "solid" | "gradient" | "pattern" | "solid" | Fill style |
fillOpacity | number | 0.15 | Solid opacity, or gradient opacity at the upper edge |
gradientToOpacity | number | 0 | Gradient opacity at the lower edge |
pattern | Pattern preset id | "diagonal" | Pattern when fillType is "pattern" |
patternColor | string | fill | Pattern stroke or tile color |
patternScale | number | — | Pattern tile scale |
patternStrokeWidth | number | — | Line stroke width for line-based patterns |
patternOpacity | number | 1 | Opacity of the pattern fill |
stroke | string | fill | Shared edge stroke color |
strokeWidth | number | 1 | Shared edge stroke width (0 hides both edges) |
strokeDasharray | string | — (solid) | Shared edge dash pattern |
strokeOpacity | number | 1 | Shared edge stroke opacity |
upperStroke | BandStrokeProps | false | — | Override the top edge, or false to hide it |
lowerStroke | BandStrokeProps | false | — | Override the bottom edge, or false to hide it |
fadeEdges | BandFadeEdges | false | Fade fill and strokes at the given sides |
fadeSize | number | 0.15 | Fraction (0–0.5) of the width / height each fade covers |
className | string | "chart-band" | Class on the band's <g> |
BandStrokeProps
Every field falls back to the matching shared Band prop.
| Prop | Type | Default | Description |
|---|---|---|---|
stroke | string | Band stroke ?? fill | Edge color |
strokeWidth | number | Band strokeWidth | Edge width (0 hides the edge) |
strokeDasharray | string | Band strokeDasharray | Edge dash pattern |
strokeOpacity | number | Band strokeOpacity | Edge opacity |
BandFadeEdges
type BandFadeEdges =
| boolean
| "left"
| "right"
| { top?: boolean; right?: boolean; bottom?: boolean; left?: boolean };| Value | Fades |
|---|---|
false | Nothing (default) |
true | All four sides |
"left" / "right" | That horizontal side only |
{ left: true, right: true } | Any combination of sides |
Studio
Edit in Studio
Open in StudioOpen Studio with the line chart and turn on the Band layer in the components panel. Set Mode to Range (upper / lower) or Bollinger bands, then tune fill, edges, and fades — the generated code includes the data shaping.