import { type GraphCamera } from './camera'; import type { GraphEdge, GraphNodeState } from './graph.types'; export interface RenderPalette { background: string; foreground: string; mutedForeground: string; border: string; ring: string; /** Literal color per node index. */ nodeColors: string[]; /** Literal color per edge index. */ edgeColors: string[]; } export interface RenderOptions { states: GraphNodeState[]; edges: GraphEdge[]; indexById: Map; radii: number[]; labels: Array; camera: GraphCamera; width: number; height: number; palette: RenderPalette; selectedIndex: number | null; hoveredIndex: number | null; /** Indices adjacent to the selection, dimmed differently from the rest. */ neighborIndices: Set | null; showLabels: boolean; /** Nodes smaller than this on screen get no label, however labels are set. */ labelMinRadiusPx: number; /** Ceiling on the largest node's on-screen radius. */ maxNodeRadiusPx: number; directed: boolean; devicePixelRatio: number; } /** * Draws one frame of the graph. * * @description * Painter's algorithm: edges first, then nodes back-to-front, so nearer things * cover further ones. There is no depth buffer and none is needed — a graph is * discs and lines, which is exactly why this does not require WebGL. * * Depth is communicated three ways at once, because a single cue reads as * ambiguous on a flat screen: perspective scale, opacity fade, and draw order. */ export declare function renderGraph(ctx: CanvasRenderingContext2D, options: RenderOptions): void;