/

Range Chart

Display data ranges with min/max bands. Perfect for temperature ranges, confidence intervals, and forecast uncertainty.

JanFebMarAprMayJun010203040LowHigh

Quick Start

import { RangeChart } from "@chartts/react"
 
const data = [
  { month: "Jan", low: -2, high: 5, avg: 1.5 },
  { month: "Feb", low: -1, high: 7, avg: 3.0 },
  { month: "Mar", low: 2, high: 12, avg: 7.0 },
  { month: "Apr", low: 5, high: 16, avg: 10.5 },
  { month: "May", low: 9, high: 21, avg: 15.0 },
  { month: "Jun", low: 13, high: 26, avg: 19.5 },
]
 
export function TemperatureRange() {
  return (
    <RangeChart
      data={data}
      x="month"
      min="low"
      max="high"
      mid="avg"
      className="h-64 w-full"
    />
  )
}

That renders a shaded band between the min and max values with an optional midline. Axes, tooltips, responsive scaling, and smooth band interpolation are all automatic.

When to Use Range Charts

Range charts show the spread between two values across a continuous axis. The filled band communicates uncertainty, variability, or the extent of a range at each point.

Use a range chart when:

  • Showing temperature ranges (daily low to high)
  • Displaying confidence intervals around a forecast or estimate
  • Visualizing min/max bounds for sensor readings, latency, or performance metrics
  • Communicating forecast uncertainty with prediction bands

Don't use a range chart when:

  • You only have a single value per point (use a line chart)
  • The range is always zero or near-zero (just use a line chart)
  • You want to show the distribution shape at each point (use a violin or box plot)
  • Precise comparison of upper and lower bounds matters (use a table)

Props Reference

PropTypeDefaultDescription
dataT[]requiredArray of data objects
xkeyof TrequiredKey for x-axis values
minkeyof TrequiredKey for the lower bound of the range
maxkeyof TrequiredKey for the upper bound of the range
midkeyof T-Key for the midpoint/average line
fillColorstring'#3b82f6'Fill color for the range band
fillOpacitynumber0.2Opacity of the range band fill (0 to 1)
strokeColorstring'#3b82f6'Stroke color for the min/max boundary lines
showMidLinebooleantrueShow the midpoint line when mid is provided
showDotsbooleanfalseShow markers at mid, min, and max points
animatebooleantrueEnable draw animation on mount
classNamestring-Tailwind classes on the root SVG

Range Band Fill

The range band is the filled area between the min and max values. It is the primary visual element of a range chart.

<RangeChart
  data={data}
  x="month"
  min="low"
  max="high"
  fillColor="#3b82f6"
  fillOpacity={0.2}
  strokeColor="#3b82f6"
  className="h-72"
/>

The fillOpacity controls how transparent the band is. Lower values produce a subtle background wash. Higher values produce a more prominent band.

// Subtle band
<RangeChart
  data={data}
  x="month"
  min="low"
  max="high"
  fillOpacity={0.1}
/>
 
// Prominent band
<RangeChart
  data={data}
  x="month"
  min="low"
  max="high"
  fillOpacity={0.4}
/>

The boundary lines at the min and max edges help define the band's shape precisely. They use strokeColor which defaults to the same hue as the fill.


Midline Overlay

When you provide a mid prop, a solid line is drawn through the center of the range. This typically represents the mean, median, or primary forecast value.

<RangeChart
  data={data}
  x="month"
  min="low"
  max="high"
  mid="avg"
  showMidLine
  strokeColor="#2563eb"
  fillColor="#3b82f6"
  fillOpacity={0.15}
  className="h-72"
/>

The midline is styled with a slightly thicker stroke than the boundary lines so it stands out as the primary data line. Disable it with showMidLine={false} if you only want the band.

// Band only, no midline
<RangeChart
  data={data}
  x="month"
  min="low"
  max="high"
  showMidLine={false}
/>

Confidence Intervals

Range charts are the standard way to visualize confidence intervals. The band represents the interval and the midline represents the point estimate.

