import type { BrokerPortfolio } from '../../../api/responses'; import { buildBrokerAllocation, type BrokerAllocationItem, } from '../../../entities/broker-position'; const RADIUS = 44; const CIRCUMFERENCE = 2 * Math.PI * RADIUS; function formatMoneyValue(value: number, currency: string) { return new Intl.NumberFormat('ru-RU', { style: 'currency', currency, maximumFractionDigits: 2, }).format(value); } function allocationCurrency(portfolio: BrokerPortfolio) { return ( portfolio.totals.portfolio?.currency || Object.values(portfolio.totals).find((total) => total?.currency)?.currency || 'RUB' ); } export function BrokerAllocationBar({ items, title, }: { items: BrokerAllocationItem[]; title: string; }) { const positiveItems = items.filter((item) => item.value > 0); if (positiveItems.length === 0) { return

Нет данных для распределения

; } return (
{positiveItems.map((item) => (
); } export function BrokerAllocationChart({ portfolio }: { portfolio: BrokerPortfolio }) { const { sectors, negative } = buildBrokerAllocation(portfolio); const currency = allocationCurrency(portfolio); let remaining = CIRCUMFERENCE; const arcs = sectors.map((sector) => { const dashOffset = -(CIRCUMFERENCE - remaining); const rawDashLength = (sector.percent / 100) * CIRCUMFERENCE; const dashLength = Math.min(Math.max(rawDashLength, 0), remaining); remaining = Math.max(0, remaining - dashLength); return { ...sector, dashOffset, dashLength }; }); return (
Структура брокерского портфеля {arcs.map((sector) => ( ))}
{sectors.length === 0 ? (

Нет данных для распределения

) : ( )} {negative.length > 0 && ( )}
); }