Я пытаюсь загрузить диаграмму js в компонент angular. Однако диаграмма (в дочернем компоненте) визуализируется до возврата данных из API и преобразуется, и я предполагаю, что именно поэтому я вижу, что оси и легенды рисуются правильно, но линий / данных нет. Как лучше всего сказать компоненту диаграммы, чтобы он дождался полного возврата и преобразования данных перед визуализацией чего-либо?
Я использую вызов API в методе getTelemetry, а затем использую loda sh метод его преобразования. Только ТОГДА я хочу, чтобы компонент графика отображался. Мне нужен какой-то прослушиватель событий или подписка для запуска переменной data_ready, но я не могу понять это правильно. Благодарим за любую идею! Вот часть моего кода. Пожалуйста, дайте мне знать, если я могу предоставить дополнительную информацию.
Вот как выглядит мой родительский компонент (незначительные части удалены для ясности):
@Component({
selector: 'app-monitoring-point',
templateUrl: './monitoring-point.component.html',
styleUrls: ['./monitoring-point.component.css']
})
export class MonitoringPointComponent extends BaseComponent implements OnInit, AfterViewInit {
telemetries;
data_ready: Boolean = false;
water_temp_data;
monitoringPointId;
constructor(
super()
}
ngOnInit() {
this.route.paramMap.subscribe(params => {
this.monitoringPointId = params.get("deviceHid")
})
this.getTelemetry()
}
private getTelemetry() {
this.telemetryService.getMeasurementDataRaw(this.monitoringPointId, localStorage.authToken, this.filterModel.fromDate, this.filterModel.toDate).subscribe(
data =>
if (data.length>0) {
var dataToMap = data.telemetries
this.water_temp_data = _.map(dataToMap, function (item, index) {
return { x: dataToMap[index].waterTemperatureFahr, y: dataToMap[index].adjustedTimestampUtc };
});
this.data_ready=true
}
else {
this.data_ready = false
this.no_data = true
}
})
}
}
Вот что за шаблон html похоже, где я называю свой компонент диаграммы:
<app-mp-chart *ngIf="data_ready==true "[water_temp_data]="water_temp_data" ></app-mp-chart>
//the *ngIf is intended to only display the component when the water temp data has been collected and transformed
Компонент графика mp-chart
<div class="chart" >
<canvas id="chartWaterTemp" class="myChart"></canvas>
</div>
диаграмма. js код
import { Component, ViewChildren, ElementRef, QueryList, OnInit, Input, ViewChild, AfterViewInit } from '@angular/core';
import { Chart, Tooltip } from 'chart.js';
import 'chartjs-plugin-zoom'
@Component({
selector: 'app-mp-chart',
templateUrl: './mp-chart.component.html',
styleUrls: ['./mp-chart.component.css']
})
export class MpChartComponent implements OnInit {
@Input() water_temp_data;
constructor(
) {}
ngOnInit() {
// console.log("TEMP", this.water_temp_data)
//^ this actually logs the data! Which is confusing. but it doesnt make it into the actual graph
var leftEnd ;
var rightEnd;
//updates the dimensions of each chart once one of them is zoomed in on/panned
function updateChart() {
Chart.helpers.each(Chart.instances, function (instance) {
instance.options.scales.xAxes[0].ticks.min = leftEnd;
instance.options.scales.xAxes[0].ticks.max = rightEnd;
// console.log(leftEnd, rightEnd)
instance.update();
});
}
function getOtherDatasets() {
var instances = []
Chart.helpers.each(Chart.instances, function (instance, data) {
instances.push(instance)
});
return instances
}
var ctxWaterTemp = document.getElementById("chartWaterTemp")
var myChartC = new Chart(<any>ctxWaterTemp, {
type: 'line',
data: {
datasets: [{
label: 'Water Temp',
data: this.water_temp_data,
borderColor: 'green',
showLine: true,
fill: false,
}]
},
options: {
tooltips: {
// Disable the on-canvas tooltip
enabled: false,
callbacks: {
label: function (tooltipItem, data) {
//reach out to outside function to get data from other charts/datasets
var charts = getOtherDatasets()
var index = tooltipItem.index;
var items = []
charts.forEach(element => {
var label;
var unit;
if (element.id == 0) { label = "Precipitation: ", unit = " in." }
if (element.id == 1) { label = "Water Temperature: ", unit = " °F" }
if (element.id == 2) { label = "Flow: ", unit = " cfs" }
if (element.id == 3) { label = "Depth: ", unit = " in." }
//grab the element in each dataset at the same index, add label from appropriate dataset, plus units
items.push(label + element.config.data.datasets[0].data[index].y + unit)
})
return items;
},
},
custom: function (tooltipModel) {
// Tooltip Element
var tooltipEl = document.getElementById('chartjs-tooltip');
// Create element on first render
if (!tooltipEl) {
tooltipEl = document.createElement('div');
tooltipEl.id = 'chartjs-tooltip';
tooltipEl.innerHTML = '<table></table>';
document.body.appendChild(tooltipEl);
}
// Hide if no tooltip
if (tooltipModel.opacity === 0) {
tooltipEl.style.opacity = "0";
return;
}
// Set caret Position
tooltipEl.classList.remove('above', 'below', 'no-transform');
if (tooltipModel.yAlign) {
tooltipEl.classList.add(tooltipModel.yAlign);
} else {
tooltipEl.classList.add('no-transform');
}
function getBody(bodyItem) {
return bodyItem.lines;
}
// Set Text
if (tooltipModel.body) {
var titleLines = tooltipModel.title || [];
var bodyLines = tooltipModel.body.map(getBody);
var innerHtml = '<thead>';
titleLines.forEach(function (title) {
innerHtml += '<tr><th>' + title + '</th></tr>';
});
innerHtml += '</thead><tbody>';
//if there are multiple datasets, only plot the tooltip labels from the first, because they will be the same
bodyLines = bodyLines[0]
bodyLines.forEach(function (body, i) {
var colors = tooltipModel.labelColors[i];
var style = 'background:' + "black";
style += '; border-color:' + "black";
style += '; border-width: 2px';
var span = '<span style="' + style + '"></span>';
innerHtml += '<tr><td>' + span + body + '</td></tr>';
});
innerHtml += '</tbody>';
var tableRoot = tooltipEl.querySelector('table');
tableRoot.innerHTML = innerHtml;
}
// `this` will be the overall tooltip
var position = this._chart.canvas.getBoundingClientRect();
// Display, position, and set styles for font
tooltipEl.style.opacity = "1";
tooltipEl.style.position = 'absolute';
tooltipEl.style.backgroundColor = '#fff';
tooltipEl.style.left = position.left + window.pageXOffset + tooltipModel.caretX + 'px';
tooltipEl.style.top = position.top + window.pageYOffset + tooltipModel.caretY + 'px';
tooltipEl.style.fontFamily = tooltipModel._bodyFontFamily;
tooltipEl.style.fontSize = '16px';
tooltipEl.style.fontStyle = tooltipModel._bodyFontStyle;
tooltipEl.style.padding = tooltipModel.yPadding + 'px ' + tooltipModel.xPadding + 'px';
tooltipEl.style.pointerEvents = 'none';
}
},
animation: {
duration: 0
},
responsive: true,
aspectRatio: 12,
legend: {
display: true,
position: 'right'
},
scales: {
xAxes: [{
type: 'time',
min: leftEnd,
max: rightEnd,
ticks: {
display: false
},
gridLines: {
display: false
},
}],
yAxes: [{
ticks: {
maxTicksLimit: 6,
beginAtZero: false,
suggestedMin: this.tempYScale[0],
suggestedMax: this.tempYScale[1]
}
}]
},
plugins: {
zoom: {
pan: {
enabled: true,
mode: 'x',
onPan: function () {
leftEnd = myChartC.getDatasetMeta(0).dataset._scale.chart.scales['x-axis-0']._table[0].time;
rightEnd = myChartC.getDatasetMeta(0).dataset._scale.chart.scales['x-axis-0']._table[1].time;
updateChart();
}
},
zoom: {
enabled: true,
mode: 'x',
onZoom: function () {
leftEnd = myChartC.getDatasetMeta(0).dataset._scale.chart.scales['x-axis-0']._table[0].time;
rightEnd = myChartC.getDatasetMeta(0).dataset._scale.chart.scales['x-axis-0']._table[1].time;
updateChart();
}
}
}
},
}
});
}
}