026 / RECHARTS / BAR & COLUMN
Interval Bars
Floating categorical ranges with explicit start and end bounds for schedules, maintenance windows, operating durations, and bounded quantitative intervals.
- SPEC
- #026
- ENGINE
- Recharts
- FAMILY
- Bar & Column
- RENDERER
- svg
- STATUS
- preview
Installation
Checking public registry…
View local registry JSONCopied as source into your project (requires recharts).
blueprint="027" engine="recharts" renderer="svg" family="bar" status="preview" title="Interval Bars" description="Floating categorical ranges with explicit start and end bounds for schedules, maintenance windows, operating durations, and bounded quantitative intervals." />
Overview
Interval Bars visualizes supplied bounded ranges where each category is defined by an explicit start bound and an explicit end bound along a continuous quantitative or temporal axis.
Unlike conventional bar charts that measure magnitude from an implicit zero baseline:
Conventional Bar (Zero Baseline) vs. Interval Bar (Floating Range)
Animated diagram showing conventional bars expanding from a pinned zero baseline origin versus interval bars floating dynamically between independent start and end coordinates without zero pinning.
both endpoints represent first-class data. The position of the interval along the axis conveys when or where the range occurs, while the bar length represents the derived span (end - start).
Neither boundary is ever defaulted to zero, the axis minimum, or an inferred reference point.
Live Preview
Installation
Checking public registry…
View local registry JSONCopied as source into your project (requires recharts).
Usage
import { IntervalBars } from "@/components/charts/recharts/bar-interval"const data = [ { service: "Authentication", start: 9.0, end: 10.5 }, { service: "Payments API", start: 10.0, end: 12.25 }, { service: "Notifications", start: 8.5, end: 9.75 }, { service: "Analytics Engine", start: 11.0, end: 13.0 }, { service: "Data Exporter", start: 12.25, end: 14.0 },]export function MaintenanceScheduleChart() { return ( <IntervalBars data={data} categoryKey="service" series={{ startKey: "start", endKey: "end", label: "Maintenance Window", startLabel: "Window Start", endLabel: "Window End", spanLabel: "Duration", valueFormatter: (h) => `${Math.floor(h).toString().padStart(2, "0")}:${((h % 1) * 60).toString().padStart(2, "0")}`, spanFormatter: (span) => `${Math.floor(span)}h ${(span % 1) * 60}m`, }} /> )}Interval Model
Floating Range Geometry: Start, End, and Span
Diagram illustrating the interval model where a floating bar begins at a supplied start coordinate and extends to an end coordinate, defining span as end minus start without an implicit zero origin.
The fundamental mathematical relationship for each categorical interval is:
span = end - startFor every valid interval:
startrepresents the coordinate where the interval opens.endrepresents the coordinate where the interval closes.spanis the non-negative scalar distance betweenstartandend.
Interval Bars does not rebase ranges to zero. An interval spanning 100 to 120 has the exact same span (20) as an interval spanning 0 to 20, but their coordinates represent completely distinct observations.
Floating Bars vs Baseline Bars
Conventional Baseline Bar vs Floating Interval Bar
Comparison diagram contrasting conventional bars rooted at zero with floating interval bars anchored at both start and end coordinates.
In standard bar charts, bar length directly encodes magnitude from zero. In Interval Bars, the bar floats between two supplied numbers:
| Feature | Conventional Bar | Interval Bar |
|---|---|---|
| Origin | Implicit zero baseline (0) | Supplied start coordinate |
| Termination | Supplied value | Supplied end coordinate |
| Visual Geometry | Rectangle anchored to baseline | Floating rectangle between bounds |
| Primary Meaning | Absolute scalar magnitude | Continuous bounded range / window |
| Zero Baseline | Semantically mandatory | Just a number along the domain |
Critical Distinction: Zero is not an implicit baseline in Interval Bars. If your data ranges from100to180, the plot domain adjusts directly to those bounds rather than anchoring to zero.
Start, End, and Span Anatomy
Category Row, Start/End Bounds, and Span Geometry
Anatomy breakdown showing the category label row, the floating bar body with rounded corners, the start bound coordinate, the end bound coordinate, and the derived span width.
Each categorical row consists of:
- Category Label: Positioned along the discrete categorical axis.
- Start Boundary: The lower coordinate where the range begins.
- End Boundary: The upper coordinate where the range concludes.
- Interval Span: The visual bar width between
x(start)andx(end). - Rounded Outer Radii: Both outer edges receive restrained corner rounding (
rx=4, ry=4) because neither edge is a grounded baseline.
Bounds Validation: Valid, Zero-Width, and Invalid Reversed
Bounds Validation: Valid, Zero-Width, and Invalid Reversed
Validation flow diagram comparing standard valid interval bounds, zero-width intervals rendered with a marker tick, and invalid reversed bounds where start is greater than end.
Interval Bars enforces strict mathematical bounds validation:
1. Valid Intervals (start < end)
The standard case. Renders a floating bar spanning between start and end. Span is calculated as end - start > 0.
2. Zero-Width Intervals (start === end)
When start === end, the interval is mathematically valid with span = 0. Plotcn renders a crisp 3px marker line at the coordinate rather than inventing an artificial minimum bar width. The category row remains fully interactive and hoverable.
3. Invalid Reversed Bounds (start > end)
If a record provides a start value greater than its end value (e.g. 20 → 10), Plotcn strictly marks the interval as Invalid bounds.
- No silent swapping: Plotcn will never silently invert
startandendor applyMath.abs(). - No misleading geometry: No bar is drawn for invalid bounds.
- Inspection preserved: The row remains inspectable, with the tooltip explicitly warning
"Invalid bounds".
Missing-Bounds Semantics
Missing-Bounds Semantics: No Zero or "Now" Substitution
Diagram showing that if start or end is missing, the interval is classified as unavailable without substituting zero, domain minimum, or current time.
A valid interval requires both boundaries to be finite numbers:
start is finite AND end is finiteIf either bound is missing (null, undefined, NaN, Infinity, or -Infinity):
- The interval is reported as Unavailable.
- Missing
startis never replaced with0or the domain minimum. - Missing
endis never replaced with current time ("now") or domain maximum. - Structured data and tooltips explicitly indicate that the interval is unavailable.
Domain Model: Bounds-Driven Resolution
Bounds-Driven Domain vs Zero-Forced Domain
Domain comparison diagram showing how bounds-driven domains cover the actual intervals efficiently while zero-forced domains waste plot area and distort positions.
Automatic domain calculation considers all valid start coordinates and all valid end coordinates across the dataset:
domain = [min(valid starts, valid ends), max(valid starts, valid ends)]Why Bounds-Driven Domain Matters
If a dataset contains maintenance windows occurring between 09:00 and 14:00, forcing zero into the domain would waste more than half the chart area with irrelevant space. Bounds-driven domain guarantees optimal visual resolution for comparative scanning.
Temporal Intervals & Timestamps
Epoch Timestamps & Duration Formatting
Diagram showing how numeric timestamps position the interval while distinct formatters render wall-clock time bounds and duration span labels.
For temporal schedules, epoch timestamps (e.g. 1770000000000) or numeric fractional hours (e.g. 9.5 for 09:30) can be supplied directly:
- Axis & Boundary Formatter (
valueFormatter): Formats coordinates into wall-clock time (09:00,13:30). - Span Formatter (
spanFormatter): Formats the derived duration (4h 30m).
Temporal formatting does not alter chart geometry or create clock-dependent state.
Negative and Cross-Zero Floating Ranges
Negative Ranges & Cross-Zero Intervals
Illustration of purely negative intervals and intervals that cross zero, showing that cross-zero intervals remain one continuous bar without splitting into directional colors.
Interval Bars naturally handles negative values and ranges that cross zero:
- Purely Negative Ranges: e.g.
-80 → -40(span40). - Cross-Zero Ranges: e.g.
-20 → +30(span50). Cross-zero intervals are rendered as a single continuous bar without splitting into artificial positive and negative colors.
Category Band & Zero-Width Hit Regions
Category Band Hit Targets Keep Zero/Tiny Bars Accessible
Interaction diagram showing how the entire categorical band acts as the hit target, allowing zero or tiny variance bars to remain inspectable on touch devices and desktop pointers.
Zero-Width Interval: Crisp Marker Tick Without Fake Width
Illustration of zero-width intervals where start equals end, showing a clean marker tick at the coordinate without inflating quantitative width.
Because intervals can be narrow, short, or zero-width (span = 0), hit testing is anchored to the entire category band:
- Hovering or tapping anywhere within the row band activates the category.
- Exact cursor precision on a thin bar or marker tick is never required.
- Touch interactions remain forgiving on mobile viewports.
Orientation: Horizontal vs Vertical
Horizontal (Default) vs Vertical Orientation
Comparison of horizontal layout for schedules and timelines versus vertical layout for numeric min/max comparisons.
Interval Bars defaults to orientation="horizontal" because:
- Schedules, durations, and timelines read left-to-right naturally.
- Long category names (e.g. "Customer Data Migration Pipeline") have ample horizontal breathing room.
For numeric min/max comparisons (e.g. daily operating temperatures), orientation="vertical" can be configured explicitly.
Rendering Architecture
Interval Bars Execution Architecture
Pipeline architecture diagram showing consumer data ingestion, finite validation, bounds validation, span derivation, domain resolution, Recharts floating bar layout, custom shape rendering, and accessible structured output.
The rendering pipeline executes deterministically:
- Data Ingestion: Immutable intake of caller data.
- Pairwise Validation: Verifies finite numeric boundaries.
- Bounds Check: Verifies
start <= end. - Domain Resolution: Bounds-driven auto-scaling.
- Recharts Floating Layout: Computes coordinate mappings via array tuples
[start, end]. - Custom Shape: Renders floating bars with outer radii and zero-width markers.
- Accessible Table: Emits offscreen semantic HTML table for assistive technology.
Props Reference
| Prop | Type | Default | Description |
|---|---|---|---|
data | readonly TData[] | [] | Array of categorical data records. Order is strictly preserved. |
categoryKey | keyof TData & string | — | Key representing the discrete category label. |
series | IntervalBarSeries<TData> | — | Series definition specifying startKey, endKey, label, and formatters. |
orientation | "horizontal" | "vertical" | "horizontal" | Layout orientation. |
height | number | string | 340 | Chart container height. |
domain | [number, number] | "auto" | "auto" | Bounds-driven domain or explicit limits. |
color | string | "var(--chart-1)" | Fill color for floating interval bars. |
selectionColor | string | "var(--chart-selection)" | Emphasis outline color for the active category. |
showGrid | boolean | true | Whether to render background Cartesian gridlines. |
showLegend | boolean | false | Whether to display series legend. |
tooltipMode | "bounds" | "bounds-and-span" | "bounds-and-span" | Tooltip detail mode. |
motion | boolean | { duration?: number } | true | Animation toggle honoring reduced motion. |
Accessibility
- Keyboard Traversal: Uses
ArrowDown/ArrowUpin horizontal mode andArrowLeft/ArrowRightin vertical mode, withHomeandEndsupport. - Single Tab Stop: The chart container receives a single focus stop (
tabIndex={0}). - Screen Reader Support: An offscreen semantic table details category, start, end, duration, and status for every row.
- Factual Summaries: Audio announcements describe positions and spans factually without assuming operational delays or conflicts.
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.
<IntervalBars
data={data}
categoryKey="service"
series={{
startKey: "start",
endKey: "end",
label: "Maintenance Window",
}}
/>Layout orientation: horizontal (default) extends bars left-to-right, vertical extends bottom-to-top.
orientation="horizontal"Default: "horizontal"Whether to render subtle background Cartesian gridlines.
showGrid={true}Default: trueWhether to display the structural series legend.
showLegend={false}Default: falseDisplay mode for permanent numeric labels.
valueLabel="none"Default: "none"Tooltip depth mode: "bounds-and-span" discloses start, end, and duration.
tooltipMode="bounds-and-span"Default: "bounds-and-span"| Property | Type | Default | Required | Description |
|---|---|---|---|---|
dataReq | readonly TData[] | [] | Yes | Array of categorical data records. Order is strictly preserved. |
categoryKeyReq | keyof TData & string | — | Yes | Key on data records representing the discrete category label. |
seriesReq | IntervalBarSeries<TData> | — | Yes | Series definition specifying startKey, endKey, label, and optional formatters. |
orientationOpt | "horizontal" | "vertical" | "horizontal" | No | Layout orientation: horizontal (default) extends bars left-to-right, vertical extends bottom-to-top. |
heightOpt | number | string | 340 | No | Container height in pixels or CSS height string. |
domainOpt | [number, number] | "auto" | "auto" | No | Quantitative domain policy. Defaults to bounds-driven extent covering observed starts and ends. |
colorOpt | string | var(--chart-1) | No | Fill color for interval bars. |
string | var(--chart-selection) | No | Stroke color for the active or keyboard-focused category row. | |
showGridOpt | boolean | true | No | Whether to render subtle background Cartesian gridlines. |
showLegendOpt | boolean | false | No | Whether to display the structural series legend. |
valueLabelOpt | "none" | "span" | "bounds" | "auto" | "none" | No | Display mode for permanent numeric labels. |
tooltipModeOpt | "bounds" | "bounds-and-span" | "bounds-and-span" | No | Tooltip depth mode: "bounds-and-span" discloses start, end, and duration. |
motionOpt | boolean | { duration?: number } | true | No | Animation toggle honoring prefers-reduced-motion. |
Component Variants & Edge States
Production cookbooks showcasing configuration variants alongside verified handling of loading, empty data, and network error states.
Service Maintenance Windows
Standard horizontal interval chart showing scheduled operational maintenance windows.
Operating Temperature Windows (Vertical)
Vertical orientation showing min/max operating thermal ranges across server zones.
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
IntervalBars uses container-driven geometry via ResizeObserver and SVG coordinate scaling. Horizontal layout reserves dedicated category label space, ensuring long names never compress the plotting area.
Horizontal layout allows long category titles to remain legible; tick frequency on the time/numeric axis is thinned accessibly.
Full category band hit regions allow comfortable touch activation of short, zero-width, or narrow intervals.
Full layout displaying Cartesian gridlines, hover cursor bands, and detailed start/end/duration tooltip cards.
Accessibility & Navigation Standards
Semantic figure region with single tab stop, orientation-specific arrow-key traversal, Home/End navigation, polite ARIA announcements, and an offscreen structured HTML table disclosing start, end, and duration values.
Container mounts as region with explicit assistive label.
Interval ranges are encoded primarily through spatial geometry along the continuous axis. Color identifies the series, not start versus end.
Embeds visually hidden summary (.sr-only) declaring: “Announces category name, start bound, end bound, and derived duration span factually without assuming operational delays or conflicts.”
All initial entrance animations are bypassed immediately when prefers-reduced-motion is detected.
| Key | Action |
|---|---|
| ArrowDown / ArrowUp | Traverse categories in horizontal orientation |
| ArrowRight / ArrowLeft | Traverse categories in vertical orientation |
| Home | Jump focus to the first category |
| End | Jump focus to the last category |
| Escape | Clear active category inspection |
Internal Architecture & File Dependencies
Source-first ownership model. Inspect the exact component call tree, dependencies, and full implementation below.
Provides responsive sizing and token styling