我创建了带有自定义范围过滤器的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
答案 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>