# Seismograph (Chartist example)

> A thin trace that scrolls every 80 ms, quiet until a quake comes through.

`src/main.ts`:

```ts
import 'chartist/styles.css';
import './style.css';
import { lineChart } from 'chartist';
import { liveDomRenderer, smilAnimations } from 'chartist/live';
import { firstReadings, onReadings } from './seismometer';

const chart = lineChart('#chart', firstReadings, {
  // Readings are known by their time, so the trace scrolls.
  renderer: liveDomRenderer({ key: 'label', animations: smilAnimations() }),
  low: -8,
  high: 8,
  showPoint: false,
  lineSmooth: false,
  axisX: { showGrid: false, showLabel: false },
  axisY: { onlyInteger: true }
});

onReadings(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/seismometer.ts`:

```ts
// A seismometer's readings from a seeded generator, so every run records
// the same quakes.

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

const READINGS = 150;
let time = 0;
let quake = 0;
const read = () => {
  time += 1;
  // Now and then a quake starts, then fades out.
  if (quake < 0.05 && random() < 0.01) {
    quake = 3 + random() * 5;
  }
  quake *= 0.96;
  const value = Math.sin(time * 0.9) * quake + (random() - 0.5) * 0.6;
  return { label: time, value: Math.round(value * 100) / 100 };
};
let readings = Array.from({ length: READINGS }, read);

/** The readings by their time. */
const dataOf = () => ({
  labels: readings.map(reading => reading.label),
  series: [readings.map(reading => reading.value)]
});

/** The last 150 readings. */
export const firstReadings = dataOf();

/** Calls `listener` with the last 150 readings, two more every 80 ms. */
export function onReadings(listener: (data: typeof firstReadings) => void) {
  setInterval(() => {
    readings = [...readings.slice(2), read(), read()];
    listener(dataOf());
  }, 80);
}
```

`src/style.css`:

```css
#chart {
  /* As long as the time between updates: the trace never stops. */
  --ct-update-duration: 80ms;
  --ct-update-easing: linear;
  --ct-line-width: 1px;
}
```
