#javascript #angular #rxjs #rxjs5 #ng2-charts
#javascript #angular #rxjs #rxjs5 #ng2-диаграммы
Вопрос:
Я не могу найти способ реализовать графики в реальном времени с помощью ng2-charts.
Я получаю сообщение об ошибке, когда я делаю :
<div *ngIf="(lineChartData$ | async)!=null">
....
<canvas baseChart width="100" height="200"
[datasets]="lineChartData$ | async" <<-ERROR: "Cannot read property 'data' of undefined"
....
</canvas>
</div>
Я думаю, что даже если бы я каким-то образом заставил это работать, это был бы худший способ сделать это.
Пожалуйста, порекомендуйте любые другие возможности, которые имеют встроенные графики в реальном времени, если нет решения для этой ошибки.
Редактировать:
app.component.html:
<div *ngIf="(lineChartData$ | async)!=null">
<div class="row">
<div class="col-md-6">
<div style="display: block;">
<canvas baseChart width="100" height="200"
[datasets]="lineChartData$ | async" <<<-- ERROR
[labels]="lineChartLabels"
[options]="lineChartOptions"
[colors]="lineChartColors"
[legend]="lineChartLegend"
[chartType]="lineChartType"
(chartHover)="chartHovered($event)"
(chartClick)="chartClicked($event)"></canvas>
</div>
</div>
<div class="col-md-6" style="margin-bottom: 10px">
<table class="table table-responsive table-condensed">
<tr>
<th *ngFor="let label of lineChartLabels"></th>
</tr>
<tr *ngFor="let d of lineChartData">
<td *ngFor="let label of lineChartLabels; let j=index"></td>
</tr>
</table>
</div>
</div>
</div>
app.component.ts:
import {Component, OnInit} from '@angular/core';
import {Observable} from "rxjs";
import {Store} from "@ngrx/store";
import {AppState} from "../../redux/design/app-state";
import {AngularFire, AuthProviders, FirebaseObjectObservable} from "angularfire2";
import 'rxjs/add/operator/withLatestFrom';
import {AuthActions} from "../../redux/actions/auth.actions";
import {UserService} from "../../services/user.service";
@Component({
selector: 'app-root',
templateUrl: 'app.component.html'
})
export class AppComponent implements OnInit
{
private lineChartData$:Observable<Array<any>>;
constructor(private authActions: AuthActions,
private af: AngularFire,
private userService:UserService,
private store:Store<AppState>){}
public ngOnInit(): void {
this.lineChartData$=Observable.interval(500)
.map(index=>[{data: [65, 59, index, 81, 56, 55, 40], label: 'Series A'},
{data: [28, 48, 40, 19, 86, 27, 90], label: 'Series B'},
{data: [18, 48, 77, 9, 100, 27, 40], label: 'Series C'}
]);
}
// lineChart
public lineChartLabels:Array<any> = ['January', 'February', 'March', 'April', 'May', 'June', 'July'];
public lineChartOptions:any = {
animation: false,
responsive: true,
maintainAspectRatio: false
};
public lineChartColors:Array<any> = [
{ // grey
backgroundColor: 'rgba(148,159,177,0.2)',
borderColor: 'rgba(148,159,177,1)',
pointBackgroundColor: 'rgba(148,159,177,1)',
pointBorderColor: '#fff',
pointHoverBackgroundColor: '#fff',
pointHoverBorderColor: 'rgba(148,159,177,0.8)'
},
{ // dark grey
backgroundColor: 'rgba(77,83,96,0.2)',
borderColor: 'rgba(77,83,96,1)',
pointBackgroundColor: 'rgba(77,83,96,1)',
pointBorderColor: '#fff',
pointHoverBackgroundColor: '#fff',
pointHoverBorderColor: 'rgba(77,83,96,1)'
},
{ // grey
backgroundColor: 'rgba(148,159,177,0.2)',
borderColor: 'rgba(148,159,177,1)',
pointBackgroundColor: 'rgba(148,159,177,1)',
pointBorderColor: '#fff',
pointHoverBackgroundColor: '#fff',
pointHoverBorderColor: 'rgba(148,159,177,0.8)'
}
];
public lineChartLegend:boolean = true;
public lineChartType:string = 'line';
// events
public chartClicked(e:any):void {
console.log(e);
}
public chartHovered(e:any):void {
console.log(e);
}
}
Комментарии:
1. Что
lineChartData$
?2. Привет @Martin , я добавил код класса. Спасибо
3. Добавьте
[data]="{}"
в свой холст, и это сработает
Ответ №1:
Я мало что знаю о ng2-charts
но ошибка предполагает, что проблема где-то в другом месте.
В документе ngOnInit
говорится:
Инициализируйте директиву / компонент после того, как Angular впервые отобразит свойства, связанные с данными, и установит входные свойства директивы / компонента.
Итак, это событие жизненного цикла вызывается после инициализации представления. Ваш lineChartData$
определяется как:
private lineChartData$:Observable<Array<any>>;
… и он не инициализируется до ngOnInit()
вызова. Итак, представление пытается выполнить привязку, lineChartData$
которая все еще undefined
выполняется в то время. Таким образом, сообщение об ошибке, вероятно, выдано из ng2-charts
внутренних компонентов.
Комментарии:
1. Хорошо, я перенес инициализацию в конструктор, и он работает нормально. Но я думаю,
<div *ngIf="(lineChartData$ | async)!=null">
не следует ничего создавать, пока lineChartData не получит что-либо в первый раз. рендеринг выглядит очень плохо. Есть ли способ сделать это лучше?2. Я не знаю, что
async
делает pipe при соединении сundefined
. Возможно, он возвращает,undefined
что не равноnull
. Я не знаю, как выглядит ваш рендеринг.