Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/376.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 从api获取数据后创建Chart.js_Javascript_Angular_Typescript_Web Services_Chart.js - Fatal编程技术网

Javascript 从api获取数据后创建Chart.js

Javascript 从api获取数据后创建Chart.js,javascript,angular,typescript,web-services,chart.js,Javascript,Angular,Typescript,Web Services,Chart.js,我有两个角度函数: 要从web服务获取一些数据并将其存储在this.apiDay和this.apiDayLabel变量中,请执行以下操作: getDayScan() { this.btcPriceService.getDailyBTCScan().subscribe(data => { data.Data.Data.forEach(price => { this.apiDay.push(price.open); this.apiDa

我有两个角度函数:

要从web服务获取一些数据并将其存储在this.apiDay和this.apiDayLabel变量中,请执行以下操作:

getDayScan() {
    this.btcPriceService.getDailyBTCScan().subscribe(data => {
      data.Data.Data.forEach(price => {
        this.apiDay.push(price.open);
        this.apiDayLabel.push(new Date(price.time * 1000).toLocaleTimeString([], {hour: '2-digit', minute: '2-digit'}));
      });
    });
}
一个是使用this.apiDay和this.apiDayLabel中的数据创建chartjs:

我在ngOnInit函数中调用这两个函数,如下所示:

ngOnInit() {
    this.getDayScan();
    this.createDay(defaultChartConfig);
}
我的问题是,图表是在我从api获得数据之前创建的

是否有办法等待数据出现,然后开始创建图表

像这样的伪代码

public createDay(defaultChartConfig: any) {

    getDayScan();

    // wait for it to finish so every necessary variable is declared
    // and only THEN go on with the other code 

    this.canvas = document.getElementById('dayChart');
    this.ctx = this.canvas.getContext('2d');

    ...

}
所以我只需要调用ngOnInit中的createDay函数

或者这种情况下的最佳实践是什么?

我建议您使用async wait等待api响应

 async getDayScan() {
        await this.btcPriceService.getDailyBTCScan().subscribe(data => {
          data.Data.Data.forEach(price => {
            this.apiDay.push(price.open);
            this.apiDayLabel.push(new Date(price.time * 1000).toLocaleTimeString([], {hour: '2-digit', minute: '2-digit'}));
          });
        });
    }
从createDay调用getDayScan

您只需要从ngOnInit调用createDay

如果您不喜欢使用AsyncWait,请使用工作示例

很抱歉输入错误。

我建议您使用async wait等待api响应

 async getDayScan() {
        await this.btcPriceService.getDailyBTCScan().subscribe(data => {
          data.Data.Data.forEach(price => {
            this.apiDay.push(price.open);
            this.apiDayLabel.push(new Date(price.time * 1000).toLocaleTimeString([], {hour: '2-digit', minute: '2-digit'}));
          });
        });
    }
从createDay调用getDayScan

您只需要从ngOnInit调用createDay

如果您不喜欢使用AsyncWait,请使用工作示例


很抱歉输入错误。

您可以在收到API的响应后填写图表数据

同时为多个调用创建一个公共函数

getJoin(URL_Array: Array<string>): Observable<any> {
    const observableBatch = [];
    URL_Array.forEach((url) => {
      observableBatch.push(this._httpClient.get<any>(`${API_URL}${url}`)
        .pipe(map(res => { return res; })));
    });
    return forkJoin(observableBatch);
};


getDayScan() {
  const urls = [
     this.btcPriceService.getDailyBTCScan1(), // API 1 URL
     this.btcPriceService.getDailyBTCScan2()  // API 2 URL
  ];
    this.btcPriceService.getJoin(urls)
     .subscribe(res => {
        // You will get array inside res with the same number of the array that you passed API. So Use for loop for res.

        for (let i = 0; i < res.length; i++) { // here will be res.length is 2 in this example
            const element = res[i];

            // Apply your logic here if you got different response in different API
            element.Data.Data.forEach(price => {
               this.apiDay.push(price.open);
               this.apiDayLabel.push(new Date(price.time * 1000)
               .toLocaleTimeString([], {hour: '2-digit', minute: '2-digit'}));
            });
        }

        // Call chart function after loop complete
        this.createDay(defaultChartConfig);            
    });
}

createDay(defaultChartConfig: any) {
   this.canvas = document.getElementById('dayChart');
   this.ctx = this.canvas.getContext('2d');

   const dataTotal = {
     // Total Shipments
     labels: this.apiDayLabel,
     datasets: [{
       label: 'Price',
       fill: true,
       backgroundColor: this.bgColorSelector(this.apiDay),
       borderColor: this.borderColorSelector(this.apiDay),
       borderWidth: 2,
       borderDash: [],
       borderDashOffset: 0.0,
       pointBackgroundColor: this.borderColorSelector(this.apiDay),
       pointBorderColor: 'rgba(255,255,255,0)',
       pointHoverBackgroundColor: this.borderColorSelector(this.apiDay),
       pointBorderWidth: 20,
       pointHoverRadius: 4,
       pointHoverBorderWidth: 15,
       pointRadius: 0,
       data: this.apiDay,
    }]
  };

  this.myChartDay = new Chart(this.ctx, {
     type: 'lineWithLine',
     data: dataTotal,
     options: defaultChartConfig
   });
}

您可以在从API获得响应后填充图表数据

同时为多个调用创建一个公共函数

getJoin(URL_Array: Array<string>): Observable<any> {
    const observableBatch = [];
    URL_Array.forEach((url) => {
      observableBatch.push(this._httpClient.get<any>(`${API_URL}${url}`)
        .pipe(map(res => { return res; })));
    });
    return forkJoin(observableBatch);
};


getDayScan() {
  const urls = [
     this.btcPriceService.getDailyBTCScan1(), // API 1 URL
     this.btcPriceService.getDailyBTCScan2()  // API 2 URL
  ];
    this.btcPriceService.getJoin(urls)
     .subscribe(res => {
        // You will get array inside res with the same number of the array that you passed API. So Use for loop for res.

        for (let i = 0; i < res.length; i++) { // here will be res.length is 2 in this example
            const element = res[i];

            // Apply your logic here if you got different response in different API
            element.Data.Data.forEach(price => {
               this.apiDay.push(price.open);
               this.apiDayLabel.push(new Date(price.time * 1000)
               .toLocaleTimeString([], {hour: '2-digit', minute: '2-digit'}));
            });
        }

        // Call chart function after loop complete
        this.createDay(defaultChartConfig);            
    });
}

createDay(defaultChartConfig: any) {
   this.canvas = document.getElementById('dayChart');
   this.ctx = this.canvas.getContext('2d');

   const dataTotal = {
     // Total Shipments
     labels: this.apiDayLabel,
     datasets: [{
       label: 'Price',
       fill: true,
       backgroundColor: this.bgColorSelector(this.apiDay),
       borderColor: this.borderColorSelector(this.apiDay),
       borderWidth: 2,
       borderDash: [],
       borderDashOffset: 0.0,
       pointBackgroundColor: this.borderColorSelector(this.apiDay),
       pointBorderColor: 'rgba(255,255,255,0)',
       pointHoverBackgroundColor: this.borderColorSelector(this.apiDay),
       pointBorderWidth: 20,
       pointHoverRadius: 4,
       pointHoverBorderWidth: 15,
       pointRadius: 0,
       data: this.apiDay,
    }]
  };

  this.myChartDay = new Chart(this.ctx, {
     type: 'lineWithLine',
     data: dataTotal,
     options: defaultChartConfig
   });
}

最佳实践是在获取数据时在回调中绘制图表,我认为这不是因为我有一个使用多个APIswave的图表,而您试图调用它。createDaydefaultChartConfig;在这个.getDayScan中;当你收到api的响应时。是的,通常这是可行的,但我有一个图表使用多个api。这意味着当我这样做时,第一个api的数据被设置,而不是第二个api的数据,我的图表是不完整的,因为我希望它位于create函数中,我可以说获取所有api数据并设置我需要的变量,然后创建此特定图表最佳做法是在获取数据时在回调中绘制图表。我认为不是因为我有一个使用多个APIswave的图表,而您尝试调用它。createDaydefaultChartConfig;在这个.getDayScan中;当你收到api的响应时。是的,通常这是可行的,但我有一个图表使用多个api。这意味着当我这样做时,第一个api的数据被设置,而不是第二个api的数据,我的图表是不完整的,因为我希望它位于create函数中,我可以说获取所有api数据并设置我需要的变量,然后创建此特定图表与以前相同的行为,使用return wait with observable不合理。你直接使用承诺来实现这个目的。与以前相同的行为使用return wait with observable是没有意义的。你直接用承诺来实现这一点。