// portfolio-chart.jsx — динамика стоимости портфеля во времени. // Чистый SVG без внешних библиотек (CSP пускает только self + unpkg). // Exports to window: HistoryChart // // props: // points — [{date: "YYYY-MM-DD", net_value_usd: number}], по возрастанию даты // cur — символ валюты пользователя ('$', '€', ...) для подписей // fx — USD за 1 единицу валюты пользователя (для пересчёта в валюту учёта) const RANGES = [ { days: 7, label: "7д" }, { days: 30, label: "30д" }, { days: 90, label: "90д" }, ]; function HistoryChart({ points, cur = "$", fx = 1 }) { const { useState } = React; const [days, setDays] = useState(30); const all = points || []; if (all.length < 2) return null; // Фильтруем по выбранному диапазону (данные приходят за макс. период разом). const cutoff = new Date(); cutoff.setDate(cutoff.getDate() - days); let series = all.filter((p) => new Date(p.date) >= cutoff); if (series.length < 2) series = all; // в выбранном окне мало точек — показываем всё const values = series.map((p) => p.net_value_usd); const lo = Math.min(...values); const hi = Math.max(...values); const span = hi - lo || 1; // Геометрия SVG (viewBox-координаты; ширина тянется через width=100%). const W = 320, H = 120, padX = 6, padY = 10; const innerW = W - padX * 2; const innerH = H - padY * 2; const xy = (v, i) => { const x = padX + (series.length === 1 ? 0 : (i / (series.length - 1)) * innerW); const y = padY + (1 - (v - lo) / span) * innerH; return [x, y]; }; const linePts = values.map((v, i) => xy(v, i)); const linePath = linePts.map(([x, y], i) => (i === 0 ? "M" : "L") + x.toFixed(1) + " " + y.toFixed(1)).join(" "); const areaPath = linePath + ` L${(padX + innerW).toFixed(1)} ${(padY + innerH).toFixed(1)}` + ` L${padX.toFixed(1)} ${(padY + innerH).toFixed(1)} Z`; const first = values[0]; const last = values[values.length - 1]; const up = last >= first; const stroke = up ? "var(--pos)" : "var(--neg)"; const change = last - first; const changePct = first > 0 ? (change / first) * 100 : 0; // Стоимость в валюте пользователя (значения снапшота — в USD). const toCur = (usd) => (fx > 0 ? usd / fx : usd); const gid = "pf-chart-grad-" + (up ? "u" : "d"); return (