010 / RECHARTS / LINE
Forecast Line
Observed-versus-forecast time-series with explicit prediction styling, truthful boundary transitions, and optional uncertainty range treatment.
- SPEC
- #010
- ENGINE
- Recharts
- FAMILY
- Line
- RENDERER
- svg
- STATUS
- preview
Installation
Checking public registry…
View local registry JSONCopied as source into your project (requires recharts).
Overview
Forecast Line is an analytical time-series component engineered around the fundamental principle of epistemic separation: strictly distinguishing what has actually occurred from what is predicted to happen next.
The central analytical question answered by this chart is:
"What has actually happened, what is predicted to happen next, and how uncertain is that prediction?"
Forecast Line must never blur the semantic difference between observed data, predicted data, and uncertainty around predictions.
Observed History Transitioning into Predicted Future with Uncertainty
import { ForecastLine } from "@/components/charts/recharts/line-forecast"const activeUserData = [ { month: "Jan", actual: 82, forecast: null, lower: null, upper: null }, { month: "Feb", actual: 91, forecast: null, lower: null, upper: null }, { month: "Mar", actual: 104, forecast: 104, lower: 104, upper: 104 }, { month: "Apr", actual: null, forecast: 112, lower: 103, upper: 121 }, { month: "May", actual: null, forecast: 121, lower: 108, upper: 134 }, { month: "Jun", actual: null, forecast: 130, lower: 114, upper: 146 },]export function MonthlyUserForecast() { return ( <ForecastLine data={activeUserData} xKey="month" series={{ actualKey: "actual", forecastKey: "forecast", lowerKey: "lower", upperKey: "upper", actualLabel: "Actual Users", forecastLabel: "Forecast Users", confidenceLabel: "Forecast Range", valueFormatter: (v) => `${v.toLocaleString()}k`, }} showLegend lockableTooltip showGrid /> )}Line-Family Positioning
Plotcn provides specialized line chart components for distinct analytical and operational roles. It is essential to select the component that accurately matches data semantics:
| Component | Number | Primary Analytical Specialty |
|---|---|---|
| Signal Line | 001 | Single continuous quantitative trend |
| Pulse Line | 002 | Live operational telemetry with rolling window and pulse marker |
| Twinline Compare | 003 | Explicit two-role comparison (primary signal vs. reference baseline) |
| Range Line | 004 | Continuous trend plus uncertainty envelope / confidence interval across all observations |
| Step Signal | 005 | Discrete state transitions and quota tier changes |
| Milestone Line | 006 | Trend line annotated with sparse releases and milestones |
| Threshold Line | 007 | Quantitative trend evaluated against operational limits and bands |
| Focus Line | 008 | High-precision single-series observation scrubbing and locked pins |
| Multi-Signal Line | 009 | Multiple peer series with deterministic identity and interactive legend |
| Forecast Line | 010 | Observed history transitioning into predicted future with uncertainty |
Critical Distinction — Forecast vs. Twinline Compare
In Twinline Compare, both lines (Current and Previous) are typically real historical peer series. In Forecast Line, the observed series and predicted series represent different epistemic realities: facts versus projections. Forecast Line uses distinct line styles (solid vs. dashed), independent confidence treatment, and differentiated tooltip semantics.
Critical Distinction — Forecast vs. Range Line
In Range Line, the interval envelope belongs to the primary series throughout the entire observation domain. In Forecast Line, uncertainty typically begins only where prediction begins. Historical facts have zero uncertainty unless explicitly documented in historical records.
Forecast Model & Principles
Forecast Line enforces strict analytical boundaries:
- Plotcn Does Not Calculate Forecasts: Forecast Line receives predicted values and bounds directly from your application or forecasting backend (e.g., ARIMA, Prophet, Holt-Winters, ML service). Plotcn never extrapolates lines or generates predictions.
- Non-Color Distinction is Mandatory: Observed data renders as a solid line (
strokeWidth={2}). Predicted data renders as a dashed line (strokeDasharray="5 5"). This ensures clear separation under any color scheme, including Monochrome or high-contrast themes. - Restrained Presentation: Forecast Line avoids distracting visual effects such as animated dash offset ("marching ants") or glowing projections. Predictions are uncertain, not "loading".
Transition Boundary Semantics
The forecast transition marks the chronological boundary where observed facts hand off to predicted values.
How Plotcn Truthfully Resolves the Forecast Transition Boundary
The final actual observation shares the exact coordinate and value with the first forecast observation.
Actual history ends at Mar, and forecast begins at Apr with no shared bridge point.
Both actual and forecast exist across multiple intervals for backtesting or model evaluation.
Forecast Line deterministically handles three data arrangements:
A. Shared Transition Bridge (Continuous Handoff)
Month Actual Forecast Lower UpperMar 104 104 104 104Apr — 112 103 121The boundary observation (Mar) contains matching values for both actual and forecast. This creates a clean, continuous transition across the timeline without gaps.
B. Discontinuous Separation (Truthful Gap)
Month Actual Forecast Lower UpperMar 104 — — —Apr — 112 103 121Observed history ends before prediction starts. Plotcn visually preserves this gap. Plotcn never fabricates an artificial bridge point just to make the chart look connected.
C. Overlapping Actual & Forecast (Evaluation / Backtesting)
Month Actual Forecast Lower UpperMar 104 98 90 106Apr 112 105 97 113When comparing historical model performance against observed outcomes, actual and forecast lines render concurrently, each retaining its respective visual style (solid vs. dashed).
Confidence & Uncertainty Treatment
When lowerKey and upperKey are configured, Forecast Line renders a translucent prediction band behind the forecast line:
- Supplied Bounds Only: Plotcn never calculates synthetic confidence bounds (e.g.,
±10%or standard errors). All bounds are supplied data. - Band Appears Only Where Bounds Exist: If bounds are missing or null for any row, the uncertainty band cleanly gaps at that point.
- Invalid Bounds Safeguard: If
lower > upper, the interval at that observation is treated as invalid. The band is omitted locally. Plotcn never silently swaps lower and upper bounds. - No Clamping: If the forecast value falls outside the
[lower, upper]interval, Plotcn renders the values truthfully without artificial clamping. - Neutral Terminology: Unless customized via
confidenceLabel, default language refers to the range neutrally as "Forecast range" rather than making unverified statistical claims like "95% confidence interval".
Data & Series Contracts
Forecast Line accepts a single ordered array of data records:
type ForecastLineData = { month: string | Date actual: number | null forecast: number | null lower?: number | null upper?: number | null}Series Configuration Object
interface ForecastLineSeries<TData> { actualKey: NumericKeyOf<TData> forecastKey: NumericKeyOf<TData> lowerKey?: NumericKeyOf<TData> upperKey?: NumericKeyOf<TData> actualLabel?: string forecastLabel?: string confidenceLabel?: string valueFormatter?: (value: number) => string}Installation
Install Forecast Line directly into your project using the shadcn CLI:
Checking public registry…
View local registry JSONCopied as source into your project (requires recharts).
Component Props
| Property | Type | Default | Required | Description |
|---|---|---|---|---|
data | readonly TData[] | [] | Required | Readonly array of observation records. Caller data is never mutated. |
xKey | keyof TData & string | — | Required | Property name for horizontal domain coordinates (e.g., month, date). |
series | ForecastLineSeries<TData> | — | Required | Semantic series configuration mapping observed, forecast, and bound keys. |
height | number | string | 320 | Optional | Container height in pixels or standard CSS dimension strings. |
curve | "monotone" | "linear" | "step" | "monotone" | Optional | Curve interpolation algorithm shared between actual, forecast, and bounds. |
domain | [number, number] | ["auto", "auto"] | ["auto", "auto"] | Optional | Vertical Y scale domain. Automatically encloses actual, forecast, and range bounds. |
actualColor | string | "var(--chart-1)" | Optional | Color for observed history line, markers, and tooltip identity. |
forecastColor | string | "var(--chart-2)" | Optional | Color for predicted future line, markers, and tooltip identity. |
confidenceColor | string | "var(--chart-2)" | Optional | Color for uncertainty band fill. |
confidenceOpacity | number | 0.15 | Optional | Opacity for the uncertainty range band (0 to 1). |
selectionColor | string | "var(--chart-selection)" | Optional | Accent color for the inspection crosshair and locked datum status indicator. |
showGrid | boolean | true | Optional | Whether to render horizontal Cartesian grid reference lines. |
showLegend | boolean | true | Optional | Whether to render the series identity legend with actual stroke samples. |
lockableTooltip | boolean | true | Optional | Enables persistent tooltip locking via click, tap, or Enter/Space. |
missingValuePolicy | "gap" | "carry" | "gap" | Optional | Visual treatment of missing values: honest visual break or forward carry. |
animation | "draw" | "fade" | "none" | "draw" | Optional | Entry reveal animation. Automatically bypassed when reduced motion is preferred. |
valueFormatter | (value: number) => string | n.toLocaleString() | Optional | Default formatter for tooltip metric values and vertical scale ticks. |
xFormatter | (value: string | number) => string | String | Optional | Custom formatter for horizontal domain tick labels. |
title | string | "Forecast Line Chart" | Optional | Accessible title for assistive technologies and screen readers. |
description | string | undefined | Optional | Accessible description detailing forecast horizon and keyboard shortcuts. |
Keyboard Navigation Reference
Forecast Line provides full single-entry-point keyboard inspection across the unified timeline:
| Key | Control Target | Action |
|---|---|---|
| → / ArrowRight | Plot Inspection | Inspect next chronological observation (observed or forecast) |
| ← / ArrowLeft | Plot Inspection | Inspect previous chronological observation |
| Home | Plot Inspection | Jump inspection to the first observed observation |
| End | Plot Inspection | Jump inspection to the latest forecast observation |
| Enter or Space | Plot Inspection | Lock or unlock persistent inspection at the active coordinate |
| Escape | Plot Inspection | Dismiss locked inspection and release pinned tooltip |
Props Reference & Interactive Prop Explorer
Inspect every component property, customize semantic color roles live with instant visual feedback, and copy production-ready code with active prop configurations.
Colors & Appearance Configuration
Customize primary, reference, or annotation series colors. Defaults derive from Plotcn theme tokens.
<ForecastLine
data={data}
xKey="date"
series={{
actualKey: "actual",
forecastKey: "forecast",
lowerKey: "lower",
upperKey: "upper",
}}
/>| Property | Type | Default | Required | Description |
|---|---|---|---|---|
dataReq | readonly TData[] | [] | Yes | Readonly array of observation records. Caller data is never mutated. Best for: Primary dataset |
xKeyReq | keyof TData & string | — | Yes | Property name for horizontal domain coordinates (e.g., month, date). Best for: Domain mapping |
seriesReq | ForecastLineSeries<TData> | — | Yes | Semantic configuration object specifying actualKey, forecastKey, optional lowerKey, upperKey, and labels. Best for: Semantic role mapping |
actualColorOpt | string | "var(--chart-1, #3b82f6)" | No | Stroke color for the solid observed historical line and past observation markers. |
string | "var(--chart-2, #10b981)" | No | Stroke color for the dashed predicted forecast line and future observation markers. | |
string | "var(--chart-2, #10b981)" | No | Fill color for the shaded forecast uncertainty and prediction interval band. | |
number | 0.18 | No | Fill opacity applied to the uncertainty prediction band (0.0 to 1.0). | |
string | "var(--chart-selection, #f59e0b)" | No | Accent color for the locked vertical crosshair and persistent inspection selection. | |
heightOpt | number | string | 320 | No | Container height in pixels or standard CSS dimension strings. |
curveOpt | "monotone" | "linear" | "step" | "monotone" | No | Curve interpolation algorithm applied consistently across actual and forecast lines. |
domainOpt | [number, number] | ["auto", "auto"] | ["auto", "auto"] | No | Vertical Y scale range calculated safely across actual, forecast, and confidence bounds. |
showGridOpt | boolean | true | No | Whether to render subtle horizontal Cartesian grid reference lines. |
showLegendOpt | boolean | true | No | Whether to render the series identity legend showing stroke samples. |
boolean | true | No | Enables interactive button controls in the legend to toggle actual, forecast, or confidence visibility. | |
boolean | true | No | Enables persistent tooltip locking via click, tap, or Enter/Space. | |
"gap" | "carry" | "gap" | No | Visual treatment of missing values: honest visual break or forward carry. | |
animationOpt | "draw" | "fade" | "none" | "draw" | No | Entry reveal animation. Bypassed automatically when reduced motion is preferred. |
(value: number) => string | n.toLocaleString() | No | Default formatter for tooltip metric values and vertical scale ticks. | |
xFormatterOpt | (value: string | number) => string | String | No | Custom formatter for horizontal domain tick labels. |
titleOpt | string | "Forecast Line Chart" | No | Accessible title for assistive technologies and screen readers. |
descriptionOpt | string | undefined | No | Accessible description detailing historical duration, forecast horizon, and keyboard shortcuts. |
Component Variants & Edge States
Production cookbooks showcasing configuration variants alongside verified handling of loading, empty data, and network error states.
Monthly Active Users Forecast
Four months of observed historical metrics transitioning at April into a three-month forecast with supplied confidence bounds.
Custom Brand Color Encodings
Explicit brand colors assigned to actual history and forecast trajectory while preserving the solid vs. dashed non-color distinction.
Discontinuous Transition Gap
Demonstrates truthful separation when history ends before forecast begins without inventing artificial bridge data.
Missing Uncertainty Bounds
Demonstrates truthful confidence treatment: when lower or upper bounds are missing, the band gaps without fabricating fake intervals.
Skeletons indicate runtime fetch or pending data queries.
Handles empty collections ([]) gracefully without crashing.
Graceful failure banner when data source or script fails.
Container-Driven Breakpoints
Forecast Line adapts legend presentation and horizontal axis ticks based on container width. The solid vs. dashed distinction and confidence range area remain visible across all viewports.
Full horizontal legend with stroke samples, complete X-axis ticks, and spacious shared tooltip readouts.
Wrapped multi-row legend, thinned categorical ticks, and synchronized nearest-X inspection.
Compact wrapped controls with 32px touch targets, pan-y page scroll safety, and viewport-clamped tooltip positioning.
Accessibility & Navigation Standards
Single keyboard tab stop on root figure with ArrowLeft, ArrowRight, Home, End, Enter, and Escape shortcuts. Screen readers announce factual observation metrics and distinguish historical actuals from predicted forecasts.
Container mounts as region with explicit assistive label.
Observed history is rendered as a solid stroke, forecast is rendered as a dashed stroke, and uncertainty is rendered as a filled area. The distinction remains fully readable in monochrome.
Embeds visually hidden summary (.sr-only) declaring: “Announces domain time, actual observed value, predicted forecast value, and supplied forecast range factually without speculative probability claims.”
All entrance transitions immediately bypass when prefers-reduced-motion is detected in system preferences.
| Key | Action |
|---|---|
| ArrowRight | Inspect next observation along the timeline. |
| ArrowLeft | Inspect previous observation along the timeline. |
| Home | Jump inspection to the first historical observation. |
| End | Jump inspection to the final forecast observation. |
| Enter / Space | Lock or unlock the currently active inspection coordinate. |
| Escape | Release locked selection and dismiss active tooltip. |
| Tab | Move focus to interactive legend series toggle buttons. |
Data Safety Checklist
- ✓ No Automatic Prediction: Plotcn visualizes forecast data supplied by the consumer; it never runs automatic regressions or forecasts.
- ✓ Missing Values Never Become Zero: Missing actual, forecast, or bound fields remain
nulland create honest gaps (null ≠ 0). - ✓ Missing Confidence Bounds Gap: Missing bounds produce a gap in the confidence band rather than synthetic bounds.
- ✓ No Silent Bound Swapping: Observations with
lower > upperinvalidate the band locally rather than swapping values. - ✓ No Bridge Fabrication: If observed history ends before forecast starts, the gap is truthfully rendered.
- ✓ Safe Domain Calculation: Vertical domain includes all valid values across actual, forecast, lower, and upper series to prevent clipping.
- ✓ Immutability: Consumer data arrays are never mutated or sorted in place.
- ✓ Non-Color Encoding: Actual renders as a solid line and forecast as a dashed line, preserving epistemic meaning in monochrome.
Internal Architecture & File Dependencies
Source-first ownership model. Inspect the exact component call tree, dependencies, and full implementation below.
Handles container dimension measurement and CSS token scoping
Coordinates coordinate scales, Cartesian grid, Area, and multiple Line elements
Semantic button controls allowing users to toggle actual, forecast, and confidence visibility