Timeline
@gravity-ui/timeline

Eine auf React basierende Bibliothek zum Erstellen interaktiver Timeline-Visualisierungen mit Canvas-Rendering.
Dokumentation
Details finden Sie in der Dokumentation.
Vorschau
Grundlegende Timeline mit Ereignissen und Achsen:

Benutzerdefiniertes Rendering mit erweiterbaren verschachtelten Ereignissen (NestedEvents Beispiel):

Funktionen
- Canvas-basiertes Rendering für hohe Leistung
- Interaktive Timeline mit Zoom- und Schwenkfunktionen
- Unterstützung für Ereignisse, Markierungen, Abschnitte, Achsen und Gitter
- Hintergrundabschnitte zur visuellen Organisation und Hervorhebung von Zeiträumen
- Intelligente Gruppierung von Markierungen mit automatischem Zoom auf die Gruppe - Klicken Sie auf gruppierte Markierungen, um in ihre einzelnen Komponenten zu zoomen
- Virtualisiertes Rendering für verbesserte Leistung bei großen Datensätzen (nur aktiv, wenn der Timeline-Inhalt den Viewport überschreitet)
- Anpassbares Erscheinungsbild und Verhalten
- TypeScript-Unterstützung mit vollständigen Typdefinitionen
- React-Integration mit benutzerdefinierten Hooks
Installation
npm install @gravity-ui/timeline
Verwendung
Die Timeline-Komponente kann in React-Anwendungen mit der folgenden grundlegenden Einrichtung verwendet werden:
import { TimelineCanvas, useTimeline } from '@gravity-ui/timeline/react';
const MyTimelineComponent = () => {
const { timeline, api, start, stop } = useTimeline({
settings: {
start: Date.now(),
end: Date.now() + 3600000, // 1 Stunde ab jetzt
axes: [],
events: [],
markers: [],
sections: []
},
viewConfiguration: {
// Optionale Ansichtskonfiguration
}
});
// timeline - Timeline-Instanz
// api - CanvasApi-Instanz (identisch mit timeline.api)
// start - Funktion zur Initialisierung der Timeline mit Canvas
// stop - Funktion zur Zerstörung der Timeline
return (
<div style={{ width: '100%', height: '100%' }}>
<TimelineCanvas timeline={timeline} />
</div>
);
};
Achsenstruktur
Jede Achse hat die folgende Struktur:
type TimelineAxis = {
id: string; // Eindeutige Achsenkennung
tracksCount: number; // Anzahl der Spuren in der Achse
top: number; // Vertikale Position (px)
height: number; // Höhe pro Spur (px)
};
Abschnittsstruktur
Jeder Abschnitt erfordert die folgende Struktur:
type TimelineSection = {
id: string; // Eindeutige Abschnittskennung
from: number; // Start-Zeitstempel
to?: number; // Optionaler End-Zeitstempel (standardmäßig das Ende der Timeline)
color: string; // Hintergrundfarbe des Abschnitts
hoverColor?: string; // Optionale Farbe, wenn der Abschnitt überfahren wird
renderer?: AbstractSectionRenderer; // Optionaler benutzerdefinierter Renderer (aus dem Paket exportiert)
};
Abschnitte bieten Hintergrundfarben für Zeiträume und helfen bei der visuellen Organisation von Timeline-Inhalten:
const MyTimelineComponent = () => {
const { timeline } = useTimeline({
settings: {
start: Date.now(),
end: Date.now() + 3600000,
axes: [],
events: [],
markers: [],
sections: [
{
id: 'morning',
from: Date.now(),
to: Date.now() + 1800000, // 30 Minuten
color: 'rgba(255, 235, 59, 0.3)', // Halbtransparentes Gelb
hoverColor: 'rgba(255, 235, 59, 0.4)'
},
{
id: 'afternoon',
from: Date.now() + 1800000,
// Kein 'to' angegeben - erstreckt sich bis zum Ende der Timeline
color: 'rgba(76, 175, 80, 0.2)', // Halbtransparentes Grün
hoverColor: 'rgba(76, 175, 80, 0.3)'
}
]
},
viewConfiguration: {
sections: {
hitboxPadding: 2 // Abstand für die Erkennung von Hover-Effekten
}
}
});
return <TimelineCanvas timeline={timeline} />;
};
Markierungsstruktur
Jede Markierung erfordert die folgende Struktur:
type TimelineMarker = {
time: number; // Zeitstempel für die Position der Markierung
color: string; // Farbe der Markierungslinie
activeColor: string; // Farbe, wenn die Markierung ausgewählt ist (erforderlich)
hoverColor: string; // Farbe, wenn die Markierung überfahren wird (erforderlich)
lineWidth?: number; // Optionale Breite der Markierungslinie
label?: string; // Optionaler Beschriftungstext
labelColor?: string; // Optionale Beschriftungsfarbe
renderer?: AbstractMarkerRenderer; // Optionaler benutzerdefinierter Renderer
nonSelectable?: boolean;// Ob die Markierung ausgewählt werden kann
group?: boolean; // Ob die Markierung eine Gruppe darstellt
};
Markierungsgruppierung und Zoom
Die Timeline gruppiert Markierungen, die nahe beieinander liegen, automatisch und bietet Zoom-Funktionalität:
const MyTimelineComponent = () => {
const { timeline } = useTimeline({
settings: {
start: Date.now(),
end: Date.now() + 3600000,
axes: [],
events: [],
markers: [
// Diese Marker werden zusammen gruppiert
{ time: Date.now(), color: '#ff0000', activeColor: '#ff5252', hoverColor: '#ff1744', label: 'Ereignis 1' },
{ time: Date.now() + 1000, color: '#ff0000', activeColor: '#ff5252', hoverColor: '#ff1744', label: 'Ereignis 2' },
{ time: Date.now() + 2000, color: '#ff0000', activeColor: '#ff5252', hoverColor: '#ff1744', label: 'Ereignis 3' },
]
},
viewConfiguration: {
markers: {
collapseMinDistance: 8, // Marker innerhalb von 8 Pixeln gruppieren
groupZoomEnabled: true, // Zoom bei Gruppenklick aktivieren
groupZoomPadding: 0.3, // 30% Abstand um die Gruppe
groupZoomMaxFactor: 0.3, // Maximaler Zoomfaktor
}
}
});
// Auf Gruppen-Zoom-Ereignisse hören
useTimelineEvent(timeline, 'on-group-marker-click', (data) => {
console.log('Gruppe gezoomt:', data);
});
return <TimelineCanvas timeline={timeline} />;
};
Funktionsweise
Die Timeline-Komponente ist mit React erstellt und bietet eine flexible Möglichkeit, interaktive Timeline-Visualisierungen zu erstellen. So funktioniert sie:
Komponentenarchitektur
Die Timeline ist als React-Komponente implementiert, die über zwei Hauptobjekte konfiguriert werden kann:
-
TimelineSettings: Steuert das Kernverhalten und die Darstellung der Timeline
start: Startzeit der Timelineend: Endzeit der Timelineaxes: Array von Achsenkonfigurationen (siehe Struktur unten)events: Array von Ereigniskonfigurationenmarkers: Array von Marker-Konfigurationensections: Array von Abschnittskonfigurationen
-
ViewConfiguration: Verwaltet die visuelle Darstellung und die Interaktionseinstellungen
- Steuert Darstellung, Zoomstufen und Interaktionsverhalten
- Kann angepasst oder Standardwerte verwendet werden
Ereignisbehandlung
Die Timeline-Komponente unterstützt mehrere interaktive Ereignisse:
on-click: Wird beim Klicken auf die Timeline ausgelöston-context-click: Wird bei Rechtsklick/Kontextmenü ausgelöston-select-change: Wird ausgelöst, wenn sich die Auswahl änderton-hover: Wird beim Überfahren von Timeline-Elementen mit der Maus ausgelöston-leave: Wird ausgelöst, wenn die Maus Timeline-Elemente verlässt
Beispiel für die Ereignisbehandlung:
import { useTimelineEvent } from '@gravity-ui/timeline/react';
const MyTimelineComponent = () => {
const { timeline } = useTimeline({ /* ... */ });
useTimelineEvent(timeline, 'on-click', (data) => {
console.log('Timeline geklickt:', data);
});
useTimelineEvent(timeline, 'on-select-change', (data) => {
console.log('Auswahl geändert:', data);
});
return <TimelineCanvas timeline={timeline} />;
};
React-Integration
Die Komponente verwendet benutzerdefinierte Hooks zur Timeline-Verwaltung:
-
useTimeline: Verwaltet die Timeline-Instanz und ihren Lebenszyklus- Erstellt und initialisiert die Timeline
- Kümmert sich um die Bereinigung beim Ausblenden der Komponente
- Bietet Zugriff auf die Timeline-Instanz
-
useTimelineEvent: Verwaltet Ereignisabonnements und die Bereinigung- Verwaltet den Lebenszyklus von Ereignis-Listenern
- Bereinigt Listener automatisch beim Ausblenden
Die Komponente kümmert sich automatisch um die Bereinigung und Zerstörung der Timeline-Instanz, wenn sie ausgeblendet wird.
Ereignisstruktur
Ereignisse in der Timeline folgen dieser Struktur:
type TimelineEvent = {
id: string; // Eindeutiger Bezeichner
from: number; // Start-Zeitstempel
to?: number; // End-Zeitstempel (optional für Punkt-Ereignisse)
axisId: string; // ID der Achse, zu der dieses Ereignis gehört
trackIndex: number; // Index im Track der Achse
renderer?: AbstractEventRenderer; // Optionaler benutzerdefinierter Renderer
color?: string; // Optionale Ereignisfarbe
selectedColor?: string; // Optionale Farbe für den ausgewählten Zustand
};
Direkte TypeScript-Nutzung
Die Timeline-Klasse kann direkt in TypeScript ohne React verwendet werden. Dies ist nützlich für die Integration mit anderen Frameworks oder Vanilla-JavaScript-Anwendungen:
import { Timeline } from '@gravity-ui/timeline';
const timestamp = Date.now();
// Eine Timeline-Instanz erstellen
const timeline = new Timeline({
settings: {
start: timestamp,
end: timestamp + 3600000, // 1 Stunde ab jetzt
axes: [
{
id: 'main',
tracksCount: 3,
top: 0,
height: 100
}
],
events: [
{
id: 'event1',
from: timestamp + 1800000, // 30 Minuten ab jetzt
to: timestamp + 2400000, // 40 Minuten ab jetzt
label: 'Beispiel-Ereignis',
axisId: 'main'
}
],
markers: [
{
id: 'marker1',
time: timestamp + 1200000, // 20 Minuten ab jetzt
label: 'Wichtiger Punkt',
color: '#ff0000',
activeColor: '#ff5252',
hoverColor: '#ff1744'
}
],
sections: [
{
id: 'section1',
from: timestamp,
to: timestamp + 1800000, // Erste 30 Minuten
color: 'rgba(33, 150, 243, 0.2)', // Hellblaue Hintergrundfarbe
hoverColor: 'rgba(33, 150, 243, 0.3)'
}
]
},
viewConfiguration: {
// Optional: Ansichtseinstellungen anpassen
zoomLevels: [1, 2, 4, 8, 16],
hideRuler: false,
showGrid: true
}
});
// Mit einem Canvas-Element initialisieren
const canvas = document.querySelector('canvas');
if (canvas instanceof HTMLCanvasElement) {
timeline.init(canvas);
}
// Ereignis-Listener hinzufügen
timeline.on('on-click', (detail) => {
console.log('Timeline geklickt:', detail);
});
timeline.on('on-select-change', (detail) => {
console.log('Auswahl geändert:', detail);
});
// Aufräumen, wenn fertig
timeline.destroy();
Die Timeline-Klasse bietet eine umfangreiche API zur Verwaltung der Timeline:
- Ereignisverwaltung:
// Ereignis-Listener hinzufügen timeline.on('eventClick', (detail) => { console.log('Ereignis geklickt:', detail); });
```markdown
// Event-Listener entfernen
const handler = (detail) => console.log(detail);
timeline.on('eventClick', handler);
timeline.off('eventClick', handler);
// Benutzerdefinierte Events auslösen
timeline.emit('customEvent', { data: 'custom data' });
- Timeline-Steuerung:
// Timeline-Daten aktualisieren timeline.api.setEvents([ { id: 'newEvent', from: Date.now(), to: Date.now() + 3600000, label: 'Neues Event', axisId: 'main', trackIndex: 0 } ]); // Achsen aktualisieren timeline.api.setAxes([ { id: 'newAxis', tracksCount: 2, top: 0, height: 80 } ]); // Marker aktualisieren timeline.api.setMarkers([ { id: 'newMarker', time: Date.now(), label: 'Neuer Marker', color: '#00ff00', activeColor: '#4caf50', hoverColor: '#2e7d32' } ]); // Abschnitte aktualisieren timeline.api.setSections([ { id: 'newSection', from: Date.now(), to: Date.now() + 1800000, color: 'rgba(255, 193, 7, 0.2)', // Heller Bernstein-Hintergrund hoverColor: 'rgba(255, 193, 7, 0.3)' } ]); // Ansichtskonfiguration aktualisieren (wird mit der aktuellen Konfiguration zusammengeführt) timeline.api.setViewConfiguration({ hideRuler: true });
Live-Beispiele
Interaktive Beispiele finden Sie in unserem Storybook:
- Basis-Timeline - Einfache Timeline mit Events und Achsen
- Endlose Timeline - Endlose Timeline mit Events und Achsen
- Marker - Timeline mit vertikalen Markern und Beschriftungen
- Benutzerdefinierte Events - Timeline mit benutzerdefinierter Event-Darstellung
- Integrationen - RangeDateSelection, DragHandler, NestedEvents, Popup, List
Entwicklung
Storybook
Dieses Projekt enthält Storybook für die Komponentenentwicklung und -dokumentation.
Um Storybook auszuführen:
npm run storybook
Dadurch wird der Storybook-Entwicklungsserver auf Port 6006 gestartet. Sie können ihn unter http://localhost:6006 aufrufen.
Um eine statische Version von Storybook für die Bereitstellung zu erstellen:
npm run build-storybook
Lizenz
MIT