# Simple SMIL Animations (Chartist example)

> Points of two series fade and slide in one after the other, replayed every eight seconds.

`src/main.ts`:

```ts
import 'chartist/styles.css';
import { lineChart, easings, findAll, Svg, type ChartPlugin } from 'chartist';

// The points fade and slide in with SMIL, one after the other.
const fadeInPoints: ChartPlugin = {
  name: 'fade-in-points',
  install(chart) {
    let timerId: ReturnType<typeof setTimeout> | undefined;

    chart.on('mount', ({ scene, elementOf }) => {
      // A sequence number, reset on every render
      let seq = 0;

      for (const point of findAll(scene, { role: 'point' })) {
        const element = elementOf(point);
        if (!element) {
          continue;
        }
        const x = point.ctx.x;
        // We use the Svg API to trigger SMIL animations on each point
        new Svg(element).animate({
          opacity: {
            // The delay when we like to start the animation
            begin: seq++ * 80,
            // Duration of the animation
            dur: 500,
            // The value where the animation should start
            from: 0,
            // The value where it should end
            to: 1
          },
          x1: {
            begin: seq++ * 80,
            dur: 500,
            from: x - 100,
            to: x,
            // You can specify an easing function name or use easing functions from `easings` directly
            easing: easings.easeOutQuart
          }
        });
      }

      // For the sake of the example we redraw the chart every time it's
      // rendered with a delay of 8 seconds
      clearTimeout(timerId);
      timerId = setTimeout(() => chart.update({}), 8000);
    });
  }
};

lineChart(
  '#chart',
  {
    labels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
    series: [
      [12, 4, 2, 8, 5, 4, 6, 2, 3, 3, 4, 6],
      [4, 8, 9, 3, 7, 2, 10, 5, 8, 1, 7, 10]
    ]
  },
  {
    plugins: [fadeInPoints],
    low: 0,
    showLine: false,
    axisX: {
      showLabel: false,
      offset: 0
    },
    axisY: {
      showLabel: false,
      offset: 0
    }
  }
);
```

`index.html`:

```html
<!doctype html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script type="module" src="/src/main.ts"></script>
  </head>
  <body>
    <div id="chart" style="height: 50vh"></div>
  </body>
</html>
```

The same chart with the 1.x classes (`src/main.classic.ts`):

```ts
import 'chartist/styles.css';
import { LineChart, easings } from 'chartist';
import { compat } from 'chartist/compat';

const chart = new LineChart(
  '#chart',
  {
    labels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
    series: [
      [12, 4, 2, 8, 5, 4, 6, 2, 3, 3, 4, 6],
      [4, 8, 9, 3, 7, 2, 10, 5, 8, 1, 7, 10]
    ]
  },
  {
    // 1.x draw events come from the compat plugin in v2.
    plugins: [compat],
    low: 0,
    showLine: false,
    axisX: {
      showLabel: false,
      offset: 0
    },
    axisY: {
      showLabel: false,
      offset: 0
    }
  }
);

// Let's put a sequence number aside so we can use it in the event callbacks
let seq = 0;

// Once the chart is fully created we reset the sequence
chart.on('created', () => {
  seq = 0;
});

// On each drawn element by Chartist we use the Svg API to trigger SMIL animations
chart.on('draw', data => {
  if (data.type === 'point') {
    // If the drawn element is a line we do a simple opacity fade in. This could also be achieved using CSS3 animations.
    data.element.animate({
      opacity: {
        // The delay when we like to start the animation
        begin: seq++ * 80,
        // Duration of the animation
        dur: 500,
        // The value where the animation should start
        from: 0,
        // The value where it should end
        to: 1
      },
      x1: {
        begin: seq++ * 80,
        dur: 500,
        from: data.x - 100,
        to: data.x,
        // You can specify an easing function name or use easing functions from `easings` directly
        easing: easings.easeOutQuart
      }
    });
  }
});

let timerId: ReturnType<typeof setTimeout> | undefined;

// For the sake of the example we update the chart every time it's created with a delay of 8 seconds
chart.on('created', () => {
  if (timerId) {
    clearTimeout(timerId);
  }

  timerId = setTimeout(chart.update.bind(chart), 8000);
});
```
