009 / RECHARTS / LINE
Multi-Signal Line
A multi-series time-series line chart with deterministic series identity, stable color assignment, readable shared tooltips, responsive legend controls, and truthful missing-series behavior.
- SPEC
- #009
- ENGINE
- Recharts
- FAMILY
- Line
- RENDERER
- svg
- STATUS
- preview
Installation
Checking public registry…
View local registry JSONCopied as source into your project (requires recharts).
Overview
Multi-Signal Line is a general analytical multi-series time-series component engineered around the principles of deterministic series identity, readable shared inspection, and truthful visibility states.
The central analytical question answered by this chart is:
"How do several comparable signals move together over the same X domain?"
Multi-Signal Line is not just a single-series line chart mapped over multiple data fields. Its reason to exist is its multi-series identity and interaction model. It allows users to inspect, distinguish, toggle visibility, and compare multiple peer signals without degrading into a confusing visual tangle.
Stable Color Assignment Across Visibility Toggles
import { MultiSignalLine } from "@/components/charts/recharts/line-multi-signal"const usageData = [ { month: "Jan", web: 120, ios: 90, android: 100 }, { month: "Feb", web: 136, ios: 105, android: 121 }, { month: "Mar", web: 154, ios: 130, android: 145 }, { month: "Apr", web: 148, ios: 138, android: 140 }, { month: "May", web: 172, ios: 152, android: 165 }, { month: "Jun", web: 189, ios: 168, android: 178 }, { month: "Jul", web: 210, ios: 185, android: 195 },]export function PlatformUsageOverview() { return ( <MultiSignalLine data={usageData} xKey="month" series={[ { key: "web", label: "Web" }, { key: "ios", label: "iOS" }, { key: "android", label: "Android" }, ]} showLegend interactiveLegend lockableTooltip valueFormatter={(v) => `${v.toLocaleString()} sessions`} showGrid /> )}Line-Family Positioning
Plotcn provides specialized line chart components for distinct analytical and operational roles. It is essential to choose the component that fits the underlying data semantics:
| Component | Number | Primary Analytical Specialty |
|---|---|---|
| Signal Line | 001 | Single primary 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 | Central trend plus uncertainty envelope / confidence interval |
| 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 |
Twinline Compare is semantically a two-role comparison (Primary vs. Reference). Multi-Signal Line is a general multi-series analytical chart where all visible signals are peers.
Deterministic Series Identity
The defining architectural guarantee of Multi-Signal Line is deterministic series identity.
Every configured series receives a stable identity resolved from its canonical definition:
series config │ ▼stable key │ ├── label ├── stroke color (theme token or explicit override) ├── stroke style (solid, dashed, dotted) ├── legend item identity ├── tooltip row entry └── active marker stylingThe Identity Rule
Hiding a series NEVER reassigns the colors of the remaining series.
In conventional charting libraries, series colors are frequently assigned by the index of currently visible items (palette[visibleIndex]). When a user toggles visibility for Series 1, every subsequent series abruptly shifts colors. This breaks spatial memory and destroys the trust of analytical dashboards.
Multi-Signal Line binds palette tokens (--chart-1 through --chart-8) to each series' original canonical index. When iOS is hidden, Web remains --chart-1 and Android remains --chart-3.
Shared Y Scale & No Dual Axes
Multi-Signal Line enforces a single, truthful vertical scale:
- Comparable Signals: All series must share the same physical or financial unit (e.g., active sessions, API requests, revenue, latency in milliseconds).
- No Dual Y Axes: Multi-Signal Line deliberately rejects dual Y axes. Dual axes create arbitrary scale relationships, mislead viewers about correlation, and distort relative magnitudes.
- Incompatible Units: To compare metrics of differing units (e.g., Revenue in dollars and Conversion in percent), use indexed normalization, small multiples, or a dedicated combo chart.
Synchronized Nearest-X Inspection
Multi-Signal Line implements a single coordinated inspection model across all visible series simultaneously.
Shared Observation Scrubbing with Independent Missing Values
Horizontal Nearest-X Scrubbing
- Single Plot Crosshair: Moving the pointer across the plot calculates the nearest domain coordinate () across the entire Cartesian frame.
- Active Points: Renders a dedicated observation marker for each visible series that possesses a valid, finite value at that observation.
- Synchronized Tooltip: Displays a single, unified inspection card listing all visible series in strict canonical configuration order.
- Excluded Hidden Series: Hidden series are completely omitted from the tooltip readout, active markers, and hit testing.
Independent Missing Value Semantics
When recording multi-source data, dropouts and missing intervals occur independently per series. Multi-Signal Line handles these variations truthfully:
| State | Definition | Visual Representation | Tooltip Readout |
|---|---|---|---|
| Valid | Numeric finite value | Continuous line path + active marker | Formatted metric value (e.g., 154,000) |
| Missing | null or undefined at this | Clean visual break (gap) in line | Explicit unavailable indicator (—) |
| Hidden | Toggled off by user in legend | Series completely removed from canvas | Row omitted from tooltip card |
March 2026Web 154,000iOS —Android 145,000Missing is not zero (null ≠ 0). Hidden is not missing. A missing value creates an honest gap in that specific series without penalizing or shifting peer lines.Interactive Legend Controls
The legend is a first-class interaction control in Multi-Signal Line:
- Semantic Toggle Buttons: Each legend item is rendered as an accessible
<button>element witharia-pressedstates. - Stroke Samples: Legend items render actual SVG stroke samples (solid, dashed, or custom colors) rather than generic colored circles.
- Keyboard Usable: Users can Tab into the legend and toggle series visibility using Enter or Space.
- All-Hidden Safe State: If every series is toggled off, the chart presents an actionable recovery message: "No visible series. Use the legend above to show a series." The legend controls remain interactive so the user can immediately restore visibility.
Installation
Install Multi-Signal 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 | readonly MultiSignalSeries<TData>[] | — | Required | Array of series configurations ({ key, label, color?, strokeStyle? }). |
height | number | string | 320 | Optional | Container height in pixels or standard CSS dimension strings. |
curve | "monotone" | "linear" | "step" | "monotone" | Optional | Curve interpolation algorithm shared across all peer series. |
domain | [number, number] | ["auto", "auto"] | ["auto", "auto"] | Optional | Vertical Y scale range with zero-span safeguarding over visible series. |
showGrid | boolean | true | Optional | Whether to render subtle horizontal Cartesian grid reference lines. |
showLegend | boolean | true | Optional | Whether to render the series identity legend. |
interactiveLegend | boolean | true | Optional | Enables interactive button controls in the legend to toggle series visibility. |
lockableTooltip | boolean | true | Optional | Enables persistent tooltip locking via click, tap, or Enter/Space. |
selectionColor | string | "var(--chart-selection)" | Optional | Accent color for the locked crosshair and locked inspection status indicator. |
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. Bypassed automatically 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 | "Multi-Signal Line Chart" | Optional | Accessible title for assistive technologies and screen readers. |
description | string | undefined | Optional | Accessible description detailing series identities and keyboard shortcuts. |
Keyboard Navigation Reference
Multi-Signal Line provides separate, dedicated focus handling for chart observation inspection and legend controls:
| Key | Control Target | Action |
|---|---|---|
| → / ArrowRight | Plot Inspection | Inspect next chronological observation across all visible series |
| ← / ArrowLeft | Plot Inspection | Inspect previous chronological observation across all visible series |
| Home | Plot Inspection | Jump inspection to the first observation |
| End | Plot Inspection | Jump inspection to the latest observation |
| Enter or Space | Plot Inspection | Lock or unlock persistent inspection at active coordinate |
| Escape | Plot Inspection | Dismiss locked inspection and release pinned tooltip |
| Tab | Legend Controls | Move keyboard focus between series toggle buttons |
| Enter or Space | Legend Item | Toggle visibility of focused series (aria-pressed updates) |
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.
<MultiSignalLine
data={data}
xKey="date"
series={[
{ key: "web", label: "Web" },
{ key: "ios", label: "iOS" },
{ key: "android", label: "Android" },
]}
/>| 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 | readonly MultiSignalSeries<TData>[] | — | Yes | Array of series configuration objects specifying key, label, and optional style. Best for: Multi-series definition |
heightOpt | number | string | 320 | No | Container height in pixels or standard CSS dimension strings. |
curveOpt | "monotone" | "linear" | "step" | "monotone" | No | Curve interpolation algorithm shared uniformly across all peer series. |
domainOpt | [number, number] | ["auto", "auto"] | ["auto", "auto"] | No | Vertical Y scale range calculated safely over currently visible series. |
showGridOpt | boolean | true | No | Whether to render subtle horizontal Cartesian grid reference lines. |
showLegendOpt | boolean | true | No | Whether to render the series identity legend. |
boolean | true | No | Enables interactive button controls in the legend to toggle series visibility. | |
boolean | true | No | Enables persistent tooltip locking via click, tap, or Enter/Space. | |
string | "var(--chart-selection)" | No | Accent color for the locked crosshair and locked inspection status indicator. | |
"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 values and vertical scale ticks. | |
xFormatterOpt | (value: string | number) => string | String | No | Custom formatter for horizontal domain tick labels. |
titleOpt | string | "Multi-Signal Line Chart" | No | Accessible title for assistive technologies and screen readers. |
descriptionOpt | string | undefined | No | Accessible description detailing series identities and keyboard shortcuts. |
Component Variants & Edge States
Production cookbooks showcasing configuration variants alongside verified handling of loading, empty data, and network error states.
Cross-Platform Usage Signals
Three peer signals (Web, iOS, Android) moving together over monthly intervals with interactive legend toggling.
Explicit Series Color Assignment
Explicit brand colors specified per series overriding semantic palette tokens while preserving deterministic identity.
Independent Missing Values Per Series
Demonstrates honest gaps when individual series have null observations without corrupting peer series.
Interactive Legend Visibility Toggles
Click or press Enter on legend items to toggle series visibility. Remaining series keep their original colors.
Skeletons indicate runtime fetch or pending data queries.
Handles empty collections ([]) gracefully without crashing.
Graceful failure banner when data source or script fails.
Responsive Legend Strategy
- Desktop (): Full horizontal inline legend with series stroke samples, labels, and toggle buttons.
- Tablet (): Wrapped multi-row legend maintaining readable text size without unreadable micro-fonts.
- Mobile (): Compact wrapped series controls with touch-friendly 32px targets.
- State Preservation: Resizing the browser or switching responsive preview modes preserves all series visibility toggles and locked inspection coordinates.
Container-Driven Breakpoints
Multi-Signal Line adapts legend wrapping and X-axis ticks based on container width. Series visibility and locked inspection are preserved across screen resizes.
Full horizontal legend row with stroke samples, complete X-axis ticks, and spacious shared tooltip readouts.
Wrapped multi-row legend maintaining readable text size, thinned categorical ticks, and synchronized nearest-X inspection.
Compact wrapped series controls with 32px touch targets, pan-y page scroll safety, and viewport-clamped tooltip positioning.
Accessibility & Screen Reader Model
- Semantic Shell: Encapsulated within a
<figure role="region" tabIndex={0}>element witharia-labelledbyandaria-describedby. - Fact-Based Screen Reader Summary: Announces the count of visible series, total observation count, and domain time range.
- Decoupled Focus: Chart plot navigation uses arrow keys on the figure; legend items are standard semantic
<button>elements in the tab flow. - Accessible Button States: Series toggle buttons expose
aria-pressed="true"when visible andaria-pressed="false"when hidden. - Color Independence: When Monochrome palette is active, series remain distinguishable via stroke patterns (solid, dashed, dotted), tooltip row labels, and legend swatches.
- Reduced Motion: Entrance draw animations automatically bypass when
prefers-reduced-motion: reduceis detected.
Accessibility & Navigation Standards
Single keyboard tab stop on root figure with ArrowLeft, ArrowRight, Home, End, Enter, and Escape shortcuts. Interactive legend items provide semantic button controls with aria-pressed states.
Container mounts as region with explicit assistive label.
Series are distinguished by stroke styling, explicit human-readable labels, and tooltip swatches. Hidden series remain visible in the legend with line-through indicators and explicit aria-pressed states.
Embeds visually hidden summary (.sr-only) declaring: “Announces domain time, count of visible series, and individual series metric values factually for the inspected observation.”
All entrance transitions immediately bypass when prefers-reduced-motion is detected in system preferences.
| Key | Action |
|---|---|
| ArrowRight | Inspect next observation across all visible series. |
| ArrowLeft | Inspect previous observation across all visible series. |
| Home | Jump inspection to the first observation. |
| End | Jump inspection to the last 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
- ✓ Deterministic Identity: Original series configuration order governs palette token assignment; hiding series never recolors peer series.
- ✓ Independent Missing Data:
nullvalues produce honest breaks per series without distorting or zeroing other lines. - ✓ Truthful Observations: Nearest-X inspection selects recorded observations; no synthetic numbers are fabricated.
- ✓ Excluded Hidden Series: Hidden series are cleanly omitted from the active Y domain calculation, tooltip cards, and active markers.
- ✓ Immutability: Caller data arrays and series configuration objects are never mutated.
- ✓ Non-Finite Filtering:
NaN,Infinity, and unparseable values are excluded from geometry calculations. - ✓ All-Hidden Recovery: An in-chart recovery state prevents broken rendering when all series are toggled off.
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, and multiple peer Line elements
Semantic button controls allowing users to toggle series visibility with aria-pressed states