API Canvas

Elenweave Canvas API

A client-only JavaScript library under canvas/lib/, framework-agnostic, shipped as ES modules. The surface is structured around Workspace, Graph, View, and Navigator.

Client-only ES modules Multi-board workspaces Export PNG + JSON HTML nodes (DOM overlay)
Structured interaction

ElenweaveWorkspace

Multi-graph container and navigation layer.

Workspace vs Graph

  • Workspace manages many boards and the active board. It is the navigation layer (create, rename, switch, move nodes between boards).
  • Graph is one board’s data model (nodes and edges) and does not know about other boards.

Methods

  • createGraph(name?: string): string → returns graph id
  • getGraph(id): ElenweaveGraph | null
  • listGraphs(): ElenweaveGraph[]
  • renameGraph(id, name): ElenweaveGraph | null
  • setActiveGraph(id): void
  • deleteGraph(id): boolean
  • moveNode(nodeId, fromGraphId, toGraphId): string | null
  • addNodesToGraph(graphId, partials): string[]
  • addEdgesToGraph(graphId, entries): string[]
  • updateNodesInGraph(graphId, entries): Node[]
  • updateEdgesInGraph(graphId, entries): Edge[]
  • addNodesBatch(entries): Array<{ graphId, id }>
  • addEdgesBatch(entries): Array<{ graphId, id }>
  • updateNodesBatch(entries): Array<{ graphId, node }>
  • updateEdgesBatch(entries): Array<{ graphId, edge }>
  • exportGraph(id): GraphJson | null
  • exportWorkspace(): WorkspaceJson
  • importGraph(payload, options?): string | null
  • importWorkspace(payload, options?): boolean

Events

  • graph:createdElenweaveGraph
  • graph:renamedElenweaveGraph
  • graph:activeElenweaveGraph
  • graph:deletedgraphId
  • node:moved{ from, to, fromId, toId }
Subscribe with workspace.on(event, handler).

Batch operations (multiple graphs)

Batch helpers accept per-graph entries and reduce rework when updating many boards.

JavaScript
workspace.addNodesBatch([
  { graphId: boardA, nodes: [{ text: 'Alpha', x: 80, y: 120 }] },
  { graph: boardB, items: [{ text: 'Beta', x: 220, y: 160 }] }
]);

workspace.updateEdgesBatch([
  { graphId: boardA, updates: [{ id: edgeId, patch: { label: 'critical' } }] },
  { boardId: boardB, entries: [{ id: edge2, label: 'ok' }] }
]);

ElenweaveGraph

Low-level graph model (nodes and edges).

Methods

  • addNode(partial): string
  • addNodes(partials: Node[]): string[]
  • updateNode(id, patch): Node | null
  • updateNodes(patches: Array<{ id, patch } | Node>): Node[]
  • removeNode(id): boolean
  • getNodeOrder(): string[]
  • moveNodeToIndex(id, index): boolean
  • moveNodeBefore(id, targetId): boolean
  • moveNodeAfter(id, targetId): boolean
  • addEdge(from, to, opts?): string | null
  • addEdges(entries: Array<{ from, to, ...opts }>): string[]
  • updateEdge(edgeId, patch): Edge | null
  • updateEdges(patches: Array<{ id, patch } | Edge>): Edge[]
  • removeEdge(edgeId): boolean
  • getNode(id): Node | null
  • clear(): void
  • serialize(): { id, name, nodes, edges }
  • ElenweaveGraph.hydrate(data): ElenweaveGraph
Edge opts for addEdge supports { color?, pulse?, label?, id? }.

Bulk updates (single graph)

JavaScript
graph.updateNodes([
  { id: nodeA, patch: { x: 120, y: 220 } },
  { id: nodeB, text: 'Renamed', color: '#78dbff' }
]);

graph.updateEdges([
  { id: edgeA, patch: { label: 'hot' } },
  { id: edgeB, color: '#41ffb4' }
]);

Placement helpers

  • autoPlace?: boolean — when true, nudges the node around the requested position to avoid overlaps.
  • avoidOverlap?: boolean — set false to keep exact placement; auto-placement runs only when autoPlace is true or x/y are omitted.

ElenweaveView

Renderer and interaction controller for a single canvas.

Construction

JavaScript
const view = new ElenweaveView({
  canvas: document.querySelector('#bp'),
  workspace,      // optional; if omitted, a workspace is created
  graphId: null,  // optional; locks the view to a specific graph
  options: {
    gridSize: 0,
    minZoom: 0.3,
    maxZoom: 2.5,
    snap: 12,
    nodeColor: '#6fe7ff',
    edgeColor: '#78dbff',
    themeName: 'blueprint',
    theme: { nodeStroke: '#6fe7ff' },
    contextMenu: true,
    domPurify: window.DOMPurify, // optional sanitizer instance
    sanitizeHtml: true,
    sanitizeSvg: true,
    allowUntrustedComponents: true,
    sanitizeConfig: { html: {}, svg: {} },
    virtualize: false,
    virtualizePadding: 200,
    virtualizeEdges: true
  }
});
If a node or edge does not specify color, the view uses options.nodeColor or options.edgeColor.

Security & trust

  • domPurify (or sanitizer) supplies a DOMPurify instance; if omitted, the view uses globalThis.DOMPurify when available.
  • sanitizeHtml / sanitizeSvg default to true.
  • sanitizeConfig merges into defaults for HTML/SVG sanitizer options.
  • allowUntrustedComponents defaults to true. When false, components marked untrusted are blocked.
  • A component is untrusted when node.trusted === false or the registry entry has trusted: false.

Methods

  • addNode(partial): string, updateNode(id, patch), removeNode(id)
  • addEdge(from, to, opts?), updateEdge(edgeId, patch), removeEdge(edgeId)
  • selectNode(id | null), selectEdge(id | null), deleteSelected()
  • setLinkMode(boolean)
  • setActiveGraph(id) (no-op if graphId was provided)
  • focusNode(id), moveTo(id)
  • invalidate(), destroy()
  • registerComponent(name, definition), unregisterComponent(name)
  • exportGraph(), exportWorkspace()
  • importGraph(payload, options?), importWorkspace(payload, options?)
  • setContextMenuConfig(config), enableContextMenu(), disableContextMenu()
  • setVirtualization({ enabled?, padding?, edges? }), getVirtualizationConfig()
  • addNotification({ nodeId, label?, timestamp? }), markNotificationRead(id, read?), clearNotifications(), getNotifications()