Загрузка данных
import { Button } from 'exchange-elements/v2';
import { GearIcon, TrashIcon } from '@src/components/Icon';
import { LegendValueItem } from '@src/types';
import styles from './index.module.scss';
interface LegendSeriesRowProps {
label: string;
values?: LegendValueItem[];
onRemove?: () => void;
onEdit?: () => void;
}
export function LegendSeriesRow({ label, values, onRemove, onEdit }: LegendSeriesRowProps) {
return (
<div className={styles.item}>
<div className={styles.symbol}>{label}</div>
<div className={styles.priceWrapper}>
{values?.map(({ id, value, color }) => (
<span
key={id}
style={{ color }}
className={styles.price}
>
{value}
</span>
))}
{onEdit && (
<Button
size="sm"
className={styles.button}
onClick={onEdit}
label={<GearIcon />}
/>
)}
{onRemove && (
<Button
size="sm"
className={styles.button}
onClick={onRemove}
label={<TrashIcon />}
/>
)}
</div>
</div>
);
}
import { Observable } from 'rxjs';
import { LegendSeriesRow } from '@src/components/LegendSeriesRow';
import { IndicatorsIds } from '@src/core/Indicators';
import { CompareMode, LegendVM, OHLCConfig } from '../../types';
import { formatPrice, getPriceColor, useObservable } from '../../utils';
import styles from './index.module.scss';
export interface LegendProps {
ohlcConfig?: OHLCConfig;
viewModel: Observable<LegendVM>;
onCompareRemove?: (symbol: string, mode: CompareMode) => void;
onIndicatorEdit?: (indicator: IndicatorsIds) => void;
onIndicatorRemove?: (indicatorId: IndicatorsIds) => void;
}
export const LegendComponent = ({
ohlcConfig,
viewModel: vm,
onCompareRemove,
onIndicatorRemove,
onIndicatorEdit,
}: LegendProps) => {
const viewModel = useObservable(vm);
const ohlc = viewModel?.ohlc ?? null;
const symbol = viewModel?.symbol ?? null;
const compareItems = viewModel?.compareItems ?? [];
const indicatorItems = viewModel?.indicatorItems ?? [];
const showOhlc = ohlcConfig?.show;
const priceColor = getPriceColor(ohlc);
const renderLegendItem = (label: string, value?: string | number, show = true) => {
if (!show || !value) return null;
return (
<div className={styles.item}>
{label} <span style={{ color: priceColor }}>{value}</span>
</div>
);
};
return (
<section className={styles.legend}>
<div className={styles.row}>
{symbol && <div className={styles.symbol}>{symbol}</div>}
{showOhlc && (
<>
{renderLegendItem('Отк.', formatPrice(ohlc?.open), !!ohlc?.open)}
{renderLegendItem('Макс.', formatPrice(ohlc?.high), !!ohlc?.high)}
{renderLegendItem('Мин.', formatPrice(ohlc?.low), !!ohlc?.low)}
{renderLegendItem('Закр.', formatPrice(ohlc?.close), !!ohlc?.close)}
{renderLegendItem(
'Изм.',
`${formatPrice(ohlc?.percentageChange)}%`,
!!ohlc?.absoluteChange && !!ohlc?.percentageChange,
)}
</>
)}
</div>
{indicatorItems.map(({ id, label, values }) => (
<LegendSeriesRow
key={id}
label={label}
values={values}
onEdit={() => onIndicatorEdit?.(id)}
onRemove={() => onIndicatorRemove?.(id)}
/>
))}
{compareItems.map(({ symbol: itemSymbol, mode, values }) => (
<LegendSeriesRow
key={`${itemSymbol}|${mode}`}
label={itemSymbol}
values={values}
onRemove={() => onCompareRemove?.(itemSymbol, mode)}
/>
))}
</section>
);
};