简体   繁体   English

Angular - Higchart 不等待 ngOnInit

[英]Angular - Higchart doesn´t wait to ngOnInit

I created a Highchart with custom range filter.我创建了一个带有自定义范围过滤器的 Highchart。 The chart data is loaded from a web service.图表数据是从 Web 服务加载的。 I call this service from ngOnInit method.我从 ngOnInit 方法调用此服务。 Like this像这样

TS TS

import { Component, OnInit } from "@angular/core";
import * as Highcharts from "highcharts/highstock";
import { HttpClient } from "@angular/common/http";
import * as moment from "moment";
declare var require: any;
require("highcharts/highcharts-more")(Highcharts);
require("highcharts/modules/exporting")(Highcharts);
require("highcharts/modules/export-data")(Highcharts);

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html"
})
export class AppComponent implements OnInit {
  seriesOptions: any = [];
  ranges: any;
  pickerlang: any;
  seriesCounter = 0;
  names = ["MSFT", "AAPL"];
  selected: any;
  chart: any;
  updateFromInput = false;
  Highcharts = Highcharts;
  chartConstructor = "stockChart";
  chartCallback: any;
  chartOptions: any;
  constructor(private http: HttpClient) {
    const self = this;

    this.chartCallback = chart => {
      self.chart = chart;
    };
  }

  ngOnInit() {
    moment.locale("es");
    this.names.forEach((element, i) => {
      this.http
        .get(
          "https://www.highcharts.com/samples/data/" +
            element.toLowerCase() +
            "-c.json"
        )
        .forEach((data: any) => {
          this.seriesOptions[i] = {
            name: element,
            data: data
          };
          this.seriesCounter += 1;
          if (this.seriesCounter === this.names.length) {
            this.createGraph();
          }
        });
    });

    this.ranges = {
      Hoy: [moment(), moment()],
      Ayer: [moment().subtract(1, "days"), moment().subtract(1, "days")],
      "Últimos 7 días": [moment().subtract(6, "days"), moment()],
      "Últimos 30 días": [moment().subtract(29, "days"), moment()],
      "Este mes": [moment().startOf("month"), moment().endOf("month")],
      "Mes pasado": [
        moment()
          .subtract(1, "month")
          .startOf("month"),
        moment()
          .subtract(1, "month")
          .endOf("month")
      ]
    };

    this.pickerlang = {
      format: "DD/MM/YYYY",
      direction: "ltr",
      weekLabel: "W",
      cancelLabel: "Cancelar",
      applyLabel: "Aceptar",
      clearLabel: "",
      daysOfWeek: moment.weekdaysMin(),
      monthNames: moment.monthsShort(),
      customRangeLabel: "Seleccionar fecha",
      firstDay: 1
    };
  }
  createGraph() {
    this.chartOptions = {
      lang: {
        loading: "Cargando...",
        months: [
          "Enero",
          "Febrero",
          "Marzo",
          "Abril",
          "Mayo",
          "Junio",
          "Julio",
          "Agosto",
          "Septiembre",
          "Octubre",
          "Noviembre",
          "Diciembre"
        ],
        weekdays: [
          "Domingo",
          "Lunes",
          "Martes",
          "Miércoles",
          "Jueves",
          "Viernes",
          "Sábado"
        ],
        shortMonths: [
          "Ene",
          "Feb",
          "Mar",
          "Abr",
          "May",
          "Jun",
          "Jul",
          "Ago",
          "Sep",
          "Oct",
          "Nov",
          "Dic"
        ],
        rangeSelectorFrom: "Desde",
        rangeSelectorTo: "Hasta",
        rangeSelectorZoom: "Período",
        downloadPNG: "Descargar imagen PNG",
        downloadJPEG: "Descargar imagen JPEG",
        downloadPDF: "Descargar imagen PDF",
        downloadSVG: "Descargar imagen SVG",
        downloadCSV: "Descargar imagen CSV",
        downloadXLS: "Descargar imagen XLS",
        printChart: "Imprimir",
        resetZoom: "Reiniciar zoom",
        resetZoomTitle: "Reiniciar zoom",
        viewData: "Ver tabla",
        openInCloud: "Ver en web",
        thousandsSep: ",",
        decimalPoint: "."
      },
      xAxis: {
        crosshair: {
          width: 1,
          color: "red"
        }
      },
      rangeSelector: {
        enabled: false
      },

      chart: {
        zoomType: "x",
        panning: true,
        panKey: "shift"
      },
      exporting: {
        enabled: true
      },

      plotOptions: {
        series: {
          showInNavigator: true
        }
      },
      tooltip: {
        pointFormat:
          '<span style="color:{series.color}">{series.name}</span>: <b>{point.y} litros</b><br/>',
        valueDecimals: 2,
        split: true
      },
      series: this.seriesOptions
    };
  }

  setExtremes() {
    const self = this,
      chart = self.chart;

    chart.showLoading();
    setTimeout(() => {
      chart.hideLoading();

      chart.xAxis[0].setExtremes(
        new Date(
          this.selected["startDate"].toJSON().substring(0, 10)
        ).getTime(),
        new Date(this.selected["startDate"].toJSON().substring(0, 10)).getTime()
      );
      self.updateFromInput = true;
    }, 1000);
  }
}

HTML HTML

 <div class="card">
    <div class="card-body">
      <input type="text" ngxDaterangepickerMd [locale]="pickerlang" [(ngModel)]="selected" class="form-control"
        placeholder="Rango de fecha" class="form-control" [ranges]="ranges" [showCustomRangeLabel]="true"
        [alwaysShowCalendars]="true" />
      <highcharts-chart id="container" [Highcharts]="Highcharts" [constructorType]="chartConstructor"
        [options]="chartOptions" [callbackFunction]="chartCallback" [(update)]="updateFromInput" [oneToOne]="true">
      </highcharts-chart>
      <button (click)=" setExtremes()" class="btn btn-primary">Buscar </button>
    </div>
  </div>

Chart is trying to load data before is start ngOninit, so return in console.log Chart 正在尝试在启动 ngOninit 之前加载数据,因此在 console.log 中返回

Cannot read property 'series' of undefined无法读取未定义的属性“系列”

Anyway all works, chart has data and filter is fine, but i want chart wait to ngOnit to show data to avoid show this error in console.无论如何一切正常,图表有数据并且过滤器很好,但我希望图表等待 ngOnit 显示数据以避免在控制台中显示此错误。

So the question is: How can i force highchart to wait to ngOnInit?所以问题是:如何强制 highchart 等待 ngOnInit?

SOLUTION解决方案

Full solution code: https://github.com/ElHombreSinNombre/angular-highcharts完整解决方案代码: https : //github.com/ElHombreSinNombre/angular-highcharts

This by trying to create a chart with undefined options.这是通过尝试创建带有未定义选项的图表来实现的。 If the options will be loaded dynamically later then you could use an empty object or add the chart component when the data will be loaded.如果稍后将动态加载选项,那么您可以使用空对象或在加载数据时添加图表组件。

Refer the issue for more details.有关更多详细信息,请参阅issue

I am just guessing that Highcharts is the one that has series property.我只是猜测 Highcharts 是具有系列属性的那个。

<highcharts-chart id="container" [Highcharts]="Highcharts ? Highcharts : []" [constructorType]="chartConstructor"
        [options]="chartOptions" [callbackFunction]="chartCallback" [(update)]="updateFromInput" [oneToOne]="true">
</highcharts-chart>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM