Incremental Chart Animations
Relevant source files
The following files were used as context for generating this wiki page:
Incremental Chart Animations provide a specialized rendering strategy for real-time data visualizations in HX-UI. This system differentiates between the "first render" and "subsequent updates" to prevent visual jitter and unnecessary full-path redraws when adding new data points to a series.
In standard Recharts implementations, adding data items often causes the entire line or bar set to re-match by index, resulting in a "stretching" effect or a complete redraw of existing points. HX-UI overrides this behavior to ensure existing points remain stationary while new points fade in or slide into place.
Sources: README.md:65-70, src/charts/animation.ts:5-15
Core Animation Logic
The system identifies the render state using a specialized React hook and applies different matching strategies based on whether the chart is displaying its initial dataset or receiving an incremental update.
Animation Matching Modes
The system supports three distinct matching modes to handle different data stream types:
| Mode | Description | Ideal Use Case |
|---|---|---|
index | Matches data by array index. Recharts default. | Initial load or batch data replacement. |
append | Sequential matching where existing items stay put and new items fade in. | Log streams or second-by-second monitoring. |
matchByDataKey | Matches items using a unique business key (e.g., id). | Sliding windows where old data exits and new data enters. |
Sources: src/charts/animation.ts:17-30, src/charts/animation.ts:40-45
Implementation Flow
The useChartAnimation hook manages the lifecycle of the animation state. It uses a ref to track if the initial render has occurred and employs requestAnimationFrame to toggle this state, preventing StrictMode double-invocations from skipping the entry animation.
Technical Architecture
Component Integration
Charts like HxLineChart, HxAreaChart, and HxBarChart integrate incremental animations by invoking the useChartAnimation hook and spreading the returned props onto the Recharts primitive components (e.g., <Line />).
// Example from HxLineChart
const anim = useChartAnimation({ ...animation }, data.length);
return (
<Line
{...anim}
dataKey={s.dataKey}
stroke={s.color ?? seriesColor(i)}
// ...other props
/>
);
Sources: src/charts/Charts.tsx:64-70, src/charts/useChartAnimation.ts:20-25
Performance Safeguards
To prevent frame drops on low-end devices, the system enforces a hard limit on data points. If the number of points exceeds ANIMATION_POINT_LIMIT (set to 800), animations are automatically disabled. This avoids the overhead of calculating interpolations for thousands of points every frame.
Sources: src/charts/animation.ts:53-60, src/charts/useChartAnimation.ts:53-55
Data Flow for Animation Props
The buildAnimationProps function generates the specific configuration required by Recharts to execute the chosen strategy.
Configuration Options
Developers can customize the animation behavior through the ChartAnimationOptions interface.
| Option | Type | Default | Description |
|---|---|---|---|
match | MatchSpec<T> | "append" | The strategy used for incremental updates. |
duration | number | 320 | Animation length in milliseconds. |
easing | string | "ease-out" | The CSS easing function. |
disabled | boolean | false | Manually disable animations for specific instances. |
Sources: src/charts/animation.ts:47-53, src/charts/animation.ts:79-81
Key Considerations
- Response to Scaling: Responsive charts use
vectorEffect="non-scaling-stroke"to ensure line widths do not distort during container resizing, maintaining visual consistency during animations. - Safety from Undefined: The
buildAnimationPropsfunction explicitly ensuresanimationMatchByis neverundefined, as Recharts internal logic can crash if an explicitundefinedvalue is provided instead of omitting the property. - Tooltip Synchronization: The
ChartTooltipis designed to work with these animations, using a custom layout that aligns multiple series values to maintain readability even as points transition.
Sources: src/charts/Charts.tsx:75-76, src/charts/animation.ts:72-76, src/charts/ChartFrame.tsx:60-75