CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-vega

A declarative visualization grammar for creating interactive data visualizations through JSON specifications.

Pending
Overview
Eval results
Files

scenegraph.mddocs/

Scene Graph & Rendering

Vega's scene graph and rendering system provides multi-backend support for Canvas, SVG, and hybrid rendering with comprehensive visual element management, bounds calculation, and high-performance drawing operations.

Capabilities

Scene Graph Structure

Core scene graph classes for hierarchical visual organization.

/**
 * Main scene graph structure
 */
class Scenegraph {
  /**
   * Create a new scenegraph
   * @param root - Optional root group item
   */
  constructor(root?: GroupItem);
  
  /** Root group item of the scene graph */
  root: GroupItem;
  
  /**
   * Serialize scenegraph to JSON
   * @param indent - Optional indentation for pretty printing
   * @returns JSON string representation
   */
  toJSON(indent?: number): string;
}

/**
 * Base scene graph item
 */
interface Item<T = any> {
  /** Associated data tuple */
  datum: T;
  
  /** Runtime mark definition */
  mark: RuntimeMark;
  
  /** Item bounds */
  bounds?: Bounds;
  
  /** Item x coordinate */
  x?: number;
  
  /** Item y coordinate */
  y?: number;
  
  /** Item width */
  width?: number;
  
  /** Item height */
  height?: number;
  
  /** Fill color */
  fill?: Color;
  
  /** Stroke color */
  stroke?: Color;
  
  /** Stroke width */
  strokeWidth?: number;
  
  /** Fill opacity */
  fillOpacity?: number;
  
  /** Stroke opacity */
  strokeOpacity?: number;
}

/**
 * Group item container for nested items
 */
class GroupItem implements Item {
  /** Child items */
  items: Item[];
  
  /** Item count */
  count: number;
  
  /**
   * Add child item
   * @param item - Item to add
   */
  add(item: Item): GroupItem;
  
  /**
   * Remove child item
   * @param item - Item to remove
   */
  remove(item: Item): GroupItem;
  
  /**
   * Clear all child items
   */
  clear(): GroupItem;
}

interface RuntimeMark {
  /** Mark type */
  marktype: string;
  
  /** Mark name */
  name?: string;
  
  /** Mark role */
  role?: string;
  
  /** Mark group */
  group?: GroupItem;
}

type Color = string;

interface Bounds {
  /** Left coordinate */
  x1: number;
  
  /** Top coordinate */
  y1: number;
  
  /** Right coordinate */
  x2: number;
  
  /** Bottom coordinate */
  y2: number;
}

Bounds Calculations

Comprehensive bounds calculation system for visual elements.

/**
 * Bounding box calculations for scene graph items
 */
class Bounds {
  /**
   * Create new bounds
   * @param bounds - Optional initial bounds
   */
  constructor(bounds?: Bounds);
  
  /** Left coordinate */
  x1: number;
  
  /** Top coordinate */
  y1: number;
  
  /** Right coordinate */
  x2: number;
  
  /** Bottom coordinate */
  y2: number;
  
  /**
   * Set bounds coordinates
   * @param x1 - Left coordinate
   * @param y1 - Top coordinate
   * @param x2 - Right coordinate
   * @param y2 - Bottom coordinate
   * @returns The bounds instance
   */
  set(x1: number, y1: number, x2: number, y2: number): Bounds;
  
  /**
   * Add coordinates to bounds
   * @param x - X coordinate to include
   * @param y - Y coordinate to include
   * @returns The bounds instance
   */
  add(x: number, y: number): Bounds;
  
  /**
   * Expand bounds by specified amounts
   * @param d - Expansion amount (all sides)
   * @returns The bounds instance
   */
  expand(d: number): Bounds;
  
  /**
   * Round bounds to integer coordinates
   * @returns The bounds instance
   */
  round(): Bounds;
  
