Angular-Higchart等不及ngOnInit

时间:2019-06-22 20:50:07

标签: javascript angular highcharts

我创建了带有自定义范围过滤器的Highchart。图表数据是从Web服务加载的。我从ngOnInit方法调用此服务。像这样

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

 <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>

图表尝试在启动ngOninit之前加载数据,因此请在console.log中返回

  

无法读取未定义的属性“系列”

无论如何,图表都具有数据并且过滤器很好,但是我希望图表等待ngOnit显示数据,以避免在控制台中显示此错误。

所以问题是:如何强制highchart等待ngOnInit?

解决方案

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

2 个答案:

答案 0 :(得分:0)

通过尝试使用未定义的选项创建图表。如果选项将在以后动态加载,则可以使用一个空对象或在加载数据时添加图表组件。

有关更多详细信息,请参考 issue

答案 1 :(得分:-1)

我只是猜猜Highcharts是具有系列属性的那个。

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