ReactでApexChartsを使ってリアルタイムにデータを更新する折れ線グラフを描画する

2020.04.21

Reactでデータがリアルタイムで更新される折れ線グラフを簡単に描画する方法がないか調べてみたところ、ApexChartsが出てきました。 ApexChartsはさまざまなグラフを描画可能なJSのOSSで、ReactやVue、Angular用ののWrapperもそれぞれ用意されています。

今回はReact用のApexChartsのWrapperであるreact-apexchartsを使って、1秒ごとに追加されるデータを描画する折れ線グラフを作ってみました。

概要

今回作成したグラフは次のようなものです。

a、b、cの3種類のデータを1秒ごとにランダムなデータを追加しています。データの追加タイミングをずらすために、データの追加は80%の確率で行うようにしました。

では、コードの各要素を見ていきます。

グラフ用コンポーネント

react-apexchartsのコンポーネントにグラフタイプやオプション、データを渡すことでグラフを描画できます。

import Chart from "react-apexcharts";

<Chart type="line" options={options} series={props.dataList} />

今回は折れ線グラフなので、グラフタイプはlineを渡しています。データseriesやオプションoptionsについてはこの後、順に説明します。 この他にもwidthheightでグラフのサイズを指定できます。

グラフオプション

今回は次のようなオプションを指定しています。

const options = {
  chart: {
    zoom: {
      enabled: false
    },
    animations: {
      easing: "linear",
      dynamicAnimation: {
        speed: 500
      }
    }
  },
  tooltip: {
    x: {
      format: "yyyy/MM/dd HH:mm:ss.f"
    }
  },
  xaxis: {
    type: "datetime",
    range: props.range
  },
  yaxis: {
    labels: {
      formatter: val => val.toFixed(0)
    },
    title: { text: "Value" }
  }
};

今回設定しているオプションの内容について順番にみていきます。

chart

chartはグラフ全体に関わる設定が可能なオプションです。

  • zoom
    • データが更新された際にズームが解除されて使いづらいため、ズーム機能は無効化しています
  • animations
    • データ追加時の描画が滑らかになるように、dynamicAnimationを有効化しています
    • アニメーションはデフォルトでは無効化されていますが、サブパラメーターを設定すると自動的に有効化されます
    • enabledtrueを設定することでも有効化できます
    • easingはアニメーションの動き方(速さの変化)です
    • 今回は動きが自然に感じたlinearを選択しています

tooltip

tooltipはグラフにカーソルを当てたときに表示される情報に関する設定が可能なオプションです。

  • x.formatでデータが表示する点のx軸の値である、日時の表示形式を指定しています

xaxis

xaxisはx軸に関する設定が可能なオプションです。

  • 時系列として扱うためにtypedatetimeに指定しています
  • rangeで表示範囲をミリ秒単位で指定します
    • 60,000を指定すると、最新の点から60秒前までの範囲が表示されます

yaxis

yaxisはy軸に関する設定が可能なオプションです。

  • labels.formatterで、y軸の値の表示形式を変化する関数を指定しています
  • titleでy軸のタイトル情報を指定しています

その他

今回紹介したもの以外にもいろいろなオプションがあります。それらの詳細についてはドキュメントをご確認ください。良さそうなリンク先が見つからなかったので、Optionsのルートページを貼っています。リンク先のサイドバーからOptions (Reference)を開くと、各オプションの一覧を確認できます。

データの生成

データの生成は次のような処理で行っています。

const addDataRandomly = data => {
  // 指定した確率`ADDING_DATA_RATIO`でデータを追加する
  if (Math.random() < 1 - ADDING_DATA_RATIO) {
    return data;
  }

  return [
    ...data,
    {
      x: new Date(),
      y: data.length * Math.random() // データの量に応じて最大値が増えるランダムな数
    }
  ];
};
const interval = setInterval(() => {
  setDataList(
    dataList.map(val => { // ラベルごとにデータを更新する
      return {
        name: val.name,
        data: addDataRandomly(val.data)
      };
    })
  );
}, ADDING_DATA_INTERVAL_IN_MILLISECONDS);

ここで出てくるラベルごとのデータ一覧であるdataListが、上で紹介したChartコンポーネントの引数seriesにそのまま渡されます。

dataListの構成は次のようになっています。

[
  {
    name: "a",
    data: [
      {
        x: 1587372999,
        y: 0.8043008268501195
      },
      ...
    ]
  },
  ...
]

seiriesに渡すデータの形式は他にもパターンがあり、要件に応じて使い分けることができます。その他のパターンや詳細については以下のドキュメントをご確認ください。

さいごに

ApexChartsを使った折れ線グラフでのリアルタイム可視化を試してみました。データセットとオプションをいくつか渡すだけで作成できるので簡単でした。今回は作成したランダムなデータを可視化しましたが、サーバ等から送られてきたデータを表示することでイベントデータやIoTデータのリアルタイム可視化に使えそうです。

参考