  /**
   * Translate bounds by offset
   * @param dx - X offset
   * @param dy - Y offset
   * @returns The bounds instance
   */
  translate(dx: number, dy: number): Bounds;
  
  /**
   * Union with another bounds
   * @param bounds - Bounds to union with
   * @returns The bounds instance
   */
  union(bounds: Bounds): Bounds;
  
  /**
   * Intersect with another bounds
   * @param bounds - Bounds to intersect with
   * @returns The bounds instance
   */
  intersect(bounds: Bounds): Bounds;
  
  /**
   * Check if bounds contains point
   * @param x - X coordinate
   * @param y - Y coordinate
   * @returns True if point is contained
   */
  contains(x: number, y: number): boolean;
  
  /**
   * Check if bounds intersects with another
   * @param bounds - Bounds to test intersection
   * @returns True if bounds intersect
   */
  intersects(bounds: Bounds): boolean;
  
  /**
   * Get bounds width
   * @returns Width value
   */
  width(): number;
  
  /**
   * Get bounds height
   * @returns Height value
   */
  height(): number;
  
  /**
   * Check if bounds is empty
   * @returns True if bounds is empty
   */
  empty(): boolean;
  
  /**
   * Clone the bounds
   * @returns New bounds instance
   */
  clone(): Bounds;
  
  /**
   * Clear the bounds
   * @returns The bounds instance
   */
  clear(): Bounds;
}

/**
 * Calculate bounds for a scene graph item
 * @param item - Scene graph item
 * @param bounds - Optional bounds to update
 * @returns Updated bounds
 */
function boundItem(item: Item, bounds?: Bounds): Bounds;

/**
 * Calculate bounds for a mark
 * @param mark - Mark definition
 * @param bounds - Optional bounds to update
 * @returns Updated bounds
 */
function boundMark(mark: RuntimeMark, bounds?: Bounds): Bounds;

/**
 * Calculate bounds with clipping
 * @param item - Scene graph item
 * @param clip - Clipping bounds
 * @param bounds - Optional bounds to update
 * @returns Updated bounds
 */
function boundClip(item: Item, clip: Bounds, bounds?: Bounds): Bounds;

/**
 * Calculate stroke bounds
 * @param item - Scene graph item
 * @param bounds - Optional bounds to update
 * @returns Updated bounds
 */
function boundStroke(item: Item, bounds?: Bounds): Bounds;

/**
 * Calculate bounds for rendering context
 * @param item - Scene graph item
 * @param context - Rendering context
 * @returns Updated bounds
 */
function boundContext(item: Item, context: any): Bounds;

Rendering System

Multi-backend rendering with Canvas, SVG, and hybrid support.

/**
 * Base renderer class
 */
abstract class Renderer {
  /**
   * Create new renderer
   * @param loader - Optional resource loader
   */
  constructor(loader?: ResourceLoader);
  
  /** Resource loader for images, fonts, etc. */
  loader: ResourceLoader;
  
  /**
   * Initialize the renderer
   * @param el - Container element
   * @param width - Canvas width
   * @param height - Canvas height
   * @param origin - Drawing origin coordinates
   * @param scaleFactor - Scale factor for high DPI
   * @returns The renderer instance
   */
  initialize(el: Element, width: number, height: number, origin: [number, number], scaleFactor?: number): Renderer;
  
  /**
   * Resize the renderer
   * @param width - New width
   * @param height - New height
   * @param origin - New origin coordinates
   * @param scaleFactor - New scale factor
   * @returns The renderer instance
   */
  resize(width: number, height: number, origin: [number, number], scaleFactor?: number): Renderer;
  
  /**
   * Render a scene graph
   * @param scene - Scene graph to render
   * @returns The renderer instance
   */
  render(scene: Scene): Renderer;
  
  /**
   * Get the rendered element
   * @returns DOM element containing the rendered output
   */
  element(): Element;
  
  /**
   * Get the rendered canvas (Canvas renderer only)
   * @returns Canvas element or null
   */
  canvas(): HTMLCanvasElement | null;
  
