从 api 获取数据后创建 Chart.js
create Chart.js after getting data from api
我在 Angular 中有两个函数:
从 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 :
public 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
});
}
我在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
await
等待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()
public async createDay(defaultChartConfig: any) {
await 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()
如果您不喜欢使用异步等待,请使用 this 工作示例。
对于任何打字错误,我们深表歉意。
得到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
});
}
我在 Angular 中有两个函数:
从 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 :
public 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
});
}
我在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
await
等待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()
public async createDay(defaultChartConfig: any) {
await 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()
如果您不喜欢使用异步等待,请使用 this 工作示例。
对于任何打字错误,我们深表歉意。
得到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
});
}