import * as react_jsx_runtime from 'react/jsx-runtime'; import * as react from 'react'; import { ReactNode } from 'react'; /** A single RDF triple/quad */ interface RdfTriple { subject: string; predicate: string; object: string; /** Optional: datatype URI for literal objects */ datatype?: string; /** Optional: language tag for literal objects */ language?: string; /** Optional: graph name for quads */ graph?: string; } /** An RDF value (literal) attached to a node as a property */ interface RdfValue { value: string; datatype?: string; language?: string; /** Metadata annotations from collapsed reification statements */ annotations?: PropertyAnnotation[]; } /** Metadata from a collapsed reified statement attached to a property */ interface PropertyAnnotation { predicate: string; value: string; datatype?: string; } /** A node in the visual graph (represents an RDF subject/object URI or blank node) */ interface GraphNode { /** URI or blank node ID — stable across updates */ id: string; /** rdf:type values (full URIs) */ types: string[]; /** Resolved display label (depends on label mode) */ label: string; /** Literal properties: predicate URI → values */ properties: Map; /** Resolved image URL for avatar rendering (null if none found) */ imageUrl: string | null; /** Extracted metadata properties (provenance, timestamps, etc.) */ metadata: Map; /** Number of edges connected to this node (in + out) */ degree: number; /** Whether this is a boundary node (has hidden neighbors in focus mode) */ isBoundary: boolean; /** Optional risk/threat score for visual emphasis (set by application code) */ riskScore?: number; /** Whether this node is in the top-N risk tier (set by application code) */ isHighRisk?: boolean; /** Optional size multiplier for featured/focal nodes (set by application code) */ sizeMultiplier?: number; /** Resolved provenance info (set by ProvenanceResolver) */ provenance?: ProvenanceInfo; } /** Provenance information for a graph node */ interface ProvenanceInfo { /** Data source URIs that contributed to this node's data */ sources: string[]; /** Human-readable names for the data sources */ sourceNames: string[]; /** ISO timestamp of when this data was generated */ generatedAt?: string; /** URI of the agent/model that generated this data */ generatedBy?: string; /** Human-readable name of the generating agent */ generatedByName?: string; /** Cryptographic content hash for data integrity */ contentHash?: string; /** DKG Uniform Asset Locator */ ual?: string; /** Blockchain anchoring info */ blockchainAnchor?: { chain?: string; txHash?: string; blockNumber?: number; }; } /** An edge in the visual graph (represents an RDF triple with URI/bnode object) */ interface GraphEdge { /** Deterministic ID: `${subject}\0${predicate}\0${object}` */ id: string; /** Source node URI */ source: string; /** Target node URI */ target: string; /** Predicate URI */ predicate: string; /** Resolved display label (depends on label mode) */ label: string; } /** Set of changes from an incremental update */ interface ChangeSet { addedNodes: string[]; removedNodes: string[]; addedEdges: string[]; removedEdges: string[]; modifiedNodes: string[]; } /** Prefix map: prefix string → namespace URI */ type PrefixMap = Record; type LabelMode = 'strict' | 'humanized'; interface LabelConfig { /** Predicates to check for display labels, in priority order */ predicates?: string[]; } interface HexagonConfig { /** Base hexagon radius in pixels */ baseSize?: number; /** Minimum hexagon radius */ minSize?: number; /** Maximum hexagon radius */ maxSize?: number; /** Whether hexagon size scales with node degree */ scaleWithDegree?: boolean; /** Predicates to check for image URLs (direct or via intermediate node) */ imagePredicates?: string[]; /** Predicate to follow on intermediate image nodes to get the actual URL */ imageUrlPredicate?: string; /** * RDF type URIs (full or compact) that should render as simple filled circles * instead of hexagons. Much faster to draw — use for high-count, low-priority * node types like SentimentAnalysis, ImageObject, Keyword, etc. */ circleTypes?: string[]; } interface StyleConfig { /** Per-node colors keyed by node URI — highest priority, wins over all other rules */ nodeColors?: Record; /** Per rdf:type class colors */ classColors?: Record; /** Per namespace prefix colors (applies to nodes whose types fall in that namespace) */ namespaceColors?: Record; /** Per predicate edge colors */ predicateColors?: Record; /** Enable subtle radial gradient on nodes */ gradient?: boolean; /** Gradient intensity (0.0 = flat, 1.0 = strong gradient). Default: 0.3 */ gradientIntensity?: number; /** Default node color */ defaultNodeColor?: string; /** Default edge color */ defaultEdgeColor?: string; /** Edge width */ edgeWidth?: number; /** Edge arrow size (0 = no arrows) */ edgeArrowSize?: number; /** Node border width */ borderWidth?: number; /** Font family for labels */ fontFamily?: string; /** Font size for labels */ fontSize?: number; } interface FocusConfig { /** URI of the initial focal node. If null, auto-selects highest-degree node. */ focalNode?: string | null; /** Number of hops from focal node to include. Default: 2 */ hops?: number; /** Maximum number of nodes to render. Default: 200 */ maxNodes?: number; /** Whether clicking a boundary node expands its neighborhood. Default: true */ expandOnClick?: boolean; } interface ReificationPattern { /** rdf:type of the reification statement node */ statementType: string; /** Predicate linking statement to the reified subject */ subjectPredicate: string; /** Predicate linking statement to the reified predicate */ predicatePredicate: string; /** Predicate linking statement to the reified object/value */ objectPredicate: string; } interface ReificationConfig { /** Enable reification collapsing. Default: false */ enabled?: boolean; /** Patterns to detect. Ships with standard rdf:Statement pattern. */ patterns?: ReificationPattern[]; } interface MetadataConfig { /** Predicates whose values are treated as metadata (shown in panel, not as edges) */ predicates?: string[]; } /** Full configuration for the visualization */ interface RdfGraphVizConfig { /** Label display mode */ labelMode?: LabelMode; /** Label resolution config */ labels?: LabelConfig; /** Hexagon rendering config */ hexagon?: HexagonConfig; /** Style/color config */ style?: StyleConfig; /** Focus/filter config for large graphs */ focus?: FocusConfig; /** Reification collapsing config */ reification?: ReificationConfig; /** Metadata extraction config */ metadata?: MetadataConfig; /** Known namespace prefixes */ prefixes?: PrefixMap; /** * Rendering backend: '2d' (Canvas, default) or '3d' (WebGL/Three.js). * 3D mode requires `3d-force-graph` and `three` as peer dependencies. */ renderer?: '2d' | '3d'; /** Disable automatic zoomToFit when the force simulation settles. */ autoFitDisabled?: boolean; } type GraphEventType = 'node:click' | 'node:hover' | 'node:unhover' | 'edge:click' | 'edge:hover' | 'edge:unhover' | 'background:click' | 'focus:change' | 'data:change' | 'temporal:change'; interface GraphEventMap { 'node:click': GraphNode; 'node:hover': GraphNode; 'node:unhover': GraphNode; 'edge:click': GraphEdge; 'edge:hover': GraphEdge; 'edge:unhover': GraphEdge; 'background:click': { x: number; y: number; }; 'focus:change': { focalNode: string | null; visibleNodes: number; }; 'data:change': ChangeSet; 'temporal:change': { cursor: Date; visibleCount: number; totalDated: number; }; } type GraphEventHandler = (data: GraphEventMap[T]) => void; /** * Subject-centric RDF graph model for visualization. * * - Literal objects → stored as properties on the subject node * - URI/blank node objects → stored as edges between nodes * - rdf:type → stored in node.types, not as an edge * * Supports incremental add/remove with stable node and edge IDs. * * Maintains adjacency indexes (_outEdges, _inEdges) for O(degree) edge * lookups instead of O(E) full scans. These are used by FocusFilter BFS, * ReificationCollapser, and ViewConfig application on the render hot path. */ declare class GraphModel { readonly nodes: Map; readonly edges: Map; prefixes: PrefixMap; /** * Stores triples in canonical form — subject, predicate, and (when the * object is a resource) object are `cleanUri`-normalised at ingress so * downstream consumers and lookup paths (e.g. `removeTriples`, * reification mirrors, diff exporters) all operate on a single * representation. Literal objects are kept verbatim so quoting, * datatypes, and language tags survive the round-trip. */ private _triples; /** Set of predicate URIs treated as metadata (not rendered as edges) */ private _metadataPredicates; /** Adjacency index: nodeId → Set of edge IDs originating from this node */ private _outEdges; /** Adjacency index: nodeId → Set of edge IDs pointing to this node */ private _inEdges; /** Knowledge Asset groups: KA URI → Set of member node IDs */ readonly kaGroups: Map>; /** Predicate used for KA membership (set via setKaMembershipPredicate) */ private _kaMembershipPredicate; constructor(metadataPredicates?: string[]); /** Get all stored triples */ get triples(): readonly RdfTriple[]; /** Set the predicate used for Knowledge Asset membership grouping */ setKaMembershipPredicate(predicate: string | null): void; /** Get or create a node */ private ensureNode; /** Ensure adjacency sets exist for a node */ private ensureAdjacency; /** Add a single triple to the model */ addTriple(triple: RdfTriple): void; /** Add multiple triples and return the changeset */ addTriples(triples: RdfTriple[]): ChangeSet; /** Remove triples matching the given criteria and return changeset */ removeTriples(triples: RdfTriple[]): ChangeSet; /** Get a node by ID */ getNode(id: string): GraphNode | undefined; /** Get all edges originating from a node — O(degree) via adjacency index */ getEdgesFrom(id: string): GraphEdge[]; /** Get all edges pointing to a node — O(degree) via adjacency index */ getEdgesTo(id: string): GraphEdge[]; /** Get all neighbor node IDs (both directions) — O(degree) via adjacency index */ getNeighborIds(id: string): Set; /** Get the node with the highest degree */ getHighestDegreeNode(): GraphNode | null; /** Clear all data */ clear(): void; /** Total number of triples */ get tripleCount(): number; } /** * Color palette system for the graph visualizer. * * A palette provides a complete, cohesive set of colors for the entire * visualization — surfaces, text, accents, semantic colors, and graph-specific * colors. Developers can use a built-in preset or supply a custom palette. */ interface ColorPalette { name: string; background: string; surface: string; surfaceBorder: string; textPrimary: string; textSecondary: string; textMuted: string; primary: string; primaryMuted: string; danger: string; warning: string; safe: string; info: string; edgeColor: string; edgeLabel: string; particleColor: string; focalGlow: string; nodeColors: string[]; } /** * Configuration for temporal filtering. */ interface TemporalConfig { /** Enable the temporal timeline. Default: false */ enabled: boolean; /** Property short names to scan for dates (checked across known namespaces). * Default: ['dateCreated'] */ dateProperties?: string[]; /** Whether to show nodes that have no date property. Default: true */ showUndated?: boolean; /** Auto-play speed in ms per step. Default: 200 */ playSpeed?: number; /** Step granularity for playback. Default: 'day' */ stepSize?: 'hour' | 'day' | 'week' | 'month'; } /** * Temporal filter: scans nodes for date properties, manages a progressive * time cursor, and returns the set of node IDs visible up to that cursor. * * Usage: * filter.scan(model); * filter.setCursor(someDate); * const visible = filter.getVisibleNodeIds(); // nodes with date <= cursor */ declare class TemporalFilter { private _nodeDates; private _dateRange; private _cursor; private _dateProperties; private _showUndated; constructor(config?: Partial); /** Scan all nodes in the model for date properties. Call after data ingestion. */ scan(model: GraphModel): void; /** Get the global date range [earliest, latest], or null if no dates found. */ get dateRange(): [Date, Date] | null; /** Get the current cursor position. */ get cursor(): Date | null; /** Number of nodes that have a date assigned. */ get datedNodeCount(): number; /** Whether to show nodes without date properties. */ get showUndated(): boolean; set showUndated(value: boolean); /** Set the cursor (cutoff date). Nodes with date <= cursor are visible. */ setCursor(date: Date): void; /** Get the date for a specific node, or null if undated. */ getNodeDate(nodeId: string): Date | null; /** * Get the set of node IDs visible at the current cursor position. * - Dated nodes: visible if date <= cursor * - Undated nodes: visible if showUndated is true * * If no date range was found (no dated nodes), returns null * (meaning: don't filter, show everything). */ getVisibleNodeIds(allNodeIds: Iterable): Set | null; /** * Compute histogram buckets for the date distribution. * Returns an array of { date: Date, count: number } entries. */ computeHistogram(bucketCount?: number): Array<{ date: Date; count: number; }>; /** Extract the earliest date from a node's properties across known namespaces. */ private _extractDate; } /** Visual configuration for a single node type */ interface NodeTypeConfig { color?: string; shape?: 'hexagon' | 'circle'; /** Icon URL or data URI — assigned as imageUrl on matching nodes */ icon?: string; /** Static size multiplier for all nodes of this type */ sizeMultiplier?: number; } /** Focal entity configuration */ interface FocalConfig { /** URI of the focal entity (checked across namespace variants) */ uri: string; /** Image URL for the focal entity */ image?: string; /** Size multiplier (default 1.5) */ sizeMultiplier?: number; } /** Highlight / risk rule configuration */ interface HighlightConfig { /** Property short name that drives visual emphasis (checked across namespaces) */ property: string; /** Where to find the property: on the node itself, or on a linked entity */ source?: 'self' | 'linked'; /** Predicate short name to follow when source='linked' (e.g., 'hasSentiment') */ linkedVia?: string; /** Absolute value above this threshold = highlighted */ threshold: number; /** Border color for highlighted nodes */ color: string; /** How many top-scoring nodes get the size boost (default 100) */ topN?: number; /** * Size multiplier for top-N nodes. * If sizeMin/sizeMax are set, this is ignored (continuous scaling is used). * Otherwise this is a flat multiplier applied to all top-N nodes (default 2). */ sizeMultiplier?: number; /** Minimum sizeMultiplier for continuous scaling (lowest-risk in top N). Default: 1.0 */ sizeMin?: number; /** Maximum sizeMultiplier for continuous scaling (highest-risk in top N). Default: 3.0 */ sizeMax?: number; /** * Invert the scoring: treat LOW values as high risk. * Useful when the property represents a "safety" signal (e.g., sentimentScore) * where 0.0 = dangerous and 1.0 = safe. * Default: false */ invert?: boolean; } /** Size-by rule: scale node size based on a property */ interface SizeByConfig { /** Property short name (e.g., 'totalInteractions') */ property: string; /** Scale function (default 'log') */ scale?: 'linear' | 'log'; } /** Icon mapping: assign icons to posts by platform edge */ interface PlatformIconConfig { /** Map of platform ID (last path segment of platform URI) to icon URL/data URI */ icons: Record; /** URL fallback patterns: map of URL substring to platform key */ urlFallbacks?: Record; } /** Configuration for a single tooltip field */ interface TooltipFieldConfig { /** Display label in the tooltip */ label: string; /** Property short name to display (checked across known namespaces) */ property: string; /** Where to find the property: directly on the node ('self') or on a linked entity */ source?: 'self' | 'linked'; /** Predicate short name to follow when source='linked' */ linkedVia?: string; /** Display format: 'text' (default), 'number', 'date' */ format?: 'text' | 'number' | 'date'; } /** Tooltip configuration */ interface TooltipConfig { /** * Properties to try for the tooltip title, in priority order. * Each entry is a short name checked across known namespaces. * Falls back to the node's resolved label if none match. * * @example ["text", "name", "title"] */ titleProperties?: string[]; /** * Template for the tooltip subtitle line. * Supports {property} placeholders (short names). * Special tokens: {platform}, {author}, {date}, {type} * * @example "{platform} · {author} · {date}" */ subtitleTemplate?: string; /** Max characters for the title before truncation. Default: 60 */ titleMaxLength?: number; /** Additional fields to show in the tooltip */ fields?: TooltipFieldConfig[]; } /** Animation configuration for visual liveliness */ interface AnimationConfig { /** Enable link particles flowing along edges. Default: false */ linkParticles?: boolean; /** Number of particles per link. Default: 1 */ linkParticleCount?: number; /** Particle speed (0-1 range, fraction of link length per frame). Default: 0.005 */ linkParticleSpeed?: number; /** Particle color. Default: 'rgba(100,150,255,0.6)' */ linkParticleColor?: string; /** Particle width in pixels. Default: 1.5 */ linkParticleWidth?: number; /** Keep the force simulation slightly warm so nodes gently drift. Default: false */ drift?: boolean; /** Alpha target for the warm simulation (0-0.1 range). Default: 0.008 */ driftAlpha?: number; /** Enable breathing/pulse animation on high-risk nodes. Default: false */ riskPulse?: boolean; /** Highlight edges of hovered node with faster, brighter particles. Default: false */ hoverTrace?: boolean; /** Fade-in nodes/edges on initial load. Default: false */ fadeIn?: boolean; } /** Trust visualization configuration */ interface TrustConfig { /** Enable trust indicators. Default: false */ enabled: boolean; /** Minimum distinct sources for "verified" visual treatment. Default: 2 */ minSources?: number; /** Show source count badge on nodes. Default: true */ showBadge?: boolean; /** Visual style for multi-source trust: 'border' | 'opacity' | 'glow'. Default: 'border' */ style?: 'opacity' | 'border' | 'glow'; } /** Knowledge Asset boundary visualization configuration */ interface KnowledgeAssetConfig { /** Enable KA boundary rendering. Default: false */ enabled: boolean; /** Predicate linking a node to its Knowledge Asset. Default: 'dkg:partOfAsset' */ membershipPredicate?: string; /** Show convex hull boundaries around KA groups. Default: true */ showBoundaries?: boolean; /** Boundary fill opacity (0-1). Default: 0.06 */ boundaryOpacity?: number; } /** * Declarative view configuration for the graph visualizer. * * Controls what nodes look like, which are important, and how they're sized — * all without writing code. The same graph data can be visualized differently * by swapping view configs. */ interface ViewConfig { /** Human-readable name for this view */ name: string; /** Visual rules per RDF type (compact or full URI) */ nodeTypes?: Record; /** Optional focal entity (rendered large, always on top) */ focal?: FocalConfig; /** Highlight rule: which property drives risk/importance coloring */ highlight?: HighlightConfig; /** Size-by rule: scale nodes by a numeric property */ sizeBy?: SizeByConfig; /** RDF type short names rendered as circles instead of hexagons */ circleTypes?: string[]; /** Platform icon mapping for SocialMediaPosting nodes */ platformIcons?: PlatformIconConfig; /** Tooltip configuration for hover cards */ tooltip?: TooltipConfig; /** Animation configuration for visual liveliness */ animation?: AnimationConfig; /** Color palette: preset name ('dark', 'midnight', 'cyberpunk', 'light') or custom palette object */ palette?: string | ColorPalette; /** Overrides for individual palette colors (merged on top of base) */ paletteOverrides?: Partial; /** Trust visualization based on multi-source provenance */ trust?: TrustConfig; /** Knowledge Asset boundary visualization */ knowledgeAssets?: KnowledgeAssetConfig; /** Temporal timeline configuration */ temporal?: TemporalConfig; /** Default SPARQL CONSTRUCT query for this view */ defaultSparql?: string; } /** Supported data formats for the `data` prop */ type DataFormat = 'ntriples' | 'nquads' | 'turtle' | 'jsonld' | 'triples'; interface RdfGraphProps { /** RDF data string (N-Triples, Turtle, etc.) or triple array */ data?: string | Array<{ subject: string; predicate: string; object: string; }>; /** Format of the data prop */ format?: DataFormat; /** Visualization configuration */ options?: RdfGraphVizConfig; /** Declarative view configuration (focal entity, highlights, icons) */ viewConfig?: ViewConfig; /** Called when a node is clicked */ onNodeClick?: (node: GraphNode) => void; /** Called when a node is hovered */ onNodeHover?: (node: GraphNode) => void; /** Called when a node hover ends */ onNodeUnhover?: (node: GraphNode) => void; /** CSS class name for the container div */ className?: string; /** Inline styles for the container div */ style?: React.CSSProperties; /** Run a single zoomToFit after the first data load (does not affect autoFitDisabled) */ initialFit?: boolean; /** * URI of a node to pan + zoom the camera to shortly after the initial * layout settles. Re-fires whenever this prop changes, so it doubles * as "focus the currently selected entity" when the caller supplies * a live selection. */ initialFocus?: string; /** Child components (can use useRdfGraph hook to access viz instance) */ children?: ReactNode; } /** * React wrapper for the RDF Graph Visualization. * * Manages the RdfGraphViz lifecycle: creates on mount, destroys on unmount. * Loads data when the `data` prop changes, applies view config reactively. * * @example * ```tsx * console.log(node)} * /> * ``` */ declare function RdfGraph({ data, format, options, viewConfig, initialFit, initialFocus, onNodeClick, onNodeHover, onNodeUnhover, className, style, children, }: RdfGraphProps): react_jsx_runtime.JSX.Element; interface NodePanelProps { /** * Custom render function. If provided, replaces the default rendering. * Receives the selected node (or null if none selected). */ renderNode?: (node: GraphNode | null) => ReactNode; /** CSS class name for the panel container */ className?: string; /** Inline styles for the panel container */ style?: React.CSSProperties; /** Whether to show the URI */ showUri?: boolean; /** Whether to show node types */ showTypes?: boolean; /** Whether to show properties */ showProperties?: boolean; /** Whether to show metadata */ showMetadata?: boolean; /** Maximum length for property values before truncation */ maxValueLength?: number; } /** * Node detail panel component. * * Subscribes to `node:click` events via RdfGraphContext and renders * the selected node's properties. Supports custom rendering via * the `renderNode` prop. * * Must be used inside a component (or any component providing RdfGraphContext). * * @example * ```tsx * * * * ``` * * @example * ```tsx * * ( * node ?
{node.label}
: null * )} /> *
* ``` */ declare function NodePanel({ renderNode, className, style, showUri, showTypes, showProperties, showMetadata, maxValueLength, }: NodePanelProps): react_jsx_runtime.JSX.Element | null; /** * A single SPARQL result binding row. * Keys are variable names (without ?), values are RDF term strings. */ type SparqlBinding = Record; /** Result of a SPARQL SELECT query */ interface SparqlSelectResult { variables: string[]; bindings: SparqlBinding[]; } /** Result of a SPARQL CONSTRUCT/DESCRIBE query — just triples */ interface SparqlConstructResult { triples: RdfTriple[]; } /** * Abstract data source for the graph visualizer. * * Implementations connect to different knowledge graph backends: * - OxigraphSource: In-browser WASM store (dev/demo) * - RemoteSparqlSource: Remote SPARQL endpoint (Blazegraph, GraphDB, DKG) * * The visualizer calls these methods to load and query graph data, * keeping the rendering layer decoupled from the storage layer. */ interface GraphDataSource { /** Human-readable name for this data source */ readonly name: string; /** * Load RDF data into the store (N-Triples string). * For remote sources, this may be a no-op or trigger an import. */ loadNTriples(data: string): Promise; /** * Execute a SPARQL SELECT query. * Returns variable bindings as plain strings. */ select(sparql: string): Promise; /** * Execute a SPARQL CONSTRUCT query. * Returns an array of RdfTriple objects ready for the visualizer. */ construct(sparql: string): Promise; /** * Get the total triple count in the store. */ tripleCount(): Promise; /** * Check if the source is ready / connected. */ isReady(): Promise; } /** * DOM-based timeline overlay rendered inside the visualization container. * * Shows a single progressive slider: drag right to reveal more of the graph * chronologically. Includes play/pause, date labels, visible node count, * and a mini histogram showing node density over time. */ declare class TimelineOverlay { private _container; private _filter; private _config; private _root; private _slider; private _dateLabel; private _countLabel; private _playBtn; private _histCanvas; private _startLabel; private _endLabel; private _playInterval; private _isPlaying; private _onChange; constructor(container: HTMLElement, filter: TemporalFilter, config: TemporalConfig); /** Set callback for cursor changes */ onChange(fn: (cursor: Date, visibleCount: number) => void): void; /** Build and attach the overlay DOM. Call after filter.scan(). */ mount(): void; /** Remove the overlay from the DOM */ unmount(): void; /** Whether the overlay is currently mounted */ get mounted(): boolean; /** Update the overlay after data changes (re-scan, redraw histogram) */ refresh(): void; /** Start auto-play from current position */ play(): void; /** Pause auto-play */ pause(): void; /** Set the slider to a specific date programmatically */ setCursor(date: Date): void; private _buildHTML; private _onSliderInput; private _updateDateLabel; /** Update the visible count badge (called externally after render) */ updateCount(count: number): void; private _togglePlay; private _getStepMs; private _drawHistogram; private _formatDateShort; private _formatDateFull; private _styleId; private _injectStyles; } /** * Manages namespace prefix ↔ URI mappings for compacting and expanding URIs. */ declare class PrefixManager { private _prefixes; /** Reverse map: namespace URI → prefix */ private _reverse; constructor(userPrefixes?: PrefixMap); /** Register a new prefix */ addPrefix(prefix: string, namespace: string): void; /** Merge in multiple prefixes */ addPrefixes(prefixes: PrefixMap): void; /** Get the namespace URI for a prefix */ getNamespace(prefix: string): string | undefined; /** Get the prefix for a namespace URI */ getPrefix(namespace: string): string | undefined; /** * Compact a full URI to prefixed form (e.g., "https://schema.org/name" → "schema:name"). * Returns null if no matching prefix is found. */ compact(uri: string): string | null; /** * Expand a prefixed term to a full URI (e.g., "schema:name" → "https://schema.org/name"). * Returns the input unchanged if it's already a full URI or no prefix matches. */ expand(term: string): string; /** * Extract a short, human-readable local name from a URI. * * Strategy, in priority order: * 1. Part after the last `#` (RDF fragment: http://ex.org/ns#Foo → Foo) * 2. Part after the last `/` (HTTP path: http://ex.org/foo/Bar → Bar) * 3. If the URI contains URL-encoded slashes (%2F), decode them and * take the basename. This handles URIs like * `urn:dkg:code:file:packages%2Fnode-ui%2Fsrc%2Fui%2FApp.tsx`, * which previously returned the entire URI. * 4. Part after the last `:` (URN tail: urn:dkg:task:my-slug → my-slug) * 5. The URI itself (last resort). */ static localName(uri: string): string; /** Get all registered prefixes */ get prefixes(): PrefixMap; } /** * Resolves colors for nodes and edges based on configurable rules. * * When a ColorPalette is provided, it drives default colors: * - defaultNodeColor → palette.primary * - defaultEdgeColor → palette.edgeColor * - Label/text colors → palette.textPrimary/textSecondary * * Priority (highest first): * 1. Per-class color (matching rdf:type) * 2. Per-namespace color (matching namespace of first rdf:type) * 3. Default color (from palette or config) */ declare class StyleEngine { private _config; private _prefixManager; private _palette; private _hasExplicitDefaultNodeColor; private _hasExplicitDefaultEdgeColor; constructor(config: StyleConfig | undefined, prefixManager: PrefixManager, palette?: ColorPalette); /** The active color palette */ get palette(): ColorPalette; /** Update the active palette (recalculates defaults not explicitly set in config) */ setPalette(palette: ColorPalette): void; get config(): Readonly>; /** Update per-node color overrides (merges with existing) */ setNodeColors(colors: Record): void; /** Get the fill color for a node */ getNodeColor(node: GraphNode): string; /** Get the color for an edge */ getEdgeColor(edge: GraphEdge): string; /** Get border color (slightly lighter than fill) */ getBorderColor(fillColor: string): string; /** Get gradient center color (lighter) */ getGradientCenter(fillColor: string): string; } /** * Main entry point for the RDF Graph Visualization library. * * @example * ```typescript * const viz = new RdfGraphViz(document.getElementById('graph')!, { * labelMode: 'humanized', * style: { classColors: { 'schema:Person': '#7C3AED' } }, * focus: { hops: 2, maxNodes: 200 }, * }); * * await viz.loadNTriples(ntriplesString); * viz.on('node:click', (node) => console.log(node)); * ``` */ declare class RdfGraphViz { private _model; private _prefixManager; private _labelResolver; private _styleEngine; private _hexPainter; private _focusFilter; private _reificationCollapser; private _metadataExtractor; private _events; private _renderer; private _config; private _collapsedNodeIds; private _rendererReady; private _container; private _temporalFilter; private _timelineOverlay; private _renderQueued; private _autoFitDisabled; constructor(container: HTMLElement, config?: RdfGraphVizConfig); /** Load N-Triples or N-Quads string */ loadNTriples(input: string): Promise; /** Load N-Quads string */ loadNQuads(input: string): Promise; /** Load Turtle string */ loadTurtle(input: string): Promise; /** Load JSON-LD (object or string) */ loadJsonLd(input: Record | string): Promise; /** Load raw triple array (synchronous — no parsing needed) */ loadTriples(input: Array): void; /** * Load data from a GraphDataSource using a SPARQL CONSTRUCT query. * * This is the recommended way to load data from a knowledge graph. * The source can be an in-browser Oxigraph store or a remote SPARQL endpoint. * * @param source - A GraphDataSource (OxigraphSource, RemoteSparqlSource, etc.) * @param sparql - SPARQL CONSTRUCT query that returns the triples to visualize * * @example * ```typescript * const source = new OxigraphSource(); * await source.init(); * await source.loadNTriples(ntData); * * await viz.loadFromSource(source, ` * CONSTRUCT { ?s ?p ?o } * WHERE { * ?s a ; * ?p ?o . * } LIMIT 5000 * `); * ``` */ loadFromSource(source: GraphDataSource, sparql: string): Promise; /** * Execute a SPARQL SELECT query against a data source. * Returns raw bindings — useful for analytics, counts, and lookups * without loading triples into the graph model. */ querySource(source: GraphDataSource, sparql: string): Promise; /** Add triples to the existing graph */ addTriples(triples: RdfTriple[]): ChangeSet; /** Remove triples from the graph */ removeTriples(triples: RdfTriple[]): ChangeSet; /** Focus on a specific node with N-hop expansion */ focus(nodeId: string, hops?: number): void; /** Recenter camera on a node without changing focus filter state. */ centerOnNode(nodeId: string, opts?: { durationMs?: number; zoomLevel?: number; }): void; /** Expand a boundary node's neighborhood */ expandNode(nodeId: string): void; /** Show all nodes (disable focus filter) */ showAll(): void; /** Get the temporal filter (for advanced usage) */ get temporalFilter(): TemporalFilter; /** Get the timeline overlay (for advanced usage, null if not enabled) */ get timelineOverlay(): TimelineOverlay | null; /** Set the temporal cursor: only show nodes with dates up to this point */ setTimeCursor(date: Date): void; /** Get the date range of nodes in the graph */ getDateRange(): [Date, Date] | null; /** Start timeline playback */ playTimeline(): void; /** Pause timeline playback */ pauseTimeline(): void; /** Count visible nodes after last render (for event payloads) */ private _lastVisibleCount; /** Fit all visible nodes in view */ zoomToFit(padding?: number): void; /** Prevent the renderer from automatically calling zoomToFit when the simulation settles. */ set autoFitDisabled(value: boolean); /** Get current label mode */ get labelMode(): LabelMode; /** Set label mode and re-render */ setLabelMode(mode: LabelMode): void; /** Subscribe to a graph event */ on(event: T, handler: GraphEventHandler): () => void; /** Unsubscribe from a graph event */ off(event: T, handler: GraphEventHandler): void; /** Get a node by ID */ getNode(id: string): GraphNode | undefined; /** Get all edges from a node */ getEdgesFrom(id: string): GraphEdge[]; /** Get all edges to a node */ getEdgesTo(id: string): GraphEdge[]; /** Get the underlying graph model (for advanced usage) */ get model(): GraphModel; /** Get the style engine (for dynamic per-node color overrides) */ get styleEngine(): StyleEngine; /** Get the prefix manager (for compact/expand operations) */ get prefixes(): PrefixManager; /** Saved visual state for highlighted nodes, used by clearHighlight() to revert */ private _highlightState; /** * Visually emphasize a set of nodes without modifying underlying data. * Typically used to highlight SPARQL query results in the current view. * * @example * ```typescript * const result = await viz.querySource(kg, ` * SELECT ?post WHERE { * ?post ?risk . * FILTER(?risk > 50) * } * `); * viz.highlightNodes(result.bindings.map(b => b.post)); * ``` */ highlightNodes(nodeIds: string[]): void; /** Revert all highlighted nodes to their original visual state */ clearHighlight(): void; /** * Export the current visualization as a PNG image. * Captures the canvas content from the active renderer backend. */ exportImage(): Promise; /** * Export the current graph model as N-Triples string. * Serializes all triples currently loaded in the visualization. */ exportTriples(): string; /** * Apply a ViewConfig to the current graph. * * Sets focal entity styling, platform icons, risk/highlight scores, * and node type icons based on the declarative config. * Automatically calls refresh() to re-render. * * @example * ```typescript * await viz.loadFromSource(kg, sparql); * viz.applyViewConfig(config); * ``` */ applyView(config: ViewConfig): void; /** Force a visual re-render (call after modifying node properties externally) */ refresh(): void; /** Destroy the visualization and clean up resources */ destroy(): void; /** Ingest triples, resolve labels/images, and render */ private _ingest; /** Post-ingestion processing: resolve images, labels, collapse, render */ private _postIngest; /** Render with current focus filter + temporal filter state */ private _renderCurrent; } /** * Hook to access the underlying RdfGraphViz instance for imperative operations. * * @example * ```tsx * function MyComponent() { * const { viz } = useRdfGraph(); * * const handleAddData = () => { * viz?.addTriples([{ subject: '...', predicate: '...', object: '...' }]); * }; * * return ; * } * ``` */ declare function useRdfGraph(): { viz: RdfGraphViz | null; selectedNode: GraphNode | null; hoveredNode: GraphNode | null; }; interface RdfGraphContextValue { /** The core RdfGraphViz instance */ viz: RdfGraphViz | null; /** Currently selected node (clicked) */ selectedNode: GraphNode | null; /** Currently hovered node */ hoveredNode: GraphNode | null; } declare const RdfGraphContext: react.Context; declare function useRdfGraphContext(): RdfGraphContextValue; export { type DataFormat, NodePanel, type NodePanelProps, RdfGraph, RdfGraphContext, type RdfGraphContextValue, type RdfGraphProps, useRdfGraph, useRdfGraphContext };