AngularJSでChart.jsを使う

Posted: , Modified:   AngularJS Chartjs Qiita

本稿は Qiita 投稿記事 のバックアップです.

概要

English

AngularJS から Chart.js を使う場合の備忘録. 結論から言えば,Angular Chart を利用すれば良い.

Angular Chart の利用

ドキュメント にもあるように,canvas タグに chart クラスと表示するグラフタイプ別のクラスを付ける. 例えば,bar グラフを表示したい場合,class="chart chart-bar" を表示先の canvas に追加する.

プロットするデータは,chart-data, chart-labels, chart-series, chart-dataset-override などの属性を使って渡す.ここの渡し方が,元々の Chart.js とは異なっていて,少しトリッキーである.

chart-data は Chart.js におけるdata.datasets に対応する項目だが,配列か二次元配列しか渡せない. Char.js では,ラベルや色情報も合わせた次のようなオブジェクトを渡していた.

datasets: [{
  label: '# of Votes',
  data: [12, 19, 3, 5, 2, 3],
  backgroundColor: [
    'rgba(255, 99, 132, 0.2)',
    'rgba(54, 162, 235, 0.2)',
    'rgba(255, 206, 86, 0.2)',
    'rgba(75, 192, 192, 0.2)',
    'rgba(153, 102, 255, 0.2)',
    'rgba(255, 159, 64, 0.2)'
  ],
  borderColor: [
    'rgba(255,99,132,1)',
    'rgba(54, 162, 235, 1)',
    'rgba(255, 206, 86, 1)',
    'rgba(75, 192, 192, 1)',
    'rgba(153, 102, 255, 1)',
    'rgba(255, 159, 64, 1)'
  ],
  borderWidth: 1
},
...
]

Angular Chart では,datasets 配列の各オブジェクトから data 属性だけ抜き出して作った配列を chart-data 属性に渡す.

class GraphCtrl{

  constructor() {

    this.data = [
      [12, 19, 3, 5, 2, 3],
      ...
    ];

  }

}

としておいて,テンプレートは<canvas class="chart chart-bar" chart-data="$ctrl.data" /> とする.

では,datasets の各オブジェクトで指定していた label はどうなるかと言うと, label だけを集めた配列を作って chart-series に渡す.

また,それ以外の項目, 上の例では,backgroundColor, borderColor, borderWidth などは, chart-dataset-override 属性を使う. この属性には,元々の datasets の内容を渡せば良い. (実際には,配列内の各オブジェクトから datalabel を除いたものを渡すべきだろう)

ただし,chart-dataset-override の方で data も渡せるのだからといって, chart-data を設定しないとエラーになる.

Chart.js のマニュアルにある Bar Chartのを Angular Chart 用に書き換えてみる.

###Chart.js 版

var myChart = new Chart(ctx, {
  type: 'bar',
  data: {
    labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
    datasets: [{
      label: '# of Votes',
      data: [12, 19, 3, 5, 2, 3],
      backgroundColor: [
        'rgba(255, 99, 132, 0.2)',
        'rgba(54, 162, 235, 0.2)',
        'rgba(255, 206, 86, 0.2)',
        'rgba(75, 192, 192, 0.2)',
        'rgba(153, 102, 255, 0.2)',
        'rgba(255, 159, 64, 0.2)'
      ],
      borderColor: [
        'rgba(255,99,132,1)',
        'rgba(54, 162, 235, 1)',
        'rgba(255, 206, 86, 1)',
        'rgba(75, 192, 192, 1)',
        'rgba(153, 102, 255, 1)',
        'rgba(255, 159, 64, 1)'
      ],
      borderWidth: 1
    }]
  },
  options: {
    scales: {
      yAxes: [{
        ticks: {
          beginAtZero: true
        }
      }]
    }
  }
});

Angular Chart 版

class ChartCtrl{

  constructor(){

    this.labels = ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"];
    this.data = [
      [12, 19, 3, 5, 2, 3]
    ];
    this.seriese = ["# of Votes"];
    this.datasets = [
      {
        backgroundColor: [
          'rgba(255, 99, 132, 0.2)',
          'rgba(54, 162, 235, 0.2)',
          'rgba(255, 206, 86, 0.2)',
          'rgba(75, 192, 192, 0.2)',
          'rgba(153, 102, 255, 0.2)',
          'rgba(255, 159, 64, 0.2)'
        ],
        borderColor: [
          'rgba(255,99,132,1)',
          'rgba(54, 162, 235, 1)',
          'rgba(255, 206, 86, 1)',
          'rgba(75, 192, 192, 1)',
          'rgba(153, 102, 255, 1)',
          'rgba(255, 159, 64, 1)'
        ],
        borderWidth: 1
      }
    ];
    this.options = {
      scales: {
        yAxes: [{
          ticks: {
            beginAtZero: true
          }
        }]
      }
    };

  }

}
<canvas class="chart chart-bar"
  chart-data="$ctrl.data"
  chart-labels="$ctrl.labels"
  chart-series="$ctrl.seriese"
  chart-dataset-override="$ctrl.datasets"
  chart-options="$ctrl.options"
/>

なお,上記の例の様に,datasets が一つしかない場合, data, datasets は配列にしなくても良いが,chart-series は無視されるようになる. つまり,

this.data = [12, 19, 3, 5, 2, 3];
this.datasets = {
  label: "# of Votes",
  backgroundColor: [
    'rgba(255, 99, 132, 0.2)',
    'rgba(54, 162, 235, 0.2)',
    'rgba(255, 206, 86, 0.2)',
    'rgba(75, 192, 192, 0.2)',
    'rgba(153, 102, 255, 0.2)',
    'rgba(255, 159, 64, 0.2)'
  ],
  borderColor: [
    'rgba(255,99,132,1)',
    'rgba(54, 162, 235, 1)',
    'rgba(255, 206, 86, 1)',
    'rgba(75, 192, 192, 1)',
    'rgba(153, 102, 255, 1)',
    'rgba(255, 159, 64, 1)'
  ],
  borderWidth: 1
};

の様に,label: "# of Votes" を追加することを忘れないようにする.