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.
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
The library uses a smart rendering system that automatically manages the transition between Canvas and React components:
- At low zoom levels, everything is rendered on Canvas for performance
- When zooming in to detailed view, the
GraphCanvascomponent:- 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 renderingconstMyGraph=()=>{return(<GraphCanvasgraph={graph}renderBlock={(graph,block)=>(<MyCustomBlockComponentgraph={graph}block={block}/>)}/>);};npm install @gravity-ui/graphDetailed React Components Documentation
importReact,{useEffect}from"react";importtype{Graph,TBlock}from"@gravity-ui/graph";import{EAnchorType,GraphState}from"@gravity-ui/graph";import{GraphCanvas,GraphBlock,useGraph}from"@gravity-ui/graph/react";constconfig={};exportfunctionGraphEditor(){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: "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: "Block #2",anchors: [{id: "in1",blockId: "action_2",type: EAnchorType.IN,index: 0,},],},],connections: [{sourceBlockId: "action_1",sourceAnchorId: "out1",targetBlockId: "action_2",targetAnchorId: "in1",},],});},[setEntities]);constrenderBlockFn=(graph: Graph,block: TBlock)=>{return(<GraphBlockgraph={graph}block={block}>{block.id}</GraphBlock>);};return(<GraphCanvasgraph={graph}renderBlock={renderBlockFn}onStateChanged={({ state })=>{if(state===GraphState.ATTACHED){start();graph.zoomTo("center",{padding: 300});}}}/>);}import{Graph}from"@gravity-ui/graph";// Create container elementconstcontainer=document.createElement('div');container.style.width='100vw';container.style.height='100vh';container.style.overflow='hidden';document.body.appendChild(container);// Initialize graph with configurationconstgraph=newGraph({configurationName: "example",blocks: [],connections: [],settings: {canDragCamera: true,canZoomCamera: true,useBezierConnections: true,showConnectionArrows: true}},container);// Add blocks and connectionsgraph.setEntities({blocks: [{is: "block-action",id: "block1",x: 100,y: 100,width: 120,height: 120,name: "Block #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: "Block #2",anchors: [{id: "in1",blockId: "block2",type: EAnchorType.IN,index: 0}]}],connections: [{sourceBlockId: "block1",sourceAnchorId: "out1",targetBlockId: "block2",targetAnchorId: "in1"}]});// Start renderinggraph.start();// Center the viewgraph.zoomTo("center",{padding: 100});System
Components
Rendering
Blocks and Connections
Distributed under the MIT License. See LICENSE for details.
A hybrid Canvas/React graph editor for node-based diagrams — reach for it to build flowcharts, node editors, or large interactive diagrams where Canvas gives performance at low zoom and React components give rich interactivity when zoomed in.
- Node-based editors (flowcharts, pipelines, visual builders) with hundreds/thousands of nodes and connections.
- Mixed rendering: Canvas for the full-graph overview, React components for the blocks visible in the viewport at high zoom.
- Vanilla JS or React consumers — the core
Graphclass is framework-agnostic;@gravity-ui/graph/reactprovides the React bindings.
- To plot numeric data series (line/bar/scatter charts), use
@gravity-ui/chartsor@gravity-ui/yagr— graph is a node/edge diagram editor, not a data chart. - For a static, non-editable diagram with few nodes, an SVG or a simpler diagram lib may suffice without the Canvas/React viewport machinery.
- Hallucinated import
GraphEditor— the React components areGraphCanvas,GraphBlock, and theuseGraphhook, imported from@gravity-ui/graph/react; the core class isGraphfrom@gravity-ui/graph. - Calling graph methods before
ATTACHEDstate — callstart()/zoomTo(...)inside theonStateChangedcallback whenstate === GraphState.ATTACHED, not on mount. - Forgetting
setEntities—useGraphreturnsgraph,setEntities,start; data only appears aftersetEntities({blocks, connections}). - Mixing anchor types — connections must reference existing anchor ids with matching
EAnchorType(IN/OUT) on the source and target blocks.
Agent-readable documentation for the installed version is located in node_modules/@gravity-ui/graph/build/docs/INDEX.md.
