Есть ли способ использовать rxjs с ng2-диаграммами?

#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 . Я не знаю, как выглядит ваш рендеринг.