---
url: https://chartbuddy.io/embed/docs/getting-started/quick-start.md
---
# Quick start

Create a ChartBuddy Insight, then update, read, and destroy it.

## Host sizing (required)

You own a **measured rectangle**; ChartBuddy draws into it. Before `new Insight()`, the mount element needs a definite width and height.

Safe recipes:

* Fixed size: `width: 800px; height: 450px`
* Fluid width: `width: 100%; aspect-ratio: 16 / 9; min-height: 380px` (preferred for cards / decks)
* Full-page fill: `html, body { height: 100% }` **and** every ancestor resolved, plus `#chart { height: 100% }`

Do **not** rely on `height: 100%` alone inside flex layouts, Reveal/slide transforms, or other parents without an explicit height. More recipes and anti-patterns: [Canvas & sizing](/concepts/canvas).

## One HTML file

```html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <title>ChartBuddy</title>
  <style>
    html, body { margin: 0; }
    #chart {
      width: 100%;
      aspect-ratio: 16 / 9;
      min-height: 380px;
    }
  </style>
</head>
<body>
  <div id="chart"></div>
  <script type="module">
    import { Insight } from 'https://unpkg.com/@chartbuddy.io/embed';

    const insight = new Insight('#chart', {
      chartData: {
        chartType: 'clusteredBar',
        isDataTransposed: true,
        seriesData: [
          ['', 'Q1', 'Q2', 'Q3', 'Q4'],
          ['Revenue', 100, 112, 125, 140],
          ['Costs', 60, 66, 70, 78],
        ],
        title: { visible: true, text: 'Revenue vs Costs' },
        subtitle: { visible: false, text: '' },
      },
    });

    await insight.ready;
  </script>
</body>
</html>
```

You get a chart in `#chart` in view mode (no spreadsheet). Hover the ChartBuddy ball (top-left) for **Download** (PNG), **Drag to slide**, and **Edit**.

For npm / single-file installs, see [Installation](/getting-started/installation).

## Create (npm)

```js
import { Insight } from '@chartbuddy.io/embed';

const insight = new Insight('#chart', {
  instanceId: 'main', // stable id for multi-mount
  chartData: { /* … */ },
});

await insight.ready;
```

`target` may be a CSS selector string or an `HTMLElement`.

## Wait for ready

Always `await insight.ready` before measuring the SVG, calling `downloadPng()`, or reading `getChartData()`. You can also subscribe:

```js
insight.on('ready', () => { /* … */ });
```

## Update data

```js
// Data only — keeps chart type and formatting
insight.setData([
  ['', 'Q1', 'Q2'],
  ['Revenue', 100, 120],
]);

// Any partial patch
insight.update({
  title: { visible: true, text: 'Updated' },
  subtitle: { visible: false, text: '' },
});

// Or setChartData — chartType is optional on partials
insight.setChartData({
  seriesData: [/* … */],
  title: { visible: true, text: 'Updated' },
});
```

Partial objects are merged over defaults (and over the current chart). Nested keys like `title`, `axes`, and `legend` are deep-merged. See [Defaults & merging](/concepts/defaults).

Invalid `chartType` / field types throw; see [Insight API → Validation](/api/).

## Read config

```js
const cd = insight.getChartData();
```

Prefer this (or `exportConfig()`) when you need a full schema example.

## Destroy

```js
insight.destroy();
```

Removes the chart and chrome from the target. Call before replacing the DOM node.

## Inspect in the console

After mount (when the host exposes it):

```js
insight.chart.cd.chartType
insight.chart.cd.orientation
insight.mode // 'view' | 'edit'
insight.isDirty()
```

## Next

* [Installation](/getting-started/installation) — npm and CDN
* [Canvas & sizing](/concepts/canvas) — host box recipes and anti-patterns
* [View vs edit](/getting-started/view-vs-edit) — chrome and editor mode
* [Data model](/concepts/data-model) — `seriesData` layouts