  /**
   * Clean up renderer resources
   */
  cleanup(): void;
}

/**
 * Canvas-based renderer
 */
class CanvasRenderer extends Renderer {
  constructor(loader?: ResourceLoader);
  
  /**
   * Get the canvas element
   * @returns Canvas element
   */
  canvas(): HTMLCanvasElement;
  
  /**
   * Get the 2D rendering context
   * @returns Canvas 2D context
   */
  context(): CanvasRenderingContext2D;
}

/**
 * SVG-based renderer
 */
class SVGRenderer extends Renderer {
  constructor(loader?: ResourceLoader);
  
  /**
   * Get the SVG element
   * @returns SVG element
   */
  svg(): SVGSVGElement;
}

/**
 * SVG string renderer (no DOM)
 */
class SVGStringRenderer extends Renderer {
  constructor(loader?: ResourceLoader);
  
  /**
   * Get SVG markup string
   * @returns SVG markup as string
   */
  svg(): string;
}

/**
 * Hybrid Canvas/SVG renderer
 */
class HybridRenderer extends Renderer {
  constructor(loader?: ResourceLoader);
  
  /**
   * Get the canvas element
   * @returns Canvas element
   */
  canvas(): HTMLCanvasElement;
  
  /**
   * Get the SVG element
   * @returns SVG element
   */
  svg(): SVGSVGElement;
}

interface Scene {
  /** Mark type */
  marktype: string;
  
  /** Scene items */
  items: Item[];
  
  /** Scene bounds */
  bounds: Bounds;
}

/** Available rendering types */
const RenderType: {
  Canvas: 'canvas';
  SVG: 'svg';
  Hybrid: 'hybrid';
  None: 'none';
};

/**
 * Get renderer module by type
 * @param type - Renderer type
 * @returns Renderer constructor
 */
function renderModule(type: string): typeof Renderer;

/**
 * Configure hybrid renderer options
 * @param options - Hybrid renderer configuration
 */
function setHybridRendererOptions(options: HybridRendererOptions): void;

interface HybridRendererOptions {
  /** Canvas marks to render on canvas */
  canvas?: string[];
  
  /** SVG marks to render as SVG */
  svg?: string[];
  
  /** Default renderer for unspecified marks */
  default?: 'canvas' | 'svg';
}

Event Handling

Event handlers for interactive scene graphs.

/**
 * Base event handler
 */
class Handler {
  /**
   * Create new event handler
   * @param loader - Resource loader
   * @param tooltip - Optional tooltip handler
   */
  constructor(loader?: ResourceLoader, tooltip?: Function);
  
  /**
   * Initialize event handling
   * @param element - DOM element to attach events
   * @param origin - Coordinate origin
   * @param obj - Handler context object
   * @returns The handler instance
   */
  initialize(element: Element, origin: [number, number], obj: any): Handler;
  
  /**
   * Set scene graph for event targeting
   * @param scene - Scene graph root
   * @returns The handler instance
   */
  scene(scene: Scene): Handler;
  
  /**
   * Enable or disable event handling
   * @param enable - Whether to enable events
   * @returns The handler instance
   */
  events(enable: boolean): Handler;
}

/**
 * Canvas-specific event handler
 */
class CanvasHandler extends Handler {
  constructor(loader?: ResourceLoader, tooltip?: Function);
}

/**
 * SVG-specific event handler
 */
class SVGHandler extends Handler {
  constructor(loader?: ResourceLoader, tooltip?: Function);
}

/**
 * Hybrid renderer event handler
 */
class HybridHandler extends Handler {
  constructor(loader?: ResourceLoader, tooltip?: Function);
}

Resource Loading

Resource loader for external assets.

/**
 * Resource loader for images, fonts, and other assets
 */
class ResourceLoader {
  /**
   * Create new resource loader
   * @param loader - Optional base loader
   */
  constructor(loader?: any);
  
