LTTB downsampling
The library uses the Largest-Triangle-Three-Buckets (LTTB) algorithm to automatically downsample large datasets while preserving their visual shape and important features.Automatic activation
LTTB downsampling automatically activates when a line series has more than 2,000 data points. This threshold balances visual fidelity with rendering performance.The LTTB algorithm is implemented in
src/math/LTTB.ts:6 and intelligently selects which points to keep based on triangle areas formed between consecutive data buckets.How LTTB preserves visual shape
The LTTB algorithm works by:- Always keeping the first and last points to preserve data boundaries
- Dividing data into buckets based on the target threshold (default 2,000 points)
- Selecting the most visually significant point from each bucket by calculating triangle areas
- Preserving peaks, valleys, and trends that would be visible in the full dataset
Divide into buckets
The algorithm divides your data into buckets. For 100,000 points downsampled to 2,000, each bucket contains approximately 50 points.
Calculate triangle areas
For each bucket, it calculates the area of triangles formed between:
- The previously selected point
- Each candidate point in the current bucket
- The average position of points in the next bucket
Performance characteristics
Canvas rendering benefits
Kinetix Charts uses HTML5 Canvas for all rendering, which provides significant performance advantages over DOM-based charting libraries:- Direct pixel manipulation instead of creating thousands of DOM elements
- Hardware acceleration for smooth rendering and animations
- Efficient redraws that only update what’s necessary
- Layered architecture with separate canvases for different components
Memory efficiency
The canvas-based approach combined with LTTB downsampling means:- Original data is stored in memory but not all rendered
- Only ~2,000 points are processed for rendering (after downsampling)
- Layer system reuses canvas contexts instead of creating new ones
- Tooltips and interactions still work with the full dataset
Complete 100k point example
Here’s a complete example from the README demonstrating smooth performance with 100,000 points:Downsampling threshold
The LTTB threshold is currently set at 2,000 points. This value was chosen because:- Most displays can’t show more than ~2,000 distinct pixel positions horizontally
- It provides smooth rendering at 60fps on most hardware
- Visual fidelity is maintained for nearly all use cases
- Interactive operations (pan, zoom) remain responsive
Bar charts and large datasets
Bar series currently don’t use LTTB downsampling because each bar represents a discrete category or value that shouldn’t be omitted:- Using scrollable mode for categorical axes
- Aggregating data before passing to the chart
- Using line charts instead if the data is continuous
Layer architecture benefits
The chart’s layer system (implemented insrc/core/SceneGraph.ts) separates rendering into multiple canvases:
- Grid layer (z-index: 0): Background grid
- Series layers (z-index: 1+): Data visualization
- Axis layer (z-index: 50): Axes and labels
- Legend layer (z-index: 100): Legend
- Only layers that change need to be redrawn
- Interactions can update just the tooltip without redrawing data
- Animations can run on one layer while others remain static