I'm having some bad times while trying to initialize a chart built using ngx-charts with API fetched data.
I built a rest api that, upon a proper call, spits out some time-series data.
{
"prices": [
{
"item": "1",
"price": 2,
"estimated": 2.1,
"date": [
2012,
8,
16
]
},
{
"item": "1",
"price": 3,
"estimated": 4.1,
"date": [
2012,
9,
16
]
},
{
"item": "1",
"price": 5,
"estimated": 7.1,
"date": [
2012,
10,
16
]
}
]
}
And I built price.model.ts to correctly handle it, and it works just fine
export class PriceModel {
public id: string;
public price: number;
public estimated: number;
public date: number[];
constructor(
id: string,
price: number,
estimated: number,
date: number[]
) {
this.id = id;
this.price = price;
this.estimated = estimated;
this.date = date;
}
}
Then, I set up my details.component.ts in order to perform such api call, get the data, parse it and render it into the chart.
import { Component } from '@angular/core';
import { NgxChartsModule } from '@swimlane/ngx-charts';
import { Http } from '@angular/http';
/** App Models **/
import { PriceModel } from '../../shared/components/prices/price.model';
import { ChartDataModel } from '../../shared/components/prices/chart-data.model';
@Component({
selector: 'app-details',
templateUrl: './details.page.html',
providers: [NgxChartsModule]
})
export class DetailsPage {
private sub: any;
private prices: PriceModel[];
ngxData: ChartDataModel = {
data: [
{
name: 'prices',
series: []
},
{
name: 'forecast',
series: []
}
]
};
view: any[] = [1000, 750];
// options
showXAxis = true;
showYAxis = true;
gradient = false;
showLegend = true;
showXAxisLabel = true;
xAxisLabel = 'Dates';
showYAxisLabel = true;
yAxisLabel = 'Prices';
colorScheme = {
domain: ['#5AA454', '#A10A28', '#C7B42C', '#AAAAAA']
};
// line, area
autoScale = true;
constructor(private _http: Http) {
console.log(this.ngxData.data);
Object.assign(this.ngxData);
}
ngOnInit() {
this.sub = this._http.get('someroute').subscribe((prices) => {
this.prices = prices.json().prices;
let currData;
this.prices.map((p) => {
currData = new Date(p.date[0], p.date[1], p.date[2]);
this.ngxData.data[0].series.push({ name: currData.getTime().toString(), value: p.price });
this.ngxData.data[1].series.push({ name: currData.getTime().toString(), value: p.estimated });
});
}, (err) => {
console.log(err);
});
}
ngOnDestroy() {
this.sub.unsubscribe();
}
}
Where my ChartDataModel.ts is defined as
export class ChartDataModel {
public data: SerieModel[];
constructor(data: SerieModel[]) {
this.data = data;
}
}
export class SerieModel {
public name: string;
public series: SeriersChildModel[];
constructor(name: string, series: SeriersChildModel[]) {
this.name = name;
this.series = series;
}
}
export class SeriersChildModel {
public name: string;
public value: number;
constructor(name: string, value: number) {
this.name = name;
this.value = value;
}
}
And, finally, here's my details.page.html
<ngx-charts-line-chart
[view]="view"
[scheme]="colorScheme"
[results]="ngxData.data"
[gradient]="gradient"
[xAxis]="showXAxis"
[yAxis]="showYAxis"
[legend]="showLegend"
[showXAxisLabel]="showXAxisLabel"
[showYAxisLabel]="showYAxisLabel"
[xAxisLabel]="xAxisLabel"
[yAxisLabel]="yAxisLabel"
[autoScale]="autoScale">
</ngx-charts-line-chart>
Logging this.ngxData.data
before Object.assign
prints everything just fine
But I end up having the following result
I followed the example available here but ended up with no data actually displaying.
I don't understand why, even though data is formatted as the library wants, data isn't shown.
What Am I doing wrong? Is it caused by a wrong initialization in the constructor?
Your issue is about modifying series by ngxData.data[x]series.push()
is not recognizing by change detection.
Reassigning ngxData.data
should be detected : this.ngxData.data = [...this.ngxData.data]
ngOnInit() {
this.sub = this._http.get('someroute').subscribe((prices) => {
this.prices = prices.json().prices;
let currData;
this.prices.map((p) => {
currData = new Date(p.date[0], p.date[1], p.date[2]);
this.ngxData.data[0].series.push({ name: currData.getTime().toString(), value: p.price });
this.ngxData.data[1].series.push({ name: currData.getTime().toString(), value: p.estimated })
});
//your solution
this.ngxData.data = [...this.ngxData.data];
}, (err) => {
console.log(err);
});
}
I managed to add a plunker https://plnkr.co/edit/JSTcS4FnJ5dshAldLWPL?p=preview