# Dashboard with animated bars (Chartist example)

> Two series by region get new numbers every two seconds, and the bars overshoot a little on their way.

`src/main.ts`:

```ts
import 'chartist/styles.css';
import './style.css';
import { barChart } from 'chartist';
import { liveDomRenderer, smilAnimations } from 'chartist/live';
import { firstNumbers, onNumbers } from './numbers';

const chart = barChart(
  '#chart',
  firstNumbers,
  // How long the animations take is up to style.css.
  { renderer: liveDomRenderer({ animations: smilAnimations() }) }
);

onNumbers(data => chart.update({ data }));
```

`index.html`:

```html
<!doctype html>
<html>
  <head>
    <meta charset="UTF-8" />
    <script type="module" src="/src/main.ts"></script>
  </head>
  <body>
    <div id="chart" class="ct-golden-section"></div>
  </body>
</html>
```

`src/numbers.ts`:

```ts
// Numbers by region from a seeded generator, so every run shows the same.

let seed = 7;
const next = () => {
  seed = (seed * 16807) % 2147483647;
  return (seed - 1) / 2147483646;
};

const labels = ['North', 'East', 'South', 'West'];
const random = () => labels.map(() => Math.round(next() * 9) + 1);

/** Two series by region. */
export const firstNumbers = {
  labels,
  series: [
    [5, 4, 3, 7],
    [3, 2, 9, 5]
  ]
};

/** Calls `listener` with new numbers every two seconds. */
export function onNumbers(listener: (numbers: typeof firstNumbers) => void) {
  setInterval(() => listener({ labels, series: [random(), random()] }), 2000);
}
```

`src/style.css`:

```css
#chart {
  /* Updates move the bars from their old values to the new ones. */
  --ct-update-duration: 700ms;
  /* A curve that overshoots a little, then settles. */
  --ct-update-easing: cubic-bezier(0.34, 1.56, 0.64, 1);
}
```
