#angular #chart.js #angular9
#angular #chart.js #angular9
Вопрос:
Вначале все работает хорошо. Эта функция вызывается, когда выбран временной диапазон (LAST_SEVEN_DAYS, LAST_THIRTY_DAYS и т. Д.). Функция вызывает серверную часть и получает результат, а затем обновляет представление
loadInstallEvolution(periodRange, label) {
this.selectedRatingRangeLabel = label;
const apkIdToUse = sessionStorage.getItem(url.apkIdInUse);
this.installChartData.datasets[0].data = [0, 0, 0, 0, 0, 0, 0];
this.installChartData.labels = [];
this.isLoading = true;
if (!apkIdToUse) {
this.isNoDataFound = true;
} else {
// tslint:disable-next-line:no-unused-expression
const param = { historyRange : periodRange, apkId : Number(apkIdToUse)};
this.searchApkControllerService.findInstallHistoryUsingGET(param).subscribe(
(reviewList) => {
let index = 0;
let max = 0;
let firstValue = 0;
for (let [key, value] of Object.entries(reviewList)) {
// change the date format
if (periodRange === 'LAST_SEVEN_DAYS' || periodRange === 'LAST_THIRTY_DAYS' ) {
key = this.datepipe.transform(key, 'MM/dd');
}
this.installChartData.datasets[0].data[index] = value;
this.installChartData.labels[index] = key;
// get first value;
if (index === 0) {
firstValue = value;
}
// calculate the max of y axis
if (max < value) {
max = value;
}
index ;
}
// update the axis
this.chartDataConfig.areaChartOptions.scales.yAxes[0].ticks.max = max 20;
this.chartDataConfig.areaChartOptions.scales.yAxes[0].ticks.beginAtZero = false;
this.isLoading = false;
},
(error) => {
this.notifications.create(
'Error',
error.error.message,
NotificationType.Error,
{ theClass: 'outline primary', timeOut: 6000, showProgressBar: false }
);
this.isLoading = false;
}
);
}
}
Поскольку у меня несколько диаграмм, вместо того, чтобы делать несколько вызовов для каждой диаграммы, я решил сделать один вызов, затем все диаграммы обновляются при появлении новых данных.
Затем я добавил
ngOnInit() {
this.sharevariableService.getApkHistoryDto().subscribe((apkHistory) => {
if(apkHistory != null) {
this.loadInstallEvolution(apkHistory);
}
});
}
тогда моя функция становится:
loadInstallEvolution(apkHistoryDto: ApkHistoryDto) {
console.log("loadInstallEvolution apps install");
const apkIdToUse = sessionStorage.getItem(url.apkIdInUse);
this.installChartData.datasets[0].data = [0, 0, 0, 0, 0, 0, 0];
this.installChartData.labels = [];
this.isLoading = true;
if (!apkIdToUse) {
this.isNoDataFound = true;
} else {
let index = 0;
let max = 0;
let firstValue = 0;
for (let [key, value] of Object.entries(apkHistoryDto.installHistory)) {
// change the date format
if (apkHistoryDto.historyRange === 'LAST_SEVEN_DAYS' || apkHistoryDto.historyRange === 'LAST_THIRTY_DAYS' ) {
key = this.datepipe.transform(key, 'MM/dd');
}
this.installChartData.datasets[0].data[index] = value;
this.installChartData.labels[index] = key;
// get first value;
if (index === 0) {
firstValue = value;
}
// calculate the max of y axis
if (max < value) {
max = value;
}
index ;
}
// update the axis
//this.installChartData.datasets[0].data = [...this.installChartData.datasets[0].data];
console.log(this.installChartData);
this.chartDataConfig.areaChartOptions.scales.yAxes[0].ticks.max = max 20;
this.chartDataConfig.areaChartOptions.scales.yAxes[0].ticks.beginAtZero = false;
this.isLoading = false;
}
}
С помощью этой новой функции моя диаграмма не обновляется. Переменные установлены правильно, но нет способа обновить представление.
в моем app-install-eveolution-chart.component.html
у меня есть:
<app-area-chart [shadow]="true" class="chart" [options]="chartDataConfig.areaChartOptions"
[data]="installChartData"></app-area-chart>
и app-area-chart
это еще один компонент
area-chart.component.html
<div [class]="class"><canvas #chart></canvas></div>
и area-chart.component.ts
export class AreaChartComponent implements AfterViewInit, OnDestroy {
@Input() shadow = false;
@Input() options;
@Input() data;
@Input() class = 'chart-container';
@ViewChild('chart', { static: true }) chartRef: ElementRef;
chart: Chart;
public constructor() {
Chart.defaults.global.defaultFontColor = 'white';
}
ngAfterViewInit() {
if (this.shadow) {
Chart.defaults.lineWithShadow = Chart.defaults.line;
Chart.controllers.lineWithShadow = Chart.controllers.line.extend({
draw(ease) {
Chart.controllers.line.prototype.draw.call(this, ease);
const chartCtx = this.chart.ctx;
chartCtx.save();
chartCtx.shadowColor = 'rgba(0,0,0,0.15)';
chartCtx.shadowBlur = 10;
chartCtx.shadowOffsetX = 0;
chartCtx.shadowOffsetY = 10;
chartCtx.responsive = true;
chartCtx.stroke();
Chart.controllers.line.prototype.draw.apply(this, arguments);
chartCtx.restore();
}
});
}
console.log("coding is awesome for brain");
const chartRefEl = this.chartRef.nativeElement;
const ctx = chartRefEl.getContext('2d');
this.chart = new Chart(ctx, {
type: this.shadow ? 'lineWithShadow' : 'line',
data: this.data,
options: this.options
});
}
ngOnDestroy() {
if (this.chart) {
this.chart.destroy();
}
}
}
Я безуспешно пробовал многие решения.
Во время тестирования с первым старым решением после каждых новых данных я могу войти внутрь ngAfterViewInit
и получить свой console.log. С новым решением у меня это только в первый раз, а не когда у меня есть обновление, ничего не происходит.
Пожалуйста, у вас есть какие-либо идеи? Любая помощь, пожалуйста? Спасибо
РЕДАКТИРОВАТЬ: я попробовал решение, используя ngOnInit
в компоненте для автоматического обнаружения изменений, но эта функция по-прежнему не вызывается.
Комментарии:
1. наконец, найдите решение. ngOnInit() { this.sharevariableService.getApkHistoryDto().subscribe((apkHistory) => { if(apkHistory != null) { this.isLoading = true; setTimeout (() => { this.loadInstallEvolution(apkHistory); }, 10); } }); } и когдазагрузка верна, я показываю счетчик вместо разрыва.
Ответ №1:
наконец, найдите решение.
ngOnInit() {
this.sharevariableService.getApkHistoryDto().subscribe((apkHistory) => {
if(apkHistory != null) {
this.isLoading = true; setTimeout (() => {
this.loadInstallEvolution(apkHistory);
}, 10); }
}); }
и когда загрузка верна, я показываю счетчик вместо разрыва.