  /**
   * Load an image resource
   * @param url - Image URL
   * @returns Promise resolving to image element
   */
  loadImage(url: string): Promise<HTMLImageElement>;
  
  /**
   * Load a font resource
   * @param name - Font name
   * @param url - Font URL
   * @returns Promise resolving when font is loaded
   */
  loadFont(name: string, url: string): Promise<void>;
  
  /**
   * Preload resources
   * @param resources - Array of resource URLs
   * @returns Promise resolving when all resources are loaded
   */
  preload(resources: string[]): Promise<void>;
  
  /**
   * Sanitize URL for loading
   * @param url - URL to sanitize
   * @returns Sanitized URL
   */
  sanitizeURL(url: string): string;
}

Gradients

Gradient definition and rendering support.

/**
 * Gradient definition for fill and stroke
 */
class Gradient {
  /**
   * Create new gradient
   * @param type - Gradient type ('linear' or 'radial')
   * @param stops - Color stops array
   */
  constructor(type: 'linear' | 'radial', stops: GradientStop[]);
  
  /** Gradient type */
  type: 'linear' | 'radial';
  
  /** Color stops */
  stops: GradientStop[];
  
  /** Start coordinates (linear gradients) */
  x1?: number;
  y1?: number;
  
  /** End coordinates (linear gradients) */
  x2?: number;
  y2?: number;
  
  /** Center coordinates (radial gradients) */
  cx?: number;
  cy?: number;
  
  /** Radius (radial gradients) */
  r?: number;
  
  /**
   * Add color stop
   * @param offset - Stop position (0-1)
   * @param color - Stop color
   * @returns The gradient instance
   */
  addStop(offset: number, color: string): Gradient;
}

interface GradientStop {
  /** Stop position (0-1) */
  offset: number;
  
  /** Stop color */
  color: string;
  
  /** Stop opacity */
  opacity?: number;
}

Path Operations

Path generation and manipulation utilities.

/**
 * Parse SVG path string
 * @param path - SVG path string
 * @returns Parsed path commands
 */
function pathParse(path: string): PathCommand[];

/**
 * Render path to context
 * @param context - Rendering context
 * @param item - Path item to render
 */
function pathRender(context: any, item: Item): void;

/**
 * Get path for symbol marks
 * @param symbol - Symbol type
 * @returns Path generator function
 */
function pathSymbols(symbol: string): Function;

/**
 * Get path for curve interpolation
 * @param curve - Curve type
 * @returns Curve generator function
 */
function pathCurves(curve: string): Function;

/**
 * Generate rectangle path
 * @param x - X coordinate
 * @param y - Y coordinate
 * @param width - Rectangle width
 * @param height - Rectangle height
 * @returns Path string
 */
function pathRectangle(x: number, y: number, width: number, height: number): string;

/**
 * Generate trail path
 * @param points - Array of points
 * @returns Path string
 */
function pathTrail(points: [number, number][]): string;

interface PathCommand {
  /** Command type */
  type: string;
  
  /** Command arguments */
  args: number[];
}

Intersection Detection

Advanced intersection detection for interactive features.

/**
 * Test intersection between shapes
 * @param item1 - First item
 * @param item2 - Second item
 * @returns True if items intersect
 */
function intersect(item1: Item, item2: Item): boolean;

/**
 * Test path intersection with point
 * @param path - Path commands
 * @param x - X coordinate
 * @param y - Y coordinate
 * @returns True if point intersects path
 */
function intersectPath(path: PathCommand[], x: number, y: number): boolean;

/**
 * Test point intersection
 * @param item - Scene graph item
 * @param x - X coordinate
 * @param y - Y coordinate
 * @returns True if point intersects item
 */
function intersectPoint(item: Item, x: number, y: number): boolean;

/**
 * Test intersection using fill rule
 * @param item - Scene graph item
 * @param x - X coordinate
 * @param y - Y coordinate
 * @param rule - Fill rule ('nonzero' or 'evenodd')
 * @returns True if point intersects using rule
 */
