ngx-chrtsへ最新データを反映する

はじめてこちらのグループに投稿させていただきます。
みなさまよろしくお願いします。

今回の質問内容

ngx-chartsを使ってAPIから取得したデータを元にしたグラフ描写を行おうとしています。

具体的にですが、お店に「行った」、「行ってない」のデータをpie-chartに描写さるのですが、データの反映が安定せず、どのようにすれば安定して描写させられるか試行錯誤しており、すでに利用中の方で詳しい方がいればアドバイスをいただきたいです。

「安定しない」の具体的な自称

下記のコードでは、3つのケースが存在しています。

  1. デフォルトのデータのまま(valueが0)で描写されないケース
  2. 行ったデータだけ描写されるケース
  3. 全て正常に描写されるケース

何度か、ブラウザリフレッシュなどを行うと3の状態になりますが、できれば最初にページを開いた段階で反映されるようにしたいです。

現状のコード

export class PiChartsComponent implements OnInit {
  data = [
    {
      name: '行った',
      value: 0,
    },
    {
      name: 'まだ行ってない!',
      value: 0,
    }
  ];

~~~~~中略~~~~~~

  ngOnInit() {
    this.「data」に値をセットする処理の呼び出し;
  }

 data」に値をセットする処理の呼び出し() {
 // ユーザーが行ったお店の数を取得するAPIからデータを取得して反映
    this.myDataService.CountUserToRestaurant(user.uid).subscribe(
      (result: number) => this.data[0].value = result
    );
 // 全体のお店の数を取得するAPIからデータを取得して反映、また全体のお店の数からユーザが行ったお店の数を引いて適用する
    this.restaurantService.getRestaurantsCount().subscribe(
    (result: number) => this.resultData[1].value = result - this.resultData[0].value,
    );
    this.resultData = [...this.resultData]; // ← stackOverflowなどで描写されない場合に追加したら動くという解決事例があったので試してみたが、動く時もあれば、動かない時もあるという感じです
  }
}

こちらを元に、描写させています。

<ngx-charts-pie-chart
    [view]="view"
    [results]="data" // ここに指定しています
    [scheme]="colorScheme"
    [gradient]="gradient"
    [legend]="showLegend"
    [legendTitle]="legendTitle"
    [labels]="labels"
    [doughnut]="isDoughnut"
    >
</ngx-charts-pie-chart>

以上、皆様アドバイスいただければ幸いです。

結果が安定しないのは非同期処理を並列に実行しているためであると考えられます。
(行っていないお店を算出する部分のthis.data[0].valueが最新の値かが保証されない)

forkJoinを使ってみてはいかがでしょうか。
https://rxjs-dev.firebaseapp.com/api/index/function/forkJoin

forkJoin([
  this.myDataService.CountUserToRestaurant(user.uid),
  this.restaurantService.getRestaurantsCount()
]).subscribe(([visitedCount, restaurantsCount]) => {
  this.data[0].value = visitedCount;
  this.data[1].value = restaurantsCount - visitedCount;
})
3 Likes

@puku0x様
上記のコードを利用させていただき、安定してデータを表示させることができました。
大変ありがとうございました。

1点、上記に加えて一行だけ追加しました。

this.resultData = [...this.resultData];

↓こうなりました。

forkJoin([
  this.myDataService.CountUserToRestaurant(user.uid),
  this.restaurantService.getRestaurantsCount()
]).subscribe(([visitedCount, restaurantsCount]) => {
  this.data[0].value = visitedCount;
  this.data[1].value = restaurantsCount - visitedCount;
  this.resultData = [...this.resultData]; // こちらを追加しました
})
3 Likes