018 / RECHARTS / AREA
Interactive Area
Inspection-first area visualization with nearest-X selection, observation-aligned crosshair, keyboard navigation, and a persistent lockable tooltip.
- SPEC
- #018
- ENGINE
- Recharts
- FAMILY
- Area
- RENDERER
- svg
- STATUS
- preview
Installation
Checking public registry…
View local registry JSONCopied as source into your project (requires recharts, @hugeicons/react, @hugeicons/core-free-icons).
Overview
Interactive Area is the inspection-specialized instrument of the Plotcn Area family. While other area components prioritize continuous visual magnitude or semantic fills, Interactive Area focuses on exact observation inspection: nearest-X pointer scrubbing, an observation-aligned neutral crosshair, keyboard navigation, touch-friendly exploration, and a persistent lockable tooltip.
The primary analytical question answered by Interactive Area is:
"What exact observed value belongs to this position on the ordered domain?"
The defining interaction question is:
"Can I inspect that observation, keep it selected, move through neighboring observations, and compare context without the tooltip disappearing?"
import { InteractiveArea } from "@/components/charts/recharts/area-interactive"const apiTrafficData = [ { date: "May 01", requests: 12400 }, { date: "May 04", requests: 14200 }, { date: "May 08", requests: 11900 }, { date: "May 12", requests: 16800 }, { date: "May 16", requests: 18500 }, { date: "May 20", requests: 15300 }, { date: "May 24", requests: 19800 }, { date: "May 28", requests: 23400 }, { date: "May 31", requests: 26100 },]export function RequestVolumeTracker() { return ( <InteractiveArea data={apiTrafficData} xKey="date" series={{ key: "requests", label: "API Requests", valueFormatter: (v) => `${v.toLocaleString()} req/s`, }} color="var(--chart-1)" selectionColor="var(--chart-selection)" fillOpacity={0.22} curve="monotone" showGrid /> )}Area-Family Positioning
The Plotcn Area family provides specialized analytical instruments across quantitative domains:
| Consideration | Prism Area (011) | Focus Line (008) | Comparison Area (015) | Baseline Area (017) | Interactive Area (018) |
|---|---|---|---|---|---|
| Primary Question | "How much magnitude relative to baseline?" | "What is the exact value along the signal curve?" | "How does primary compare to reference series?" | "How far above or below the baseline?" | "What exact observed value belongs to this domain position?" |
| Defining Feature | Restrained translucent fill magnitude | High-precision line inspection | Overlapping dual-series fill | Dual-color deviation fill | Nearest-X scrubbing + observation crosshair + persistent lock |
| Geometry | 1 filled area polygon | 1 continuous stroke (no fill) | 2 overlapping areas | Dual-region baseline partitioned area | 1 filled area polygon + 1 observation crosshair + 0–1 marker dot |
| Inspection Model | Standard pointer hover | Nearest-X line focus & lock | Multi-series hover inspection | Signed deviation inspection | Inspection-first nearest-X scrubbing, crosshair snap, persistent lock |
| Interaction Surface | Standard plot container | Plot-wide Cartesian surface | Standard plot container | Standard plot container | Unified touch-action: pan-y hit region with resolver |
Interactive Area vs. Focus Line (008)
- Focus Line: Best when lower visual mass is desired and the line trajectory alone provides sufficient analytical context.
- Interactive Area: Best when the occupied space between trend and baseline communicates essential volume context, while high-precision nearest-X inspection remains the primary user task.
Interactive Area vs. Prism Area (011)
- Prism Area: The visual area itself is the primary experience, using conventional hover tooltips.
- Interactive Area: The filled area provides ambient context, while exact observation inspection, keyboard traversal, and persistent locking are the primary experience.
Inspection Model
Governing Principle: Interaction may help users reach data more easily, but it must never manufacture data that was not observed.
If the user points between observations:
The component resolves the nearest real observation ( or ). It never calculates synthetic midpoints, interpolated Y values, or fictional timestamps.
Input Coordinate to Persistent Observation Lock
Inspection flow diagram showing input events mapped to nearest domain X coordinates, resolving real observations without interpolation, and driving crosshair, marker, and persistent lockable tooltip.
The inspection lifecycle follows a deterministic pipeline:
- Input Event: Dispatched via pointer move, keyboard arrow navigation, or mobile tap.
- Coordinate Normalization: Normalizes viewport coordinates against chart plot margins.
- Nearest-X Resolution: Maps horizontal plot position to the nearest ordered domain observation index.
- Real Observation Binding: Pulls the authentic datum from caller data. No curve interpolation is presented as observed data.
- Observation-Aligned Crosshair: Snaps the structural crosshair to the exact observation X coordinate.
- Persistent Lock: Prevents incidental pointer drift from changing the selected observation.
Nearest-X Model
In Cartesian time-series analysis, inspection is strictly horizontal:
Pointer Y does not choose the observation. Only horizontal plot position resolves the nearest ordered domain observation.
Midpoint Boundary Zones and Observation-Aligned Snapping
Conceptual diagram showing ordered domain observations, midpoint boundaries dividing screen zones, a pointer in zone 2, and the resulting snapped crosshair at the real observation coordinate.
Midpoint boundaries conceptually partition the domain:
Tie-Break Rule
When the pointer coordinate lands at the exact mathematical midpoint between two observations:
The resolver deterministically chooses the earlier index (). This prevents visual flickering and floating-point oscillations.
Algorithmic Complexity
Because domain coordinates are ordered, nearest-X resolution runs via binary search in time, avoiding expensive linear scans or per-point DOM hit rectangles.
Interaction States
Interactive Area decouples three distinct states that are often conflated in lesser charting libraries:
Interaction State Transitions & Input Decoupling
State machine diagram illustrating transitions between IDLE, FOCUSED, ACTIVE, and LOCKED states. Shows keyboard focus, arrow navigation, click-to-lock, and escape-to-unlock flows.
1. FOCUSED State
The chart interaction surface currently holds keyboard focus. It is visually framed by the standard focus ring:
outline: none;box-shadow: 0 0 0 2px var(--chart-focus, #38bdf8);Focus does not require a point to be locked.
2. ACTIVE State
A real observation is actively inspected through transient pointer scrubbing, initial keyboard focus, or tap. The observation is indicated by:
- A solid marker dot in series
color - An observation-aligned crosshair in neutral
--chart-crosshair - A synchronized inspection tooltip
3. LOCKED State
The user has intentionally pinned the observation. It gains:
- A concentric double-ring marker (───◎───) using
selectionColor - A persistent crosshair using
selectionColor - A persistent tooltip with a
Lockedbadge and lock icon - Pointer Immunity: Incidental pointer movement across the plot does not move or dismiss the locked observation.
Locking Behavior
Locking turns fleeting inspection into stable analysis:
- Locking on Desktop: Click any observation or press
EnterorSpacewhile focused. - Moving Locked Observation:
- Click any other observation to move the lock directly to that coordinate.
- Press
ArrowLeftorArrowRightwhile locked to advance the locked selection step-by-step.
- Unlocking:
- Press
Escape. - Click the currently locked observation again to release the lock.
- Press
- Touch Behavior: Tap any observation to inspect and pin. Tapping elsewhere moves the lock.
- Resize & Theme Immunity: Resizing the window, toggling dark mode, or updating series colors does not clear the locked observation.
Missing Observations
An observation can exist along an ordered domain even when its quantitative value was not recorded:
Interactive Area treats missingness truthfully:
- Domain Preservation: Missing observations remain in the domain and are navigable via keyboard arrows and pointer scrub.
- Truthful Tooltip: The tooltip reports
"Unavailable"or"—". It never fabricates zero. - Crosshair Continuity: The crosshair snaps to the missing observation's horizontal X coordinate.
- No Fake Dot: No marker dot is rendered on the canvas because there is no observed Y coordinate.
- Zero is Valid: A recorded value of
0is rendered at zero; it is never treated as missing. - Non-Finite Sanitization:
NaN,Infinity, and-Infinityare safely treated as missing to protect SVG path geometry.
Keyboard Navigation
Interactive Area provides a single accessible tab stop on its root <figure> element. Observations are not individually tabbable:
| Key | Action | Description |
|---|---|---|
Tab | Focus Chart | Moves focus to the chart container; displays --chart-focus ring. |
ArrowRight | Next Observation | Steps forward to the next domain coordinate (including missing observations). |
ArrowLeft | Previous Observation | Steps backward to the previous domain coordinate. |
Home | First Observation | Jumps immediately to observation index 0. |
End | Last Observation | Jumps immediately to the final observation in the dataset. |
Enter / Space | Toggle Lock | Locks or unlocks the currently active observation. Page scroll is prevented. |
Escape | Release Lock | Unlocks the persistent selection without clearing active focus. |
Touch Exploration
Touch interactions are engineered to respect page scrolling:
- Scroll Preservation: The container uses
touch-action: pan-y. Vertical swipes scroll the page naturally without being hijacked by chart gestures. - Tap Inspection: Tapping anywhere within the plot region resolves the nearest observation X and pins the tooltip.
- Zero Gesture Dependencies: Implemented purely using native Pointer Events; no Hammer.js or external gesture frameworks required.
Color Customization
The component enforces a clean, multi-token color hierarchy:
<InteractiveArea data={data} xKey="date" series={{ key: "requests", label: "Requests" }} color="var(--chart-1)" selectionColor="var(--chart-selection)"/>- Series Color (
color): Controls the area fill, boundary stroke, active marker point, and tooltip dot. Defaults tovar(--chart-1). - Selection Color (
selectionColor): Controls the locked concentric double-ring marker, locked crosshair, and locked tooltip badge. Defaults tovar(--chart-selection). - Crosshair Token (
--chart-crosshair): Structural neutral line (rgba(255, 255, 255, 0.28)). Not modified by series colors. - Focus Token (
--chart-focus): Structural keyboard focus ring (#38bdf8).
Rendering Architecture
Interactive Area is built purely on top of Recharts and native SVG primitives:
Recharts Area Chart and Synchronized Inspection Layers
System architecture diagram detailing raw data ingestion, normalizer, domain and scale computation, Recharts Area rendering, nearest-X resolution, and synchronized crosshair and HTML tooltip overlays.
- Single Interaction Surface: The entire plot region acts as one unified hit area. There are no per-datum invisible DOM rectangles.
- Deterministic Resolver: Binary search calculates the active observation index without querying or parsing SVG path geometry.
- Observation-Aligned Crosshair: Crosshair rendered via
<ReferenceLine x={activeX} />, strictly locked to the observation's scaled coordinate. - Active / Locked Dot Callback: Exactly 0 or 1 marker is rendered by the Area component, preventing DOM bloat on dense datasets.
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.
<InteractiveArea
data={data}
xKey="date"
seriesKey="value"
/>Primary stroke color, area fill, active marker point, and tooltip dot.
color="function"Default: "var(--chart-1, #3b82f6)"Accent color for persistent locked marker ring, locked tooltip badge, and locked crosshair.
selectionColor="function"Default: "var(--chart-selection, #f59e0b)"Fill opacity for the occupied area polygon below the signal curve.
fillOpacity={0.22}Default: 0.22Curve interpolation algorithm for the continuous area boundary stroke.
curve="monotone"Default: "monotone"Baseline anchor for the area polygon baseValue.
baseline="zero"Default: "zero"Visual container height in pixels or CSS dimension string.
height={320}Default: 320Whether clicking or pressing Enter/Space locks the currently inspected observation.
lockable={true}Default: trueTruthful handling of null/undefined observations. Under gap, missing points remain inspectable without area fill.
missingValuePolicy="gap"Default: "gap"Whether to render subtle horizontal background reference gridlines.
showGrid={true}Default: trueWhether to render the horizontal category scale ticks and domain labels.
showXAxis={true}Default: trueWhether to render the vertical numeric scale ticks and metric values.
showYAxis={true}Default: trueWhether to render the single-series identity legend.
showLegend={false}Default: false| Property | Type | Default | Required | Description |
|---|---|---|---|---|
dataReq | readonly TData[] | [] | Yes | Readonly array of observation records. Caller data is never mutated or reordered. |
xKeyReq | keyof TData & string | — | Yes | Property name on data records representing the horizontal domain coordinate. |
seriesReq | InteractiveAreaSeries<TData> | — | Yes | Single quantitative series configuration defining metric key, label, and valueFormatter. |
colorOpt | string | "var(--chart-1, #3b82f6)" | No | Primary stroke color, area fill, active marker point, and tooltip dot. |
string | "var(--chart-selection, #f59e0b)" | No | Accent color for persistent locked marker ring, locked tooltip badge, and locked crosshair. | |
fillOpacityOpt | number | 0.22 | No | Fill opacity for the occupied area polygon below the signal curve. |
curveOpt | "monotone" | "linear" | "step" | "monotone" | No | Curve interpolation algorithm for the continuous area boundary stroke. |
baselineOpt | number | "zero" | "domain-min" | "zero" | No | Baseline anchor for the area polygon baseValue. |
domainOpt | [number, number] | "auto" | "auto" | No | Explicit vertical Y-axis scale bounds, or automatic padding computation. |
heightOpt | number | string | 320 | No | Visual container height in pixels or CSS dimension string. |
lockableOpt | boolean | true | No | Whether clicking or pressing Enter/Space locks the currently inspected observation. |
number | null | null | No | Initial observation index to pin/lock on mount. | |
initialFocusOpt | "none" | "first" | "last" | "none" | No | Initial inspection position upon keyboard focus entry into the chart. |
"gap" | "carry" | "connect" | "gap" | No | Truthful handling of null/undefined observations. Under gap, missing points remain inspectable without area fill. | |
showGridOpt | boolean | true | No | Whether to render subtle horizontal background reference gridlines. |
showXAxisOpt | boolean | true | No | Whether to render the horizontal category scale ticks and domain labels. |
showYAxisOpt | boolean | true | No | Whether to render the vertical numeric scale ticks and metric values. |
showLegendOpt | boolean | false | No | Whether to render the single-series identity legend. |
(active: ActiveDatum | null, index: number | null) => void | — | No | Callback fired whenever the active inspected observation changes. | |
onLockChangeOpt | (locked: ActiveDatum | null, index: number | null) => void | — | No | Callback fired whenever the persistent locked observation changes. |
titleOpt | string | — | No | Accessible name announced to assistive technologies. |
descriptionOpt | string | — | No | Detailed descriptive summary announced to assistive technologies. |
Component Variants & Edge States
Production cookbooks showcasing configuration variants alongside verified handling of loading, empty data, and network error states.
Basic Inspection
Pointer scrub along the timeline, snapping crosshair to observations with synchronized tooltips.
Persistent Locked Tooltip
Click or press Enter to pin the observation. Pointer movement no longer drifts the tooltip.
Missing Observation Handling
Unrecorded observations exist in the domain and report as unavailable without synthetic values.
Custom Series and Selection Theming
Independent series color for the area fill and selectionColor for the locked double ring.
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
Interactive Area preserves the full inspection hit surface, nearest-X resolution, observation-aligned crosshair, and persistent lock state across all viewport dimensions down to 320px.
Spacious Cartesian grid, full domain tick density, observation-aligned crosshair, anchored inspection card, and complete keyboard shortcuts.
Adaptive domain tick thinning, preserved hit region, and compact inspection gutters.
Compact gutters, touch-forgiving tap inspection, pan-y scroll preservation, and persistent locked inspection card.
Accessibility & Data Safety
- One Tab Stop: Chart shell receives keyboard focus without trapping the user or creating dozens of SVG tab stops.
- Screen Reader Announcements: An off-screen live region provides concise, factual orientation:
> "Interactive time-series area chart depicting 30 observations for API Requests. Currently locked on observation 8 of 30 at May 08 with value 11,900."
- Structured Data Table: A complete HTML
<table>is provided in an off-screen container for non-visual exploration. - No Live-Region Spam: Rapid pointer scrubbing does not flood screen readers with aria-live announcements.
- Reduced Motion: Respects
prefers-reduced-motionby disabling path animations while keeping pointer and keyboard inspection immediate.
Accessibility & Navigation Standards
Single keyboard tab stop on root figure with ArrowLeft, ArrowRight, Home, End, Enter/Space, and Escape shortcuts. Complete structured data table provided for screen readers.
Container mounts as region with explicit assistive label.
Concentric double-ring marker (◎), observation-aligned vertical crosshair, textual lock badge, and offscreen structured HTML table ensure non-color accessibility.
Embeds visually hidden summary (.sr-only) declaring: “Announces domain coordinate, observed value, observation index and count, and locked status factually without editorial commentary.”
All entrance animations immediately bypass when prefers-reduced-motion is detected in user system preferences.
| Key | Action |
|---|---|
| ArrowRight | Inspect next chronological observation across the domain. |
| ArrowLeft | Inspect previous chronological observation across the domain. |
| Home | Jump inspection directly to the first observation. |
| End | Jump inspection directly to the final observation. |
| Enter / Space | Lock or unlock persistent inspection at the active coordinate. |
| Escape | Release locked selection without losing active keyboard focus. |
Data Safety Guarantees
- ✓ Active values always correspond to real observations
- ✓ Pointer position never manufactures an interpolated value
- ✓ Crosshair snaps to the selected observation X, not raw cursor X
- ✓ Pointer Y does not alter horizontal nearest-X selection
- ✓ Missing observations remain inspectable as unavailable
- ✓ Missing values are never silently coerced to zero
- ✓ Zero remains a valid quantitative observation
- ✓ Non-finite values (
NaN,Infinity) never reach SVG path strings - ✓ Locking alters interaction state only; underlying caller data is never mutated
- ✓ Resizing the viewport preserves active and locked observations
- ✓ Theme switches and color changes preserve lock state without remounting
- ✓ Single plot-level interaction surface with zero per-point DOM overhead
- ✓ Caller data array is treated as strictly readonly
Internal Architecture & File Dependencies
Source-first ownership model. Inspect the exact component call tree, dependencies, and full implementation below.
Handles container dimension measurement and SVG viewBox sizing
Coordinates scales, Cartesian grid, Area geometry, ReferenceLine crosshair, and Tooltip