# Terminal rendering

> Draw charts from the ct-cli command or from your own CLI tool, and as text art in HTML, with the data and options of Chartist's presets.

`@chartist-js/terminal` draws Chartist's charts with characters. This guide covers the three ways to use it: the `ct-cli` command, the API for your own CLI tools, and text art in HTML.

## From the command line

`ct-cli` draws a chart from numbers. Each argument is one series:

```sh
npx @chartist-js/terminal@next line 12,9,7,8,5 2,1,3.5,7,3 --labels Mon,Tue,Wed,Thu,Fri --area
npx @chartist-js/terminal@next bar 5,4,3,7 3,2,9,5 --labels Q1,Q2,Q3,Q4 --stack
npx @chartist-js/terminal@next pie 20,10,30 --labels Bananas,Apples,Kiwis --donut
```

Installed globally (`npm install -g @chartist-js/terminal@next`), the command is `ct-cli`. `ct-cli demo` shows one of each chart type.

Without series arguments, it reads the data from a file (`--data`) or from a pipe. JSON works, and so do rows of numbers, one series per row, with optional labels in the first row and series names in the first column:

```sh
printf ',Mon,Tue,Wed\nVisitors,3,5,4\nSign-ups,1,2,3\n' | ct-cli bar --stack
```

`--width` and `--height` set the size in columns and rows, and `ct-cli --help` lists the rest. Colors follow your terminal: 24-bit or 256 colors in one, none when the output goes into a file or a pipe, or when `NO_COLOR` is set.

## In your CLI tool

Your tool has numbers and a terminal, so give it a chart. `lineChart()`, `barChart()` and `pieChart()` from `@chartist-js/terminal` take the data and options of Chartist's presets, plus a size in cells, and return a string:

```ts
import { detectColorMode, legend, lineChart } from '@chartist-js/terminal';

const data = {
  labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'],
  series: [
    { name: 'Visitors', data: [12, 9, 7, 8, 5] },
    { name: 'Sign-ups', data: [2, 1, 3.5, 7, 3] }
  ]
};
const color = detectColorMode(process.stdout, process.env);

console.log(lineChart(data, { columns: 60, rows: 14, showArea: true, color }));
console.log(legend(data, { columns: 60, color }));
```

Every preset option works: `stackBars`, `horizontalBars`, `low` and `high`, `axisY.labelInterpolationFnc` and so on. The terminal adds `columns` and `rows`, `color` (`truecolor`, `256`, `16` or `none`), `palette` for other series colors, and `format`.

### Any scene

The chart functions cover the presets. For a [composed chart](https://chartist.dev/docs/composed-charts/), or a scene a plugin changed, lay it out with `terminalSize()` and render it with `renderToTerminal()`:

```ts
import { barChartConfig, toScene } from 'chartist';
import { renderToTerminal, terminalSize } from '@chartist-js/terminal';

const scene = toScene(
  barChartConfig({ labels: ['Q1', 'Q2', 'Q3'], series: [[5, 4, 3]] }),
  terminalSize(40, 10)
);
console.log(renderToTerminal(scene, { color: 'none' }));
```

[`lineChartConfig()`](https://chartist.dev/api/charts/#lineChartConfig), `barChartConfig()` and `pieChartConfig()` come from `chartist`: they build the config a preset draws, for any renderer. [`toScene()`](https://chartist.dev/api/rendering/#toScene) and the other renderers are in the [Rendering](https://chartist.dev/api/rendering/) part of the API reference. A terminal cell stands for 8 × 16 px of the scene, so a braille dot is 4 × 4 px and circles stay round. Labels are measured one cell per character, so they land on the character grid.

## Text art in HTML

`format: 'html'` (or `renderToHtml(scene)`) gives the text art as a `pre` element, with classes where the terminal has colors: `ct-series-a`, `ct-grid`, `ct-label` and so on. Its stylesheet colors them with [the custom properties](https://chartist.dev/docs/styling-with-css/#custom-properties) your charts already use, so a theme colors the text art too:

```ts
import '@chartist-js/terminal/styles.css';
```

The stylesheet also brings a small font of its own for the dots, grid lines and bars, drawn to fill each character cell, so the text art looks the same in every browser. `ct-cli pie 3,2,1 --html --standalone` writes a whole page.

This example draws a donut as text art, framed as a terminal window:

**A donut as text art** (runs in the browser):

`src/main.ts`:

```ts
import '@chartist-js/terminal/styles.css';
import './style.css';
import { pieChart } from '@chartist-js/terminal';

const art = document.querySelector('#art');
if (art) {
  art.innerHTML = pieChart(
    { labels: ['Bananas', 'Apples', 'Kiwis'], series: [20, 10, 30] },
    { donut: true, columns: 34, rows: 16, format: 'html' }
  );
}
```

`src/style.css`:

```css
/* A terminal window around the text art, for the looks. It takes the
   chart's size: more columns or rows make it bigger. */
.window {
  width: fit-content;
  max-width: 100%;
  margin: 0 auto;
  border-radius: 10px;
  overflow: hidden;
  background: #17161c;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.06) inset,
    0 12px 32px rgba(0, 0, 0, 0.35);
}

.title-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  background: #2a2830;
}

.dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: #ff5f57;
}

.dot:nth-child(2) {
  background: #febc2e;
}

.dot:nth-child(3) {
  background: #28c840;
}

.title {
  flex: 1;
  margin-right: 52px;
  text-align: center;
  color: #a8a6b0;
  font:
    600 12px system-ui,
    sans-serif;
}

.screen {
  padding: 12px;
  color: #e6e4ec;
  /* Text art reads the same custom properties as SVG charts. */
  --ct-label-color: rgba(255, 255, 255, 0.7);
  --ct-grid-color: rgba(255, 255, 255, 0.16);
}

.screen .ct-terminal {
  margin: 0;
  font-size: 13px;
  /* Narrower than the chart, the window cuts it off. */
  overflow: hidden;
  /* Bold labels; the dots and lines come from the stylesheet's own font. */
  font-weight: 700;
}

/* On the dark screen, the area shading needs a little more. */
.screen .ct-area {
  opacity: 0.75;
}
```

`index.html`:

```html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>A donut as text art</title>
  </head>
  <body>
    <div class="window">
      <div class="title-bar" aria-hidden="true">
        <span class="dot"></span>
        <span class="dot"></span>
        <span class="dot"></span>
        <span class="title">ct-cli</span>
      </div>
      <div class="screen">
        <div id="art"></div>
      </div>
    </div>
    <script type="module" src="/src/main.ts"></script>
  </body>
</html>
```

## Fonts and limits

In a terminal, braille and box-drawing characters need a font that has them. Most terminal fonts do; if the dots look scattered or the grid has gaps, the font is missing some. HTML output doesn't depend on the reader's fonts: the stylesheet brings its own for those characters.

Each character of a label is one cell, so wide characters (CJK, emoji) push the columns after them. And it's a printout: no tooltips, no animation.

Next: Chartist's options in the terminal in [Customizing charts](https://chartist.dev/packages/terminal/customizing-charts/), [plugins](https://chartist.dev/packages/terminal/plugins/), or the same scene as SVG markup in [server rendering](https://chartist.dev/docs/server-rendering/).
