LoginSignup
2
3

More than 5 years have passed since last update.

【chart.js】FirebaseAPIで取得したデータを表示しようとするとうまく表示されない

Last updated at Posted at 2017-10-18

そろそろ娘が起きそうです。ionic2で家計簿アプリ作ってます。
https://qiita.com/irohamaru/items/3df901cd7e12e3c85e9a

家計簿をリスト表示するだけでなく、グラフで収支の推移がわかると便利だなぁと思い、支出・収入グラフの実装をすることにしました。

chart.jsを採用

chart.jsなるものが使えるそうな。
https://liginc.co.jp/web/js/40934

自分のアプリに導入してみたのですが、思ったより簡単にグラフ表示できました。

自分の場合は、Firebaseから取得したデータをグラフ化するのですが、その際に詰まった点が1つありました。

Firebaseからデータを取得するよりも先にグラフが表示されてしまう

どういうことかというと、以下ソースのspendListよりもlineChartが先に描画されてしまい、グラフがうまく表示されない場合があるのです。

sample.html
<!-- canvasタグの部分さえ書いてあれば表示される -->
<ion-card>
  <ion-card-header>
    家計簿ですぞ
  </ion-card-header>
  <ion-card-content>
    <canvas #lineCanvas></canvas>
  </ion-card-content>
</ion-card>
sample.ts
export class HomePage {
  @ViewChild('lineCanvas') lineCanvas;
  lineChart: any;
  public spendList: string[]; // 支出リスト

  ...(省略)...

  constructor(public navCtrl: NavController, public afdb: AngularFireDatabase) {
    ...(省略)...    

    // 支出リスト
    this.spendList = this.getSpendList(...);
  });

  // 支出リストを取得
  // Firebase APIを使ってFirebaseのDBからデータを取得するメソッド
  getSpendList(...) {
    ...(省略)...
    this.afdb.list('kakeibo', {
      ...(省略)...
    }).subscribe(list => {
      ...(省略)...
    });
    return resultList;
  }

 ionViewDidLoad() {
   this.lineChart = new Chart(this.lineCanvas.nativeElement, {
     type: 'line',
     data: {
       labels: this.thisMonthDayList, //今月の日付リスト(1,2,...31)
       datasets: [
         {
           label: '支出',
           fill: false,
           lineTension: 0.1,
           backgroundColor: "rgba(75,192,192,0.4)",
           borderColor: "rgba(75,192,192,1)",
           borderCapStyle: 'butt',
           borderDash: [],
           borderDashOffset: 0.0,
           borderJoinStyle: 'miter',
           pointBorderColor: "rgba(75,192,192,1)",
           pointBackgroundColor: "#fff",
           pointBorderWidth: 1,
           pointHoverRadius: 5,
           pointHoverBackgroundColor: "rgba(75,192,192,1)",
           pointHoverBorderColor: "rgba(220,220,220,1)",
           pointHoverBorderWidth: 2,
           pointRadius: 1,
           pointHitRadius: 10,
           data: this.spendList, // Firebaseから取得する支出データ
           spanGaps: false,
         }
       ]
     });
   }

本当はデータはあるのに、横一列の点の集まりになってしまう。

スクリーンショット 2017-10-19 1.44.48.png

もしくは、グラフの描画部分にカーソルが触れるとエラー画面が表示されることも。

スクリーンショット 2017-10-19 1.47.21.png

解決策

支出リストのデータ取得後、意図的にグラフを遅延表示する。
(グラフ表示をsetTimeoutで1000msだけ遅延させる)

sample.ts
export class HomePage {
  @ViewChild('lineCanvas') lineCanvas;
  lineChart: any;
  public spendList: string[]; // 支出リスト

  ...(省略)...

  constructor(public navCtrl: NavController, public afdb: AngularFireDatabase) {
    ...(省略)...    

    // 支出リスト
    this.spendList = this.getSpendList(...);
  }

  ionViewDidLoad() {
    // 支出リストの取得よりグラフが先に表示されないように遅延させる
    setTimeout(() => {
      this.showChart();
    }, 1000);
  }

  showChart() {
    this.lineChart = new Chart(this.lineCanvas.nativeElement, {
      ...(省略)...  
    });
  }

※ionicサンプルプロジェクトのソースを眺めてたら、jsonファイルからデータを引き出すのに時間がかかるため、意図的に処理を遅延させてる箇所があったので参考にしました。

schedule.ts
// simulate a network request that would take longer
// than just pulling from out local json file
setTimeout(() => {
  refresher.complete();

  const toast = this.toastCtrl.create({
    message: 'Sessions have been updated.',
    duration: 3000
  });
  toast.present();
}, 1000);
2
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3