> ## Documentation Index
> Fetch the complete documentation index at: https://docs.visk.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Charts

> Native, editable PowerPoint charts from HTML

`<Chart>` maps to Chart.js syntax and converts to a native PowerPoint chart.

Supported types are `line`, `bar`, `area`, `scatter`, `pie`, `radar`, `bubble` and `waterfall`. Combo charts, mixing line, bar and area in one chart, are also supported.

## Components

### `<Chart>`

The container. Type is set with `type`, and size and position with ordinary CSS, either in document flow or absolutely with `box`.

```html theme={null}
<Chart type="bar" style="width: 500pt; height: 200pt" class="z-5">
  ...
</Chart>
```

Background fills (gradients included), outlines and border radius all work through `style`.

### `<ChartTitle>` and `<Legend>`

Both optional.

```html theme={null}
<ChartTitle text="Revenue" font='{"size":"16pt","weight":"bold"}' color="#333" />
<ChartTitle />  <!-- auto-set from the series label when there is only one -->

<Legend position="bottom" />  <!-- top | bottom | left | right -->
<Legend position="bottom" labels='{"font":{"size":"9pt"}}' />
```

### `<XAxis>` and `<YAxis>`

`XAxis` defaults to a category axis, `YAxis` to linear. Override with `type`.

| Attribute     | Type        | Description                                                                                               |
| ------------- | ----------- | --------------------------------------------------------------------------------------------------------- |
| `labels`      | JSON array  | Category labels: `'["A","B","C"]'`                                                                        |
| `border`      | JSON object | Axis line: `'{"display":true,"width":1,"color":"#333"}'`                                                  |
| `grid`        | JSON object | Gridlines: `'{"display":true,"borderDash":[4,4],"color":"#ccc"}'`                                         |
| `ticks`       | JSON object | Tick label font and colour                                                                                |
| `displayUnit` | JSON object | Axis label scaling: `'{"unit":"millions","display":true}'`. Data values and `min`/`max` stay full numbers |
| `title`       | JSON object | Axis title: `'{"text":"Units","font":{"size":"11pt"}}'`                                                   |
| `min` / `max` | number      | Explicit range                                                                                            |
| `stacked`     | string      | `"true"` to stack, `"single"` for 100% normalised                                                         |
| `display`     | string      | `"false"` hides the axis entirely                                                                         |
| `tickFormat`  | string      | Excel format code, e.g. `'"£"#,##0,,"m"'`                                                                 |
| `type`        | string      | `linear`, `category` or `time`                                                                            |

JSON attributes use a single-quoted outer wrapper: `attr='{"key":"val"}'`.

<Note>
  **Number formatting gotchas.** In `tickFormat`, wrap alphabetic literals in quotes, because bare `m`, `d`, `y`, `h`, `s`, `a` and `p` are date and time tokens. For percentages use decimals with `tickFormat=0%`, so `0.08` renders as 8%.
</Note>

### `<Dataset>`

| Attribute                                   | Type        | Description                                                                                                                                          |
| ------------------------------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `label`                                     | string      | Series and legend name                                                                                                                               |
| `data`                                      | JSON array  | Values, `null` for gaps. Full numbers, so `530000` rather than `530` for £530k; scale axis labels with `displayUnit`. Scatter uses `[["x","y"],...]` |
| `borderColor`                               | CSS colour  | Line or bar border                                                                                                                                   |
| `backgroundColor`                           | CSS colour  | Bar fill or area fill                                                                                                                                |
| `borderWidth`                               | number      | Thickness in pt                                                                                                                                      |
| `borderDash`                                | JSON array  | Dash pattern, e.g. `[5,5]`                                                                                                                           |
| `fill`                                      | bool        | Fill under a line                                                                                                                                    |
| `tension`                                   | 0–1         | Curve smoothing                                                                                                                                      |
| `pointRadius`                               | number      | Marker size, 0 hides                                                                                                                                 |
| `pointStyle`                                | string      | `circle`, `rect`, `triangle`, `star`, `cross`                                                                                                        |
| `pointBackgroundColor` / `pointBorderColor` | CSS colour  | Marker fill and border                                                                                                                               |
| `stack`                                     | string      | Datasets sharing a stack ID are stacked together                                                                                                     |
| `dataLabels`                                | JSON object | e.g. `'{"color":"#fff","font":{"weight":"bold"}}'`                                                                                                   |

Any attribute Chart.js accepts per point can take an array of values, one per data point. For bar charts, `position: insideEnd` in `dataLabels` puts the label inside the bar rather than above it.

## Colours

Theme variables `var(--accent1)` through `var(--accent6)` track the deck palette, so a theme change carries into the chart. Literal `rgb()` and hex values also work.

## Defaults

Styling is optional throughout, and PowerPoint's defaults apply when omitted: 1pt dark grey lines, dark grey text in the theme font, no gridlines.

| Element          | Default size |
| ---------------- | ------------ |
| Title            | 18.6pt       |
| Legend labels    | 12pt         |
| Axis tick labels | 12pt         |
| Axis title       | 13.3pt       |

## Examples

### Line chart with a forecast series

```html theme={null}
<Chart type="line" style="width: 500pt; height: 200pt">
  <XAxis labels='["Apr","May","Jun","Jul","Aug","Sep"]' border='{"display":true}'/>
  <YAxis border='{"display":false}' displayUnit='{"unit":"millions"}' tickFormat='"£"#,##0"m"'/>
  <Dataset label="FY25" data="[954030,1971771,2802570,3710154,4316313,5222065]" borderColor="var(--accent1)" borderWidth="3"/>
  <Dataset label="FY26A" data="[924080,1848681,2754879,3616107,null,null]" borderColor="var(--accent2)" borderWidth="3"/>
  <Dataset label="FY26F" data="[null,null,null,3616107,4477335,5415034]" borderColor="var(--accent3)" borderWidth="3" borderDash="[5,5]"/>
  <Legend position="bottom"/>
</Chart>
```