function intersectRule(item: Item, x: number, y: number, rule: 'nonzero' | 'evenodd'): boolean;

/**
 * Test box-line intersection
 * @param x1 - Box left
 * @param y1 - Box top
 * @param x2 - Box right
 * @param y2 - Box bottom
 * @param ax - Line start X
 * @param ay - Line start Y
 * @param bx - Line end X
 * @param by - Line end Y
 * @returns True if box and line intersect
 */
function intersectBoxLine(x1: number, y1: number, x2: number, y2: number, ax: number, ay: number, bx: number, by: number): boolean;

Scene Operations

Scene graph traversal and manipulation utilities.

/**
 * Test scene graph equality
 * @param scene1 - First scene
 * @param scene2 - Second scene
 * @returns True if scenes are equal
 */
function sceneEqual(scene1: Scene, scene2: Scene): boolean;

/**
 * Test path equality
 * @param path1 - First path
 * @param path2 - Second path
 * @returns True if paths are equal
 */
function pathEqual(path1: string, path2: string): boolean;

/**
 * Convert scene graph to JSON
 * @param scene - Scene graph to serialize
 * @param indent - Optional indentation
 * @returns JSON string
 */
function sceneToJSON(scene: Scene, indent?: number): string;

/**
 * Parse scene graph from JSON
 * @param json - JSON string to parse
 * @returns Parsed scene graph
 */
function sceneFromJSON(json: string): Scene;

/**
 * Visit scene graph nodes
 * @param scene - Root scene
 * @param visitor - Visitor function
 */
function sceneVisit(scene: Scene, visitor: (item: Item) => void): void;

/**
 * Visit scene graph for picking
 * @param scene - Root scene
 * @param visitor - Visitor function
 * @param filter - Optional filter function
 */
function scenePickVisit(scene: Scene, visitor: (item: Item) => void, filter?: (item: Item) => boolean): void;

/**
 * Set Z-order for scene items
 * @param scene - Scene to reorder
 * @param zorder - Z-order comparison function
 */
function sceneZOrder(scene: Scene, zorder: (a: Item, b: Item) => number): void;

Mark System

Mark type definitions and configuration.

/** Mark type registry and definitions */
const Marks: {
  /** Arc mark */
  arc: MarkDefinition;
  
  /** Area mark */
  area: MarkDefinition;
  
  /** Image mark */
  image: MarkDefinition;
  
  /** Line mark */
  line: MarkDefinition;
  
  /** Path mark */
  path: MarkDefinition;
  
  /** Rectangle mark */
  rect: MarkDefinition;
  
  /** Rule (line segment) mark */
  rule: MarkDefinition;
  
  /** Shape mark */
  shape: MarkDefinition;
  
  /** Symbol mark */
  symbol: MarkDefinition;
  
  /** Text mark */
  text: MarkDefinition;
  
  /** Trail mark */
  trail: MarkDefinition;
  
  /** Group mark */
  group: MarkDefinition;
};

interface MarkDefinition {
  /** Mark type name */
  type: string;
  
  /** Mark drawing function */
  draw: (context: any, scene: Scene) => void;
  
  /** Mark bounds calculation function */
  bounds: (item: Item, bounds: Bounds) => Bounds;
  
  /** Mark picking function */
  pick: (context: any, item: Item, x: number, y: number) => boolean;
}

Text Operations

Text measurement and styling utilities.

/**
 * Get font specification string
 * @param item - Text item
 * @returns Font specification
 */
function font(item: Item): string;

/**
 * Get font family
 * @param item - Text item
 * @returns Font family string
 */
function fontFamily(item: Item): string;

/**
 * Get font size
 * @param item - Text item
 * @returns Font size in pixels
 */
function fontSize(item: Item): number;

/**
 * Calculate line height
 * @param item - Text item
 * @returns Line height in pixels
 */
