我正在尝试使用angular 2和chart.js(通过ngcharts)为图表构建仪表板。我想要一个图表数组,每个图表都通过自定义间隔的http请求进行更新。
现在我有三个单独的图表调用将数据推送到数组。我在下一次迭代时遇到了麻烦 - 如果我再次推送到阵列,我最终会再增加3个图表。我希望数组中的订阅者在间隔发出时使用新数据进行更新。
我对如何正确构建我的用例的组件/服务/ http关系感到困惑。我觉得我很亲密,但我肯定错过了一些东西。如何让间隔/订户关系映射到视图并在一定时间间隔内更新现有图表? 任何帮助都会很棒!
现在:
服务
我在这里实施间隔:
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)
);
}
}
extractJsonData只是接受响应并操纵它以使用图表JS。它返回一个Graph对象,该对象具有易于使用的属性。我无法控制API,因此我无法重新配置响应以包含多个图表。
组件:
<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>
观点:
contact_id | phone_number
1 | 55551002
1 | 55551003
1 | 55551000
2 | 55552001
2 | 55552008
2 | 55552003
2 | 55552007
3 | 55553001
3 | 55553002
3 | 55553009
3 | 55553004
4 | 55554000
答案 0 :(得分: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获得一个新值,则将使用旧值1,新值2和旧值3调用函数(combineLatest的第三个参数)。
在你的模板中你可以使用它:
<div *ngFor="let graph of graphs | async" ...>
CombineLatest:https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/combinelatest.md
答案 1 :(得分: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>