Complete API documentation for the EIDOS JavaScript bindings.
embed(container, spec, onEvent?, renderer?)Embeds an EIDOS visualization in a DOM container element.
| Parameter | Type | Required | Description |
|---|---|---|---|
container |
HTMLElement |
Yes | DOM element to embed the visualization in |
spec |
EidosSpec |
Yes | EIDOS specification object |
onEvent |
(event: any) => void |
No | Callback for events from the renderer |
renderer |
string |
No | URL of the EIDOS renderer (default: https://render.eidos.oceanum.io) |
Promise<EidosInstance> - A promise that resolves to a reactive EIDOS instance
import { embed } from '@oceanum/eidos';
const container = document.getElementById('my-container');
const spec = {
id: 'my-viz',
name: 'My Visualization',
root: { /* ... */ },
data: [],
transforms: []
};
const eidos = await embed(container, spec, (event) => {
console.log('Event received:', event);
});
// Natural object mutations
eidos.name = 'Updated Name';
eidos.root.children.push(newLayer);
Error - If the spec fails AJV schema validationError - If the container element is invalidError - If the renderer fails to loadvalidateSchema(spec)Validates an EIDOS specification against the JSON schema.
| Parameter | Type | Required | Description |
|---|---|---|---|
spec |
any |
Yes | EIDOS specification to validate |
Promise<boolean> - True if validation passes
import { validateSchema } from '@oceanum/eidos';
try {
await validateSchema(mySpec);
console.log('Spec is valid');
} catch (error) {
console.error('Validation failed:', error.message);
}
Error - With detailed validation error messages if spec is invalidEidosSpecThe main EIDOS specification interface.
interface EidosSpec {
id: string; // Unique identifier
name: string; // Display name
root: EidosNode; // Root node of the visualization
data: EidosDataSource[]; // Data sources
transforms: EidosTransform[]; // Data transformations
modalNodes?: EidosNode[]; // Optional modal nodes
}
EidosNodeRepresents a node in the EIDOS visualization tree.
interface EidosNode {
id: string; // Unique node ID
nodeType: 'grid' | 'world' | 'plot' | 'worldlayer' | 'menu'; // Node type
children: EidosNode[]; // Child nodes
[key: string]: any; // Additional properties
}
grid - Layout container for organizing child nodesworld - 3D/2D mapping visualization containerplot - Chart/graph visualization containerworldlayer - Individual layer within a world (tracks, grids, etc.)menu - UI control panels and menusEidosDataSourceDefines a data source for the visualization.
interface EidosDataSource {
id: string; // Unique data source ID
url?: string; // URL to fetch data from
data?: any; // Inline data
[key: string]: any; // Additional properties (format, transforms, etc.)
}
EidosTransformDefines a data transformation.
interface EidosTransform {
id: string; // Unique transform ID
type: string; // Transform type
[key: string]: any; // Transform-specific properties
}
EidosInstanceThe reactive EIDOS instance returned by embed().
interface EidosInstance extends EidosSpec {
// All EidosSpec properties are directly mutable
// Changes automatically propagate to renderer via JSON patches
}
EidosEventEvents received from the EIDOS renderer.
interface EidosEvent {
type: string; // Event type
payload?: any; // Event data
timestamp?: number; // Event timestamp
source?: string; // Event source
}
The default renderer URL can be overridden:
// Using custom renderer
const eidos = await embed(container, spec, onEvent, 'https://my-renderer.com');
AJV validation is configured with:
{
allErrors: true, // Collect all validation errors
verbose: true, // Provide detailed error information
strict: false // Allow additional properties
}
Schema validation errors provide detailed information:
try {
await embed(container, invalidSpec);
} catch (error) {
// Error message includes:
// - Field path where validation failed
// - Specific validation rule that failed
// - Expected vs actual values
console.error(error.message);
// Example: "EIDOS spec validation failed: root/nodeType: must be equal to one of the allowed values"
}
| Error Type | Description | Solution |
|---|---|---|
| Validation Error | Spec doesn’t match schema | Fix spec properties to match schema requirements |
| Network Error | Can’t reach renderer | Check renderer URL and network connection |
| Container Error | Invalid DOM element | Ensure container exists and is a valid HTMLElement |
| Initialization Error | Renderer failed to initialize | Check browser console for detailed errors |
Common event types from the renderer:
| Event Type | Description | Payload |
|---|---|---|
init |
Renderer initialized | { ready: true } |
click |
User clicked on visualization | { position: [x, y], feature?: object } |
hover |
User hovered over element | { position: [x, y], feature?: object } |
data-loaded |
Data source finished loading | { dataId: string, status: 'success' \| 'error' } |
view-changed |
Viewport/camera changed | { bounds: [...], zoom: number } |
function handleEidosEvent(event) {
switch (event.type) {
case 'click':
console.log('Clicked at:', event.payload.position);
if (event.payload.feature) {
showFeatureDetails(event.payload.feature);
}
break;
case 'data-loaded':
if (event.payload.status === 'error') {
showDataError(event.payload.dataId);
}
break;
default:
console.log('Unhandled event:', event);
}
}
const eidos = await embed(container, spec, handleEidosEvent);
The EIDOS instance uses Valtio under the hood to provide reactive object mutations:
// Direct property assignment
eidos.name = 'New Name';
// Array operations
eidos.root.children.push(newLayer);
eidos.data.splice(0, 1); // Remove first data source
// Nested object updates
eidos.root.children[0].visible = false;
eidos.data[0].url = 'https://new-url.com/data.json';
// Bulk updates
Object.assign(eidos.root, {
backgroundColor: '#fff',
showGrid: true
});
Managing multiple EIDOS instances:
const instances = new Map();
async function createInstance(id, container, spec) {
const eidos = await embed(container, spec, (event) => {
console.log(`Event from ${id}:`, event);
});
instances.set(id, eidos);
return eidos;
}
function updateInstance(id, updates) {
const eidos = instances.get(id);
if (eidos) {
Object.assign(eidos, updates);
}
}
Using a custom renderer endpoint:
const customRenderer = 'https://my-company.com/eidos-renderer';
const eidos = await embed(container, spec, onEvent, customRenderer);
Creating reusable spec templates:
function createWorldSpec(id, name) {
return {
id,
name,
root: {
id: 'root',
nodeType: 'world',
children: [],
projection: 'mercator',
bounds: [[-180, -90], [180, 90]]
},
data: [],
transforms: []
};
}
const spec = createWorldSpec('my-world', 'My World Map');
// Add data source dynamically
eidos.data.push({
id: 'dynamic-data',
url: 'https://api.example.com/live-data.json',
format: 'geojson'
});
// Add layer that uses the data
eidos.root.children.push({
id: 'dynamic-layer',
nodeType: 'worldlayer',
layerType: 'feature',
dataId: 'dynamic-data'
});
| Browser | Version | Notes |
|---|---|---|
| Chrome | 80+ | Full support |
| Firefox | 75+ | Full support |
| Safari | 13+ | Full support |
| Edge | 80+ | Full support |
| IE | Not supported | Use modern browser |
// Enable console logging for patch operations
localStorage.setItem('eidos-debug', 'true');
// Inspect current spec
console.log('Current spec:', JSON.stringify(eidos, null, 2));
// Monitor patches
const originalPostMessage = iframe.contentWindow.postMessage;
iframe.contentWindow.postMessage = function(data, origin) {
if (data.type === 'patch') {
console.log('Patch sent:', data.payload);
}
return originalPostMessage.call(this, data, origin);
};
// Validate spec manually
import { validateSchema } from '@oceanum/eidos';
validateSchema(eidos).catch(console.error);