@gravity-ui/graph
TypeScript icon, indicating that this package has built-in type declarations

0.4.2 • Public • Published

@gravity-ui/graph · npm package Release storybook

A graph visualization library that combines the best of both worlds:

  • Canvas for high performance when viewing the full graph
  • HTML/React for rich interactions when zoomed in

No more choosing between performance and interactivity. Perfect for large diagrams, flowcharts, and node-based editors.

Motivation

Modern web applications often require complex visualization and interactivity, but existing solutions typically focus on a single rendering technology:

  • Canvas offers high performance for complex graphics but is limited in text handling and interactivity.
  • HTML DOM is convenient for interfaces but less efficient for complex graphics or large numbers of elements.

@gravity-ui/graph solves this by automatically switching between Canvas and HTML based on zoom level:

  • Zoomed Out: Uses Canvas for efficient rendering of the full graph
  • Medium Zoom: Shows schematic view with basic interactivity
  • Zoomed In: Switches to HTML/React components for rich interactions

How It Works

The library uses a smart rendering system that automatically manages the transition between Canvas and React components:

  1. At low zoom levels, everything is rendered on Canvas for performance
  2. When zooming in to detailed view, the BlocksList component:
    • Tracks camera viewport and scale changes
    • Calculates which blocks are visible in the current viewport (with padding for smooth scrolling)
    • Renders React components only for visible blocks
    • Automatically updates the list when scrolling or zooming
    • Removes React components when zooming out
// Example of React components rendering
const MyGraph = () => {
  return (
    <GraphCanvas
      graph={graph}
      renderBlock={(graph, block) => (
        <MyCustomBlockComponent 
          graph={graph} 
          block={block}
        />
      )}
    />
  );
};

Storybook

Install

npm install @gravity-ui/graph

Examples

React Example

Detailed React Components Documentation

import { GraphCanvas, GraphState, GraphBlock, useGraph } from "@gravity-ui/graph";
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: "Block #1",
          anchors: [],
        },
        {
          id: "action_2",
          is: "block-action",
          x: 253,
          y: 176,
          width: 126,
          height: 126,
          selected: false,
          name: "Block #2",
          anchors: [],
        }
      ],
      connections: [
        {
          sourceBlockId: "action_1",
          targetBlockId: "action_2",
        }
      ]
    });
  }, [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 });
        }
      }}
    />
  );
}

Vanilla JavaScript Example

import { Graph } from "@gravity-ui/graph";

// Create container element
const container = document.createElement('div');
container.style.width = '100vw';
container.style.height = '100vh';
container.style.overflow = 'hidden';
document.body.appendChild(container);

// Initialize graph with configuration
const graph = new Graph({
    configurationName: "example",
    blocks: [],
    connections: [],
    settings: {
        canDragCamera: true,
        canZoomCamera: true,
        useBezierConnections: true,
        showConnectionArrows: true
    }
}, container);

// Add blocks and connections
graph.setEntities({
    blocks: [
        {
            is: "block-action",
            id: "block1",
            x: 100,
            y: 100,
            width: 120,
            height: 120,
            name: "Block #1"
        },
        {
            is: "block-action",
            id: "block2",
            x: 300,
            y: 300,
            width: 120,
            height: 120,
            name: "Block #2"
        }
    ],
    connections: [
        {
            sourceBlockId: "block1",
            targetBlockId: "block2"
        }
    ]
});

// Start rendering
graph.start();

// Center the view
graph.zoomTo("center", { padding: 100 });

Live Examples

Documentation

Table of Contents

  1. System

  2. Components

  3. Rendering

  4. Blocks and Connections

/@gravity-ui/graph/

    Package Sidebar

    Install

    npm i @gravity-ui/graph

    Weekly Downloads

    241

    Version

    0.4.2

    License

    MIT

    Unpacked Size

    484 kB

    Total Files

    234

    Last publish

    Collaborators

    • resure
    • amje
    • gravity-ui-bot