55 lines
3.1 KiB
Markdown
55 lines
3.1 KiB
Markdown
# Диаграмма распределения портфеля — Спецификация
|
||
|
||
## Обзор
|
||
Добавить аналитическую диаграмму (donut) на страницу детального просмотра портфеля, показывающую распределение стоимости между акциями и облигациями, с количеством позиций в легенде.
|
||
|
||
## Источник данных
|
||
`PortfolioDetail.positions[]` — бэкенд уже возвращает:
|
||
- `type: 'share' | 'bond'`
|
||
- `currentValue: number | null`
|
||
- `quantity: number`
|
||
|
||
Агрегация на клиенте. Изменений бэкенда не требуется.
|
||
|
||
## Компонент: `AllocationChart`
|
||
- Чистый SVG (два сектора + текст в центре)
|
||
- Без внешних зависимостей
|
||
- Размещается внутри `PortfolioSummary` первым ребенком flex-ряда
|
||
- В центре — общая стоимость портфеля (или «Нет позиций»)
|
||
- Справа — легенда с разбивкой по типу: количество / процент
|
||
|
||
### Цветовая схема
|
||
| Сектор | Цвет | Легенда |
|
||
|--------|------|---------|
|
||
| Акции | `var(--color-primary)` / #1976d2 | `Акции: N / XX.X%` |
|
||
| Облигации | #f57c00 | `Облигации: N / XX.X%` |
|
||
|
||
### Состояния
|
||
- **Обычное (оба типа):** две дуги пропорционально стоимости, в центре — сумма
|
||
- **Один тип (только акции или только облигации):** полный круг цветом сектора
|
||
- **Пусто (нет позиций):** серый круг, в центре «Нет позиций»
|
||
|
||
### Расположение
|
||
```
|
||
┌────────────────────────────────────────────────────────┐
|
||
│ [⭕ donut] Общая стоимость Позиций │
|
||
│ [xxx,xxx] xxx,xxx.xx RUB 12 │
|
||
│ Акции: 8 / 70.5% │
|
||
│ Облигации: 4 / 29.5% │
|
||
└────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
## Изменяемые файлы
|
||
|
||
### Новый
|
||
- `apps/frontend/src/components/portfolios/AllocationChart.tsx`
|
||
|
||
### Изменяемый
|
||
- `apps/frontend/src/components/portfolios/PortfolioSummary.tsx` — импорт и рендер `AllocationChart`
|
||
|
||
## Граничные случаи
|
||
|
||
- `currentValue === null` — считается как 0
|
||
- У всех позиций `currentValue === 0` — серый круг, в центре «0»
|
||
- Один из типов отсутствует (0 позиций) — в легенде `0 / 0.0%`, дуга заполняет 100% для непустого типа
|