Подождать, пока рендеринг Angular дочернего компонента не будет получен и преобразован? - PullRequest
0 голосов
/ 06 мая 2020

Я пытаюсь загрузить диаграмму 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();
              }
            }
          }
        },
      }
    });



  }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...