function lineHeight(item: Item): number;

/**
 * Calculate multi-line text offset
 * @param item - Text item
 * @param dy - Line offset
 * @returns Calculated offset
 */
function multiLineOffset(item: Item, dy: number): number;

/**
 * Measure text metrics
 * @param item - Text item
 * @param text - Text to measure
 * @param context - Optional rendering context
 * @returns Text measurement object
 */
function textMetrics(item: Item, text: string, context?: any): TextMetrics;

interface TextMetrics {
  /** Text width */
  width: number;
  
  /** Text height */
  height: number;
  
  /** Baseline offset */
  baseline: number;
}

DOM Utilities

DOM manipulation and SVG utilities.

/**
 * Create DOM element
 * @param tag - Element tag name
 * @param ns - Optional namespace
 * @returns Created element
 */
function domCreate(tag: string, ns?: string): Element;

/**
 * Find DOM element by selector
 * @param selector - CSS selector
 * @param root - Optional root element
 * @returns Found element or null
 */
function domFind(selector: string, root?: Element): Element | null;

/**
 * Get child element
 * @param parent - Parent element
 * @param tag - Child tag name
 * @param ns - Optional namespace
 * @returns Child element
 */
function domChild(parent: Element, tag: string, ns?: string): Element;

/**
 * Clear element contents
 * @param element - Element to clear
 */
function domClear(element: Element): void;

/**
 * Create coordinate point
 * @param x - X coordinate
 * @param y - Y coordinate
 * @returns Point object
 */
function point(x: number, y: number): Point;

/**
 * Create markup element
 * @param markup - HTML/SVG markup string
 * @returns Created element
 */
function markup(markup: string): Element;

/**
 * Serialize element to XML
 * @param element - Element to serialize
 * @returns XML string
 */
function serializeXML(element: Element): string;

/**
 * Reset SVG definition IDs
 */
function resetSVGDefIds(): void;

interface Point {
  /** X coordinate */
  x: number;
  
  /** Y coordinate */
  y: number;
}

Usage Examples

Basic Scene Graph

import { Scenegraph, GroupItem, Bounds } from "vega";

// Create scene graph
const scenegraph = new Scenegraph();
const root = scenegraph.root;

// Add items
const item = {
  marktype: 'rect',
  x: 10,
  y: 10,
  width: 100,
  height: 50,
  fill: 'blue'
};

root.add(item);

// Calculate bounds
const bounds = new Bounds();
boundItem(item, bounds);
console.log(bounds); // {x1: 10, y1: 10, x2: 110, y2: 60}

Canvas Rendering

import { CanvasRenderer, parse, View } from "vega";

const renderer = new CanvasRenderer();
const view = new View(runtime, { renderer: 'canvas' });

// Initialize and render
view.initialize('#chart');
view.run();

// Get canvas for export
const canvas = view.toCanvas().then(canvas => {
  document.body.appendChild(canvas);
});

Custom Path Generation

import { pathParse, pathRender } from "vega";

// Parse SVG path
const commands = pathParse('M10,10 L50,50 Z');

// Create path item
const pathItem = {
  marktype: 'path',
  path: 'M10,10 L50,50 Z',
  stroke: 'red',
  strokeWidth: 2
};

// Render to canvas context
pathRender(context, pathItem);

Intersection Testing

import { intersectPoint, intersectPath } from "vega";

// Test point intersection
const item = {
  marktype: 'rect',
  x: 0, y: 0,
  width: 100, height: 50
};

const hit = intersectPoint(item, 25, 25); // true

// Test path intersection
const path = pathParse('M0,0 L100,100 Z');
const pathHit = intersectPath(path, 50, 50); // depends on path

Install with Tessl CLI

npx tessl i tessl/npm-vega

docs

data-loading.md

dataflow.md

events.md

expressions.md

index.md

parsing.md

scales.md

scenegraph.md

statistics.md

time.md

utilities.md

view.md

tile.json