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


private setupDataSourceSubs(): void {
  const getWarmupFrom = (): number => {
    if (
      this.currentInterval &&
      this.currentInterval !== Intervals.All
    ) {
      return getIntervalRange(
        this.currentInterval,
      ).from;
    }

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

    if (!range) return 0;

    const { from } =
      range as IRange<number>;

    return from;
  };

  const warmupSymbolIds = (
    symbolIds: string[],
  ): void => {
    if (!symbolIds.length) return;

    const from = getWarmupFrom();

    if (!from) return;

    Promise.all(
      symbolIds.map((symbolId) =>
        this.dataSource.loadTill(
          symbolId,
          from,
        ),
      ),
    ).catch((error) => {
      console.error(
        '[Chart] Ошибка при прогреве символов:',
        error,
      );
    });
  };

  const symbolIds$ = combineLatest([
    this.eventManager.symbolId(),
    this.compareManager.itemsObs(),
  ]).pipe(
    map(([mainSymbolId, items]) =>
      Array.from(
        new Set([
          mainSymbolId,
          ...items.map(
            ({ symbolId }) =>
              symbolId,
          ),
        ]),
      ),
    ),
  );

  this.subscriptions.add(
    this.eventManager
      .getInterval()
      .pipe(withLatestFrom(symbolIds$))
      .subscribe(
        ([interval, symbolIds]) => {
          this.currentInterval = interval;

          if (!interval) return;

          if (
            interval === Intervals.All
          ) {
            Promise.all(
              symbolIds.map(
                (symbolId) =>
                  this.dataSource.loadAllHistory(
                    symbolId,
                  ),
              ),
            )
              .then(() => {
                requestAnimationFrame(
                  () =>
                    this.lwcChart
                      .timeScale()
                      .fitContent(),
                );
              })
              .catch((error) =>
                console.error(
                  '[Chart] Ошибка при загрузке всей истории:',
                  error,
                ),
              );

            return;
          }

          const { from, to } =
            getIntervalRange(interval);

          Promise.all(
            symbolIds.map(
              (symbolId) =>
                this.dataSource.loadTill(
                  symbolId,
                  from,
                ),
            ),
          )
            .then(() => {
              this.lwcChart
                .timeScale()
                .setVisibleRange({
                  from: from as Time,
                  to: to as Time,
                });
            })
            .catch((error) => {
              console.error(
                '[Chart] Ошибка при применении интервала:',
                error,
              );
            });
        },
      ),
  );

  this.subscriptions.add(
    symbolIds$.subscribe(
      (symbolIds) => {
        const previousSymbolIds =
          this.activeSymbolIds;

        this.activeSymbolIds =
          symbolIds;

        this.dataSource.setSymbols(
          symbolIds,
        );

        const previousSymbolIdsSet =
          new Set(previousSymbolIds);

        const addedSymbolIds: string[] =
          [];

        for (
          let index = 0;
          index < symbolIds.length;
          index += 1
        ) {
          const symbolId =
            symbolIds[index];

          if (!symbolId) continue;

          if (
            previousSymbolIdsSet.has(
              symbolId,
            )
          ) {
            continue;
          }

          addedSymbolIds.push(
            symbolId,
          );
        }

        if (addedSymbolIds.length) {
          warmupSymbolIds(
            addedSymbolIds,
          );
        }
      },
    ),
  );
}