# Rendering (Chartist API)

> From scene to output: renderers, text measuring, and rendering on the server.

## toScene

*experimental*

```ts
function toScene(config: ChartConfig, size: SceneSize): SceneNode
```

Builds a chart's scene without rendering it: no DOM, timers or globals. Runs the phases `resolve` to `scene` with the config's plugins and listeners.

It takes the same config as `chart()`, and the SVG gets the same chart type class without `className`. Listeners of `render` and `mount` never run, responsive overrides and the `renderer` are ignored, and calling `update()`, `detach()` or `destroy()` on the handle a plugin gets throws. Turn the scene into markup with [`renderToString`](https://chartist.dev/api/rendering/#renderToString).

Parameters:

- `config: ChartConfig` The chart: data, axes, layers, plugins and listeners
- `size: SceneSize` The size to lay out at, in px, and how to measure text

Returns: The scene, its root the `svg`

```ts
import {
  autoScaleAxis,
  axisGrid,
  axisLabels,
  cartesianAxes,
  line,
  node,
  renderToString,
  stepAxis,
  toScene
} from 'chartist';

const labels = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'];
const scene = toScene(
  {
    data: { labels, series: [[12, 9, 7, 8, 5]] },
    axes: cartesianAxes([
      { id: 'x', side: 'bottom', type: stepAxis(), ticks: labels },
      { id: 'y', side: 'left', type: autoScaleAxis() }
    ]),
    layers: [axisGrid(), line(), axisLabels()],
    viewBox: { width: 600, height: 300 },
    on: {
      // Styles inside the SVG, for tools that read it on its own.
      scene: ({ scene }) => ({
        scene: scene.append(
          node('style').text('.ct-line { fill: none; stroke: #d70206; }'),
          true
        )
      })
    }
  },
  { width: 600, height: 300 }
);

export const markup = renderToString(scene);
```

## seriesColors

*experimental*

```ts
const seriesColors: readonly string[]
```

The default series colors, `a` to `o`, as hex: the colors of `chartist/styles.css` (`$ct-series-colors` in the Sass settings). Renderers without CSS use them to color series the way the styles do. The styles color the first fifteen series only.

```ts
import { seriesColors } from 'chartist';

// The color of series `c`, the third.
export const third = seriesColors[2];
```

## domRenderer

*experimental*

```ts
function domRenderer(): Renderer<DomRenderOutput>
```

Creates the renderer `chart()` uses by default: it renders scenes as inline SVG into the container, replacing an earlier Chartist SVG there (as 1.x does), and measures text and reads styles for layout in the container, so its CSS applies. Wrap it to change what every render puts on the page.

```ts
import { chart, domRenderer, pie, type Renderer } from 'chartist';

const dom = domRenderer();
// The DOM renderer, with a name for screen readers on every render.
const renderer: Renderer = {
  ...dom,
  render(scene, container) {
    const output = dom.render(scene, container);
    output.svg.setAttribute('role', 'img');
    output.svg.setAttribute('aria-label', 'Monthly budget');
    return output;
  }
};

chart('#chart', {
  data: { series: [50, 30, 20] },
  coordinates: 'polar',
  layers: [pie()],
  renderer
});
```

## textAscent

*experimental*

```ts
const textAscent: 0.85
```

Where SVG text labels put a line's baseline: this share of the font size below the top of the line (a typical font's ascent). Lines are one font size apart, so a renderer finds a line's vertical center at `y - (textAscent - 0.5) * fontSize` from its `y`.

## estimateText

*experimental*

```ts
const estimateText: MeasureText
```

Estimates text size without a DOM: an average glyph is 0.6 em wide, and a line is 1.2 em high, at `fontSize` or else 12 px. `toScene()` measures with it unless you pass your own, which can build on it.

```ts
import { estimateText, type MeasureText } from 'chartist';

// Bold labels: a tenth wider than the estimate.
export const measureText: MeasureText = (text, options) => {
  const size = estimateText(text, options);
  return { ...size, width: size.width * 1.1 };
};
```

## renderToString

*experimental*

```ts
function renderToString(scene: SceneNode): string
```

Serializes a scene to standalone SVG markup. Needs no DOM, so it works in Node.js and in server bundles.

The root gets the SVG and `ct:` namespaces, and attribute values and text are escaped. The markup has the chart's classes but no styles: load `chartist/styles.css` where it's shown, or add a `style` element to the scene.

Parameters:

- `scene: SceneNode` A scene, usually from `toScene()`

Returns: The SVG markup, e.g. `<svg xmlns="…" …>…</svg>`

```ts
import {
  autoScaleAxis,
  axisGrid,
  axisLabels,
  cartesianAxes,
  line,
  renderToString,
  stepAxis,
  toScene
} from 'chartist';

export function weekChart(values: number[]): string {
  const labels = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'];
  const scene = toScene(
    {
      data: { labels, series: [values] },
      axes: cartesianAxes([
        { id: 'x', side: 'bottom', type: stepAxis(), ticks: labels },
        { id: 'y', side: 'left', type: autoScaleAxis() }
      ]),
      layers: [axisGrid(), line(), axisLabels()],
      className: 'ct-chart-line'
    },
    { width: 600, height: 300 }
  );
  return renderToString(scene);
}
```

