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


import { MoexChart, Timeframes } from 'moex-chart';
import type { IMoexChart } from 'moex-chart';

// eslint-disable-next-line import/no-unresolved -- MOEX_CHART
import { CompareManager } from 'moex-chart/dist/types/core/CompareManager';
import { useEffect, useRef, useState } from 'react';

import { useChangeProperties, useSelectProperties } from '@modules/widgetProperties';
import { ChartIndicativeData, ChartProps } from '@widgets/Chart/types';

import { MOEX_CHART_CONFIG } from '../constants';
import { dataSourceProvider, DataSourceProvider } from '../dataSourceProvide';

type TUseMoexChartProps = {
  symbol: string;
  indicativeData: ChartIndicativeData | undefined;
};

export const useMoexChart = ({ symbol, indicativeData }: TUseMoexChartProps) => {
  const moexChartTimeFrame = useSelectProperties((wProps: Partial<ChartProps>) => wProps.moexChartState?.tf);

  const { updateProperties } = useChangeProperties<ChartProps>();

  const [isCompareOpen, setIsCompareOpen] = useState(false);

  const containerRef = useRef<HTMLDivElement | null>(null);
  const compareManagerRef = useRef<null | CompareManager>(null);
  const timeframeRef = useRef<Timeframes | undefined>(moexChartTimeFrame);
  const updateTimeframeRef = useRef<(tf: Timeframes) => void>(() => undefined);

  useEffect(() => {
    timeframeRef.current = moexChartTimeFrame;
  }, [moexChartTimeFrame]);

  updateTimeframeRef.current = (tf: Timeframes) => {
    if (timeframeRef.current === tf) {
      return;
    }

    timeframeRef.current = tf;

    updateProperties((state) => {
      if (state.moexChartState) {
        state.moexChartState.tf = tf;
        return;
      }

      state.moexChartState = {
        tf,
      };
    });
  };

  useEffect(() => {
    const container = containerRef.current;

    if (!container) {
      return undefined;
    }

    const initialTimeframe = timeframeRef.current || Timeframes['1m'];

    const charts: IMoexChart['snapshot']['charts'] = MOEX_CHART_CONFIG.snapshot.charts.map(
      (chartSnapshot, index): IMoexChart['snapshot']['charts'][number] => ({
        ...chartSnapshot,
        symbol: index === 0 || !('symbol' in chartSnapshot) ? symbol : chartSnapshot.symbol,
        timeframe:
          index === 0 || !('timeframe' in chartSnapshot)
            ? initialTimeframe
            : chartSnapshot.timeframe,
      }),
    );

    const chart = new MoexChart({
      ...MOEX_CHART_CONFIG,

      container,

      snapshot: {
        ...MOEX_CHART_CONFIG.snapshot,
        charts,
      },

      chartCollectionPreset: {
        ...MOEX_CHART_CONFIG.chartCollectionPreset,

        openCompareModal: () => setIsCompareOpen(true),

        getDataSource: DataSourceProvider.getDataSource(indicativeData, (tf) => {
          updateTimeframeRef.current(tf);
        }),

        startRealtime: (getSymbols, getTimeframe, update) =>
          dataSourceProvider.startRealtime({
            getSymbols,
            getTimeframe,
            update,
          }),
      },
    });

    compareManagerRef.current = chart.getCompareManager();

    return () => {
      compareManagerRef.current = null;
      chart.destroy();
    };
  }, [symbol, indicativeData]);

  return {
    containerRef,
    isCompareOpen,
    compareManagerRef,
    setIsCompareOpen,
  };
};