2016-10-24 9 views
1

角度2とchart.js(ngcharts経由)を使ってグラフ用のダッシュボードを作成しようとしています。私はカスタムインターバルでhttpリクエストを介して更新される一連のチャートを持っていたいと思います。間隔を使用してオブザーバブルの配列を更新するにはどうすればよいですか?

今、データを配列にプッシュする3つのチャートコールがあります。私は次の繰り返しになると困っています。もし配列にもう一度行くと、3つのグラフが追加されます。私は、配列のサブスクライバが、間隔がそれを発行するときに新しいデータで更新することを望みます。

私のユースケースのコンポーネント/サービス/ http関係を正しく構造化する方法について少し混乱します。私は近くにいると感じますが、私は間違いなく何かを欠いています。インターバル/サブスクライバ関係をビューにマップし、ある間隔で既存のグラフを更新するにはどうすればよいですか? 助けがあれば助かります!今

サービス:

は、私がここに間隔を実装しています:

getSingleChartObsinterval(id: number, interval: number) : Observable<Graph> { 

return Observable.interval(interval).flatMap(() => this.getSingleChartobs(id));   
} 


getSingleChartobs(id: number) : Observable<Graph> { 

    return this.jsonp.get(“api location”) 
      .map(response => this.extractJsonData(response, id) as Graph) 
} 

extractJsonDataだけの応答を取得し、チャートJSで動作するように、それを操作しています。これは、使いやすいプロパティを持つGraphオブジェクトを返します。私はAPIのコントロールを持っていないので、複数のグラフを含むようにレスポンスを再構成することはできません。

コンポーネント:

import { Component } from '@angular/core'; 
import { ChartsModule } from 'ng2-charts/ng2-charts'; 
import { ChartService } from './chart.service'; 
import { Graph } from './graph'; 
import { OnInit } from '@angular/core'; 
import { Observable } from 'rxjs/Rx'; 


@Component({ 
    selector: 'ab-chart', 
    styles: [` 
    .chart { 
     display: block; 
    } 
    `], 
    templateUrl: 'app/chart.component.html' 
}) 
export class ChartComponent implements OnInit { 

    ngOnInit(): void { 
     console.log("Chart component init"); 

     this.getSingleChart(3, 5000); 
     this.getSingleChart(5, 4000); 
     this.getSingleChart(6, 5000); 
    } 

    graph: Graph; 
    graphs: Graph[] = []; 


    constructor(
     private chartService: ChartService 
    ) {} 


    getSingleChart(id: number, interval: number): void { 
    this.chartService.getSingleChartObsinterval(id, interval) 
     .subscribe(x => 
     this.graphs.push(x) 
    ); 
} 
} 

ビュー:

<div *ngFor="let graph of graphs" class="chart-container"> 
    <base-chart 
     class="chart" 
     [datasets]="graph.datasets" 
     [labels]="graph.labels" 
     [options]="graph.options" 
     [chartType]="graph.type"> 
     </base-chart> 
    </div> 
+0

代わりの新しいをプッシュします既存のグラフを新しいデータで置き換えることはできないのですか?chart.jsについては何も知らないので、データを置き換えずに単に新しいグラフを描画するのを待つだけです –

+0

@ NoémiSalaün私はそれが私が求めているもののようなものだと思う。それぞれのチャートは異なる間隔にあるので、私は各アイテムiアレイを吹き飛ばすことなく、変更に加入し更新するアレイ。私は各オブジェクトを配列のサブスクライバとしてプッシュしようとしましたが、動作しませんでした。配列を検索してデータを更新しなくても、これを実行できる方法があることを願っています。 – Skerrvy

答えて

1

<div *ngFor="let graph of graphs | async" ...> 

CombineLatestを特定のキーでgraphsオブジェクトを更新します。私は配列からオブジェクトにgraphsプロパティを変更注意:

graphs: {[key: number]: Graph} = {}; 

getSingleChart(id: number, interval: number): void { 
    this.chartService.getSingleChartObsinterval(id, interval) 
    .subscribe(x => this.graphs[id] = x); 
} 

get graphIds() { 
    return Object.keys(this.graphs); 
} 

その後、あなたはキーの配列を反復処理する必要があるテンプレートで(あなたがgraphsオブジェクト繰り返すことができます。

<div *ngFor="let id of graphIds" class="chart-container"> 
    <base-chart 
     class="chart" 
     [datasets]="graphs[id].datasets" 
     [labels]="graphs[id].labels" 
     [options]="graphs[id].options" 
     [chartType]="graphs[id].type"> 
    </base-chart> 
</div> 
+0

この回答をありがとう。どちらの答えもうまくいきましたが、これは私が試みていたものに近いものであり、既存のアプローチの変更を最小限に抑えました。 – Skerrvy

1

はあなたがチャートの限られた量を持っていますか?あなたは常に3つを持っている場合はcombineLatest演算子を利用することができます(もし私が推測するような再帰を使用しなければならない場合)。

次の操作を行うことができ、あなたのコンポーネントで

this.graphs = this.getSingleChart(3, 5000).combineLatest(
     this.getSingleChart(5, 4000), 
     this.getSingleChart(6, 5000), 
     (val1, val2, val3) => return [val1, val2, val3]) 
     //.subscribe((arrayOfVal) => console.log(arrayOfVal); 

これはチャートのたびに1が更新される新しい配列を返します。チャート2が新しい値を取得した場合、関数の値(combineLatestの3番目の引数)は、1の古い値、2の新しい値、3の古い値で呼び出されます。

あなたはこの使用することができ、あなたのテンプレートで

:各グラフはid独自のを持っている(私はその独特のを想定)ので、私はちょうどにgetSingleChart()方法を変更したいのでhttps://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/combinelatest.md

+0

実際には、 'combineLatest()'がコールバックから返された値ではなくObservableを返すので、これはうまくいきません。また、これは、常にすべてのチャートを一度に更新する必要があることを意味します。 – martin

+0

それは確かに観察可能なものを返すでしょう。しかし、それはちょっとしたことです。その場合、オブザーバブルはテンプレートで非同期パイプで使用できます。 combineLatestはすべてのチャートを再更新するよう強制しません。カバーの下で、これは3つのコールすべての最新の値を保持します。たとえば、A1、B1、C1などです。 B1がB2に更新された場合、次の値はA1、B2、C1になります。 AとCの参照は変更されていないことに注意してください。それで、それはあなたの答えと同じです。しかし、よりエレガントにAFAIACあなたは後で定期購読をきれいにする必要はないので。 – KwintenP

+0

あなたは私がそれに気付かなかった 'async'について正しいです。しかし、すべてのグラフを一度に更新する必要があります。 async'は新しい配列を受け取り、3つの ''要素をすべて再び破壊して再作成します。しかし、あなたのソリューションは私よりもはるかに簡単です。 – martin

関連する問題