## SceneSize

```ts
interface SceneSize
```

The size [`toScene`](https://chartist.dev/api/rendering/#toScene) lays a chart out at, since there's no container to measure, and how to measure text there.

Properties:

- `width: number` The width to lay out at, in px. The root svg gets it as its `width`, unless the config sets one.
- `height: number` The height to lay out at, in px. The root svg gets it as its `height`, unless the config sets one.
- `measureText?: MeasureText` Text measurement for layout; an estimate by default.
- `labels?: LabelMode` Label mode when the config sets none: `svg` by default, since string output often goes to tools without HTML support.

## DomRenderOutput

*experimental*

```ts
interface DomRenderOutput extends RenderOutput
```

What [`domRenderer`](https://chartist.dev/api/rendering/#domRenderer) returns from `render()`: the inline SVG it added to the container.

Properties:

- `svg: SVGSVGElement` The chart's `svg` element, in the container.
- `elementOf: (node: SceneNode) => Element | undefined` The rendered element of a scene node of this render.
- `remove: () => void` Takes the SVG out of the container again.

## TextMetrics

```ts
interface TextMetrics
```

The size of a measured text, as a [`MeasureText`](https://chartist.dev/api/rendering/#MeasureText) function returns it.

Properties:

- `width: number` The text's width in px.
- `height: number` The text's height in px: one line.
- `fontSize?: number` The font size in px the text was measured with, when known.

## LabelMode

*experimental*

```ts
type LabelMode = 'html' | 'svg'
```

How labels are drawn: HTML in a `foreignObject` (1.x) or SVG `text`.

## MeasureTextOptions

```ts
interface MeasureTextOptions
```

What a [`MeasureText`](https://chartist.dev/api/rendering/#MeasureText) function gets with the text to measure.

Properties:

- `classes?: readonly string[]` Class names of the text, for renderers that apply CSS.
- `fontSize?: number` Font size in px. Without it, the browser measures with the CSS font size and the estimate uses 12, the size of 1.x `.ct-label`.
- `rootClass?: string` Classes of the chart's root svg, so chart-type CSS applies.
- `container?: Element` Where to measure (the chart container), so its CSS applies.

## MeasureText

```ts
type MeasureText = (text: string, options?: MeasureTextOptions) => TextMetrics
```

Measures how much space a text takes, in px, so labels can be wrapped and aligned. In the browser, Chartist measures with the page's fonts; `toScene()` estimates (0.6 em per character, 1.2 em per line) unless you pass your own in its size.

```ts
import type { MeasureText } from 'chartist';

// Wider glyphs than the estimate, for a wide font.
export const measureText: MeasureText = (text, options = {}) => {
  const fontSize = options.fontSize ?? 12;
  return { width: text.length * fontSize * 0.7, height: fontSize * 1.25 };
};
```

## MeasureStyleOptions

```ts
interface MeasureStyleOptions
```

What a [`MeasureStyle`](https://chartist.dev/api/rendering/#MeasureStyle) function gets with the property to read.

Properties:

- `classes?: readonly string[]` Class names of the element whose style is read.
- `rootClass?: string` Classes of the chart's root svg, so chart-type CSS applies.
- `container?: Element` Where to measure (the chart container), so its CSS applies.

## MeasureStyle

```ts
type MeasureStyle = (property: string, options?: MeasureStyleOptions) => string | undefined
```

Reads a computed CSS property of an SVG `path` with the given classes, for values that the stylesheet decides and layout needs: the pie layer reads the `stroke-width` of a donut slice to fit the ring. Returns `undefined` when it can't tell. In the browser, Chartist reads it in the chart's container; `toScene()` has no stylesheet, so layout uses its defaults there.

```ts
import { domRenderer, type Renderer } from 'chartist';

// The DOM renderer, but donuts are laid out for 30px rings, whatever
// the stylesheet says. Pass it as `renderer` to `chart()`.
export const renderer: Renderer = {
  ...domRenderer(),
  measureStyle: property => (property === 'stroke-width' ? '30px' : undefined)
};
```

## RenderOutput

```ts
interface RenderOutput
```

What a renderer returns from `render()`. The `render` and `mount` phase events pass it on as `output`.

Properties:

- `elementOf?: (node: SceneNode) => Element | undefined` The rendered element of a scene node, if the output is DOM.
- `remove?: () => void` Removes the output again.

## Renderer

*experimental*

```ts
interface Renderer<TOutput extends RenderOutput = RenderOutput>
```

Turns a scene into output. `chart()` renders inline SVG into its container with the DOM renderer, unless its config sets a `renderer`. To get markup instead, without a DOM, use `toScene()` and [`renderToString`](https://chartist.dev/api/rendering/#renderToString).

Properties:

- `render: (scene: SceneNode, target: Element) => TOutput` Renders a scene into the chart's container, after the `scene` phase and on every update and resize.
- `measureText?: MeasureText` Measures text for layout, in the container so its CSS applies; without it, Chartist estimates text sizes.
- `measureStyle?: MeasureStyle` Reads computed styles for layout, in the container so its CSS applies; without it, layout uses its defaults (a donut's ring is laid out for 60 px).
- `labels?: LabelMode` The default label mode of this renderer; `html` if omitted.
