in web/frontend/src/app/pages/streams/components/deltix-charts/charts/deltix-charts.component.ts [786:965]
private initChart(TAB: TabModel, streamRangeStart: number, colors: StoredColorsMap, showLines: string[]) {
this.hideTooltip();
const fromTime = new Date(TAB.filter.from).getTime();
const minTime = Math.min(streamRangeStart, fromTime);
const chartConfig = {
pads: this.getPads(TAB.filter.chart_type, colors, showLines),
maxBucketSize: 1000,
initialTime: [new Date(TAB.filter.from).getTime(), new Date(TAB.filter.to).getTime()] as [
number,
number,
],
minTime,
animationDuration: 0,
disableBackButton: true,
formatFunctions: {
xCrosshair: (tick) => {
const formatted_date_string = formatDateTime(
tick,
this.format,
this.filter_timezone.name,
);
return formatted_date_string + ' ';
},
xAxis: (tick: number, interval: number): string => {
if (!tick) {
return '';
}
let format = 'ss.fff';
if (interval >= 1000) {
format = 'HH:mm:ss';
}
if (interval >= 60 * 1000) {
format = 'HH:mm';
}
if (interval >= 60 * 60 * 1000) {
format = 'dd/MM HH';
}
if (interval >= 24 * 60 * 60 * 1000) {
format = 'dd/MM';
}
return formatDateTime(tick, format, this.filter_timezone.name);
},
yAxis: (numberToFormat: string, an): IFormattedNumber => {
const decimals = this.everChartFeedService.maxDecimals$.getValue();
const split = parseFloat(numberToFormat.toString())
.toFixed(decimals || 1)
.toString()
.split('.');
return {
integerPart: split[0],
fractionalPart: split[1],
decimalSeparator: '.',
};
},
},
};
this.everChartFeedService.runChart();
const {width, height} = this.getSize();
this.appFacade
.createApp(
'everChart',
'1',
{
height,
width,
x: 0,
y: 0,
},
chartConfig,
)
.pipe(
// @ts-ignore
catchError((e) => {
console.log(e);
return of();
}),
takeUntil(this.chartDestroy$),
)
.subscribe((value) => {
if (value === 'initialized') {
this.hideTooltip$.next(false);
this.resize$.next(this.getSize());
this.resizeObserveService
.observe(this.container.nativeElement)
.pipe(takeUntil(this.chartDestroy$))
.subscribe(() => {
this.resize$.next(this.getSize());
});
const borders$ = this.appStore.pipe(
select(getActiveTabFilters),
filter((f) => !!f),
map((filters) => [filters.from, filters.to]),
distinctUntilChanged(equal),
map(([from, to]) => [new Date(from).getTime(), new Date(to).getTime()]),
);
this.linearChartsService.colors().pipe(takeUntil(this.chartDestroy$)).subscribe(colors => {
this.updatePads(TAB.filter.chart_type, colors, showLines);
});
combineLatest([borders$, this.everChartFeedService.onEndOfStream()])
.pipe(
takeUntil(this.chartDestroy$),
withLatestFrom(this.chartTrackService.onTrack()),
switchMap(([data, track]) => timer(track ? 300 : 0).pipe(map(() => data))),
distinctUntilChanged(equal),
map(([[from, to], end]) => {
const length = to - from;
const noDataLength = to - end;
return Math.max(0, Math.min((noDataLength / length) * 100, 100));
}),
distinctUntilChanged(),
)
.subscribe((right) => {
this.elementRef.nativeElement.style.setProperty('--end-of-stream-right', `${right}%`);
this.endOfStreamOutOfRange$.next([0, 100].includes(right));
this.showNoData$.next(right === 100);
});
this.everChartFeedService
.onEndOfStream()
.pipe(
debounceTime(400),
takeUntil(this.destroy$),
tap(() =>
this.elementRef.nativeElement.style.setProperty('--end-of-stream-opacity', '1'),
),
delay(300),
)
.subscribe(() => {
this.elementRef.nativeElement.style.setProperty('--end-of-stream-opacity', '0.1');
});
const stopTrack$ = this.chartTrackService.onTrack().pipe(filter((s) => !s));
const loading$ = this.everChartFeedService.onLoading();
this.chartTrackService
.onTrack()
.pipe(
filter(Boolean),
switchMap(() => {
const first$ = this.everChartFeedService.onEndOfStream().pipe(
take(1),
map((time) => [time]),
);
const next$ = combineLatest([
this.everChartFeedService.onEndOfStream().pipe(skip(1)),
loading$,
]).pipe(
filter(([time, loading]) => !loading),
takeUntil(stopTrack$),
);
return merge(first$, next$);
}),
withLatestFrom(this.currentTab$),
takeUntil(this.chartDestroy$),
)
.subscribe(([[time], tab]) => {
const screenSize =
new Date(tab.filter.to).getTime() - new Date(tab.filter.from).getTime();
this.appFacade.dispatchTo(
everChartScrollToTimeAction(time + screenSize * 0.15),
'everChart',
'1',
);
});
}
});
}