--- url: https://chartbuddy.io/embed/docs/api.md --- > Docs index: [llms.txt](https://chartbuddy.io/embed/docs/llms.txt) # Insight API ```js import { Insight, version, } from '@chartbuddy.io/embed'; ``` ## Constructor ```js const insight = new Insight(target, options?); ``` ### `target` CSS selector string or `HTMLElement`. ### `options` | Option | Type | Default | Description | |---|---|---|---| | `chartData` | `object` | – | Partial or full chart config ([schema](https://chartbuddy.io/embed/docs/api/chart-data.md)) | | `instanceId` | `string` | random UUID | Stable id for `getInsights()`. Must be unique on the page – duplicates **throw**. Several charts: [Single vs multi mounts](https://chartbuddy.io/embed/docs/api/multi-mount.md). | | `editable` | `boolean` | `false` | Start in editor mode | | `allowEdit` | `boolean` | `true` | When `false`, hide Edit on the view ball and no-op `enterEditMode()`. Download / Drag still work. Ignored when locked. | | `editSession` | `'toggle'` | `'locked'` | `'toggle'` | `'locked'` = always edit (no Done / morph chrome). Implies edit boot. | | `host` | `object` | – | Host chrome hooks – see [Host overrides](#host-overrides) | | `assetBase` | `string` | – | Only for multi-file loader; ignore with single-file | ## Instance | Member | Description | |---|---| | `ready` | `Promise` – resolves when mounted | | `mode` | `'view'` | `'edit'` | | `editSession` | `'toggle'` | `'locked'` | | `allowEdit` | `boolean` – whether Edit is offered | | `chart` | Engine chart instance | | `instanceId` | Stable id for this mount | | `setChartData(cd)` | Merge a full or **partial** config and redraw (`chartType` optional) | | `setData(seriesData)` | Refresh only the data grid – keeps type and formatting | | `update(patch?)` | Partial patch + redraw; no argument = redraw only | | `getChartData()` | Full `cd` snapshot | | `on(event, handler)` | Subscribe to `ready` | `mode` | `change` (returns unsubscribe) | | `off(event, handler)` | Remove a handler | | `isDirty()` | `true` when the chart changed since boot / last Done | | `getRevision()` | Monotonic edit counter | | `toPngBlob()` / `toPngBase64()` | PNG bytes/base64 without a Save dialog | | `downloadPng()` | Download PNG (human Save dialog) | | `exportConfig()` | Download current `chartData` as JSON | | `enterEditMode()` | View → edit (no-op when locked or `allowEdit: false`) | | `exitEditMode()` | Edit → view (no-op when locked) | | `focus()` | Focus the insight | | `destroy()` | Tear down | ## Host overrides Optional `options.host` hooks for embedding inside your own chrome: | Hook | Description | |---|---| | `getToolbarPlacement()` | Where the formatting toolbar lives: `'widget'` (default embed edit – morph rail), `'float'`, or `'dock'`. | | `getToolbarContainer()` | Mount point for the toolbar (selector or element). Ignored when placement is `'widget'` (modules mount in the morph). | | `positionToolbar(toolbar, target)` | Float-only XY override. Ignored for `'dock'` / `'widget'`. | | `getPopupContainer()` | Where portaled menus mount (selector or element). Default: `document.body`. Use your dialog root when the editor sits in a high-z overlay. | | `startDragging(event)` | Forward chart-background drag to host window chrome. | ```js new Insight('#chart', { editable: true, editSession: 'locked', host: { getToolbarPlacement: () => ({ mode: 'dock', side: 'right' }), getToolbarContainer: () => '#my-toolbar-rail', getPopupContainer: () => '#my-dialog', }, }); ``` ## Partial updates ```js await insight.ready; // Data only – 2D seriesData grid insight.setData([ ['', 'Q1', 'Q2'], ['Revenue', 100, 120], ]); // Any partial patch insight.update({ title: { text: 'FY26' } }); // Redraw without changing config insight.update(); // setChartData also accepts partials – chartType is not required insight.setChartData({ seriesData: [/* … */] }); ``` ## Events ```js insight.on('ready', () => { /* booted */ }); insight.on('mode', (mode) => { /* 'view' | 'edit' */ }); insight.on('change', (cd) => { /* after meaningful edits */ }); insight.isDirty(); // since boot / last Done checkpoint insight.getRevision(); // increments on every meaningful change ``` `change` fires after programmatic `setChartData` / `setData` / `update`, live edits in edit mode, and Done. ## Validation `new Insight({ chartData })`, `setChartData`, `setData`, and `update` validate input at the API boundary: | Input | Behaviour | |---|---| | Unknown `chartType` (e.g. `bubbleChart3D`) | **Throws** (with a did-you-mean hint) | | Wrong field type / enum / range | **Throws** (lists every path) | | Foreign option bag (`pie` + `bar: {…}`) | **Throws** | | Ragged `seriesData` (unequal row lengths) | **Warns**, still accepts | | Duplicate `instanceId` on the page | **Throws** | | Unknown keys | Always allowed (forward-compatible) | Throws are `ChartDataValidationError`, which carries the problems as structured data – and the same checks are callable directly, so you can validate before you mount. See [Validation](https://chartbuddy.io/embed/docs/quality-assurance/validation.md). ```js import { validateChartData } from '@chartbuddy.io/embed'; const { valid, errors } = validateChartData(candidate); if (!valid) console.log(errors[0].path, errors[0].code, errors[0].suggestion); ``` ## PNG / export ```js await insight.ready; const png = await insight.toPngBase64(); // default background #ffffff await insight.downloadPng(); insight.exportConfig(); ``` PNG download and drag-to-slide are also available from the view-mode hover ball.