Я пытаюсь реализовать образец отложенной загрузки HighStock в моем приложении angular -cli (https://www.highcharts.com/stock/demo/lazy-loading). Образец, когда страница загружается, делает запрос к веб-интерфейсу и получает данные для диаграммы. Это отлично работает.
Диаграмма имеет элемент управления уточнения диапазона дат, который позволяет выбрать новый диапазон данных. Это создает новый запрос к webapi. Это та часть, которую я не могу заставить работать.
Когда я выбираю новый диапазон данных, на элементе управления диаграммы запускается событие afterSetExtremes. Это событие срабатывает очень хорошо, но в конечном итоге приводит к ошибке:
core.js:9110 ERROR TypeError: this.getChartData is not a function
at I.afterSetExtremes (candlestick-and-volume.component.ts:92)
at highcharts.js:32
at a.fireEvent (highcharts.js:32)
at highcharts.js:272
at highcharts.js:273
at Array.forEach (<anonymous>)
at a.Chart.redraw (highcharts.js:273)
at I.<anonymous> (highcharts.js:162)
at a.fireEvent (highcharts.js:32)
at I.setExtremes (highcharts.js:162)
Позвольте мне провести вас от выбора нового диапазона дат до ошибки.
Вот фрагмент конфигурации диаграммы, в которой определяется событие.
xAxis: {
events: {
afterSetExtremes: this.afterSetExtremes
},
minRange: 3600 * 1000 // one hour
},
Вот функция "afterSetExtremes":
afterSetExtremes(e: { min: number; max: number }) {
console.log('Here we should load data. min: ' + e.min + ' max: ' + e.max);
this.getChartData(e.min, e.max);
}
это моя функция getChartData
getChartData(min?: number, max?: number) {
this.apiService
.getChartData({ correlationId: this.correlationId, startdateAsUnixTimeStamp: -1, enddateAsUnixTimeStamp: -1 })
.pipe(
finalize(() => {
if (this.chartData.length > 0) {
this.updateChart();
}
})
)
.subscribe(response => {
this.chartData = response.ChartData;
});
}
Это полный код моего компонента
import { StockChart } from 'angular-highcharts';
import { ApiService } from '@app/services/snakeApi/api.service';
import { ActivatedRoute } from '@angular/router';
import { finalize } from 'rxjs/operators';
import { ChartData } from '@app/model/ChartData';
import { Options } from 'highcharts/highstock';
@Component({
selector: 'app-candlestick-and-volume',
templateUrl: './candlestick-and-volume.component.html',
styleUrls: ['./candlestick-and-volume.component.scss']
})
export class CandlestickAndVolumeComponent implements OnInit {
stock: StockChart;
chartData: Array<ChartData> = new Array<ChartData>();
sub: any;
correlationId: string;
chartOptions: Options;
candleStickDataArray: any = [];
volumeDataArray: any = [];
indicatorUpperDataArray: any = [];
indicatorLowerDataArray: any = [];
constructor(private apiService: ApiService, private activateRoute: ActivatedRoute) {
this.sub = this.activateRoute.params.subscribe(params => {
this.correlationId = params.correlationId;
this.getChartData();
});
}
getChartData(min?: number, max?: number) {
this.apiService
.getChartData({ correlationId: this.correlationId, startdateAsUnixTimeStamp: -1, enddateAsUnixTimeStamp: -1 })
.pipe(
finalize(() => {
if (this.chartData.length > 0) {
this.updateChart();
}
})
)
.subscribe(response => {
this.chartData = response.ChartData;
});
}
updateChart() {
const dataLength = this.chartData.length;
// set the allowed units for data grouping
let groupingUnits = [],
i = 0;
for (i; i < dataLength; i += 1) {
this.candleStickDataArray.push([
this.chartData[i].Date, // the date
this.chartData[i].Open, // open
this.chartData[i].High, // high
this.chartData[i].Low, // low
this.chartData[i].Close // close
]);
this.volumeDataArray.push([
this.chartData[i].Date, // the date
this.chartData[i].Volume // the volume
]);
this.indicatorUpperDataArray.push([
this.chartData[i].Date, // the date
this.chartData[i].IndicatorUpper // the upper indicator
]);
this.indicatorLowerDataArray.push([
this.chartData[i].Date, // the date
this.chartData[i].IndicatorLower // the lower indicator
]);
}
// Add a null value for the end date
var endDate = this.chartData[dataLength - 1].Date;
this.chartData = [].concat(this.chartData, [[endDate, null, null, null, null]]);
console.log('EndData: ' + endDate);
this.stock = new StockChart(this.chartOptions);
}
afterSetExtremes(e: { min: number; max: number }) {
console.log('Here we should load data. min: ' + e.min + ' max: ' + e.max);
this.getChartData(e.min, e.max);
}
ngOnInit() {
this.chartOptions = {
rangeSelector: {
buttons: [
{
type: 'hour',
count: 1,
text: '1h'
},
{
type: 'day',
count: 1,
text: '1d'
},
{
type: 'week',
count: 1,
text: '1w'
},
{
type: 'month',
count: 1,
text: '1m'
},
{
type: 'year',
count: 1,
text: '1y'
},
{
type: 'all',
text: 'All'
}
],
inputEnabled: false, // it supports only days
selected: 0 // all
},
title: {
text: 'AAPL Historical'
},
navigator: {
adaptToUpdatedData: false,
series: {
data: this.chartData
}
},
scrollbar: {
liveRedraw: false
},
xAxis: {
events: {
afterSetExtremes: this.afterSetExtremes
},
minRange: 3600 * 1000 // one hour
},
yAxis: [
{
labels: {
align: 'right',
x: -3
},
title: {
text: 'OHLC'
},
height: '80%',
lineWidth: 1,
resize: {
enabled: true
}
},
{
labels: {
align: 'right',
x: -3
},
title: {
text: 'Volume'
},
top: '90%',
height: '10%',
offset: 0,
lineWidth: 1
}
],
series: [
{
type: 'candlestick',
zoomType: 'x',
name: 'AAPL',
id: 'aapl',
data: this.candleStickDataArray,
dataGrouping: {
enabled: false
}
},
{
type: 'column',
zoomType: 'x',
name: 'Volume',
data: this.volumeDataArray,
yAxis: 1,
dataGrouping: {
enabled: false
}
},
{
type: 'spline',
zoomType: 'x',
name: 'indicatorUpper',
id: 'indicatorUpper',
data: this.indicatorUpperDataArray,
dataGrouping: {
enabled: false
}
},
{
type: 'spline',
zoomType: 'x',
name: 'indicatorLower',
id: 'indicatorLower',
data: this.indicatorLowerDataArray,
dataGrouping: {
enabled: false
}
}
]
};
}
}