The Graph class is the primary entry point for G6, providing comprehensive lifecycle management, canvas control, and viewport operations. It extends EventEmitter for event handling and manages a multi-layer rendering system.
import { Graph } from '@antv/g6';
import { Renderer as CanvasRenderer } from '@antv/g-canvas';
import type {
GraphOptions,
GraphData,
ViewportAnimationEffectTiming,
FitViewOptions,
Point
} from '@antv/g6';
const graph = new Graph({
container: 'container',
width: 800,
height: 600,
renderer: (layer) => new CanvasRenderer(), // Custom renderer per layer
background: '#f9f9f9',
autoFit: { type: 'view' },
animation: true,
theme: 'light',
data: {
nodes: [],
edges: [],
combos: []
}
});// Initialize and render
await graph.render(); // Full render with layout
await graph.draw(); // Draw only (no layout)
// Resize operations
graph.setSize(1000, 700);
const [width, height] = graph.getSize();
graph.resize(); // Auto-resize to container
graph.resize(1200, 800); // Specific size
// Cleanup
await graph.clear(); // Clear canvas elements
graph.destroy(); // Destroy graph instance// Options management
const options: GraphOptions = graph.getOptions();
graph.setOptions({
animation: { duration: 500, easing: 'ease-in-out' },
theme: 'dark'
});
// Zoom range control
graph.setZoomRange([0.1, 10]);
const [minZoom, maxZoom] = graph.getZoomRange();// Get canvas instance
const canvas = graph.getCanvas();
// Canvas configuration
const config = canvas.getConfig();
const container = canvas.getContainer();
const [width, height] = canvas.getSize();
// Layer management
const mainLayer = canvas.getLayer('main');
const labelLayer = canvas.getLayer('label');
const backgroundLayer = canvas.getLayer('background');
const transientLayer = canvas.getLayer('transient');
const allLayers = canvas.getLayers();
// Renderer and camera access
const renderer = canvas.getRenderer('main');
const camera = canvas.getCamera('main');
const root = canvas.getRoot('main');// Zoom operations
await graph.zoomBy(1.2); // Relative zoom
await graph.zoomTo(2.0); // Absolute zoom
await graph.zoomBy(0.8, { duration: 300 }, [400, 300]); // With animation and origin
const currentZoom = graph.getZoom();
// Rotation operations
await graph.rotateBy(Math.PI / 4); // Rotate by 45 degrees
await graph.rotateTo(Math.PI / 2); // Rotate to 90 degrees
const currentRotation = graph.getRotation();
// Translation operations
await graph.translateBy([100, 50]); // Relative translate
await graph.translateTo([200, 200]); // Absolute translate
const currentPosition = graph.getPosition();// Fit operations with animation
await graph.fitView({
padding: [20, 20, 20, 20],
rules: {
direction: 'both', // 'x' | 'y' | 'both'
ratioRule: 'max', // 'max' | 'min'
onlyOutOfViewport: false
}
}, {
duration: 500,
easing: 'ease-out'
});
await graph.fitCenter({ duration: 300 });
// Focus on specific elements
await graph.focusElement('node1');
await graph.focusElement(['node1', 'node2'], { duration: 400 });// Coordinate system conversions
const canvasPoint = graph.getCanvasByViewport([100, 100]);
const viewportPoint = graph.getViewportByCanvas([200, 200]);
const clientPoint = graph.getClientByCanvas([150, 150]);
const canvasFromClient = graph.getCanvasByClient([300, 300]);
// Viewport centers
const viewportCenter = graph.getViewportCenter(); // In canvas coordinates
const canvasCenter = graph.getCanvasCenter(); // In viewport coordinates// Canvas layer types
type CanvasLayer = 'background' | 'main' | 'label' | 'transient';
// Layer-specific operations
const mainLayer = canvas.getLayer('main');
const labelCamera = canvas.getCamera('label');
const backgroundRenderer = canvas.getRenderer('background');
// Add elements to appropriate layers
const element = canvas.appendChild(displayObject, 0); // Auto-layer assignment// Canvas management
canvas.setCursor('pointer'); // Set cursor style
await canvas.resize(1000, 600); // Resize canvas
// Bounds calculation
const elementBounds = canvas.getBounds('elements');
const pluginBounds = canvas.getBounds('plugins');
// Export functionality
const dataURL = await canvas.toDataURL({
type: 'image/png',
encoderOptions: 0.8
});// Canvas-specific coordinate conversions
const canvasPoint = canvas.getCanvasByViewport([x, y]);
const viewportPoint = canvas.getViewportByCanvas([x, y]);
const clientPoint = canvas.getViewportByClient([x, y]);
const viewportFromClient = canvas.getClientByViewport([x, y]);
const canvasFromClient = canvas.getCanvasByClient([x, y]);
const clientFromCanvas = canvas.getClientByCanvas([x, y]);// Graph export options
interface DataURLOptions {
type?: 'image/png' | 'image/jpeg' | 'image/webp';
encoderOptions?: number; // 0-1 for JPEG/WebP quality
pixelRatio?: number; // For high DPI exports
}
// Export graph as image
const imageDataURL = await graph.toDataURL({
type: 'image/png',
encoderOptions: 1.0,
pixelRatio: 2 // High DPI export
});
// Convert to blob for download
const response = await fetch(imageDataURL);
const blob = await response.blob();// Default graph configuration
const defaultOptions = Graph.defaultOptions;
// Check graph state
const isRendered = graph.rendered;
const isDestroyed = graph.destroyed;// Element positioning
await graph.translateElementBy('node1', [50, 30]); // Move element relatively
await graph.translateElementBy({ 'node1': [50, 30], 'node2': [100, 60] }); // Batch move
await graph.translateElementTo('node1', [200, 150]); // Move element to absolute position
await graph.translateElementTo({ 'node1': [200, 150], 'node2': [400, 300] }); // Batch move
const elementPosition = graph.getElementPosition('node1'); // Get element position// Visibility control
await graph.showElement('node1'); // Show single element
await graph.showElement(['node1', 'node2']); // Show multiple elements
await graph.hideElement(['edge1', 'edge2']); // Hide elements
const visibility = graph.getElementVisibility('node1'); // Get visibility state
// Z-index management
await graph.setElementZIndex('node1', 10); // Set single element z-index
await graph.setElementZIndex({ 'node1': 10, 'node2': 5 }); // Batch set z-index
await graph.frontElement('node1'); // Bring element to front
await graph.frontElement(['node1', 'node2']); // Bring multiple elements to front
const zIndex = graph.getElementZIndex('node1'); // Get element z-index// State management
await graph.setElementState('node1', 'selected'); // Set single state
await graph.setElementState('node1', ['selected', 'hover']); // Set multiple states
await graph.setElementState({ 'node1': 'selected', 'node2': 'hover' }); // Batch set states
const states = graph.getElementState('node1'); // Get element states// Style and rendering
const renderStyle = graph.getElementRenderStyle('node1'); // Get computed styles
const bounds = graph.getElementRenderBounds('node1'); // Get element bounds// Hierarchical operations
await graph.collapseElement('combo1', true); // Collapse with default options
await graph.collapseElement('combo1', {
animation: { duration: 500 },
sillyNodesNumber: 10
}); // Advanced collapse
await graph.expandElement('combo1', true); // Expand with default options
await graph.expandElement('combo1', {
animation: { duration: 300 }
}); // Advanced expand// Element information
const elementType = graph.getElementType('node1'); // 'node' | 'edge' | 'combo'
// Relationship queries
const relatedEdges = graph.getRelatedEdgesData('node1', 'both'); // Get connected edges
const neighbors = graph.getNeighborNodesData('node1'); // Get neighbor nodes
// Hierarchical relationships
const ancestors = graph.getAncestorsData('node1', 'parent'); // Get parent hierarchy
const parent = graph.getParentData('node1', 'parent'); // Get direct parent
const children = graph.getChildrenData('combo1'); // Get child elements
const descendants = graph.getDescendantsData('combo1'); // Get all descendants// Query elements by state
const selectedNodes = graph.getElementDataByState('node', 'selected');
const hoveredEdges = graph.getElementDataByState('edge', 'hover');
const activeCombos = graph.getElementDataByState('combo', 'active');// Event subscription
graph.on<IElementEvent>('node:click', (event) => {
console.log('Node clicked:', event.target.id);
});
graph.once<IViewportEvent>('viewport:transform', (event) => {
console.log('Viewport transformed once:', event.transform);
});
// Event unsubscription
graph.off(); // Remove all listeners
graph.off('node:click'); // Remove all listeners for event
graph.off('node:click', specificHandler); // Remove specific handler
// Lifecycle events
graph.on('render', () => console.log('Graph rendered'));
graph.on('destroy', () => console.log('Graph destroyed'));
// Viewport events
graph.on('viewport:transform', (event) => {
console.log('Transform changed:', event.transform);
});
// Canvas events
graph.on('canvas:resize', (event) => {
console.log('Canvas resized:', event.size);
});interface GraphOptions extends CanvasOptions, ViewportOptions {
animation?: boolean | AnimationEffectTiming;
data?: GraphData;
layout?: LayoutOptions;
node?: NodeOptions;
edge?: EdgeOptions;
combo?: ComboOptions;
theme?: ThemeOptions;
behaviors?: BehaviorOptions;
plugins?: PluginOptions;
transforms?: TransformOptions;
}
interface CanvasConfig {
container: HTMLElement | string;
width?: number;
height?: number;
renderer?: 'canvas' | 'svg' | 'webgl';
devicePixelRatio?: number;
background?: string;
cursor?: string;
}
interface ViewportAnimationEffectTiming {
duration?: number;
easing?: string | ((t: number) => number);
delay?: number;
fill?: 'none' | 'forwards' | 'backwards' | 'both';
}
interface FitViewOptions {
padding?: number | number[];
rules?: {
direction?: 'x' | 'y' | 'both';
ratioRule?: 'max' | 'min';
onlyOutOfViewport?: boolean;
};
}
type Point = [number, number];