2016-10-24 2 views
1

각도 2 및 chart.js (ngcharts를 통해)를 사용하여 차트 용 대시 보드를 만들려고합니다. 사용자 정의 간격에서 http 요청을 통해 각각 업데이트되는 차트 배열을 갖고 싶습니다.interval을 사용하여 observables의 배열을 업데이트하는 방법은 무엇입니까?

지금 당장 데이터를 배열에 푸시하는 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 나는 그것이 내가 묻고있는 것과 비슷하다고 생각한다. 각 차트는 다른 간격을두고 있으므로 각 항목을 가질 수 있기를 바란다. 어레이를 날려 보내지 않고도 변경 사항을 구독하고 업데이트하는 어레이. 배열에 구독자로 각 개체를 밀어 넣으려고했지만 작동하지 않았다. ID 배열을 검색하고 데이터를 직접 업데이트하지 않고도이 작업을 수행 할 수있는 방법이 있기를 바라고 있습니다. – Skerrvy

답변

1

때문에 자신의 id (나는 독특한 가정) 그래서 난 그냥에 getSingleChart() 방법을 변경할 것 특정 키에 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

당신이 차트의 제한된 양의가 있습니까? 항상 세 개가 있다면 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); 

이 새로운 배열을 차트 중 하나가 업데이트 될 때마다 반환합니다. 차트 2가 새로운 값을 얻으면, combineLatest의 세 번째 인수 인 함수는 이전 값 1, 새 값 2 및 이전 값 3으로 호출됩니다. 템플릿에서

당신은이를 사용할 수 있습니다 :

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

CombineLatest : 각 그래프는이 https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/combinelatest.md

+0

실제로'combineLatest()'가 콜백에서 반환 된 값이 아닌 Observable을 반환하기 때문에 이것은 이렇게 작동하지 않습니다. 또한 이것은 항상 모든 차트를 한 번에 새로 고쳐야 함을 의미합니다. – martin

+0

그것은 참으로 관찰 할 수있는 것을 돌려 줄 것입니다. 그러나 그것은 주목할만한 점입니다. 관측 대상은 비동기 파이프를 사용하여 템플릿에서 사용할 수 있습니다. 그리고 combineLatest는 모든 차트를 다시 업데이트하지 않습니다. 커버 아래에는 세 가지 호출의 최신 값이 저장됩니다. 예 : A1, B1 및 C1. B1이 B2로 업데이트하면 다음 값은 A1, B2, C1이됩니다. A 및 C 참조가 변경되지 않았 음을 확인하십시오. 따라서 귀하의 답변과 동일합니다. 하지만 더 우아하게 AFAIAC 이후에 가입을 정리할 필요가 없으므로 AFAIAC. – KwintenP

+0

당신은 내가 알아 차리지 못했던'async'에 대해 옳았습니다. 그러나, 모든 차트를 한 번에 업데이트해야합니다. 모든 변경시에'graphs | async'가 새로운 배열을 받으면 3 개의 모든 ''원소를 다시 파괴하고 다시 만듭니다. 하지만 당신의 솔루션은 제 것보다 훨씬 쉽습니다. – martin

관련 문제