Загрузка данных


private scheduleHistoryBatch(): void {
  if (
    this.subscriptions.closed ||
    this.historyBatchRunning ||
    this.activeSymbolIds.length === 0 ||
    this.currentInterval === Intervals.All
  ) {
    return;
  }

  this.historyBatchRunning = true;

  requestAnimationFrame(() => {
    if (this.subscriptions.closed || this.currentInterval === Intervals.All) {
      this.historyBatchRunning = false;

      return;
    }

    const symbolIds = this.activeSymbolIds.slice();
    const timeframe = this.eventManager.getTimeframe();
    const oldestTimes = symbolIds.map((symbolId) => this.dataSource.getOldestTime(symbolId));

    Promise.all(symbolIds.map((symbolId) => this.dataSource.loadMoreHistory(symbolId))).finally(() => {
      this.finishHistoryBatch(symbolIds, oldestTimes, timeframe);
    });
  });
}

private finishHistoryBatch(
  symbolIds: string[],
  oldestTimes: (number | null)[],
  timeframe: ReturnType<EventManager['getTimeframe']>,
): void {
  this.historyBatchRunning = false;

  if (this.subscriptions.closed || this.currentInterval === Intervals.All) {
    return;
  }

  const contextChanged =
    timeframe !== this.eventManager.getTimeframe() || !sameSymbolIds(symbolIds, this.activeSymbolIds);

  const hasProgress = this.hasHistoryProgress(symbolIds, oldestTimes);

  if (!contextChanged && !hasProgress) {
    return;
  }

  const range = this.lwcChart.timeScale().getVisibleLogicalRange();

  if (range && range.from < HISTORY_LOAD_THRESHOLD) {
    this.scheduleHistoryBatch();
  }
}

private hasHistoryProgress(symbolIds: string[], oldestTimes: (number | null)[]): boolean {
  return symbolIds.some((symbolId, index) => {
    if (!this.activeSymbolIds.includes(symbolId)) {
      return false;
    }

    const previousOldestTime = oldestTimes[index];
    const currentOldestTime = this.dataSource.getOldestTime(symbolId);

    return currentOldestTime !== null && (previousOldestTime === null || currentOldestTime < previousOldestTime);
  });
}