const forecast = [
  { date: "Week 1", predicted: 1200, lower95: 1050, upper95: 1350 },
  { date: "Week 2", predicted: 1350, lower95: 1120, upper95: 1580 },
  { date: "Week 3", predicted: 1500, lower95: 1180, upper95: 1820 },
  { date: "Week 4", predicted: 1620, lower95: 1210, upper95: 2030 },
  { date: "Week 5", predicted: 1700, lower95: 1200, upper95: 2200 },
]
 
<RangeChart
  data={forecast}
  x="date"
  min="lower95"
  max="upper95"
  mid="predicted"
  fillColor="#8b5cf6"
  fillOpacity={0.15}
  strokeColor="#8b5cf6"
  className="h-72 w-full"
/>

The widening band communicates increasing uncertainty further into the future, which is exactly how forecast confidence intervals behave.


Temperature Range Pattern

Displaying daily temperature ranges is one of the most intuitive uses for a range chart. People naturally understand a band representing "low to high" temperatures.

const weeklyTemps = [
  { day: "Mon", low: 12, high: 22, avg: 17 },
  { day: "Tue", low: 14, high: 25, avg: 19 },
  { day: "Wed", low: 11, high: 20, avg: 15 },
  { day: "Thu", low: 13, high: 23, avg: 18 },
  { day: "Fri", low: 15, high: 27, avg: 21 },
  { day: "Sat", low: 16, high: 28, avg: 22 },
  { day: "Sun", low: 14, high: 24, avg: 19 },
]
 
<RangeChart
  data={weeklyTemps}
  x="day"
  min="low"
  max="high"
  mid="avg"
  fillColor="#f97316"
  fillOpacity={0.2}
  strokeColor="#f97316"
  showDots
  className="h-72 w-full"
/>

Adding showDots marks the exact low, high, and average values at each point, making the chart useful for reading specific values as well as seeing the overall pattern.


Accessibility

  • The chart has role="img" with an aria-label summarizing the overall range and number of data points
  • Each data point is announced with its x-value, min, max, and mid values
  • Keyboard navigation: Tab to focus the chart, arrow keys to move between data points
  • The tooltip follows the focused point and displays the full range values
  • Range boundaries are rendered as visible lines in addition to the filled area, ensuring readability at all opacity levels
  • Animation respects prefers-reduced-motion

Real-World Examples

API response time range

const latencyData = [
  { hour: "00:00", p5: 12, p50: 45, p95: 180 },
  { hour: "04:00", p5: 10, p50: 38, p95: 150 },
  { hour: "08:00", p5: 15, p50: 62, p95: 280 },
  { hour: "12:00", p5: 18, p50: 75, p95: 350 },
  { hour: "16:00", p5: 20, p50: 80, p95: 310 },
  { hour: "20:00", p5: 14, p50: 55, p95: 220 },
]
 
<RangeChart
  data={latencyData}
  x="hour"
  min="p5"
  max="p95"
  mid="p50"
  fillColor="#22c55e"
  fillOpacity={0.15}
  strokeColor="#22c55e"
  className="h-64 w-full rounded-lg bg-zinc-950 p-4"
/>

Sales forecast with uncertainty

<RangeChart
  data={quarterlyForecast}
  x="quarter"
  min="lowerBound"
  max="upperBound"
  mid="forecast"
  fillColor="#6366f1"
  fillOpacity={0.2}
  strokeColor="#6366f1"
  showDots
  className="h-72 w-full"
/>

Blood pressure tracking

const bpReadings = [
  { date: "Mon", systolic: 128, diastolic: 82 },
  { date: "Tue", systolic: 135, diastolic: 88 },
  { date: "Wed", systolic: 122, diastolic: 78 },
  { date: "Thu", systolic: 130, diastolic: 85 },
  { date: "Fri", systolic: 126, diastolic: 80 },
]
 
<RangeChart
  data={bpReadings}
  x="date"
  min="diastolic"
  max="systolic"
  fillColor="#ef4444"
  fillOpacity={0.15}
  strokeColor="#ef4444"
  showDots
  className="h-64 w-full"
/>

Other Charts