Graph
Une bibliothèque de visualisation de graphes qui combine le meilleur des deux mondes :
- Canvas pour des performances élevées lors de la visualisation du graphe complet
- HTML/React pour des interactions riches lorsque l'on zoome
Fini le choix entre performance et interactivité. Idéal pour les diagrammes complexes, les organigrammes et les éditeurs basés sur des nœuds.
Motivation
Les applications web modernes nécessitent souvent une visualisation et une interactivité complexes, mais les solutions existantes se concentrent généralement sur une seule technologie de rendu :
- Canvas offre des performances élevées pour les graphiques complexes, mais est limité dans la gestion du texte et l'interactivité.
- DOM HTML est pratique pour les interfaces, mais moins efficace pour les graphiques complexes ou un grand nombre d'éléments.
@gravity-ui/graph résout ce problème en basculant automatiquement entre Canvas et HTML en fonction du niveau de zoom :
- Dézoomé : Utilise Canvas pour un rendu efficace du graphe complet
- Zoom moyen : Affiche une vue schématique avec une interactivité de base
- Zoomé : Bascule vers des composants HTML/React pour des interactions riches
Comment ça marche
La bibliothèque utilise un système de rendu intelligent qui gère automatiquement la transition entre les composants Canvas et React :
- Aux niveaux de zoom bas, tout est rendu sur Canvas pour des raisons de performance.
- Lors du zoom avant vers une vue détaillée, le composant
GraphCanvas
:- Suit les changements de la caméra (position et échelle).
- Calcule quels blocs sont visibles dans la fenêtre d'affichage actuelle (avec un padding pour un défilement fluide).
- Rend les composants React uniquement pour les blocs visibles.
- Met à jour automatiquement la liste lors du défilement ou du zoom.
- Supprime les composants React lors du dézoom.
// Exemple de rendu de composants React
const MyGraph = () => {
return (
<GraphCanvas
graph={graph}
renderBlock={(graph, block) => (
<MyCustomBlockComponent
graph={graph}
block={block}
/>
)}
/>
);
};
Installation
npm install @gravity-ui/graph
Exemples
Exemple React
Documentation détaillée des composants React
import { EAnchorType, Graph, GraphState } from "@gravity-ui/graph";
import { GraphCanvas, GraphBlock, useGraph } from "@gravity-ui/graph/react";
import React from "react";
const config = {};
export function GraphEditor() {
const { graph, setEntities, start } = useGraph(config);
useEffect(() => {
setEntities({
blocks: [
{
is: "block-action",
id: "action_1",
x: -100,
y: -450,
width: 126,
height: 126,
selected: true,
name: "Bloc #1",
anchors: [
{
id: "out1",
blockId: "action_1",
type: EAnchorType.OUT,
index: 0
}
],
},
{
id: "action_2",
is: "block-action",
x: 253,
y: 176,
width: 126,
height: 126,
selected: false,
name: "Bloc #2",
anchors: [
{
id: "in1",
blockId: "action_2",
type: EAnchorType.IN,
index: 0
}
],
}
],
connections: [
{
sourceBlockId: "action_1",
sourceAnchorId: "out1",
targetBlockId: "action_2",
targetAnchorId: "in1",
}
]
});
}, [setEntities]);
const renderBlockFn = (graph, block) => {
return <GraphBlock graph={graph} block={block}>{block.id}</GraphBlock>;
};
return (
<GraphCanvas
graph={graph}
renderBlock={renderBlockFn}
onStateChanged={({ state }) => {
if (state === GraphState.ATTACHED) {
start();
graph.zoomTo("center", { padding: 300 });
}
}}
/>
);
}
Exemple JavaScript Vanilla
import { Graph } from "@gravity-ui/graph";
// Créer un élément conteneur
const container = document.createElement('div');
container.style.width = '100vw';
container.style.height = '100vh';
container.style.overflow = 'hidden';
document.body.appendChild(container);
// Initialiser le graphe avec la configuration
const graph = new Graph({
configurationName: "example",
blocks: [],
connections: [],
settings: {
canDragCamera: true,
canZoomCamera: true,
useBezierConnections: true,
showConnectionArrows: true
}
}, container);
<div class="language-selector">
<a href="/README.md">English</a>
<a href="/README.fr.md">Français</a>
</div>
// Ajout de blocs et de connexions
graph.setEntities({
blocks: [
{
is: "block-action",
id: "block1",
x: 100,
y: 100,
width: 120,
height: 120,
name: "Bloc #1",
anchors: [
{
id: "out1",
blockId: "block1",
type: EAnchorType.OUT,
index: 0
}
]
},
{
is: "block-action",
id: "block2",
x: 300,
y: 300,
width: 120,
height: 120,
name: "Bloc #2",
anchors: [
{
id: "in1",
blockId: "block2",
type: EAnchorType.IN,
index: 0
}
]
}
],
connections: [
{
sourceBlockId: "block1",
sourceAnchorId: "out1",
targetBlockId: "block2",
targetAnchorId: "in1"
}
]
});
// Démarrage du rendu
graph.start();
// Centrage de la vue
graph.zoomTo("center", { padding: 100 });
Exemples en direct
- Exemple de base
- Exemple à grande échelle
- Vue de blocs personnalisés
- Connexion Bézier
- Personnalisation des connexions
Documentation
Table des matières
-
Système
-
Composants
-
Rendu
-
Blocs et Connexions