A React-based library for building interactive timeline visualizations with canvas rendering.
For details see Documentation.
- Canvas-based rendering for high performance
- Interactive timeline with zoom and pan capabilities
- Support for events, markers, axes, and grid
- Smart marker grouping with automatic zoom to group - Click on grouped markers to zoom into their individual components
- Virtualized rendering for improved performance with large datasets (only active when timeline content exceeds the viewport)
- Customizable appearance and behavior
- TypeScript support with full type definitions
- React integration with custom hooks
npm install @gravity-ui/timeline
The timeline component can be used in React applications with the following basic setup:
import { TimelineCanvas, useTimeline } from '@gravity-ui/timeline/react';
const MyTimelineComponent = () => {
const { timeline } = useTimeline({
settings: {
start: Date.now(),
end: Date.now() + 3600000, // 1 hour from now
axes: [],
events: [],
markers: []
},
viewConfiguration: {
// Optional view configuration
}
});
return (
<div style={{ width: '100%', height: '100%' }}>
<TimelineCanvas timeline={timeline} />
</div>
);
};
The timeline automatically groups markers that are close together and provides zoom functionality:
const MyTimelineComponent = () => {
const { timeline } = useTimeline({
settings: {
start: Date.now(),
end: Date.now() + 3600000,
axes: [],
events: [],
markers: [
// These markers will be grouped together
{ time: Date.now(), color: '#ff0000', label: 'Event 1' },
{ time: Date.now() + 1000, color: '#ff0000', label: 'Event 2' },
{ time: Date.now() + 2000, color: '#ff0000', label: 'Event 3' },
]
},
viewConfiguration: {
markers: {
collapseMinDistance: 8, // Group markers within 8 pixels
groupZoomEnabled: true, // Enable zoom on group click
groupZoomPadding: 0.3, // 30% padding around group
groupZoomMaxFactor: 0.3, // Max zoom factor
}
}
});
// Listen for group zoom events
useTimelineEvent(timeline, 'on-group-marker-click', (data) => {
console.log('Group zoomed:', data);
});
return <TimelineCanvas timeline={timeline} />;
};
The timeline component is built using React and provides a flexible way to create interactive timeline visualizations. Here's how it works:
The timeline is implemented as a React component that can be configured through two main objects:
-
TimelineSettings: Controls the core timeline behavior and appearance
start
: Start time of the timelineend
: End time of the timelineaxes
: Array of axis configurationsevents
: Array of event configurationsmarkers
: Array of marker configurations
-
ViewConfiguration: Manages the visual representation and interaction settings
- Controls appearance, zoom levels, and interaction behavior
- Can be customized or use default values
The timeline component supports several interactive events:
on-click
: Triggered when clicking on the timelineon-context-click
: Triggered on right-click/context menuon-select-change
: Fired when the selection changeson-hover
: Triggered when hovering over timeline elementson-leave
: Fired when the mouse leaves timeline elements
Example of event handling:
import { useTimelineEvent } from '@gravity-ui/timeline/react';
const MyTimelineComponent = () => {
const { timeline } = useTimeline({ /* ... */ });
useTimelineEvent(timeline, 'on-click', (data) => {
console.log('Timeline clicked:', data);
});
useTimelineEvent(timeline, 'on-select-change', (data) => {
console.log('Selection changed:', data);
});
return <TimelineCanvas timeline={timeline} />;
};
The component uses custom hooks for timeline management:
-
useTimeline
: Manages the timeline instance and its lifecycle- Creates and initializes the timeline
- Handles cleanup on component unmount
- Provides access to the timeline instance
-
useTimelineEvent
: Handles event subscriptions and cleanup- Manages event listener lifecycle
- Automatically cleans up listeners on unmount
The component automatically handles cleanup and destruction of the timeline instance when unmounted.
The Timeline class can be used directly in TypeScript without React. This is useful for integrating with other frameworks or vanilla JavaScript applications:
import { Timeline } from '@gravity-ui/timeline';
const timestamp = Date.now();
// Create a timeline instance
const timeline = new Timeline({
settings: {
start: timestamp,
end: timestamp + 3600000, // 1 hour from now
axes: [
{
id: 'main',
label: 'Main Axis',
color: '#000000'
}
],
events: [
{
id: 'event1',
start: timestamp + 1800000, // 30 minutes from now
end: timestamp + 2400000, // 40 minutes from now
label: 'Sample Event',
axisId: 'main'
}
],
markers: [
{
id: 'marker1',
time: timestamp + 1200000, // 20 minutes from now
label: 'Important Point',
color: '#ff0000'
}
]
},
viewConfiguration: {
// Optional: customize view settings
zoomLevels: [1, 2, 4, 8, 16],
hideRuler: false,
showGrid: true
}
});
// Initialize with a canvas element
const canvas = document.querySelector('canvas');
if (canvas instanceof HTMLCanvasElement) {
timeline.init(canvas);
}
// Add event listeners
timeline.on('on-click', (detail) => {
console.log('Timeline clicked:', detail);
});
timeline.on('on-select-change', (detail) => {
console.log('Selection changed:', detail);
});
// Clean up when done
timeline.destroy();
The Timeline class provides a rich API for managing the timeline:
-
Event Management:
// Add event listener timeline.on('eventClick', (detail) => { console.log('Event clicked:', detail); }); // Remove event listener const handler = (detail) => console.log(detail); timeline.on('eventClick', handler); timeline.off('eventClick', handler); // Emit custom events timeline.emit('customEvent', { data: 'custom data' });
-
Timeline Control:
// Update timeline data timeline.api.setEvents([ { id: 'newEvent', start: Date.now(), end: Date.now() + 3600000, label: 'New Event' } ]); // Update axes timeline.api.setAxes([ { id: 'newAxis', label: 'New Axis', color: '#0000ff' } ]); // Update markers timeline.api.setMarkers([ { id: 'newMarker', time: Date.now(), label: 'New Marker', color: '#00ff00' } ]);
Explore interactive examples in our Storybook:
- Basic Timeline - Simple timeline with events and axes
- Endless Timeline - Endless timeline with events and axes
- Markers - Timeline with vertical markers and labels
- Custom Events - Timeline with custom event rendering
This project includes Storybook for component development and documentation.
To run Storybook:
npm run storybook
This will start the Storybook development server on port 6006. You can access it at http://localhost:6006.
To build a static version of Storybook for deployment:
npm run build-storybook
MIT