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


import { Locale } from '@lib';
import { Ohlc } from '@src/core/Legend';

import { getThemeStore } from '@src/theme/store';
import { getLocale } from '@src/translations';

import { getPercentPrecision, getPricePrecision } from '@src/utils/precision';

import { isBarData } from './typeGuards';

export function formatCompactNumber(
  value: number,
  locale: Locale = getLocale(),
  maxFractionDigits: number = getPricePrecision(),
): string {
  const unitList: { divisor: number; suffix: string }[] = [
    { divisor: 1, suffix: '' },
    { divisor: 1_000, suffix: 'k' },
    { divisor: 1_000_000, suffix: 'm' },
    { divisor: 1_000_000_000, suffix: 'b' },
    { divisor: 1_000_000_000_000, suffix: 't' },
  ];

  let selectedUnit = unitList[0];
  for (let i = unitList.length - 1; i >= 0; i--) {
    if (Math.abs(value) >= unitList[i].divisor) {
      selectedUnit = unitList[i];
      break;
    }
  }
  const divided = value / selectedUnit.divisor;

  const formatter = new Intl.NumberFormat(locale, {
    maximumFractionDigits: maxFractionDigits,
    minimumFractionDigits: 0,
    useGrouping: false,
  });
  const formattedNumber = formatter.format(divided);

  return formattedNumber + selectedUnit.suffix;
}

export const formatPrice = (price?: number | string, precision = getPricePrecision()): string | undefined => {
  if (price === undefined) {
    return undefined;
  }

  return Number(price)
    .toFixed(precision)
    .replace(/\.?0+$/, '');
};

export const formatPercent = (value: number, precision = getPercentPrecision()): string => {
  if (!Number.isFinite(value)) {
    return '0%';
  }

  return `${value.toFixed(precision)}%`;
};

export const formatSignedNumber = (value: number): string => {
  if (!Number.isFinite(value)) {
    return '0';
  }

  const formatted = formatPrice(Math.abs(value)) ?? '0';

  return value < 0 ? `-${formatted}` : formatted;
};

export const formatVolume = (volume?: number): string => {
  if (!volume) return '';

  if (volume >= 1000000) {
    return `${(volume / 1000000).toFixed(1).replace(/\.0$/, '')}M`;
  }

  if (volume >= 1000) {
    return `${(volume / 1000).toFixed(1).replace(/\.0$/, '')}K`;
  }

  return volume.toString();
};

export function getPriceColor(ohlc: Ohlc | null, upColor?: string, downColor?: string): string {
  if (!ohlc) return '';

  const { colors } = getThemeStore();

  const positiveColor = upColor ?? colors.chartCandleUp;
  const negativeColor = downColor ?? colors.chartCandleDown;

  if (ohlc.open && ohlc.close && isBarData(ohlc)) {
    return ohlc.close >= ohlc.open ? positiveColor : negativeColor;
  }

  if (typeof ohlc.absoluteChange === 'number') {
    return ohlc.absoluteChange >= 0 ? positiveColor : negativeColor;
  }

  return '';
}