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


import { DataSource } from '@core/DataSource';
import { DrawingsManager, DrawingsManagerSnapshot } from '@core/DrawingsManager';
import { Pane, PaneParams } from '@core/Pane';
import { ISerializable, PaneSnapshot } from '@src/types/snapshot';

interface PaneManagerParams extends Omit<PaneParams, 'isMainPane' | 'id' | 'basedOn' | 'onDelete'> {
  panesSnapshot: PaneSnapshot[];
}

// todo: PaneManager, регулирует порядок пейнов. Знает про MainPane.
// todo: Также перекинуть соответствующие/необходимые свойства из чарта, и из чарта удалить
// todo: в CompareManage, при создании нового пейна для сравнения - инициализируем новый dataSource, принадлежащий только конкретному пейну. Убираем возможность добавлять индикаторы на такие пейны
// todo: на каждый символ свой DataSource (учитывать что есть MainPane и "главный" DataSource, который инициализиурется во время старта moexChart)
// todo: сделать два разных представления для compare, в зависимости от отображения на главном пейне или на второстепенном

export class PaneManager implements ISerializable<PaneSnapshot[]> {
  private mainPane: Pane;
  private paneChartInheritedParams: PaneManagerParams & { isMainPane: boolean };
  private panesMap: Map<number, Pane> = new Map<number, Pane>();
  private nextPaneId = 0;

  constructor(params: PaneManagerParams) {
    this.paneChartInheritedParams = { ...params, isMainPane: false };

    this.mainPane = new Pane({ ...params, isMainPane: true, id: 0, onDelete: () => {} });

    this.panesMap.set(this.nextPaneId++, this.mainPane);
    this.setup(params.panesSnapshot);
  }

  private setup(panesSnapshot: PaneSnapshot[]) {
    panesSnapshot.forEach((paneSnap: PaneSnapshot) => {
      const { isMain, id, drawings } = paneSnap;

      this.destroyPane(id, false);

      if (isMain) {
        this.mainPane = new Pane({ ...this.paneChartInheritedParams, isMainPane: true, id: 0, onDelete: () => {} });

        this.panesMap.set(id, this.mainPane);

        this.mainPane.setDrawingsSnapshot(drawings);
      } else {
        const pane = this.addPane(undefined, id);
        pane.setDrawingsSnapshot(drawings);
      }
    });

    this.syncPaneContainers();
  }

  public getPaneById(id: number): Pane | undefined {
    return this.panesMap.get(id);
  }

  public getDrawingsSnapshot(): DrawingsManagerSnapshot {
    return this.mainPane.getDrawingsSnapshot();
  }

  public setDrawingsSnapshot(snapshot: DrawingsManagerSnapshot): void {
    this.mainPane.setDrawingsSnapshot(snapshot);
  }

  public getPanes() {
    return this.panesMap;
  }

  public getMainPane: () => Pane = () => {
    return this.mainPane;
  };

  private destroyPane(id: number, syncAfter = true): void {
    const pane = this.panesMap.get(id);

    if (!pane) {
      return;
    }

    this.panesMap.delete(id);
    pane.destroy();

    if (syncAfter) {
      this.syncPaneContainers();
    }
  }

  public addPane(dataSource?: DataSource, paneId?: number): Pane {
    const id = paneId ?? this.nextPaneId++;
    this.nextPaneId = Math.max(this.nextPaneId, id + 1);

    const newPane = new Pane({
      ...this.paneChartInheritedParams,
      id,
      dataSource: dataSource ?? null,
      basedOn: dataSource ? undefined : this.mainPane,
      onDelete: () => this.destroyPane(id),
    });

    this.panesMap.set(id, newPane);
    this.syncPaneContainers();

    return newPane;
  }

  private syncPaneContainers(): void {
    this.panesMap.forEach((pane) => {
      pane.schedulePaneContainerSync();
    });
  }

  public getDrawingsManager(): DrawingsManager {
    // todo: temp
    return this.mainPane.getDrawingManager();
  }

  public getSnapshot(): PaneSnapshot[] {
    const res: PaneSnapshot[] = [];
    this.panesMap.forEach((pane) => {
      res.push(pane.getSnapshot());
    });

    return res;
  }

  public updatePriceScaleControls(): void {
    this.panesMap.forEach((pane) => {
      pane.updatePriceScaleControls();
    });
  }

  public resetPriceScalesAutoScale(): void {
    this.panesMap.forEach((pane) => {
      pane.resetPriceScalesAutoScale();
    });

    this.updatePriceScaleControls();
  }
}