Multiple series, `null` for gaps, a dashed forecast that continues from the last actual, and currency formatting in millions.

### Stacked bar with data labels

```html theme={null}
<Chart type="bar" style="width: 600pt; height: 300pt">
  <ChartTitle text="Revenue breakdown"/>
  <XAxis labels='["Q1","Q2","Q3","Q4"]' border='{"display":true}'/>
  <YAxis border='{"display":false}' grid='{"display":true}' stacked="true"/>
  <Dataset label="Product" data="[4.3,2.5,3.5,4.5]" backgroundColor="var(--accent1)" stack="s1" dataLabels='{"color":"#fff"}'/>
  <Dataset label="Services" data="[2.4,4.4,1.8,2.8]" backgroundColor="var(--accent2)" stack="s1"/>
  <Dataset label="Other" data="[2,2,3,5]" backgroundColor="var(--accent3)" stack="s1"/>
  <Legend position="bottom"/>
</Chart>
```

Stacking needs both a shared `stack` ID on the datasets and `stacked="true"` on the value axis.

### Pie

```html theme={null}
<Chart type="pie" style="width: 400pt; height: 300pt" labels='["Q1","Q2","Q3","Q4"]'>
  <ChartTitle/>
  <Dataset label="Sales" data="[8.2,3.2,1.4,1.2]" dataLabels='{"font":{"weight":"bold"},"color":"var(--lt1)"}'/>
  <Legend position="bottom"/>
</Chart>
```

For pie charts `labels` goes on `<Chart>` rather than on an axis.

### Scatter and bubble

```html theme={null}
<Chart type="scatter" style="width: 500pt; height: 300pt">
  <XAxis type="linear" grid='{"display":true}'/>
  <YAxis grid='{"display":true}'/>
  <Dataset label="Points" data='[["0.7","2.7"],["1.8","3.2"],["2.6","0.8"]]' pointBackgroundColor="var(--accent1)" pointRadius="7" pointStyle="circle"/>
</Chart>
```

Bubble charts use the same `scatter` type with a third value per point for the radius: `data="[[0.7, 2.7, 10], [1.8, 3.2, 4]]"`.

## Chart variations

| Variation         | How                                                                            |
| ----------------- | ------------------------------------------------------------------------------ |
| Area              | `type="area"`, or `type="line"` with `fill="true"` on the dataset              |
| Dashed line       | `borderDash="[5,5]"` on the dataset                                            |
| Stacked bar       | Shared `stack="id"` on datasets, `stacked="true"` on the value axis            |
| 100% stacked      | As stacked, plus `stacked="single"` and `tickFormat=0%`                        |
| Horizontal bar    | Categories on `YAxis` (`type="category"`), values on `XAxis` (`type="linear"`) |
| Line with markers | Add `pointRadius`, `pointStyle`, `pointBackgroundColor`                        |
| Time axis         | `type="time"` on `XAxis` with `tickFormat="m/d/yyyy"`                          |
| Radar             | `type="radar"`, using `XAxis` for spoke labels                                 |
| Hide an axis      | `display="false"`                                                              |

## Waterfall

A single series showing deltas from a starting value. Bars listed in `subtotals` are absolute and anchored to zero; everything else floats as a delta.

```html theme={null}
<Chart type="waterfall" formatOverrides='{"decrease": {"backgroundColor": "rgb(255 0 0)"}}'>
  <XAxis labels='["Opening","Revenue","COGS","OpEx","Closing"]' border='{"display":true}'/>
  <YAxis grid='{"display":true}'/>
  <Dataset label="Cash flow" data="[1000, 500, -300, -150, 1050]"
           subtotals="[0, 4]" dataLabels='{"display": true}'/>
  <Legend position="bottom"/>
</Chart>
```

Increase, decrease and total default to accents 1, 2 and 3. Override them with `formatOverrides` on the chart, or style individual bars with `pointOverrides` on the dataset.

## Combo charts

Combos mix `line`, `bar` and `area`. Instead of one type on `<Chart>`, each type gets a `<Plot>` with its datasets nested inside.

For a secondary axis, mark the second `<YAxis>` with `secondary="true"` (it moves to the right) and set `axis="secondary"` on the datasets that belong to it.

```html theme={null}
<Chart style="width: 600pt; height: 250pt">
  <ChartTitle text="Volume and margin"/>
  <XAxis border='{"display": true}' labels='["Q1","Q2","Q3","Q4"]'/>
  <YAxis border='{"display": false}' grid='{"display": true}'/>
  <YAxis border='{"display": false}' secondary="true"/>
  <Plot type="bar" options='{"gap": 219, "overlap": -27}'>
    <Dataset backgroundColor="var(--accent1)" data="[4.3, 2.5, 3.5, 4.5]" label="Product"/>
    <Dataset backgroundColor="var(--accent2)" data="[2.4, 4.4, 1.8, 2.8]" label="Services"/>
  </Plot>
  <Plot type="line">
    <Dataset axis="secondary" borderColor="var(--accent3)" borderWidth="3" data="[2, 2, 3, 5]" label="Margin %"/>
  </Plot>
  <Legend position="bottom"/>
</Chart>
```
