angular - API'den alınan verilerle ngx-charts başlatılamıyor


API'den alınan verilerle oluşturulmuş bir grafiği ngx-charts kullanarak başlatmaya çalışırken bazı kötü zamanlar yaşıyorum.

Doğru bir çağrı yapıldığında bazı zaman serisi verilerini dışarı veren bir REST API oluşturdum.

{
    "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
            ]
        }
    ]
}

Ve bunu doğru şekilde ele almak için price.model.ts dosyasını oluşturdum ve gayet iyi çalışıyor

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;
     }
}

Sonra, böyle bir API çağrısı yapmak, veriyi almak, analiz etmek ve grafiğe render etmek için details.component.ts dosyamı ayarladım.

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();
  }

}

Benim ChartDataModel.ts olarak tanımlandığı yer

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;
    }
}

Ve son olarak, işte benim details.page.html'im

<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>

Object.assign işleminden önce this.ngxData.data kaydı almak her şeyi sorunsuz bir şekilde yazdırıyor

Ama sonunda şu sonucu elde ediyorum

Burada mevcut olan örneği takip ettim ama aslında hiçbir veri görüntülenmedi.

Veriler kütüphanenin istediği şekilde biçimlendirilmiş olmasına rağmen neden verilerin gösterilmediğini anlamıyorum.

Ben neyi yanlış yapıyorum? Bu, yapıcıda yanlış bir başlatmadan mı kaynaklanıyor?

Cevap #1

Sorununuz, ngxData.data[x]series.push() ile serileri değiştirmeye çalıştığınızda bunun değişiklik algılama tarafından tanınmaması ile ilgilidir.

ngxData.data yeniden atanması tespit edilmelidir: 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);
    });
  }

Bir plunker eklemeyi başardım https://plnkr.co/edit/JSTcS4FnJ5dshAldLWPL?p=preview

Cevap #2

BENİM KULLANIM DURUMUM İÇİN ....

önce iki dizi başlatmanız gerekir

O zaman servisinizi çağırmanız gerekiyor ve her yinelemede, saleData dizisine bir nesne ekleyeceğiz

customers: Customer[] = [];
  saleData: any = [];
    ngOnInit(): void {
        this.customerService.getTop10Customers().subscribe(data => {
          this.customers = data._embedded.customers
          console.log(this.customers)
          let sales:any = [];
           this.customers.forEach(c =>{
             sales.push({name: c.designation,value: c.totalMoneySpent})
           })
          // clone the sales array to saleData 
          this.saleData = [...sales]
          console.log(this.saleData)
    
        })
      }

Ve işte sonuç:

İlgili makaleler